@sanity/cli 7.12.1 → 7.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +88 -0
- package/dist/actions/api/constants.js +13 -0
- package/dist/actions/api/constants.js.map +1 -0
- package/dist/actions/api/distillApiRoutes.js +106 -0
- package/dist/actions/api/distillApiRoutes.js.map +1 -0
- package/dist/actions/api/errors.js +18 -0
- package/dist/actions/api/errors.js.map +1 -0
- package/dist/actions/api/parseFields.js +183 -0
- package/dist/actions/api/parseFields.js.map +1 -0
- package/dist/actions/api/resolveEndpoint.js +159 -0
- package/dist/actions/api/resolveEndpoint.js.map +1 -0
- package/dist/actions/api/types.js +10 -0
- package/dist/actions/api/types.js.map +1 -0
- package/dist/actions/auth/getProviderName.js +13 -0
- package/dist/actions/auth/getProviderName.js.map +1 -1
- package/dist/actions/build/buildApp.js +3 -1
- package/dist/actions/build/buildApp.js.map +1 -1
- package/dist/actions/build/buildStudio.js +104 -13
- package/dist/actions/build/buildStudio.js.map +1 -1
- package/dist/actions/build/eventListenerFactory.js +70 -0
- package/dist/actions/build/eventListenerFactory.js.map +1 -0
- package/dist/actions/debug/types.js.map +1 -1
- package/dist/actions/deploy/deployApp.js +1 -0
- package/dist/actions/deploy/deployApp.js.map +1 -1
- package/dist/actions/deploy/deployChecks.js +25 -4
- package/dist/actions/deploy/deployChecks.js.map +1 -1
- package/dist/actions/deploy/resolveDeployTarget.js +23 -4
- package/dist/actions/deploy/resolveDeployTarget.js.map +1 -1
- package/dist/actions/dev/servers/startStudioDevServer.js +5 -1
- package/dist/actions/dev/servers/startStudioDevServer.js.map +1 -1
- package/dist/actions/init/initAction.js +3 -3
- package/dist/actions/init/initAction.js.map +1 -1
- package/dist/commands/api.js +294 -0
- package/dist/commands/api.js.map +1 -0
- package/dist/commands/cors/add.js +13 -7
- package/dist/commands/cors/add.js.map +1 -1
- package/dist/commands/datasets/copy.js +6 -3
- package/dist/commands/datasets/copy.js.map +1 -1
- package/dist/commands/debug.js +1 -1
- package/dist/commands/debug.js.map +1 -1
- package/dist/exports/invokeSanityCli/commandPolicies/index.js +6 -0
- package/dist/exports/invokeSanityCli/commandPolicies/index.js.map +1 -0
- package/dist/exports/invokeSanityCli/commandPolicies/mcpPolicy.js +167 -0
- package/dist/exports/invokeSanityCli/commandPolicies/mcpPolicy.js.map +1 -0
- package/dist/exports/invokeSanityCli/commandPolicies/policy.js +46 -0
- package/dist/exports/invokeSanityCli/commandPolicies/policy.js.map +1 -0
- package/dist/exports/invokeSanityCli/help.js +146 -0
- package/dist/exports/invokeSanityCli/help.js.map +1 -0
- package/dist/exports/invokeSanityCli/index.d.ts +60 -0
- package/dist/exports/invokeSanityCli/index.js +177 -0
- package/dist/exports/invokeSanityCli/index.js.map +1 -0
- package/dist/generated/apiRoutes.js +401 -0
- package/dist/generated/apiRoutes.js.map +1 -0
- package/dist/server/devServer.js +16 -2
- package/dist/server/devServer.js.map +1 -1
- package/dist/services/api.js +116 -0
- package/dist/services/api.js.map +1 -0
- package/dist/util/getProjectDefaults.js +4 -1
- package/dist/util/getProjectDefaults.js.map +1 -1
- package/dist/util/packageManager/preferredPm.js +45 -6
- package/dist/util/packageManager/preferredPm.js.map +1 -1
- package/oclif.manifest.json +709 -528
- package/package.json +14 -7
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/actions/api/resolveEndpoint.ts"],"sourcesContent":["import {parse} from 'node:querystring'\n\nimport {API_DEFAULT_VERSION, API_VERSION_SEGMENT_RE} from './constants.js'\nimport {ApiUsageError, ProjectIdRequiredError} from './errors.js'\nimport {type ApiHost, type ApiRouteEntry} from './types.js'\n\n/**\n * Options for {@link resolveEndpoint}.\n */\nexport interface ResolveEndpointOptions {\n /** The endpoint argument: a path, optionally with placeholders, or a full URL. */\n endpoint: string\n\n /** The generated routing manifest. */\n routes: ApiRouteEntry[]\n\n /** Explicit API version (`--api-version`), wins over everything else. */\n apiVersion?: string\n\n /** Dataset used to fill `{dataset}` / `{datasetName}` placeholders. */\n dataset?: string\n\n /** Force a host family (`--global` / `--project-hosted`), restricting route matching to it. */\n forceHost?: ApiHost\n\n /** Project ID used to fill `{projectId}` placeholders and project-hosted requests. */\n projectId?: string\n}\n\n/**\n * A fully resolved request target.\n */\nexport type ResolvedEndpoint =\n | {\n /** API version path segment, eg `v2021-06-07`. */\n apiVersion: string\n host: ApiHost\n kind: 'path'\n /** Slug of the OpenAPI spec whose paths matched, if any. */\n matchedSlug?: string\n /** Version-less path, without leading slash. */\n path: string\n /** Project ID; always set when `host` is `project`. */\n projectId?: string\n /** Query parameters parsed from the endpoint argument. */\n query: Record<string, string | string[]>\n }\n | {\n kind: 'url'\n query: Record<string, string | string[]>\n /** Absolute URL, used verbatim (query string stripped into `query`). */\n url: string\n }\n\nconst PLACEHOLDER_RE = /^\\{([^{}]+)\\}$/\n\nconst ALLOWED_URL_HOST_RE = /(?:^|\\.)api\\.sanity\\.(?:io|work)$/\n\n/**\n * Resolve the endpoint argument of `sanity api` into a concrete request\n * target: substitute placeholders, split off the query string, determine the\n * host family (via the generated OpenAPI routing manifest) and the API\n * version.\n *\n * Throws {@link ProjectIdRequiredError} when the request needs a project ID\n * that hasn't been provided - the command catches this to resolve one (flags,\n * CLI config or interactive prompt) and retries.\n */\nexport function resolveEndpoint(options: ResolveEndpointOptions): ResolvedEndpoint {\n const {apiVersion, dataset, endpoint, forceHost, projectId, routes} = options\n\n if (/^https?:\\/\\//.test(endpoint)) {\n return resolveUrlEndpoint(endpoint)\n }\n\n const [pathPart = '', ...queryParts] = endpoint.split('?')\n const query = parseQueryString(queryParts.join('?'))\n\n const segments = pathPart.split('/').filter((segment) => segment !== '')\n\n // An API version embedded in the path (eg `v2021-06-07/projects`) is peeled\n // off and re-applied as the version segment of the final URL.\n let embeddedVersion: string | undefined\n if (segments[0] === '{apiVersion}') {\n segments.shift()\n } else if (segments.length > 0 && API_VERSION_SEGMENT_RE.test(segments[0])) {\n embeddedVersion = segments.shift()\n }\n\n // Checked after version peeling so a bare version (eg `v2025-02-19`) is\n // also rejected as an empty path.\n if (segments.length === 0) {\n throw new ApiUsageError('Endpoint path is empty')\n }\n\n const unresolved: string[] = []\n const substituted = segments.map((segment, index) => {\n const placeholder = PLACEHOLDER_RE.exec(segment)?.[1]\n if (!placeholder) return segment\n if (placeholder === 'projectId') {\n if (!projectId) throw new ProjectIdRequiredError()\n return projectId\n }\n // The projects spec names the dataset placeholder `{name}` (eg\n // `projects/{projectId}/datasets/{name}`) - only that context is a\n // dataset; `{name}` elsewhere (eg video renditions) stays unresolved.\n const isDatasetName = placeholder === 'name' && segments[index - 1] === 'datasets'\n if (placeholder === 'dataset' || placeholder === 'datasetName' || isDatasetName) {\n if (!dataset) {\n throw new ApiUsageError(\n `Unable to resolve {${placeholder}} - provide a dataset with --dataset or configure one in sanity.cli.ts`,\n )\n }\n return dataset\n }\n unresolved.push(segment)\n return segment\n })\n\n if (unresolved.length > 0) {\n throw new ApiUsageError(\n `Unable to resolve placeholder(s) ${unresolved.join(', ')} - replace them with actual values`,\n )\n }\n\n // Forcing a host restricts matching to specs served on that host, so the\n // matched spec's default API version still applies when one exists there.\n const candidates = forceHost ? routes.filter((entry) => entry.host === forceHost) : routes\n const match = matchRoutes(substituted, candidates)\n const host = forceHost ?? match?.host ?? 'global'\n\n if (host === 'project' && !projectId) {\n throw new ProjectIdRequiredError()\n }\n\n return {\n apiVersion: apiVersion ?? embeddedVersion ?? match?.defaultApiVersion ?? API_DEFAULT_VERSION,\n host,\n kind: 'path',\n matchedSlug: match?.slug,\n path: substituted.join('/'),\n ...(host === 'project' ? {projectId} : {}),\n query,\n }\n}\n\nfunction resolveUrlEndpoint(endpoint: string): ResolvedEndpoint {\n let url: URL\n try {\n url = new URL(endpoint)\n } catch {\n throw new ApiUsageError(`Invalid URL \"${endpoint}\"`)\n }\n\n // Never put the token on the wire unencrypted\n if (url.protocol !== 'https:') {\n throw new ApiUsageError(\n `Refusing to send requests over \"${url.protocol}//\" - only https:// URLs are supported`,\n )\n }\n\n if (!ALLOWED_URL_HOST_RE.test(url.hostname)) {\n throw new ApiUsageError(\n `Refusing to send authenticated requests to \"${url.hostname}\" - only *.api.sanity.io hosts are supported`,\n )\n }\n\n const query = parseQueryString(url.search.replace(/^\\?/, ''))\n url.search = ''\n\n return {kind: 'url', query, url: url.toString()}\n}\n\ninterface RouteMatch {\n host: ApiHost\n score: number\n slug: string\n\n defaultApiVersion?: string\n}\n\n/**\n * Find the route entry whose path pattern best matches the request segments.\n *\n * A pattern only matches when the request path consumes it completely, and\n * segments are compared pairwise: literal matches score higher than\n * placeholder matches, and a literal mismatch disqualifies the pattern. On\n * equal scores across hosts the global host wins (APIs served on both hosts\n * don't need a project ID there); on equal scores within the same host the\n * first entry wins, keeping the result independent of later entries.\n */\nfunction matchRoutes(segments: string[], routes: ApiRouteEntry[]): RouteMatch | undefined {\n let best: RouteMatch | undefined\n\n for (const entry of routes) {\n for (const pattern of entry.pathPatterns) {\n const score = scorePattern(segments, pattern.split('/'))\n if (score === 0) continue\n const isBetter =\n !best ||\n score > best.score ||\n (score === best.score && best.host === 'project' && entry.host === 'global')\n if (isBetter) {\n best = {\n defaultApiVersion: entry.defaultApiVersion,\n host: entry.host,\n score,\n slug: entry.slug,\n }\n }\n }\n }\n\n return best\n}\n\nfunction scorePattern(segments: string[], patternSegments: string[]): number {\n // A pattern only matches when the request path consumes it completely - a\n // request that is a mere prefix of a longer pattern (eg `data` vs\n // `data/query/{dataset}`) must not inherit that route's host or version.\n if (patternSegments.length > segments.length) return 0\n\n let score = 0\n let literalMatches = 0\n\n for (const [index, patternSegment] of patternSegments.entries()) {\n if (PLACEHOLDER_RE.test(patternSegment)) {\n score += 1\n } else if (patternSegment === segments[index]) {\n score += 2\n literalMatches += 1\n } else {\n return 0\n }\n }\n\n // Require at least one literal segment match so a placeholder-only pattern\n // like `{resourceType}/{resourceId}` can't capture arbitrary paths.\n return literalMatches === 0 ? 0 : score\n}\n\nfunction parseQueryString(queryString: string): Record<string, string | string[]> {\n // node:querystring collects repeated keys into arrays and returns a\n // null-prototype object, so user-supplied keys like `__proto__` stay\n // ordinary own properties. Parsed values are never `undefined`, hence the\n // narrowing cast.\n return parse(queryString) as Record<string, string | string[]>\n}\n"],"names":["parse","API_DEFAULT_VERSION","API_VERSION_SEGMENT_RE","ApiUsageError","ProjectIdRequiredError","PLACEHOLDER_RE","ALLOWED_URL_HOST_RE","resolveEndpoint","options","apiVersion","dataset","endpoint","forceHost","projectId","routes","test","resolveUrlEndpoint","pathPart","queryParts","split","query","parseQueryString","join","segments","filter","segment","embeddedVersion","shift","length","unresolved","substituted","map","index","placeholder","exec","isDatasetName","push","candidates","entry","host","match","matchRoutes","defaultApiVersion","kind","matchedSlug","slug","path","url","URL","protocol","hostname","search","replace","toString","best","pattern","pathPatterns","score","scorePattern","isBetter","patternSegments","literalMatches","patternSegment","entries","queryString"],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Which Sanity API host family a request targets.
|
|
3
|
+
*
|
|
4
|
+
* - `global` - `https://api.sanity.io` (projects, organizations, jobs, ...)
|
|
5
|
+
* - `project` - `https://<projectId>.api.sanity.io` (data, agent actions, assets, ...)
|
|
6
|
+
*/ /**
|
|
7
|
+
* Minimal shape of an OpenAPI document needed to distill routing information.
|
|
8
|
+
*/ export { };
|
|
9
|
+
|
|
10
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/actions/api/types.ts"],"sourcesContent":["/**\n * Which Sanity API host family a request targets.\n *\n * - `global` - `https://api.sanity.io` (projects, organizations, jobs, ...)\n * - `project` - `https://<projectId>.api.sanity.io` (data, agent actions, assets, ...)\n */\nexport type ApiHost = 'global' | 'project'\n\n/**\n * A single API family entry in the generated routing manifest, distilled from\n * a published OpenAPI specification.\n */\nexport interface ApiRouteEntry {\n /** Which host family serves these paths. */\n host: ApiHost\n\n /**\n * Normalized path patterns for the endpoints in this spec: no leading slash and\n * no API version segment. Placeholders (eg `{dataset}`) match any path segment.\n */\n pathPatterns: string[]\n\n /** Spec slug, as used by `sanity openapi get <slug>`. */\n slug: string\n\n /** Human-readable spec title. */\n title: string\n\n /**\n * Default API version declared by the spec's server template (eg `v2021-06-07`),\n * if any.\n */\n defaultApiVersion?: string\n}\n\n/**\n * Minimal shape of an OpenAPI document needed to distill routing information.\n */\nexport interface OpenApiDocument {\n info?: {title?: string}\n paths?: Record<string, unknown>\n servers?: OpenApiServer[]\n}\n\n/**\n * An OpenAPI server entry (subset).\n */\ninterface OpenApiServer {\n url: string\n\n variables?: Record<string, {default?: string}>\n}\n"],"names":[],"mappings":"AAAA;;;;;CAKC,GA8BD;;CAEC,GACD,WAIC"}
|
|
@@ -8,8 +8,21 @@
|
|
|
8
8
|
if (provider === 'google') return 'Google';
|
|
9
9
|
if (provider === 'github') return 'GitHub';
|
|
10
10
|
if (provider === 'sanity') return 'Email';
|
|
11
|
+
if (provider === 'sanity-token') return 'an API token';
|
|
11
12
|
if (provider.startsWith('saml-')) return 'SAML';
|
|
12
13
|
return provider.charAt(0).toUpperCase() + provider.slice(1);
|
|
13
14
|
}
|
|
15
|
+
/**
|
|
16
|
+
* Get a human-readable identifier for a user, preferring email.
|
|
17
|
+
*
|
|
18
|
+
* API tokens resolve to a user with a null `email`, so falling back to the
|
|
19
|
+
* name (and finally the id) keeps a literal "null" out of user-facing output.
|
|
20
|
+
*
|
|
21
|
+
* @param user - The user to describe.
|
|
22
|
+
* @returns The user's email, or their name, or their id.
|
|
23
|
+
* @internal
|
|
24
|
+
*/ export function getUserDisplayName(user) {
|
|
25
|
+
return user.email || user.name || user.id;
|
|
26
|
+
}
|
|
14
27
|
|
|
15
28
|
//# sourceMappingURL=getProviderName.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/actions/auth/getProviderName.ts"],"sourcesContent":["/**\n * Try to get a (prettier) name for a provider by ID.\n *\n * @param provider - The provider ID, e.g., 'google', 'github', 'sanity', or 'saml-<name>'.\n * @returns The display name for the provider.\n * @internal\n */\nexport function getProviderName(provider: string): string {\n if (provider === 'google') return 'Google'\n if (provider === 'github') return 'GitHub'\n if (provider === 'sanity') return 'Email'\n if (provider.startsWith('saml-')) return 'SAML'\n return provider.charAt(0).toUpperCase() + provider.slice(1)\n}\n"],"names":["getProviderName","provider","startsWith","charAt","toUpperCase","slice"],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../../../src/actions/auth/getProviderName.ts"],"sourcesContent":["import {type SanityOrgUser} from '@sanity/cli-core'\n\n/**\n * Try to get a (prettier) name for a provider by ID.\n *\n * @param provider - The provider ID, e.g., 'google', 'github', 'sanity', or 'saml-<name>'.\n * @returns The display name for the provider.\n * @internal\n */\nexport function getProviderName(provider: string): string {\n if (provider === 'google') return 'Google'\n if (provider === 'github') return 'GitHub'\n if (provider === 'sanity') return 'Email'\n if (provider === 'sanity-token') return 'an API token'\n if (provider.startsWith('saml-')) return 'SAML'\n return provider.charAt(0).toUpperCase() + provider.slice(1)\n}\n\n/**\n * Get a human-readable identifier for a user, preferring email.\n *\n * API tokens resolve to a user with a null `email`, so falling back to the\n * name (and finally the id) keeps a literal \"null\" out of user-facing output.\n *\n * @param user - The user to describe.\n * @returns The user's email, or their name, or their id.\n * @internal\n */\nexport function getUserDisplayName(user: SanityOrgUser): string {\n return user.email || user.name || user.id\n}\n"],"names":["getProviderName","provider","startsWith","charAt","toUpperCase","slice","getUserDisplayName","user","email","name","id"],"mappings":"AAEA;;;;;;CAMC,GACD,OAAO,SAASA,gBAAgBC,QAAgB;IAC9C,IAAIA,aAAa,UAAU,OAAO;IAClC,IAAIA,aAAa,UAAU,OAAO;IAClC,IAAIA,aAAa,UAAU,OAAO;IAClC,IAAIA,aAAa,gBAAgB,OAAO;IACxC,IAAIA,SAASC,UAAU,CAAC,UAAU,OAAO;IACzC,OAAOD,SAASE,MAAM,CAAC,GAAGC,WAAW,KAAKH,SAASI,KAAK,CAAC;AAC3D;AAEA;;;;;;;;;CASC,GACD,OAAO,SAASC,mBAAmBC,IAAmB;IACpD,OAAOA,KAAKC,KAAK,IAAID,KAAKE,IAAI,IAAIF,KAAKG,EAAE;AAC3C"}
|
|
@@ -3,6 +3,7 @@ import { buildAppId, resolveWorkbenchApp } from '@sanity/workbench-cli/build';
|
|
|
3
3
|
import { getAppId } from '../../util/appId.js';
|
|
4
4
|
import { warnAboutMissingAppId } from '../../util/warnAboutMissingAppId.js';
|
|
5
5
|
import { determineBasePath } from './determineBasePath.js';
|
|
6
|
+
import { preReleaseEventListenerFactory } from './eventListenerFactory.js';
|
|
6
7
|
/**
|
|
7
8
|
* Build the Sanity app.
|
|
8
9
|
*
|
|
@@ -53,7 +54,8 @@ import { determineBasePath } from './determineBasePath.js';
|
|
|
53
54
|
// Shared with deploy: it passes the resolved application id (minted by the
|
|
54
55
|
// API on a first deploy) to inline; a plain build has none, so it hashes the shape.
|
|
55
56
|
workbenchAppId: workbench ? options.applicationId ?? await buildAppId(workbench) : undefined,
|
|
56
|
-
workDir
|
|
57
|
+
workDir,
|
|
58
|
+
eventListener: preReleaseEventListenerFactory(output)
|
|
57
59
|
});
|
|
58
60
|
}
|
|
59
61
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/actions/build/buildApp.ts"],"sourcesContent":["import {\n compareDependencyVersions,\n buildApp as internalBuildApp,\n} from '@sanity/cli-build/_internal/build'\nimport {buildAppId, resolveWorkbenchApp} from '@sanity/workbench-cli/build'\n\nimport {getAppId} from '../../util/appId.js'\nimport {warnAboutMissingAppId} from '../../util/warnAboutMissingAppId.js'\nimport {determineBasePath} from './determineBasePath.js'\nimport {type BuildOptions} from './types.js'\n\n/**\n * Build the Sanity app.\n *\n * @internal\n */\nexport async function buildApp(options: BuildOptions): Promise<void> {\n const {cliConfig, flags, outDir, output, workDir} = options\n\n const app = cliConfig && 'app' in cliConfig ? cliConfig.app : undefined\n // `views`/`services` live on the branded `unstable_defineApp` result, not the\n // legacy `app` config object — resolve the workbench capability to read them.\n const workbench = resolveWorkbenchApp(cliConfig)\n const exposes = workbench\n ? {config: workbench.config, services: workbench.services, views: workbench.views}\n : undefined\n\n const appId = getAppId(cliConfig)\n\n await internalBuildApp({\n appId,\n appTitle: app?.title,\n autoUpdatesEnabled: options.autoUpdatesEnabled,\n checkAppId: () => {\n // Warn if auto updates enabled but no appId configured.\n // Skip when called from deploy, since deploy handles appId itself\n // (prompts the user and tells them to add it to config).\n if (!appId && !options.calledFromDeploy) {\n warnAboutMissingAppId({appType: 'app', output})\n }\n },\n compareDependencyVersions: (packages) => compareDependencyVersions(packages, workDir, {appId}),\n determineBasePath: () => determineBasePath(cliConfig, 'app', output),\n entry: app?.entry,\n exposes,\n isWorkbenchApp: !!workbench,\n minify: flags.minify,\n outDir,\n output,\n reactCompiler: cliConfig && 'reactCompiler' in cliConfig ? cliConfig.reactCompiler : undefined,\n schemaExtraction: cliConfig?.schemaExtraction,\n sourceMap: Boolean(flags['source-maps']),\n stats: flags.stats,\n unattendedMode: flags.yes,\n vite: cliConfig.vite,\n // Shared with deploy: it passes the resolved application id (minted by the\n // API on a first deploy) to inline; a plain build has none, so it hashes the shape.\n workbenchAppId: workbench\n ? (options.applicationId ?? (await buildAppId(workbench)))\n : undefined,\n workDir,\n })\n}\n"],"names":["compareDependencyVersions","buildApp","internalBuildApp","buildAppId","resolveWorkbenchApp","getAppId","warnAboutMissingAppId","determineBasePath","options","cliConfig","flags","outDir","output","workDir","app","undefined","workbench","exposes","config","services","views","appId","appTitle","title","autoUpdatesEnabled","checkAppId","calledFromDeploy","appType","packages","entry","isWorkbenchApp","minify","reactCompiler","schemaExtraction","sourceMap","Boolean","stats","unattendedMode","yes","vite","workbenchAppId","applicationId"],"mappings":"AAAA,SACEA,yBAAyB,EACzBC,YAAYC,gBAAgB,QACvB,oCAAmC;AAC1C,SAAQC,UAAU,EAAEC,mBAAmB,QAAO,8BAA6B;AAE3E,SAAQC,QAAQ,QAAO,sBAAqB;AAC5C,SAAQC,qBAAqB,QAAO,sCAAqC;AACzE,SAAQC,iBAAiB,QAAO,yBAAwB;
|
|
1
|
+
{"version":3,"sources":["../../../src/actions/build/buildApp.ts"],"sourcesContent":["import {\n compareDependencyVersions,\n buildApp as internalBuildApp,\n} from '@sanity/cli-build/_internal/build'\nimport {buildAppId, resolveWorkbenchApp} from '@sanity/workbench-cli/build'\n\nimport {getAppId} from '../../util/appId.js'\nimport {warnAboutMissingAppId} from '../../util/warnAboutMissingAppId.js'\nimport {determineBasePath} from './determineBasePath.js'\nimport {preReleaseEventListenerFactory} from './eventListenerFactory.js'\nimport {type BuildOptions} from './types.js'\n\n/**\n * Build the Sanity app.\n *\n * @internal\n */\nexport async function buildApp(options: BuildOptions): Promise<void> {\n const {cliConfig, flags, outDir, output, workDir} = options\n\n const app = cliConfig && 'app' in cliConfig ? cliConfig.app : undefined\n // `views`/`services` live on the branded `unstable_defineApp` result, not the\n // legacy `app` config object — resolve the workbench capability to read them.\n const workbench = resolveWorkbenchApp(cliConfig)\n const exposes = workbench\n ? {config: workbench.config, services: workbench.services, views: workbench.views}\n : undefined\n\n const appId = getAppId(cliConfig)\n\n await internalBuildApp({\n appId,\n appTitle: app?.title,\n autoUpdatesEnabled: options.autoUpdatesEnabled,\n checkAppId: () => {\n // Warn if auto updates enabled but no appId configured.\n // Skip when called from deploy, since deploy handles appId itself\n // (prompts the user and tells them to add it to config).\n if (!appId && !options.calledFromDeploy) {\n warnAboutMissingAppId({appType: 'app', output})\n }\n },\n compareDependencyVersions: (packages) => compareDependencyVersions(packages, workDir, {appId}),\n determineBasePath: () => determineBasePath(cliConfig, 'app', output),\n entry: app?.entry,\n exposes,\n isWorkbenchApp: !!workbench,\n minify: flags.minify,\n outDir,\n output,\n reactCompiler: cliConfig && 'reactCompiler' in cliConfig ? cliConfig.reactCompiler : undefined,\n schemaExtraction: cliConfig?.schemaExtraction,\n sourceMap: Boolean(flags['source-maps']),\n stats: flags.stats,\n unattendedMode: flags.yes,\n vite: cliConfig.vite,\n // Shared with deploy: it passes the resolved application id (minted by the\n // API on a first deploy) to inline; a plain build has none, so it hashes the shape.\n workbenchAppId: workbench\n ? (options.applicationId ?? (await buildAppId(workbench)))\n : undefined,\n workDir,\n\n eventListener: preReleaseEventListenerFactory(output),\n })\n}\n"],"names":["compareDependencyVersions","buildApp","internalBuildApp","buildAppId","resolveWorkbenchApp","getAppId","warnAboutMissingAppId","determineBasePath","preReleaseEventListenerFactory","options","cliConfig","flags","outDir","output","workDir","app","undefined","workbench","exposes","config","services","views","appId","appTitle","title","autoUpdatesEnabled","checkAppId","calledFromDeploy","appType","packages","entry","isWorkbenchApp","minify","reactCompiler","schemaExtraction","sourceMap","Boolean","stats","unattendedMode","yes","vite","workbenchAppId","applicationId","eventListener"],"mappings":"AAAA,SACEA,yBAAyB,EACzBC,YAAYC,gBAAgB,QACvB,oCAAmC;AAC1C,SAAQC,UAAU,EAAEC,mBAAmB,QAAO,8BAA6B;AAE3E,SAAQC,QAAQ,QAAO,sBAAqB;AAC5C,SAAQC,qBAAqB,QAAO,sCAAqC;AACzE,SAAQC,iBAAiB,QAAO,yBAAwB;AACxD,SAAQC,8BAA8B,QAAO,4BAA2B;AAGxE;;;;CAIC,GACD,OAAO,eAAeP,SAASQ,OAAqB;IAClD,MAAM,EAACC,SAAS,EAAEC,KAAK,EAAEC,MAAM,EAAEC,MAAM,EAAEC,OAAO,EAAC,GAAGL;IAEpD,MAAMM,MAAML,aAAa,SAASA,YAAYA,UAAUK,GAAG,GAAGC;IAC9D,8EAA8E;IAC9E,8EAA8E;IAC9E,MAAMC,YAAYb,oBAAoBM;IACtC,MAAMQ,UAAUD,YACZ;QAACE,QAAQF,UAAUE,MAAM;QAAEC,UAAUH,UAAUG,QAAQ;QAAEC,OAAOJ,UAAUI,KAAK;IAAA,IAC/EL;IAEJ,MAAMM,QAAQjB,SAASK;IAEvB,MAAMR,iBAAiB;QACrBoB;QACAC,UAAUR,KAAKS;QACfC,oBAAoBhB,QAAQgB,kBAAkB;QAC9CC,YAAY;YACV,wDAAwD;YACxD,kEAAkE;YAClE,yDAAyD;YACzD,IAAI,CAACJ,SAAS,CAACb,QAAQkB,gBAAgB,EAAE;gBACvCrB,sBAAsB;oBAACsB,SAAS;oBAAOf;gBAAM;YAC/C;QACF;QACAb,2BAA2B,CAAC6B,WAAa7B,0BAA0B6B,UAAUf,SAAS;gBAACQ;YAAK;QAC5Ff,mBAAmB,IAAMA,kBAAkBG,WAAW,OAAOG;QAC7DiB,OAAOf,KAAKe;QACZZ;QACAa,gBAAgB,CAAC,CAACd;QAClBe,QAAQrB,MAAMqB,MAAM;QACpBpB;QACAC;QACAoB,eAAevB,aAAa,mBAAmBA,YAAYA,UAAUuB,aAAa,GAAGjB;QACrFkB,kBAAkBxB,WAAWwB;QAC7BC,WAAWC,QAAQzB,KAAK,CAAC,cAAc;QACvC0B,OAAO1B,MAAM0B,KAAK;QAClBC,gBAAgB3B,MAAM4B,GAAG;QACzBC,MAAM9B,UAAU8B,IAAI;QACpB,2EAA2E;QAC3E,oFAAoF;QACpFC,gBAAgBxB,YACXR,QAAQiC,aAAa,IAAK,MAAMvC,WAAWc,aAC5CD;QACJF;QAEA6B,eAAenC,+BAA+BK;IAChD;AACF"}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
+
import { styleText } from 'node:util';
|
|
1
2
|
import { compareDependencyVersions, buildStudio as internalBuildStudio } from '@sanity/cli-build/_internal/build';
|
|
3
|
+
import { confirm, logSymbols, select, spinner } from '@sanity/cli-core/ux';
|
|
2
4
|
import { buildAppId, resolveWorkbenchApp } from '@sanity/workbench-cli/build';
|
|
3
5
|
import { getAppId } from '../../util/appId.js';
|
|
4
6
|
import { determineIsApp } from '../../util/determineIsApp.js';
|
|
@@ -6,6 +8,7 @@ import { getPackageManagerChoice } from '../../util/packageManager/packageManage
|
|
|
6
8
|
import { upgradePackages } from '../../util/packageManager/upgradePackages.js';
|
|
7
9
|
import { warnAboutMissingAppId } from '../../util/warnAboutMissingAppId.js';
|
|
8
10
|
import { determineBasePath } from './determineBasePath.js';
|
|
11
|
+
import { checkDependenciesEventListenerFactory, preReleaseEventListenerFactory } from './eventListenerFactory.js';
|
|
9
12
|
/**
|
|
10
13
|
* Build the Sanity Studio.
|
|
11
14
|
*
|
|
@@ -20,17 +23,8 @@ import { determineBasePath } from './determineBasePath.js';
|
|
|
20
23
|
views: workbench.views
|
|
21
24
|
} : undefined;
|
|
22
25
|
const appId = getAppId(cliConfig);
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
packageManager: (await getPackageManagerChoice(workDir, {
|
|
26
|
-
interactive: false
|
|
27
|
-
})).chosen,
|
|
28
|
-
packages: options.packages
|
|
29
|
-
}, {
|
|
30
|
-
output,
|
|
31
|
-
workDir
|
|
32
|
-
});
|
|
33
|
-
};
|
|
26
|
+
let cleanOutputDirSpinner;
|
|
27
|
+
let buildSpinner;
|
|
34
28
|
await internalBuildStudio({
|
|
35
29
|
appId,
|
|
36
30
|
autoUpdatesEnabled: options.autoUpdatesEnabled,
|
|
@@ -61,12 +55,109 @@ import { determineBasePath } from './determineBasePath.js';
|
|
|
61
55
|
sourceMap: Boolean(flags['source-maps']),
|
|
62
56
|
stats: flags.stats,
|
|
63
57
|
unattendedMode: Boolean(flags.yes),
|
|
64
|
-
upgradePackages: upgradePkgs,
|
|
65
58
|
vite: cliConfig.vite,
|
|
66
59
|
// Shared with deploy: it passes the resolved application id (minted by the
|
|
67
60
|
// API on a first deploy) to inline; a plain build has none, so it hashes the shape.
|
|
68
61
|
workbenchAppId: workbench ? options.applicationId ?? await buildAppId(workbench) : undefined,
|
|
69
|
-
workDir
|
|
62
|
+
workDir,
|
|
63
|
+
eventListener: {
|
|
64
|
+
...preReleaseEventListenerFactory(output),
|
|
65
|
+
...checkDependenciesEventListenerFactory(output),
|
|
66
|
+
onBuildEnd ({ message }) {
|
|
67
|
+
if (buildSpinner) {
|
|
68
|
+
buildSpinner.text = message;
|
|
69
|
+
buildSpinner.succeed();
|
|
70
|
+
}
|
|
71
|
+
},
|
|
72
|
+
onBuildFail ({ message }) {
|
|
73
|
+
if (buildSpinner) {
|
|
74
|
+
buildSpinner.fail();
|
|
75
|
+
}
|
|
76
|
+
output.error(message, {
|
|
77
|
+
exit: 1
|
|
78
|
+
});
|
|
79
|
+
},
|
|
80
|
+
onBuildStart ({ message }) {
|
|
81
|
+
if (!buildSpinner) {
|
|
82
|
+
buildSpinner = spinner(message).start();
|
|
83
|
+
}
|
|
84
|
+
},
|
|
85
|
+
onCleanOutputDirEnd ({ message }) {
|
|
86
|
+
if (cleanOutputDirSpinner) {
|
|
87
|
+
cleanOutputDirSpinner.text = message;
|
|
88
|
+
cleanOutputDirSpinner.succeed();
|
|
89
|
+
}
|
|
90
|
+
},
|
|
91
|
+
onCleanOutputDirStart ({ message }) {
|
|
92
|
+
if (!cleanOutputDirSpinner) {
|
|
93
|
+
cleanOutputDirSpinner = spinner(message).start();
|
|
94
|
+
}
|
|
95
|
+
},
|
|
96
|
+
async onInteractiveNonDefaultOutputDir ({ message }) {
|
|
97
|
+
const shouldClean = await confirm({
|
|
98
|
+
default: true,
|
|
99
|
+
message
|
|
100
|
+
});
|
|
101
|
+
return {
|
|
102
|
+
shouldClean
|
|
103
|
+
};
|
|
104
|
+
},
|
|
105
|
+
async onVersionMismatchInInteractiveAutoUpdate ({ mismatched, versionMismatchWarning }) {
|
|
106
|
+
const choice = await select({
|
|
107
|
+
choices: [
|
|
108
|
+
{
|
|
109
|
+
name: `Upgrade local versions (recommended). You will need to run the build command again`,
|
|
110
|
+
value: 'upgrade'
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
name: `Upgrade and proceed with build`,
|
|
114
|
+
value: 'upgrade-and-proceed'
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
name: `Continue anyway`,
|
|
118
|
+
value: 'continue'
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
name: 'Cancel',
|
|
122
|
+
value: 'cancel'
|
|
123
|
+
}
|
|
124
|
+
],
|
|
125
|
+
default: 'upgrade',
|
|
126
|
+
message: styleText('yellow', `${logSymbols.warning} ${versionMismatchWarning}\n\nDo you want to upgrade local versions before deploying?`)
|
|
127
|
+
});
|
|
128
|
+
if (choice === 'cancel') {
|
|
129
|
+
output.error('Declined to continue with build', {
|
|
130
|
+
exit: 1
|
|
131
|
+
});
|
|
132
|
+
return {
|
|
133
|
+
stopBuild: true
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
if (choice === 'upgrade' || choice === 'upgrade-and-proceed') {
|
|
137
|
+
await upgradePackages({
|
|
138
|
+
packageManager: (await getPackageManagerChoice(workDir, {
|
|
139
|
+
interactive: false
|
|
140
|
+
})).chosen,
|
|
141
|
+
packages: mismatched.map((res)=>[
|
|
142
|
+
res.pkg,
|
|
143
|
+
res.remote
|
|
144
|
+
])
|
|
145
|
+
}, {
|
|
146
|
+
output,
|
|
147
|
+
workDir
|
|
148
|
+
});
|
|
149
|
+
return {
|
|
150
|
+
stopBuild: choice === 'upgrade'
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
return {
|
|
154
|
+
stopBuild: false
|
|
155
|
+
};
|
|
156
|
+
},
|
|
157
|
+
onVersionMismatchInNonInteractiveAutoUpdate ({ versionMismatchWarning }) {
|
|
158
|
+
output.warn(versionMismatchWarning);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
70
161
|
});
|
|
71
162
|
}
|
|
72
163
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/actions/build/buildStudio.ts"],"sourcesContent":["import {\n compareDependencyVersions,\n buildStudio as internalBuildStudio,\n} from '@sanity/cli-build/_internal/build'\nimport {buildAppId, resolveWorkbenchApp} from '@sanity/workbench-cli/build'\n\nimport {getAppId} from '../../util/appId.js'\nimport {determineIsApp} from '../../util/determineIsApp.js'\nimport {getPackageManagerChoice} from '../../util/packageManager/packageManagerChoice.js'\nimport {upgradePackages} from '../../util/packageManager/upgradePackages.js'\nimport {warnAboutMissingAppId} from '../../util/warnAboutMissingAppId.js'\nimport {determineBasePath} from './determineBasePath.js'\nimport {type BuildOptions} from './types.js'\n\n/**\n * Build the Sanity Studio.\n *\n * @internal\n */\nexport async function buildStudio(options: BuildOptions): Promise<void> {\n const {calledFromDeploy, cliConfig, flags, outDir, output, workDir} = options\n\n // `views`/`services` live on the branded `unstable_defineApp` result — resolve\n // the workbench capability so it's gated on the brand, like the app build.\n const workbench = resolveWorkbenchApp(cliConfig)\n const exposes = workbench ? {services: workbench.services, views: workbench.views} : undefined\n\n const appId = getAppId(cliConfig)\n\n const upgradePkgs = async (options: {\n packages: [name: string, version: string][]\n }): Promise<void> => {\n await upgradePackages(\n {\n packageManager: (await getPackageManagerChoice(workDir, {interactive: false})).chosen,\n packages: options.packages,\n },\n {output, workDir},\n )\n }\n\n await internalBuildStudio({\n appId,\n autoUpdatesEnabled: options.autoUpdatesEnabled,\n checkAppId: () => {\n // Warn if auto updates enabled but no appId configured.\n // Skip when called from deploy, since deploy handles appId itself\n // (prompts the user and tells them to add it to config).\n if (!appId && !calledFromDeploy) {\n warnAboutMissingAppId({appType: 'studio', output, projectId: cliConfig?.api?.projectId})\n }\n },\n compareDependencyVersions: (packages) => compareDependencyVersions(packages, workDir, {appId}),\n determineBasePath: () => determineBasePath(cliConfig, 'studio', output),\n exposes,\n isApp: determineIsApp(cliConfig),\n isWorkbenchApp: !!workbench,\n minify: Boolean(flags.minify),\n outDir,\n output,\n reactCompiler: cliConfig.reactCompiler,\n schemaExtraction: cliConfig.schemaExtraction,\n sourceMap: Boolean(flags['source-maps']),\n stats: flags.stats,\n unattendedMode: Boolean(flags.yes),\n upgradePackages: upgradePkgs,\n vite: cliConfig.vite,\n // Shared with deploy: it passes the resolved application id (minted by the\n // API on a first deploy) to inline; a plain build has none, so it hashes the shape.\n workbenchAppId: workbench\n ? (options.applicationId ?? (await buildAppId(workbench)))\n : undefined,\n workDir,\n })\n}\n"],"names":["compareDependencyVersions","buildStudio","internalBuildStudio","buildAppId","resolveWorkbenchApp","getAppId","determineIsApp","getPackageManagerChoice","upgradePackages","warnAboutMissingAppId","determineBasePath","options","calledFromDeploy","cliConfig","flags","outDir","output","workDir","workbench","exposes","services","views","undefined","appId","upgradePkgs","packageManager","interactive","chosen","packages","autoUpdatesEnabled","checkAppId","appType","projectId","api","isApp","isWorkbenchApp","minify","Boolean","reactCompiler","schemaExtraction","sourceMap","stats","unattendedMode","yes","vite","workbenchAppId","applicationId"],"mappings":"AAAA,SACEA,yBAAyB,EACzBC,eAAeC,mBAAmB,QAC7B,oCAAmC;AAC1C,SAAQC,UAAU,EAAEC,mBAAmB,QAAO,8BAA6B;AAE3E,SAAQC,QAAQ,QAAO,sBAAqB;AAC5C,SAAQC,cAAc,QAAO,+BAA8B;AAC3D,SAAQC,uBAAuB,QAAO,oDAAmD;AACzF,SAAQC,eAAe,QAAO,+CAA8C;AAC5E,SAAQC,qBAAqB,QAAO,sCAAqC;AACzE,SAAQC,iBAAiB,QAAO,yBAAwB;AAGxD;;;;CAIC,GACD,OAAO,eAAeT,YAAYU,OAAqB;IACrD,MAAM,EAACC,gBAAgB,EAAEC,SAAS,EAAEC,KAAK,EAAEC,MAAM,EAAEC,MAAM,EAAEC,OAAO,EAAC,GAAGN;IAEtE,+EAA+E;IAC/E,2EAA2E;IAC3E,MAAMO,YAAYd,oBAAoBS;IACtC,MAAMM,UAAUD,YAAY;QAACE,UAAUF,UAAUE,QAAQ;QAAEC,OAAOH,UAAUG,KAAK;IAAA,IAAIC;IAErF,MAAMC,QAAQlB,SAASQ;IAEvB,MAAMW,cAAc,OAAOb;QAGzB,MAAMH,gBACJ;YACEiB,gBAAgB,AAAC,CAAA,MAAMlB,wBAAwBU,SAAS;gBAACS,aAAa;YAAK,EAAC,EAAGC,MAAM;YACrFC,UAAUjB,QAAQiB,QAAQ;QAC5B,GACA;YAACZ;YAAQC;QAAO;IAEpB;IAEA,MAAMf,oBAAoB;QACxBqB;QACAM,oBAAoBlB,QAAQkB,kBAAkB;QAC9CC,YAAY;YACV,wDAAwD;YACxD,kEAAkE;YAClE,yDAAyD;YACzD,IAAI,CAACP,SAAS,CAACX,kBAAkB;gBAC/BH,sBAAsB;oBAACsB,SAAS;oBAAUf;oBAAQgB,WAAWnB,WAAWoB,KAAKD;gBAAS;YACxF;QACF;QACAhC,2BAA2B,CAAC4B,WAAa5B,0BAA0B4B,UAAUX,SAAS;gBAACM;YAAK;QAC5Fb,mBAAmB,IAAMA,kBAAkBG,WAAW,UAAUG;QAChEG;QACAe,OAAO5B,eAAeO;QACtBsB,gBAAgB,CAAC,CAACjB;QAClBkB,QAAQC,QAAQvB,MAAMsB,MAAM;QAC5BrB;QACAC;QACAsB,eAAezB,UAAUyB,aAAa;QACtCC,kBAAkB1B,UAAU0B,gBAAgB;QAC5CC,WAAWH,QAAQvB,KAAK,CAAC,cAAc;QACvC2B,OAAO3B,MAAM2B,KAAK;QAClBC,gBAAgBL,QAAQvB,MAAM6B,GAAG;QACjCnC,iBAAiBgB;QACjBoB,MAAM/B,UAAU+B,IAAI;QACpB,2EAA2E;QAC3E,oFAAoF;QACpFC,gBAAgB3B,YACXP,QAAQmC,aAAa,IAAK,MAAM3C,WAAWe,aAC5CI;QACJL;IACF;AACF"}
|
|
1
|
+
{"version":3,"sources":["../../../src/actions/build/buildStudio.ts"],"sourcesContent":["import {styleText} from 'node:util'\n\nimport {\n compareDependencyVersions,\n buildStudio as internalBuildStudio,\n} from '@sanity/cli-build/_internal/build'\nimport {confirm, logSymbols, select, spinner} from '@sanity/cli-core/ux'\nimport {buildAppId, resolveWorkbenchApp} from '@sanity/workbench-cli/build'\n\nimport {getAppId} from '../../util/appId.js'\nimport {determineIsApp} from '../../util/determineIsApp.js'\nimport {getPackageManagerChoice} from '../../util/packageManager/packageManagerChoice.js'\nimport {upgradePackages} from '../../util/packageManager/upgradePackages.js'\nimport {warnAboutMissingAppId} from '../../util/warnAboutMissingAppId.js'\nimport {determineBasePath} from './determineBasePath.js'\nimport {\n checkDependenciesEventListenerFactory,\n preReleaseEventListenerFactory,\n} from './eventListenerFactory.js'\nimport {type BuildOptions} from './types.js'\n\n/**\n * Build the Sanity Studio.\n *\n * @internal\n */\nexport async function buildStudio(options: BuildOptions): Promise<void> {\n const {calledFromDeploy, cliConfig, flags, outDir, output, workDir} = options\n\n // `views`/`services` live on the branded `unstable_defineApp` result — resolve\n // the workbench capability so it's gated on the brand, like the app build.\n const workbench = resolveWorkbenchApp(cliConfig)\n const exposes = workbench ? {services: workbench.services, views: workbench.views} : undefined\n\n const appId = getAppId(cliConfig)\n\n let cleanOutputDirSpinner: ReturnType<typeof spinner> | undefined\n let buildSpinner: ReturnType<typeof spinner> | undefined\n\n await internalBuildStudio({\n appId,\n autoUpdatesEnabled: options.autoUpdatesEnabled,\n checkAppId: () => {\n // Warn if auto updates enabled but no appId configured.\n // Skip when called from deploy, since deploy handles appId itself\n // (prompts the user and tells them to add it to config).\n if (!appId && !calledFromDeploy) {\n warnAboutMissingAppId({appType: 'studio', output, projectId: cliConfig?.api?.projectId})\n }\n },\n compareDependencyVersions: (packages) => compareDependencyVersions(packages, workDir, {appId}),\n determineBasePath: () => determineBasePath(cliConfig, 'studio', output),\n exposes,\n isApp: determineIsApp(cliConfig),\n isWorkbenchApp: !!workbench,\n minify: Boolean(flags.minify),\n outDir,\n output,\n reactCompiler: cliConfig.reactCompiler,\n schemaExtraction: cliConfig.schemaExtraction,\n sourceMap: Boolean(flags['source-maps']),\n stats: flags.stats,\n unattendedMode: Boolean(flags.yes),\n vite: cliConfig.vite,\n // Shared with deploy: it passes the resolved application id (minted by the\n // API on a first deploy) to inline; a plain build has none, so it hashes the shape.\n workbenchAppId: workbench\n ? (options.applicationId ?? (await buildAppId(workbench)))\n : undefined,\n workDir,\n\n eventListener: {\n ...preReleaseEventListenerFactory(output),\n\n ...checkDependenciesEventListenerFactory(output),\n\n onBuildEnd({message}) {\n if (buildSpinner) {\n buildSpinner.text = message\n buildSpinner.succeed()\n }\n },\n onBuildFail({message}) {\n if (buildSpinner) {\n buildSpinner.fail()\n }\n\n output.error(message, {exit: 1})\n },\n onBuildStart({message}) {\n if (!buildSpinner) {\n buildSpinner = spinner(message).start()\n }\n },\n onCleanOutputDirEnd({message}) {\n if (cleanOutputDirSpinner) {\n cleanOutputDirSpinner.text = message\n cleanOutputDirSpinner.succeed()\n }\n },\n onCleanOutputDirStart({message}) {\n if (!cleanOutputDirSpinner) {\n cleanOutputDirSpinner = spinner(message).start()\n }\n },\n async onInteractiveNonDefaultOutputDir({message}: {message: string}) {\n const shouldClean = await confirm({\n default: true,\n message,\n })\n return {shouldClean}\n },\n async onVersionMismatchInInteractiveAutoUpdate({mismatched, versionMismatchWarning}) {\n const choice = await select({\n choices: [\n {\n name: `Upgrade local versions (recommended). You will need to run the build command again`,\n value: 'upgrade',\n },\n {\n name: `Upgrade and proceed with build`,\n value: 'upgrade-and-proceed',\n },\n {\n name: `Continue anyway`,\n value: 'continue',\n },\n {name: 'Cancel', value: 'cancel'},\n ],\n default: 'upgrade',\n message: styleText(\n 'yellow',\n `${logSymbols.warning} ${versionMismatchWarning}\\n\\nDo you want to upgrade local versions before deploying?`,\n ),\n })\n\n if (choice === 'cancel') {\n output.error('Declined to continue with build', {exit: 1})\n return {stopBuild: true}\n }\n\n if (choice === 'upgrade' || choice === 'upgrade-and-proceed') {\n await upgradePackages(\n {\n packageManager: (await getPackageManagerChoice(workDir, {interactive: false})).chosen,\n packages: mismatched.map((res) => [res.pkg, res.remote]),\n },\n {output, workDir},\n )\n\n return {stopBuild: choice === 'upgrade'}\n }\n\n return {stopBuild: false}\n },\n onVersionMismatchInNonInteractiveAutoUpdate({versionMismatchWarning}) {\n output.warn(versionMismatchWarning)\n },\n },\n })\n}\n"],"names":["styleText","compareDependencyVersions","buildStudio","internalBuildStudio","confirm","logSymbols","select","spinner","buildAppId","resolveWorkbenchApp","getAppId","determineIsApp","getPackageManagerChoice","upgradePackages","warnAboutMissingAppId","determineBasePath","checkDependenciesEventListenerFactory","preReleaseEventListenerFactory","options","calledFromDeploy","cliConfig","flags","outDir","output","workDir","workbench","exposes","services","views","undefined","appId","cleanOutputDirSpinner","buildSpinner","autoUpdatesEnabled","checkAppId","appType","projectId","api","packages","isApp","isWorkbenchApp","minify","Boolean","reactCompiler","schemaExtraction","sourceMap","stats","unattendedMode","yes","vite","workbenchAppId","applicationId","eventListener","onBuildEnd","message","text","succeed","onBuildFail","fail","error","exit","onBuildStart","start","onCleanOutputDirEnd","onCleanOutputDirStart","onInteractiveNonDefaultOutputDir","shouldClean","default","onVersionMismatchInInteractiveAutoUpdate","mismatched","versionMismatchWarning","choice","choices","name","value","warning","stopBuild","packageManager","interactive","chosen","map","res","pkg","remote","onVersionMismatchInNonInteractiveAutoUpdate","warn"],"mappings":"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"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { styleText } from 'node:util';
|
|
2
|
+
import { select } from '@sanity/cli-core/ux';
|
|
3
|
+
/**
|
|
4
|
+
* Creates check dependency event handlers that are shared between buildStudio and startStudioDevServer.
|
|
5
|
+
*/ export function checkDependenciesEventListenerFactory(output) {
|
|
6
|
+
return {
|
|
7
|
+
onIncompatibleDeclaredStyledComponentsVersionRange ({ message }) {
|
|
8
|
+
output.warn(message);
|
|
9
|
+
},
|
|
10
|
+
onIncompatibleInstalledStyledComponentsVersionRange ({ message }) {
|
|
11
|
+
output.warn(message);
|
|
12
|
+
},
|
|
13
|
+
onInvalidStyledComponentsVersionRange ({ message }) {
|
|
14
|
+
output.error(message, {
|
|
15
|
+
exit: 1
|
|
16
|
+
});
|
|
17
|
+
},
|
|
18
|
+
onNoDeclaredStyledComponentsVersion ({ message }) {
|
|
19
|
+
output.error(message, {
|
|
20
|
+
exit: 1
|
|
21
|
+
});
|
|
22
|
+
},
|
|
23
|
+
onNoInstalledSanityVersion ({ message }) {
|
|
24
|
+
output.error(message, {
|
|
25
|
+
exit: 1
|
|
26
|
+
});
|
|
27
|
+
},
|
|
28
|
+
onNoInstalledStyledComponentsVersion ({ message }) {
|
|
29
|
+
output.error(message, {
|
|
30
|
+
exit: 1
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Creates pre-release event handlers that are shared between buildApp and buildStudio.
|
|
37
|
+
*/ export function preReleaseEventListenerFactory(output) {
|
|
38
|
+
return {
|
|
39
|
+
async onPreReleaseInInteractiveAutoUpdate ({ prereleaseMessage }) {
|
|
40
|
+
const choice = await select({
|
|
41
|
+
choices: [
|
|
42
|
+
{
|
|
43
|
+
name: 'Disable auto-updates for this build and continue',
|
|
44
|
+
value: 'disable-auto-updates'
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
name: 'Cancel build',
|
|
48
|
+
value: 'cancel'
|
|
49
|
+
}
|
|
50
|
+
],
|
|
51
|
+
default: 'disable-auto-updates',
|
|
52
|
+
message: styleText('yellow', prereleaseMessage)
|
|
53
|
+
});
|
|
54
|
+
if (choice === 'cancel') {
|
|
55
|
+
output.error('Declined to continue with build', {
|
|
56
|
+
exit: 1
|
|
57
|
+
});
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
output.warn('Auto-updates disabled for this build');
|
|
61
|
+
},
|
|
62
|
+
onPreReleaseInNonInteractiveAutoUpdate ({ message }) {
|
|
63
|
+
output.error(message, {
|
|
64
|
+
exit: 1
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
//# sourceMappingURL=eventListenerFactory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/actions/build/eventListenerFactory.ts"],"sourcesContent":["import {styleText} from 'node:util'\n\nimport {Output} from '@sanity/cli-core'\nimport {select} from '@sanity/cli-core/ux'\n\n/**\n * Creates check dependency event handlers that are shared between buildStudio and startStudioDevServer.\n */\nexport function checkDependenciesEventListenerFactory(output: Output) {\n return {\n onIncompatibleDeclaredStyledComponentsVersionRange({message}: {message: string}) {\n output.warn(message)\n },\n onIncompatibleInstalledStyledComponentsVersionRange({message}: {message: string}) {\n output.warn(message)\n },\n onInvalidStyledComponentsVersionRange({message}: {message: string}) {\n output.error(message, {exit: 1})\n },\n onNoDeclaredStyledComponentsVersion({message}: {message: string}) {\n output.error(message, {exit: 1})\n },\n onNoInstalledSanityVersion({message}: {message: string}) {\n output.error(message, {exit: 1})\n },\n onNoInstalledStyledComponentsVersion({message}: {message: string}) {\n output.error(message, {exit: 1})\n },\n }\n}\n\n/**\n * Creates pre-release event handlers that are shared between buildApp and buildStudio.\n */\nexport function preReleaseEventListenerFactory(output: Output) {\n return {\n async onPreReleaseInInteractiveAutoUpdate({prereleaseMessage}: {prereleaseMessage: string}) {\n const choice = await select({\n choices: [\n {\n name: 'Disable auto-updates for this build and continue',\n value: 'disable-auto-updates',\n },\n {name: 'Cancel build', value: 'cancel'},\n ],\n default: 'disable-auto-updates',\n message: styleText('yellow', prereleaseMessage),\n })\n\n if (choice === 'cancel') {\n output.error('Declined to continue with build', {exit: 1})\n return\n }\n\n output.warn('Auto-updates disabled for this build')\n },\n onPreReleaseInNonInteractiveAutoUpdate({message}: {message: string}) {\n output.error(message, {exit: 1})\n },\n }\n}\n"],"names":["styleText","select","checkDependenciesEventListenerFactory","output","onIncompatibleDeclaredStyledComponentsVersionRange","message","warn","onIncompatibleInstalledStyledComponentsVersionRange","onInvalidStyledComponentsVersionRange","error","exit","onNoDeclaredStyledComponentsVersion","onNoInstalledSanityVersion","onNoInstalledStyledComponentsVersion","preReleaseEventListenerFactory","onPreReleaseInInteractiveAutoUpdate","prereleaseMessage","choice","choices","name","value","default","onPreReleaseInNonInteractiveAutoUpdate"],"mappings":"AAAA,SAAQA,SAAS,QAAO,YAAW;AAGnC,SAAQC,MAAM,QAAO,sBAAqB;AAE1C;;CAEC,GACD,OAAO,SAASC,sCAAsCC,MAAc;IAClE,OAAO;QACLC,oDAAmD,EAACC,OAAO,EAAoB;YAC7EF,OAAOG,IAAI,CAACD;QACd;QACAE,qDAAoD,EAACF,OAAO,EAAoB;YAC9EF,OAAOG,IAAI,CAACD;QACd;QACAG,uCAAsC,EAACH,OAAO,EAAoB;YAChEF,OAAOM,KAAK,CAACJ,SAAS;gBAACK,MAAM;YAAC;QAChC;QACAC,qCAAoC,EAACN,OAAO,EAAoB;YAC9DF,OAAOM,KAAK,CAACJ,SAAS;gBAACK,MAAM;YAAC;QAChC;QACAE,4BAA2B,EAACP,OAAO,EAAoB;YACrDF,OAAOM,KAAK,CAACJ,SAAS;gBAACK,MAAM;YAAC;QAChC;QACAG,sCAAqC,EAACR,OAAO,EAAoB;YAC/DF,OAAOM,KAAK,CAACJ,SAAS;gBAACK,MAAM;YAAC;QAChC;IACF;AACF;AAEA;;CAEC,GACD,OAAO,SAASI,+BAA+BX,MAAc;IAC3D,OAAO;QACL,MAAMY,qCAAoC,EAACC,iBAAiB,EAA8B;YACxF,MAAMC,SAAS,MAAMhB,OAAO;gBAC1BiB,SAAS;oBACP;wBACEC,MAAM;wBACNC,OAAO;oBACT;oBACA;wBAACD,MAAM;wBAAgBC,OAAO;oBAAQ;iBACvC;gBACDC,SAAS;gBACThB,SAASL,UAAU,UAAUgB;YAC/B;YAEA,IAAIC,WAAW,UAAU;gBACvBd,OAAOM,KAAK,CAAC,mCAAmC;oBAACC,MAAM;gBAAC;gBACxD;YACF;YAEAP,OAAOG,IAAI,CAAC;QACd;QACAgB,wCAAuC,EAACjB,OAAO,EAAoB;YACjEF,OAAOM,KAAK,CAACJ,SAAS;gBAACK,MAAM;YAAC;QAChC;IACF;AACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/actions/debug/types.ts"],"sourcesContent":["export interface UserInfo {\n email: string\n id: string\n name: string\n provider: string\n}\n\nexport interface AuthInfo {\n authToken: string | undefined\n hasToken: boolean\n userType: string\n}\n\nexport interface CliInfo {\n installContext: string\n version: string\n}\n\nexport interface ProjectInfo {\n cliConfigPath: string | undefined\n rootPath: string\n studioConfigPath: string | undefined\n}\n\nexport interface StudioWorkspace {\n dataset: string\n name: string | undefined\n projectId: string\n}\n\nexport interface ResolvedWorkspace {\n name: string\n roles: string[]\n title: string\n}\n"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../../../src/actions/debug/types.ts"],"sourcesContent":["export interface UserInfo {\n /** Null when authenticating with an API token rather than a user account. */\n email: string | null\n id: string\n name: string\n provider: string\n}\n\nexport interface AuthInfo {\n authToken: string | undefined\n hasToken: boolean\n userType: string\n}\n\nexport interface CliInfo {\n installContext: string\n version: string\n}\n\nexport interface ProjectInfo {\n cliConfigPath: string | undefined\n rootPath: string\n studioConfigPath: string | undefined\n}\n\nexport interface StudioWorkspace {\n dataset: string\n name: string | undefined\n projectId: string\n}\n\nexport interface ResolvedWorkspace {\n name: string\n roles: string[]\n title: string\n}\n"],"names":[],"mappings":"AA+BA,WAIC"}
|
|
@@ -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 {type AppVisibility, 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 createCoreApp,\n deployConfig,\n deployWorkbenchApp,\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 {\n extractCoreAppManifest,\n readIconFromPath,\n resolveTitleUpdate,\n} from '../manifest/extractCoreAppManifest.js'\nimport {type CoreAppManifest} from '../manifest/types.js'\nimport {createUserApplication} 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 // A first deploy mints the app id and the build inlines it; --no-build would\n // ship an existing bundle carrying a different id, so it can't be a first deploy.\n if (deployApplication && workbench && !appId && !flags.external && !flags.build) {\n reporter.report({\n exitCode: exitCodes.USAGE_ERROR,\n message: 'A first deploy cannot skip the build (--no-build)',\n solution: 'Drop --no-build so the new application id is inlined into the build',\n status: 'fail',\n })\n }\n\n // Read up front so a bad icon path fails before we create or build.\n const appIcon =\n !dryRun && workbench?.icon ? await readIconFromPath(workDir, workbench.icon) : undefined\n\n // Create the app before the build so the bundle carries its real id. A\n // redeploy already has it from `deployment.appId`; a dry run skips creation.\n let applicationId = appId\n let applicationCreated = false\n let rollbackApp: (() => Promise<void>) | undefined\n if (!dryRun && deployApplication && workbench && organizationId && !applicationId) {\n ;({applicationId, rollback: rollbackApp} = await createCoreApp({\n isSingleton: workbench.isSingleton,\n organizationId,\n slug: workbench.slug,\n title: appTitle,\n visibility: workbench.visibility,\n }))\n applicationCreated = true\n }\n\n // A record created above is stranded at its slug (and blocks retries) if any\n // step before it fully deploys fails, so undo the creation on failure.\n try {\n await checkBuild(reporter, {\n build: () =>\n buildApp({\n applicationId: workbench ? applicationId : undefined,\n autoUpdatesEnabled: isAutoUpdating,\n calledFromDeploy: true,\n cliConfig,\n flags,\n outDir: sourceDir,\n output,\n workDir,\n }),\n skipReason: 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 // Workbench apps ship their icon straight to Brett (below) and don't read the\n // core-app manifest; only plain core-apps do. Manifests aren't strictly\n // essential, so a failure warns and continues.\n let manifest: CoreAppManifest | undefined\n if (!workbench) {\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\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:\n '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 // Applied after the app is live (see below) so a failed deploy never leaves\n // the org's installation config without its application.\n const deployApplicationConfig = async (): Promise<void> => {\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\n // Dry run stops here — everything below mutates.\n if (dryRun) return\n\n // A config-only singleton ships no application, only its config.\n if (!deployApplication) {\n await deployApplicationConfig()\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 // The app was created (or resolved from `deployment.appId`) before the build,\n // so this only ships the deployment; plain coreApps use user-applications below.\n if (workbench && organizationId && applicationId) {\n await deployWorkbenchApp({\n applicationId,\n icon: appIcon,\n interfaces: buildExposes(workbench, {\n appName: workbench.name,\n appTitle,\n exposesAppView: workbench.entry !== undefined,\n version,\n }),\n isAutoUpdating,\n // Once the deployment is live, a metadata-sync or later config failure\n // must not delete the app.\n onDeployed: () => {\n rollbackApp = undefined\n },\n sourceDir,\n title: appTitle,\n version,\n visibility: workbench.visibility,\n })\n await deployApplicationConfig()\n const url = getApplicationUrl({id: applicationId, organizationId, type: 'coreApp'})\n logAppDeployed({\n applicationId,\n cliConfig,\n created: applicationCreated,\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: applicationCreated ? 'create' : 'update',\n applicationId,\n // A redeploy targets an existing app; only a create reports the slug.\n ...(applicationCreated ? {slug: workbench.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 syncApplicationMetadata({\n application,\n manifest,\n output,\n visibility: cliConfig.app?.visibility,\n })\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 } catch (err) {\n await rollbackApp?.()\n throw err\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, cliConfig.app?.visibility)\n deployDebug('User application created', application)\n return {application, created: true}\n }\n\n return {application, created: false}\n}\n\n/**\n * Syncs application metadata on redeploy when it has changed: the title from the\n * manifest and the dashboard visibility from config. Sends a single PATCH with\n * only the changed fields, and skips the request entirely when nothing changed.\n */\nexport async function syncApplicationMetadata({\n application,\n manifest,\n output,\n visibility,\n}: {\n application: UserApplicationResolved\n manifest: CoreAppManifest | undefined\n output: DeployAppOptions['output']\n visibility: AppVisibility | undefined\n}): Promise<UserApplicationResolved> {\n const titleUpdate = resolveTitleUpdate(manifest, application)\n // Treat an unset server value as `default` so a config of `default` is a no-op.\n const visibilityChanged =\n visibility !== undefined && visibility !== (application.dashboardStatus ?? 'default')\n\n if (!titleUpdate && !visibilityChanged) return application\n\n if (titleUpdate) {\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 }\n if (visibilityChanged) {\n output.log(`Setting dashboard visibility to \"${visibility}\"`)\n }\n\n const spin = spinner('Updating application').start()\n try {\n const updated = await updateUserApplication({\n applicationId: application.id,\n appType: 'coreApp',\n body: {\n ...(titleUpdate ? {title: titleUpdate.to} : {}),\n ...(visibilityChanged ? {dashboardStatus: visibility} : {}),\n },\n })\n spin.succeed()\n return updated\n } catch (err) {\n spin.fail()\n const message = getErrorMessage(err)\n deployDebug('Error updating application metadata', {message})\n output.warn(`Error updating application metadata: ${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","createCoreApp","deployConfig","deployWorkbenchApp","getApplicationUrl","getWorkbench","resolveInstallationId","summarizeConfig","pack","createDeployment","updateUserApplication","getAppId","EXTERNAL_APP_NOT_SUPPORTED","NO_ORGANIZATION_ID","buildApp","extractCoreAppManifest","readIconFromPath","resolveTitleUpdate","createUserApplication","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","appIcon","icon","undefined","applicationId","applicationCreated","rollbackApp","rollback","isSingleton","visibility","autoUpdatesEnabled","calledFromDeploy","outDir","skipReason","successMessage","manifest","installationId","config","configAppType","appType","exposes","deployApplicationConfig","applicationType","applicationVersion","target","interfaces","appName","exposesAppView","entry","onDeployed","url","id","logAppDeployed","length","action","syncApplicationMetadata","shipAppDeployment","unattended","yes","titleUpdate","visibilityChanged","dashboardStatus","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 {type AppVisibility, 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 createCoreApp,\n deployConfig,\n deployWorkbenchApp,\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 {\n extractCoreAppManifest,\n readIconFromPath,\n resolveTitleUpdate,\n} from '../manifest/extractCoreAppManifest.js'\nimport {type CoreAppManifest} from '../manifest/types.js'\nimport {createUserApplication} 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 organizationId,\n slug: workbench.slug,\n title: appTitle,\n })\n } else if (deployApplication) {\n ;({application, created: appCreated} = await resolveAppApplication(options, {dryRun, reporter}))\n }\n\n // A first deploy mints the app id and the build inlines it; --no-build would\n // ship an existing bundle carrying a different id, so it can't be a first deploy.\n if (deployApplication && workbench && !appId && !flags.external && !flags.build) {\n reporter.report({\n exitCode: exitCodes.USAGE_ERROR,\n message: 'A first deploy cannot skip the build (--no-build)',\n solution: 'Drop --no-build so the new application id is inlined into the build',\n status: 'fail',\n })\n }\n\n // Read up front so a bad icon path fails before we create or build.\n const appIcon =\n !dryRun && workbench?.icon ? await readIconFromPath(workDir, workbench.icon) : undefined\n\n // Create the app before the build so the bundle carries its real id. A\n // redeploy already has it from `deployment.appId`; a dry run skips creation.\n let applicationId = appId\n let applicationCreated = false\n let rollbackApp: (() => Promise<void>) | undefined\n if (!dryRun && deployApplication && workbench && organizationId && !applicationId) {\n ;({applicationId, rollback: rollbackApp} = await createCoreApp({\n isSingleton: workbench.isSingleton,\n organizationId,\n slug: workbench.slug,\n title: appTitle,\n visibility: workbench.visibility,\n }))\n applicationCreated = true\n }\n\n // A record created above is stranded at its slug (and blocks retries) if any\n // step before it fully deploys fails, so undo the creation on failure.\n try {\n await checkBuild(reporter, {\n build: () =>\n buildApp({\n applicationId: workbench ? applicationId : undefined,\n autoUpdatesEnabled: isAutoUpdating,\n calledFromDeploy: true,\n cliConfig,\n flags,\n outDir: sourceDir,\n output,\n workDir,\n }),\n skipReason: 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 // Workbench apps ship their icon straight to Brett (below) and don't read the\n // core-app manifest; only plain core-apps do. Manifests aren't strictly\n // essential, so a failure warns and continues.\n let manifest: CoreAppManifest | undefined\n if (!workbench) {\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\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:\n '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 // Applied after the app is live (see below) so a failed deploy never leaves\n // the org's installation config without its application.\n const deployApplicationConfig = async (): Promise<void> => {\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\n // Dry run stops here — everything below mutates.\n if (dryRun) return\n\n // A config-only singleton ships no application, only its config.\n if (!deployApplication) {\n await deployApplicationConfig()\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 // The app was created (or resolved from `deployment.appId`) before the build,\n // so this only ships the deployment; plain coreApps use user-applications below.\n if (workbench && organizationId && applicationId) {\n await deployWorkbenchApp({\n applicationId,\n icon: appIcon,\n interfaces: buildExposes(workbench, {\n appName: workbench.name,\n appTitle,\n exposesAppView: workbench.entry !== undefined,\n version,\n }),\n isAutoUpdating,\n // Once the deployment is live, a metadata-sync or later config failure\n // must not delete the app.\n onDeployed: () => {\n rollbackApp = undefined\n },\n sourceDir,\n title: appTitle,\n version,\n visibility: workbench.visibility,\n })\n await deployApplicationConfig()\n const url = getApplicationUrl({id: applicationId, organizationId, type: 'coreApp'})\n logAppDeployed({\n applicationId,\n cliConfig,\n created: applicationCreated,\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: applicationCreated ? 'create' : 'update',\n applicationId,\n // A redeploy targets an existing app; only a create reports the slug.\n ...(applicationCreated ? {slug: workbench.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 syncApplicationMetadata({\n application,\n manifest,\n output,\n visibility: cliConfig.app?.visibility,\n })\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 } catch (err) {\n await rollbackApp?.()\n throw err\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, cliConfig.app?.visibility)\n deployDebug('User application created', application)\n return {application, created: true}\n }\n\n return {application, created: false}\n}\n\n/**\n * Syncs application metadata on redeploy when it has changed: the title from the\n * manifest and the dashboard visibility from config. Sends a single PATCH with\n * only the changed fields, and skips the request entirely when nothing changed.\n */\nexport async function syncApplicationMetadata({\n application,\n manifest,\n output,\n visibility,\n}: {\n application: UserApplicationResolved\n manifest: CoreAppManifest | undefined\n output: DeployAppOptions['output']\n visibility: AppVisibility | undefined\n}): Promise<UserApplicationResolved> {\n const titleUpdate = resolveTitleUpdate(manifest, application)\n // Treat an unset server value as `default` so a config of `default` is a no-op.\n const visibilityChanged =\n visibility !== undefined && visibility !== (application.dashboardStatus ?? 'default')\n\n if (!titleUpdate && !visibilityChanged) return application\n\n if (titleUpdate) {\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 }\n if (visibilityChanged) {\n output.log(`Setting dashboard visibility to \"${visibility}\"`)\n }\n\n const spin = spinner('Updating application').start()\n try {\n const updated = await updateUserApplication({\n applicationId: application.id,\n appType: 'coreApp',\n body: {\n ...(titleUpdate ? {title: titleUpdate.to} : {}),\n ...(visibilityChanged ? {dashboardStatus: visibility} : {}),\n },\n })\n spin.succeed()\n return updated\n } catch (err) {\n spin.fail()\n const message = getErrorMessage(err)\n deployDebug('Error updating application metadata', {message})\n output.warn(`Error updating application metadata: ${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","createCoreApp","deployConfig","deployWorkbenchApp","getApplicationUrl","getWorkbench","resolveInstallationId","summarizeConfig","pack","createDeployment","updateUserApplication","getAppId","EXTERNAL_APP_NOT_SUPPORTED","NO_ORGANIZATION_ID","buildApp","extractCoreAppManifest","readIconFromPath","resolveTitleUpdate","createUserApplication","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","appIcon","icon","undefined","applicationId","applicationCreated","rollbackApp","rollback","isSingleton","visibility","autoUpdatesEnabled","calledFromDeploy","outDir","skipReason","successMessage","manifest","installationId","config","configAppType","appType","exposes","deployApplicationConfig","applicationType","applicationVersion","target","interfaces","appName","exposesAppView","entry","onDeployed","url","id","logAppDeployed","length","action","syncApplicationMetadata","shipAppDeployment","unattended","yes","titleUpdate","visibilityChanged","dashboardStatus","log","from","to","spin","start","updated","body","succeed","fail","warn","tarball","entries","pipe","isApp","error","clear","named"],"mappings":"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"}
|
|
@@ -152,6 +152,24 @@ export async function checkBuild(reporter, { build, skipReason, successMessage }
|
|
|
152
152
|
status: 'fail'
|
|
153
153
|
};
|
|
154
154
|
}
|
|
155
|
+
// A deployment with no `appId` collides with an app already at this slug —
|
|
156
|
+
// point at the existing app's id so a redeploy targets it instead of failing.
|
|
157
|
+
case 'slug-taken':
|
|
158
|
+
{
|
|
159
|
+
const { existing: application } = resolution;
|
|
160
|
+
return {
|
|
161
|
+
exitCode: exitCodes.USAGE_ERROR,
|
|
162
|
+
message: `An application already exists at slug "${application.appHost}" in this organization (app ID ${application.id})`,
|
|
163
|
+
solution: `Add \`deployment: {appId: '${application.id}'}\` to sanity.cli.ts to redeploy it`,
|
|
164
|
+
status: 'fail',
|
|
165
|
+
target: {
|
|
166
|
+
action: 'update',
|
|
167
|
+
applicationId: application.id,
|
|
168
|
+
title: application.title,
|
|
169
|
+
url: application.url ?? null
|
|
170
|
+
}
|
|
171
|
+
};
|
|
172
|
+
}
|
|
155
173
|
// Without --title, creating an app needs a prompt no unattended run can answer
|
|
156
174
|
case 'would-create':
|
|
157
175
|
{
|
|
@@ -189,14 +207,17 @@ export function describeAppTargetError(err, organizationId) {
|
|
|
189
207
|
*/ export async function checkAppTarget(reporter, options) {
|
|
190
208
|
const { title } = options;
|
|
191
209
|
if (options.isWorkbenchApp) {
|
|
192
|
-
const { appId, slug } = options;
|
|
210
|
+
const { appId, organizationId, slug } = options;
|
|
193
211
|
return runStep(reporter, {
|
|
194
212
|
debug: deployDebug,
|
|
195
213
|
name: 'target',
|
|
196
214
|
work: async ()=>{
|
|
197
|
-
const
|
|
198
|
-
appId
|
|
199
|
-
|
|
215
|
+
const resolution = await resolveWorkbenchApp({
|
|
216
|
+
appId,
|
|
217
|
+
organizationId,
|
|
218
|
+
slug
|
|
219
|
+
});
|
|
220
|
+
const check = describeAppTarget(resolution, {
|
|
200
221
|
slug,
|
|
201
222
|
title
|
|
202
223
|
});
|