@sanity/cli 7.17.0 → 8.0.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 +81 -6
- package/dist/SanityHelp.js +1 -35
- package/dist/SanityHelp.js.map +1 -1
- package/dist/actions/assets/assetFileError.js +9 -0
- package/dist/actions/assets/assetFileError.js.map +1 -0
- package/dist/actions/assets/uploadAssetFromFile.js +40 -0
- package/dist/actions/assets/uploadAssetFromFile.js.map +1 -0
- package/dist/actions/assets/uploadAssetWithProgress.js +76 -0
- package/dist/actions/assets/uploadAssetWithProgress.js.map +1 -0
- package/dist/actions/deploy/deployApp.js +39 -44
- package/dist/actions/deploy/deployApp.js.map +1 -1
- package/dist/actions/deploy/deployChecks.js +21 -13
- package/dist/actions/deploy/deployChecks.js.map +1 -1
- package/dist/actions/deploy/deployRunner.js +8 -7
- package/dist/actions/deploy/deployRunner.js.map +1 -1
- package/dist/actions/deploy/deployStudio.js +55 -35
- package/dist/actions/deploy/deployStudio.js.map +1 -1
- package/dist/actions/deploy/deploymentPlan.js +17 -29
- package/dist/actions/deploy/deploymentPlan.js.map +1 -1
- package/dist/actions/deploy/resolveDeployTarget.js +2 -8
- package/dist/actions/deploy/resolveDeployTarget.js.map +1 -1
- package/dist/actions/dev/servers/getDevServerConfig.js +2 -8
- package/dist/actions/dev/servers/getDevServerConfig.js.map +1 -1
- package/dist/actions/dev/servers/startStudioDevServer.js +7 -1
- package/dist/actions/dev/servers/startStudioDevServer.js.map +1 -1
- package/dist/actions/init/bootstrapRemoteTemplate.js +2 -2
- package/dist/actions/init/bootstrapRemoteTemplate.js.map +1 -1
- package/dist/actions/schema/listSchemas.js +1 -1
- package/dist/actions/schema/listSchemas.js.map +1 -1
- package/dist/actions/tokens/constants.js +2 -2
- package/dist/actions/tokens/constants.js.map +1 -1
- package/dist/actions/tokens/expiry.js +35 -0
- package/dist/actions/tokens/expiry.js.map +1 -0
- package/dist/actions/tokens/types.js.map +1 -1
- package/dist/actions/tokens/validateRole.js +5 -2
- package/dist/actions/tokens/validateRole.js.map +1 -1
- package/dist/actions/typegen/count.js +6 -0
- package/dist/actions/typegen/count.js.map +1 -0
- package/dist/actions/typegen/formatPath.js +5 -0
- package/dist/actions/typegen/formatPath.js.map +1 -0
- package/dist/actions/typegen/percent.js +8 -0
- package/dist/actions/typegen/percent.js.map +1 -0
- package/dist/actions/typegen/renderTypegenProgress.js +88 -0
- package/dist/actions/typegen/renderTypegenProgress.js.map +1 -0
- package/dist/actions/undeploy/adapters.js +6 -9
- package/dist/actions/undeploy/adapters.js.map +1 -1
- package/dist/actions/undeploy/runUndeploy.js +12 -4
- package/dist/actions/undeploy/runUndeploy.js.map +1 -1
- package/dist/actions/undeploy/undeployPlan.js +6 -14
- package/dist/actions/undeploy/undeployPlan.js.map +1 -1
- package/dist/commands/assets/upload.js +126 -0
- package/dist/commands/assets/upload.js.map +1 -0
- package/dist/commands/backups/list.js +1 -1
- package/dist/commands/backups/list.js.map +1 -1
- package/dist/commands/datasets/copy.js +1 -1
- package/dist/commands/datasets/copy.js.map +1 -1
- package/dist/commands/login.js +2 -8
- package/dist/commands/login.js.map +1 -1
- package/dist/commands/mcp/configure.js.map +1 -1
- package/dist/commands/migrations/list.js +1 -1
- package/dist/commands/migrations/list.js.map +1 -1
- package/dist/commands/migrations/run.js +67 -3
- package/dist/commands/migrations/run.js.map +1 -1
- package/dist/commands/new.js +56 -4
- package/dist/commands/new.js.map +1 -1
- package/dist/commands/organizations/list.js +1 -1
- package/dist/commands/organizations/list.js.map +1 -1
- package/dist/commands/projects/list.js +39 -12
- package/dist/commands/projects/list.js.map +1 -1
- package/dist/commands/projects/unclaimed.js +39 -33
- package/dist/commands/projects/unclaimed.js.map +1 -1
- package/dist/commands/tokens/create.js +92 -7
- package/dist/commands/tokens/create.js.map +1 -1
- package/dist/commands/tokens/delete.js +2 -2
- package/dist/commands/tokens/delete.js.map +1 -1
- package/dist/commands/tokens/list.js +12 -11
- package/dist/commands/tokens/list.js.map +1 -1
- package/dist/commands/tokens/rotate.js +95 -0
- package/dist/commands/tokens/rotate.js.map +1 -0
- package/dist/commands/typegen/generate.js +222 -0
- package/dist/commands/typegen/generate.js.map +1 -0
- package/dist/commands/users/list.js +8 -8
- package/dist/commands/users/list.js.map +1 -1
- package/dist/exports/_internal.d.ts +29 -0
- package/dist/exports/_internal.js +1 -0
- package/dist/exports/_internal.js.map +1 -1
- package/dist/exports/invokeSanityCli/commandPolicies/mcpPolicy.js +29 -14
- package/dist/exports/invokeSanityCli/commandPolicies/mcpPolicy.js.map +1 -1
- package/dist/exports/invokeSanityCli/help.js +4 -0
- package/dist/exports/invokeSanityCli/help.js.map +1 -1
- package/dist/exports/invokeSanityCli/index.js +2 -0
- package/dist/exports/invokeSanityCli/index.js.map +1 -1
- package/dist/hooks/commandNotFound/topicAliases.js +13 -40
- package/dist/hooks/commandNotFound/topicAliases.js.map +1 -1
- package/dist/hooks/prerun/setupTelemetry.js +3 -2
- package/dist/hooks/prerun/setupTelemetry.js.map +1 -1
- package/dist/server/vite/plugin-typegen.js +4 -16
- package/dist/server/vite/plugin-typegen.js.map +1 -1
- package/dist/services/assets.js +46 -0
- package/dist/services/assets.js.map +1 -0
- package/dist/services/newInstructions.js +48 -0
- package/dist/services/newInstructions.js.map +1 -0
- package/dist/services/tokens.js +81 -31
- package/dist/services/tokens.js.map +1 -1
- package/dist/topicAliases.js +43 -0
- package/dist/topicAliases.js.map +1 -1
- package/dist/util/parseArguments.js +7 -2
- package/dist/util/parseArguments.js.map +1 -1
- package/dist/util/readTokenFromStdin.js +17 -0
- package/dist/util/readTokenFromStdin.js.map +1 -0
- package/dist/util/responsiveTable.js +97 -0
- package/dist/util/responsiveTable.js.map +1 -0
- package/dist/util/telemetry/commandTelemetry.js +34 -0
- package/dist/util/telemetry/commandTelemetry.js.map +1 -0
- package/dist/util/unclaimedProjects.js +10 -0
- package/dist/util/unclaimedProjects.js.map +1 -1
- package/oclif.config.js +2 -4
- package/oclif.manifest.json +224 -2
- package/package.json +12 -10
- package/templates/shopify/components/inputs/ShopifyMetafield.tsx +20 -0
- package/templates/shopify/docs/features.md +24 -0
- package/templates/shopify/schemaTypes/index.ts +2 -0
- package/templates/shopify/schemaTypes/objects/shopify/shopifyCollectionType.ts +18 -1
- package/templates/shopify/schemaTypes/objects/shopify/shopifyMetafieldType.ts +47 -0
- package/templates/shopify/schemaTypes/objects/shopify/shopifyProductType.ts +17 -0
- package/templates/shopify/utils/formatMetafieldValue.ts +30 -0
- package/templates/shopify-online-storefront/components/inputs/ShopifyMetafield.tsx +22 -0
- package/templates/shopify-online-storefront/schemaTypes/index.ts +4 -0
- package/templates/shopify-online-storefront/schemaTypes/objects/shop.ts +16 -0
- package/templates/shopify-online-storefront/schemaTypes/objects/shopifyCollection.ts +19 -0
- package/templates/shopify-online-storefront/schemaTypes/objects/shopifyMetafield.ts +53 -0
- package/templates/shopify-online-storefront/schemaTypes/objects/shopifyProduct.ts +19 -0
- package/templates/shopify-online-storefront/utils/formatMetafieldValue.ts +30 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/actions/dev/servers/startStudioDevServer.ts"],"sourcesContent":["import {styleText} from 'node:util'\n\nimport {\n checkRequiredDependencies,\n checkStudioDependencyVersions,\n compareDependencyVersions,\n} from '@sanity/cli-build/_internal/build'\nimport {getLocalPackageVersion, isInteractive} from '@sanity/cli-core'\nimport {confirm, logSymbols, spinner} from '@sanity/cli-core/ux'\nimport {isWorkbenchApp} from '@sanity/workbench-cli'\nimport {parse as semverParse} from 'semver'\n\nimport {startDevServer} from '../../../server/devServer.js'\nimport {gracefulServerDeath} from '../../../server/gracefulServerDeath.js'\nimport {getProjectById} from '../../../services/projects.js'\nimport {getAppId} from '../../../util/appId.js'\nimport {getPackageManagerChoice} from '../../../util/packageManager/packageManagerChoice.js'\nimport {upgradePackages} from '../../../util/packageManager/upgradePackages.js'\nimport {checkDependenciesEventListenerFactory} from '../../build/eventListenerFactory.js'\nimport {shouldAutoUpdate} from '../../build/shouldAutoUpdate.js'\nimport {devDebug} from '../devDebug.js'\nimport {type DevActionOptions, type StartDevServerResult} from '../types.js'\nimport {getDashboardAppURL} from './getDashboardAppUrl.js'\nimport {getDevServerConfig} from './getDevServerConfig.js'\n\nexport async function startStudioDevServer(\n options: DevActionOptions,\n): Promise<StartDevServerResult> {\n const {announceUrl = true, cliConfig, flags, httpPort, output, workDir} = options\n const projectId = cliConfig?.api?.projectId\n let organizationId: string | undefined\n\n // Workbench apps don't load through the dashboard, so the flag has no\n // meaning for them and is ignored.\n const loadInDashboard = flags['load-in-dashboard'] && !isWorkbenchApp(cliConfig?.app)\n\n // Check studio dependency versions\n await checkStudioDependencyVersions(workDir, output)\n\n const {installedSanityVersion} = await checkRequiredDependencies({\n ...options,\n ...checkDependenciesEventListenerFactory(output),\n })\n\n // Check if auto-updates are enabled\n const autoUpdatesEnabled = shouldAutoUpdate({cliConfig, flags, output})\n\n if (autoUpdatesEnabled) {\n // Get the clean version without build metadata: https://semver.org/#spec-item-10\n const cleanSanityVersion = semverParse(installedSanityVersion)?.version\n if (!cleanSanityVersion) {\n throw new Error(`Failed to parse installed Sanity version: ${installedSanityVersion}`)\n }\n\n const sanityDependencies = [\n {name: 'sanity', version: cleanSanityVersion},\n {name: '@sanity/vision', version: cleanSanityVersion},\n ]\n\n output.log(`${logSymbols.info} Running with auto-updates enabled`)\n\n // Check local versions against deployed versions\n let result: Awaited<ReturnType<typeof compareDependencyVersions>> | undefined\n\n const appId = getAppId(cliConfig)\n\n try {\n result = await compareDependencyVersions(sanityDependencies, workDir, {appId})\n } catch (err) {\n output.warn(`Failed to compare local versions against auto-updating versions: ${err}`)\n }\n\n if (result?.unresolvedPrerelease.length) {\n for (const mod of result.unresolvedPrerelease) {\n output.warn(\n `Your local version of ${mod.pkg} (${mod.version}) is a prerelease not available on the auto-updates CDN. The locally installed version will be used.`,\n )\n }\n }\n\n // mismatch between local and auto-updating dependencies\n if (result?.mismatched.length) {\n const message =\n `The following local package versions are different from the versions currently served at runtime.\\n` +\n `When using auto updates, we recommend that you run with the same versions locally as will be used when deploying.\\n\\n` +\n `${result.mismatched.map((mod) => ` - ${mod.pkg} (local version: ${mod.installed}, runtime version: ${mod.remote})`).join('\\n')}\\n\\n`\n\n if (isInteractive()) {\n const shouldUpgrade = await confirm({\n default: true,\n message: styleText('yellow', `${message}Do you want to upgrade local versions?`),\n })\n if (shouldUpgrade) {\n await upgradePackages(\n {\n packageManager: (await getPackageManagerChoice(workDir, {interactive: false})).chosen,\n packages: result.mismatched.map((res) => [res.pkg, res.remote]),\n },\n {output, workDir},\n )\n }\n } else {\n // In this case we warn the user but we don't ask them if they want to upgrade because it's not interactive.\n output.log(styleText('yellow', message))\n }\n }\n }\n\n if (cliConfig?.schemaExtraction?.enabled) {\n output.log(`${logSymbols.info} Running dev server with schema extraction enabled`)\n }\n\n const config = getDevServerConfig({cliConfig, flags, httpPort, output, workDir})\n\n if (loadInDashboard) {\n if (!projectId) {\n output.error('Project Id is required to load in dashboard', {exit: 1})\n }\n\n try {\n const project = await getProjectById(projectId!)\n organizationId = project.organizationId!\n } catch (error) {\n devDebug('Error getting organization id from project id', error)\n output.error('Failed to get organization id from project id', {exit: 1})\n }\n }\n\n try {\n const startTime = Date.now()\n const spin = spinner('Starting dev server').start()\n const {close, server} = await startDevServer(config)\n\n const {info: loggerInfo} = server.config.logger\n const {port} = server.config.server\n const httpHost = config.httpHost || 'localhost'\n\n if (loadInDashboard) {\n spin.succeed()\n\n output.log(`Dev server started on port ${port}`)\n output.log(`View your studio in the Sanity dashboard here:`)\n output.log(\n styleText(\n ['blue', 'underline'],\n await getDashboardAppURL({\n httpHost,\n httpPort: port,\n organizationId: organizationId!,\n }),\n ),\n )\n } else {\n const startupDuration = Date.now() - startTime\n const url = `http://${httpHost || 'localhost'}:${port}${config.basePath}`\n const appType = 'Sanity Studio'\n\n const viteVersion = await getLocalPackageVersion('vite', import.meta.url)\n spin.succeed()\n\n loggerInfo(\n `${appType} ` +\n `using ${styleText('cyan', `vite@${viteVersion}`)} ` +\n `ready in ${styleText('cyan', `${Math.ceil(startupDuration)}ms`)}` +\n (announceUrl ? ` and running at ${styleText('cyan', url)}` : ''),\n )\n }\n\n return {close, server, started: true}\n } catch (err) {\n devDebug('Error starting studio dev server', err)\n throw gracefulServerDeath('dev', config.httpHost, config.httpPort, err)\n }\n}\n"],"names":["styleText","checkRequiredDependencies","checkStudioDependencyVersions","compareDependencyVersions","getLocalPackageVersion","isInteractive","confirm","logSymbols","spinner","isWorkbenchApp","parse","semverParse","startDevServer","gracefulServerDeath","getProjectById","getAppId","getPackageManagerChoice","upgradePackages","checkDependenciesEventListenerFactory","shouldAutoUpdate","devDebug","getDashboardAppURL","getDevServerConfig","startStudioDevServer","options","announceUrl","cliConfig","flags","httpPort","output","workDir","projectId","api","organizationId","loadInDashboard","app","installedSanityVersion","autoUpdatesEnabled","cleanSanityVersion","version","Error","sanityDependencies","name","log","info","result","appId","err","warn","unresolvedPrerelease","length","mod","pkg","mismatched","message","map","installed","remote","join","shouldUpgrade","default","packageManager","interactive","chosen","packages","res","schemaExtraction","enabled","config","error","exit","project","startTime","Date","now","spin","start","close","server","loggerInfo","logger","port","httpHost","succeed","startupDuration","url","basePath","appType","viteVersion","Math","ceil","started"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../../src/actions/dev/servers/startStudioDevServer.ts"],"sourcesContent":["import {styleText} from 'node:util'\n\nimport {\n checkRequiredDependencies,\n checkStudioDependencyVersions,\n compareDependencyVersions,\n} from '@sanity/cli-build/_internal/build'\nimport {getLocalPackageVersion, isInteractive} from '@sanity/cli-core'\nimport {confirm, logSymbols, spinner} from '@sanity/cli-core/ux'\nimport {isWorkbenchApp} from '@sanity/workbench-cli'\nimport {parse as semverParse} from 'semver'\n\nimport {startDevServer} from '../../../server/devServer.js'\nimport {gracefulServerDeath} from '../../../server/gracefulServerDeath.js'\nimport {getProjectById} from '../../../services/projects.js'\nimport {getAppId} from '../../../util/appId.js'\nimport {getPackageManagerChoice} from '../../../util/packageManager/packageManagerChoice.js'\nimport {upgradePackages} from '../../../util/packageManager/upgradePackages.js'\nimport {hasLocalUnclaimedProject} from '../../../util/unclaimedProjects.js'\nimport {checkDependenciesEventListenerFactory} from '../../build/eventListenerFactory.js'\nimport {shouldAutoUpdate} from '../../build/shouldAutoUpdate.js'\nimport {devDebug} from '../devDebug.js'\nimport {type DevActionOptions, type StartDevServerResult} from '../types.js'\nimport {getDashboardAppURL} from './getDashboardAppUrl.js'\nimport {getDevServerConfig} from './getDevServerConfig.js'\n\nexport async function startStudioDevServer(\n options: DevActionOptions,\n): Promise<StartDevServerResult> {\n const {announceUrl = true, cliConfig, flags, httpPort, output, workDir} = options\n const projectId = cliConfig?.api?.projectId\n let organizationId: string | undefined\n\n // Workbench apps don't load through the dashboard, so the flag has no\n // meaning for them and is ignored.\n const loadInDashboard = flags['load-in-dashboard'] && !isWorkbenchApp(cliConfig?.app)\n\n // Check studio dependency versions\n await checkStudioDependencyVersions(workDir, output)\n\n const {installedSanityVersion} = await checkRequiredDependencies({\n ...options,\n ...checkDependenciesEventListenerFactory(output),\n })\n\n // Check if auto-updates are enabled\n const autoUpdatesEnabled = shouldAutoUpdate({cliConfig, flags, output})\n\n if (autoUpdatesEnabled) {\n // Get the clean version without build metadata: https://semver.org/#spec-item-10\n const cleanSanityVersion = semverParse(installedSanityVersion)?.version\n if (!cleanSanityVersion) {\n throw new Error(`Failed to parse installed Sanity version: ${installedSanityVersion}`)\n }\n\n const sanityDependencies = [\n {name: 'sanity', version: cleanSanityVersion},\n {name: '@sanity/vision', version: cleanSanityVersion},\n ]\n\n output.log(`${logSymbols.info} Running with auto-updates enabled`)\n\n // Check local versions against deployed versions\n let result: Awaited<ReturnType<typeof compareDependencyVersions>> | undefined\n\n const appId = getAppId(cliConfig)\n\n try {\n result = await compareDependencyVersions(sanityDependencies, workDir, {appId})\n } catch (err) {\n output.warn(`Failed to compare local versions against auto-updating versions: ${err}`)\n }\n\n if (result?.unresolvedPrerelease.length) {\n for (const mod of result.unresolvedPrerelease) {\n output.warn(\n `Your local version of ${mod.pkg} (${mod.version}) is a prerelease not available on the auto-updates CDN. The locally installed version will be used.`,\n )\n }\n }\n\n // mismatch between local and auto-updating dependencies\n if (result?.mismatched.length) {\n const message =\n `The following local package versions are different from the versions currently served at runtime.\\n` +\n `When using auto updates, we recommend that you run with the same versions locally as will be used when deploying.\\n\\n` +\n `${result.mismatched.map((mod) => ` - ${mod.pkg} (local version: ${mod.installed}, runtime version: ${mod.remote})`).join('\\n')}\\n\\n`\n\n if (isInteractive()) {\n const shouldUpgrade = await confirm({\n default: true,\n message: styleText('yellow', `${message}Do you want to upgrade local versions?`),\n })\n if (shouldUpgrade) {\n await upgradePackages(\n {\n packageManager: (await getPackageManagerChoice(workDir, {interactive: false})).chosen,\n packages: result.mismatched.map((res) => [res.pkg, res.remote]),\n },\n {output, workDir},\n )\n }\n } else {\n // In this case we warn the user but we don't ask them if they want to upgrade because it's not interactive.\n output.log(styleText('yellow', message))\n }\n }\n }\n\n if (cliConfig?.schemaExtraction?.enabled) {\n output.log(`${logSymbols.info} Running dev server with schema extraction enabled`)\n }\n\n const config = getDevServerConfig({cliConfig, flags, httpPort, output, workDir})\n\n if (loadInDashboard) {\n if (!projectId) {\n output.error('Project Id is required to load in dashboard', {exit: 1})\n }\n\n try {\n const project = await getProjectById(projectId!)\n organizationId = project.organizationId!\n } catch (error) {\n devDebug('Error getting organization id from project id', error)\n output.error('Failed to get organization id from project id', {exit: 1})\n }\n }\n\n try {\n const startTime = Date.now()\n const spin = spinner('Starting dev server').start()\n const {close, server} = await startDevServer(config)\n\n const {info: loggerInfo} = server.config.logger\n const {port} = server.config.server\n const httpHost = config.httpHost || 'localhost'\n\n if (loadInDashboard) {\n spin.succeed()\n\n output.log(`Dev server started on port ${port}`)\n output.log(`View your studio in the Sanity dashboard here:`)\n output.log(\n styleText(\n ['blue', 'underline'],\n await getDashboardAppURL({\n httpHost,\n httpPort: port,\n organizationId: organizationId!,\n }),\n ),\n )\n } else {\n const startupDuration = Date.now() - startTime\n const url = withUnclaimedSignInHash(\n `http://${httpHost || 'localhost'}:${port}${config.basePath}`,\n projectId,\n )\n const appType = 'Sanity Studio'\n\n const viteVersion = await getLocalPackageVersion('vite', import.meta.url)\n spin.succeed()\n\n loggerInfo(\n `${appType} ` +\n `using ${styleText('cyan', `vite@${viteVersion}`)} ` +\n `ready in ${styleText('cyan', `${Math.ceil(startupDuration)}ms`)}` +\n (announceUrl ? ` and running at ${styleText('cyan', url)}` : ''),\n )\n }\n\n return {close, server, started: true}\n } catch (err) {\n devDebug('Error starting studio dev server', err)\n throw gracefulServerDeath('dev', config.httpHost, config.httpPort, err)\n }\n}\n\nfunction withUnclaimedSignInHash(url: string, projectId: string | undefined): string {\n const token = process.env.SANITY_AUTH_TOKEN\n if (!token || !projectId || !hasLocalUnclaimedProject(projectId)) return url\n return `${url}#token=${encodeURIComponent(token)}`\n}\n"],"names":["styleText","checkRequiredDependencies","checkStudioDependencyVersions","compareDependencyVersions","getLocalPackageVersion","isInteractive","confirm","logSymbols","spinner","isWorkbenchApp","parse","semverParse","startDevServer","gracefulServerDeath","getProjectById","getAppId","getPackageManagerChoice","upgradePackages","hasLocalUnclaimedProject","checkDependenciesEventListenerFactory","shouldAutoUpdate","devDebug","getDashboardAppURL","getDevServerConfig","startStudioDevServer","options","announceUrl","cliConfig","flags","httpPort","output","workDir","projectId","api","organizationId","loadInDashboard","app","installedSanityVersion","autoUpdatesEnabled","cleanSanityVersion","version","Error","sanityDependencies","name","log","info","result","appId","err","warn","unresolvedPrerelease","length","mod","pkg","mismatched","message","map","installed","remote","join","shouldUpgrade","default","packageManager","interactive","chosen","packages","res","schemaExtraction","enabled","config","error","exit","project","startTime","Date","now","spin","start","close","server","loggerInfo","logger","port","httpHost","succeed","startupDuration","url","withUnclaimedSignInHash","basePath","appType","viteVersion","Math","ceil","started","token","process","env","SANITY_AUTH_TOKEN","encodeURIComponent"],"mappings":"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"}
|
|
@@ -59,12 +59,12 @@ export async function bootstrapRemoteTemplate(opts) {
|
|
|
59
59
|
label: READ_TOKEN_LABEL,
|
|
60
60
|
projectId: variables.projectId,
|
|
61
61
|
roleName: API_READ_TOKEN_ROLE
|
|
62
|
-
})).
|
|
62
|
+
})).token : undefined;
|
|
63
63
|
const writeToken = needsWriteToken ? (await createToken({
|
|
64
64
|
label: WRITE_TOKEN_LABEL,
|
|
65
65
|
projectId: variables.projectId,
|
|
66
66
|
roleName: API_WRITE_TOKEN_ROLE
|
|
67
|
-
})).
|
|
67
|
+
})).token : undefined;
|
|
68
68
|
for (const pkg of packages ?? [
|
|
69
69
|
''
|
|
70
70
|
]){
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/actions/init/bootstrapRemoteTemplate.ts"],"sourcesContent":["import {mkdir} from 'node:fs/promises'\nimport {join} from 'node:path'\n\nimport {Output, subdebug} from '@sanity/cli-core'\nimport {logSymbols, spinner} from '@sanity/cli-core/ux'\nimport {getMonoRepo, GitHubFileReader, validateTemplate} from '@sanity/template-validator'\nimport {type Framework, frameworks} from '@vercel/frameworks'\n\nimport {createCorsOrigin} from '../../services/cors.js'\nimport {createToken} from '../../services/tokens.js'\nimport {detectFrameworkRecord} from '../../util/detectFramework.js'\nimport {getDefaultPortForFramework} from '../../util/frameworkPort.js'\nimport {type GenerateConfigOptions} from './createStudioConfig.js'\nimport {tryGitInit} from './git.js'\nimport {\n applyEnvVariables,\n checkIfNeedsApiToken,\n downloadAndExtractRepo,\n getGitHubRawContentUrl,\n type RepoInfo,\n tryApplyPackageName,\n} from './remoteTemplate.js'\nimport {updateInitialTemplateMetadata} from './updateInitialTemplateMetadata.js'\n\nconst debug = subdebug('init:bootstrapRemoteTemplate')\n\ninterface BootstrapRemoteOptions {\n output: Output\n outputPath: string\n packageName: string\n repoInfo: RepoInfo\n variables: GenerateConfigOptions['variables']\n\n bearerToken?: string\n}\n\nconst SANITY_DEFAULT_PORT = 3333\nconst READ_TOKEN_LABEL = 'Live Preview API'\nconst WRITE_TOKEN_LABEL = 'App Write Token'\nconst INITIAL_COMMIT_MESSAGE = 'Initial commit from Sanity CLI'\nconst API_READ_TOKEN_ROLE = 'viewer'\nconst API_WRITE_TOKEN_ROLE = 'editor'\n\nexport async function bootstrapRemoteTemplate(opts: BootstrapRemoteOptions): Promise<void> {\n const {bearerToken, output, outputPath, packageName, repoInfo, variables} = opts\n const name = [repoInfo.username, repoInfo.name, repoInfo.filePath].filter(Boolean).join('/')\n const contentsUrl = getGitHubRawContentUrl(repoInfo)\n const headers: Record<string, string> = {}\n if (bearerToken) {\n headers.Authorization = `Bearer ${bearerToken}`\n }\n const spin = spinner(`Bootstrapping files from template \"${name}\"`).start()\n const corsAdded: number[] = [SANITY_DEFAULT_PORT]\n\n debug('Validating remote template')\n const fileReader = new GitHubFileReader(contentsUrl, headers)\n const packages = await getMonoRepo(fileReader)\n const validation = await validateTemplate(fileReader, packages)\n if (!validation.isValid) {\n throw new Error(validation.errors.join('\\n'))\n }\n\n debug('Create new directory \"%s\"', outputPath)\n await mkdir(outputPath, {recursive: true})\n\n debug('Downloading and extracting repo to %s', outputPath)\n await downloadAndExtractRepo(outputPath, repoInfo, bearerToken)\n\n debug('Checking if template needs read token')\n const needsReadToken = await Promise.all(\n (packages ?? ['']).map((pkg) => checkIfNeedsApiToken(join(outputPath, pkg), 'read')),\n ).then((results) => results.some(Boolean))\n const needsWriteToken = await Promise.all(\n (packages ?? ['']).map((pkg) => checkIfNeedsApiToken(join(outputPath, pkg), 'write')),\n ).then((results) => results.some(Boolean))\n\n debug('Applying environment variables')\n const readToken = needsReadToken\n ? (\n await createToken({\n label: READ_TOKEN_LABEL,\n projectId: variables.projectId,\n roleName: API_READ_TOKEN_ROLE,\n })\n ).
|
|
1
|
+
{"version":3,"sources":["../../../src/actions/init/bootstrapRemoteTemplate.ts"],"sourcesContent":["import {mkdir} from 'node:fs/promises'\nimport {join} from 'node:path'\n\nimport {Output, subdebug} from '@sanity/cli-core'\nimport {logSymbols, spinner} from '@sanity/cli-core/ux'\nimport {getMonoRepo, GitHubFileReader, validateTemplate} from '@sanity/template-validator'\nimport {type Framework, frameworks} from '@vercel/frameworks'\n\nimport {createCorsOrigin} from '../../services/cors.js'\nimport {createToken} from '../../services/tokens.js'\nimport {detectFrameworkRecord} from '../../util/detectFramework.js'\nimport {getDefaultPortForFramework} from '../../util/frameworkPort.js'\nimport {type GenerateConfigOptions} from './createStudioConfig.js'\nimport {tryGitInit} from './git.js'\nimport {\n applyEnvVariables,\n checkIfNeedsApiToken,\n downloadAndExtractRepo,\n getGitHubRawContentUrl,\n type RepoInfo,\n tryApplyPackageName,\n} from './remoteTemplate.js'\nimport {updateInitialTemplateMetadata} from './updateInitialTemplateMetadata.js'\n\nconst debug = subdebug('init:bootstrapRemoteTemplate')\n\ninterface BootstrapRemoteOptions {\n output: Output\n outputPath: string\n packageName: string\n repoInfo: RepoInfo\n variables: GenerateConfigOptions['variables']\n\n bearerToken?: string\n}\n\nconst SANITY_DEFAULT_PORT = 3333\nconst READ_TOKEN_LABEL = 'Live Preview API'\nconst WRITE_TOKEN_LABEL = 'App Write Token'\nconst INITIAL_COMMIT_MESSAGE = 'Initial commit from Sanity CLI'\nconst API_READ_TOKEN_ROLE = 'viewer'\nconst API_WRITE_TOKEN_ROLE = 'editor'\n\nexport async function bootstrapRemoteTemplate(opts: BootstrapRemoteOptions): Promise<void> {\n const {bearerToken, output, outputPath, packageName, repoInfo, variables} = opts\n const name = [repoInfo.username, repoInfo.name, repoInfo.filePath].filter(Boolean).join('/')\n const contentsUrl = getGitHubRawContentUrl(repoInfo)\n const headers: Record<string, string> = {}\n if (bearerToken) {\n headers.Authorization = `Bearer ${bearerToken}`\n }\n const spin = spinner(`Bootstrapping files from template \"${name}\"`).start()\n const corsAdded: number[] = [SANITY_DEFAULT_PORT]\n\n debug('Validating remote template')\n const fileReader = new GitHubFileReader(contentsUrl, headers)\n const packages = await getMonoRepo(fileReader)\n const validation = await validateTemplate(fileReader, packages)\n if (!validation.isValid) {\n throw new Error(validation.errors.join('\\n'))\n }\n\n debug('Create new directory \"%s\"', outputPath)\n await mkdir(outputPath, {recursive: true})\n\n debug('Downloading and extracting repo to %s', outputPath)\n await downloadAndExtractRepo(outputPath, repoInfo, bearerToken)\n\n debug('Checking if template needs read token')\n const needsReadToken = await Promise.all(\n (packages ?? ['']).map((pkg) => checkIfNeedsApiToken(join(outputPath, pkg), 'read')),\n ).then((results) => results.some(Boolean))\n const needsWriteToken = await Promise.all(\n (packages ?? ['']).map((pkg) => checkIfNeedsApiToken(join(outputPath, pkg), 'write')),\n ).then((results) => results.some(Boolean))\n\n debug('Applying environment variables')\n const readToken = needsReadToken\n ? (\n await createToken({\n label: READ_TOKEN_LABEL,\n projectId: variables.projectId,\n roleName: API_READ_TOKEN_ROLE,\n })\n ).token\n : undefined\n const writeToken = needsWriteToken\n ? (\n await createToken({\n label: WRITE_TOKEN_LABEL,\n projectId: variables.projectId,\n roleName: API_WRITE_TOKEN_ROLE,\n })\n ).token\n : undefined\n\n for (const pkg of packages ?? ['']) {\n const packagePath = join(outputPath, pkg)\n const packageFramework: Framework | null = await detectFrameworkRecord({\n frameworkList: frameworks as readonly Framework[],\n rootPath: packagePath,\n })\n\n const port = getDefaultPortForFramework(packageFramework?.slug)\n if (!corsAdded.includes(port)) {\n debug('Setting CORS origin to http://localhost:%d', port)\n await createCorsOrigin({\n allowCredentials: true,\n origin: `http://localhost:${port}`,\n projectId: variables.projectId,\n })\n corsAdded.push(port)\n }\n\n debug('Applying environment variables to %s', pkg)\n // Next.js uses `.env.local` for local environment variables\n const envName = packageFramework?.slug === 'nextjs' ? '.env.local' : '.env'\n await applyEnvVariables(packagePath, {...variables, readToken, writeToken}, envName)\n }\n\n debug('Setting package name to %s', packageName)\n await tryApplyPackageName(outputPath, packageName)\n\n debug('Initializing git repository')\n tryGitInit(outputPath, INITIAL_COMMIT_MESSAGE)\n\n debug('Updating initial template metadata')\n await updateInitialTemplateMetadata(variables.projectId, `external-${name}`)\n\n spin.succeed()\n const newlyAddedPorts = corsAdded.slice(1)\n if (newlyAddedPorts.length > 0) {\n output.log(\n `${logSymbols.success} CORS origins added (${newlyAddedPorts.map((p) => `localhost:${p}`).join(', ')})`,\n )\n }\n if (readToken) output.log(`${logSymbols.success} API token generated (${READ_TOKEN_LABEL})`)\n if (writeToken) output.log(`${logSymbols.success} API token generated (${WRITE_TOKEN_LABEL})`)\n}\n"],"names":["mkdir","join","subdebug","logSymbols","spinner","getMonoRepo","GitHubFileReader","validateTemplate","frameworks","createCorsOrigin","createToken","detectFrameworkRecord","getDefaultPortForFramework","tryGitInit","applyEnvVariables","checkIfNeedsApiToken","downloadAndExtractRepo","getGitHubRawContentUrl","tryApplyPackageName","updateInitialTemplateMetadata","debug","SANITY_DEFAULT_PORT","READ_TOKEN_LABEL","WRITE_TOKEN_LABEL","INITIAL_COMMIT_MESSAGE","API_READ_TOKEN_ROLE","API_WRITE_TOKEN_ROLE","bootstrapRemoteTemplate","opts","bearerToken","output","outputPath","packageName","repoInfo","variables","name","username","filePath","filter","Boolean","contentsUrl","headers","Authorization","spin","start","corsAdded","fileReader","packages","validation","isValid","Error","errors","recursive","needsReadToken","Promise","all","map","pkg","then","results","some","needsWriteToken","readToken","label","projectId","roleName","token","undefined","writeToken","packagePath","packageFramework","frameworkList","rootPath","port","slug","includes","allowCredentials","origin","push","envName","succeed","newlyAddedPorts","slice","length","log","success","p"],"mappings":"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"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { styleText } from 'node:util';
|
|
2
2
|
import { studioWorkerTask } from '@sanity/cli-core';
|
|
3
3
|
import { logSymbols } from '@sanity/cli-core/ux';
|
|
4
|
-
import { Table } from 'console-table-printer';
|
|
5
4
|
import { getSchemas } from '../../services/schemas.js';
|
|
5
|
+
import { Table } from '../../util/responsiveTable.js';
|
|
6
6
|
import { isDefined } from '../manifest/schemaTypeHelpers.js';
|
|
7
7
|
import { getDatasetsOutString } from './utils/schemaStoreOutStrings.js';
|
|
8
8
|
import { SCHEMA_PERMISSION_HELP_TEXT } from './utils/schemaStoreValidation.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/actions/schema/listSchemas.ts"],"sourcesContent":["import {styleText} from 'node:util'\n\nimport {type Output, studioWorkerTask} from '@sanity/cli-core'\nimport {logSymbols} from '@sanity/cli-core/ux'\nimport {
|
|
1
|
+
{"version":3,"sources":["../../../src/actions/schema/listSchemas.ts"],"sourcesContent":["import {styleText} from 'node:util'\n\nimport {type Output, studioWorkerTask} from '@sanity/cli-core'\nimport {logSymbols} from '@sanity/cli-core/ux'\nimport {type Workspace} from 'sanity'\n\nimport {getSchemas} from '../../services/schemas.js'\nimport {Table} from '../../util/responsiveTable.js'\nimport {isDefined} from '../manifest/schemaTypeHelpers.js'\nimport {type StoredWorkspaceSchema} from '../manifest/types.js'\nimport {type UniqWorkspaceWorkerData} from './types.js'\nimport {getDatasetsOutString} from './utils/schemaStoreOutStrings.js'\nimport {SCHEMA_PERMISSION_HELP_TEXT} from './utils/schemaStoreValidation.js'\n\ninterface ListSchemasOptions {\n configPath: string\n json: boolean\n output: Output\n workDir: string\n\n id?: string\n}\n\nclass DatasetError extends Error {\n public dataset: string\n public projectId: string\n constructor(args: {dataset: string; options?: ErrorOptions; projectId: string}) {\n super((args.options?.cause as {message?: string})?.message, args.options)\n this.projectId = args.projectId\n this.dataset = args.dataset\n this.name = 'DatasetError'\n }\n}\n\nexport async function listSchemas(options: ListSchemasOptions): Promise<void> {\n const {configPath, id, json, output, workDir} = options\n\n const projectDatasets = await studioWorkerTask<(Workspace & {key: string})[]>(\n new URL('uniqueWorkspaces.worker.js', import.meta.url),\n {\n name: 'uniqueWorkspaces',\n studioRootPath: workDir,\n workerData: {configPath} satisfies UniqWorkspaceWorkerData,\n },\n )\n\n const schemas = await getDatasetSchemas(projectDatasets, id)\n const parsedSchemas = parseSchemas(schemas, output, json)\n\n if (parsedSchemas.length === 0) {\n const datasetString = getDatasetsOutString(projectDatasets.map((dataset) => dataset.dataset))\n\n throw new Error(\n id\n ? `Schema for id \"${id}\" not found in ${datasetString}`\n : `No schemas found in ${datasetString}`,\n )\n }\n\n if (json) {\n output.log(JSON.stringify(id ? parsedSchemas[0] : parsedSchemas, null, 2))\n } else {\n printSchemas({output, schemas: parsedSchemas, workspaces: projectDatasets})\n }\n}\n\nasync function getDatasetSchemas(projectDatasets: Workspace[], id?: string) {\n return Promise.allSettled(\n projectDatasets.map(async ({dataset, projectId}) => {\n try {\n return await getSchemas(dataset, projectId, id)\n } catch (error) {\n throw new DatasetError({dataset, options: {cause: error}, projectId})\n }\n }),\n )\n}\n\nfunction parseSchemas(\n schemas: PromiseSettledResult<StoredWorkspaceSchema[]>[],\n output: Output,\n json: boolean,\n) {\n return schemas\n .map((schema) => {\n if (schema.status === 'fulfilled') return schema.value\n\n const error = schema.reason\n\n if (error instanceof DatasetError) {\n if (\n 'cause' in error &&\n error.cause &&\n typeof error.cause === 'object' &&\n 'statusCode' in error.cause &&\n error.cause.statusCode === 401\n ) {\n const logDiagnostic = json ? output.warn.bind(output) : output.log.bind(output)\n logDiagnostic(\n styleText(\n 'yellow',\n `${logSymbols.warning} ↳ No permissions to read schema from \"${error.dataset}\". ${\n SCHEMA_PERMISSION_HELP_TEXT\n }:\\n ${styleText('red', `${error.message}`)}`,\n ),\n )\n return []\n }\n\n const logDiagnostic = json ? output.warn.bind(output) : output.log.bind(output)\n logDiagnostic(\n styleText('red', `↳ Failed to fetch schema from \"${error.dataset}\":\\n ${error.message}`),\n )\n return []\n } else {\n //hubris inc: given the try-catch wrapping all the full promise \"this should never happen\"\n throw error\n }\n })\n .filter((schema) => isDefined(schema))\n .flat()\n}\n\nfunction printSchemas({\n output,\n schemas,\n workspaces,\n}: {\n output: Output\n schemas: StoredWorkspaceSchema[]\n workspaces: Workspace[]\n}) {\n const rows = schemas\n .toSorted((a, b) => -(a._createdAt || '').localeCompare(b._createdAt || ''))\n .map(({_createdAt: createdAt, _id: id, workspace}) => {\n const workspaceData = workspaces.find((w) => w.name === workspace.name)\n if (!workspaceData) return\n\n return {\n CreatedAt: createdAt,\n Dataset: workspaceData.dataset,\n Id: id,\n ProjectId: workspaceData.projectId,\n Workspace: workspace.name,\n }\n })\n .filter((schema) => isDefined(schema))\n\n const table = new Table({\n columns: [\n {alignment: 'left', name: 'Id'},\n {alignment: 'left', name: 'Workspace'},\n {alignment: 'left', name: 'Dataset'},\n {alignment: 'left', name: 'ProjectId'},\n {alignment: 'left', name: 'CreatedAt'},\n ],\n })\n\n table.addRows(rows)\n output.log(table.render())\n}\n"],"names":["styleText","studioWorkerTask","logSymbols","getSchemas","Table","isDefined","getDatasetsOutString","SCHEMA_PERMISSION_HELP_TEXT","DatasetError","Error","dataset","projectId","args","options","cause","message","name","listSchemas","configPath","id","json","output","workDir","projectDatasets","URL","url","studioRootPath","workerData","schemas","getDatasetSchemas","parsedSchemas","parseSchemas","length","datasetString","map","log","JSON","stringify","printSchemas","workspaces","Promise","allSettled","error","schema","status","value","reason","statusCode","logDiagnostic","warn","bind","warning","filter","flat","rows","toSorted","a","b","_createdAt","localeCompare","createdAt","_id","workspace","workspaceData","find","w","CreatedAt","Dataset","Id","ProjectId","Workspace","table","columns","alignment","addRows","render"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/actions/tokens/constants.ts"],"sourcesContent":["/**\n * API version for tokens
|
|
1
|
+
{"version":3,"sources":["../../../src/actions/tokens/constants.ts"],"sourcesContent":["/**\n * API version for the Access API endpoints backing the tokens commands\n */\nexport const TOKENS_API_VERSION = 'v2025-07-11'\n"],"names":["TOKENS_API_VERSION"],"mappings":"AAAA;;CAEC,GACD,OAAO,MAAMA,qBAAqB,cAAa"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
const MS_PER_DAY = 24 * 60 * 60 * 1000;
|
|
2
|
+
/**
|
|
3
|
+
* Parse a user-supplied expiry date or timestamp into an ISO 8601 timestamp
|
|
4
|
+
* @param value - The raw flag or prompt input
|
|
5
|
+
* @returns The normalized timestamp, or an error message describing why the
|
|
6
|
+
* input was rejected
|
|
7
|
+
*
|
|
8
|
+
* @internal
|
|
9
|
+
*/ export function parseExpiryDate(value) {
|
|
10
|
+
const date = new Date(value);
|
|
11
|
+
if (Number.isNaN(date.getTime())) {
|
|
12
|
+
return {
|
|
13
|
+
error: `Invalid expiry date "${value}". Pass an ISO 8601 date or timestamp, for example 2027-01-01 or 2027-01-01T12:00:00Z.`
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
if (date.getTime() <= Date.now()) {
|
|
17
|
+
return {
|
|
18
|
+
error: `Expiry date "${value}" must be in the future.`
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
return {
|
|
22
|
+
expiresAt: date.toISOString()
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Get the expiry timestamp a number of days from now
|
|
27
|
+
* @param days - The number of days until expiry
|
|
28
|
+
* @returns An ISO 8601 timestamp
|
|
29
|
+
*
|
|
30
|
+
* @internal
|
|
31
|
+
*/ export function expiryInDays(days) {
|
|
32
|
+
return new Date(Date.now() + days * MS_PER_DAY).toISOString();
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
//# sourceMappingURL=expiry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/actions/tokens/expiry.ts"],"sourcesContent":["const MS_PER_DAY = 24 * 60 * 60 * 1000\n\n/**\n * Parse a user-supplied expiry date or timestamp into an ISO 8601 timestamp\n * @param value - The raw flag or prompt input\n * @returns The normalized timestamp, or an error message describing why the\n * input was rejected\n *\n * @internal\n */\nexport function parseExpiryDate(value: string): {error: string} | {expiresAt: string} {\n const date = new Date(value)\n if (Number.isNaN(date.getTime())) {\n return {\n error: `Invalid expiry date \"${value}\". Pass an ISO 8601 date or timestamp, for example 2027-01-01 or 2027-01-01T12:00:00Z.`,\n }\n }\n if (date.getTime() <= Date.now()) {\n return {error: `Expiry date \"${value}\" must be in the future.`}\n }\n return {expiresAt: date.toISOString()}\n}\n\n/**\n * Get the expiry timestamp a number of days from now\n * @param days - The number of days until expiry\n * @returns An ISO 8601 timestamp\n *\n * @internal\n */\nexport function expiryInDays(days: number): string {\n return new Date(Date.now() + days * MS_PER_DAY).toISOString()\n}\n"],"names":["MS_PER_DAY","parseExpiryDate","value","date","Date","Number","isNaN","getTime","error","now","expiresAt","toISOString","expiryInDays","days"],"mappings":"AAAA,MAAMA,aAAa,KAAK,KAAK,KAAK;AAElC;;;;;;;CAOC,GACD,OAAO,SAASC,gBAAgBC,KAAa;IAC3C,MAAMC,OAAO,IAAIC,KAAKF;IACtB,IAAIG,OAAOC,KAAK,CAACH,KAAKI,OAAO,KAAK;QAChC,OAAO;YACLC,OAAO,CAAC,qBAAqB,EAAEN,MAAM,sFAAsF,CAAC;QAC9H;IACF;IACA,IAAIC,KAAKI,OAAO,MAAMH,KAAKK,GAAG,IAAI;QAChC,OAAO;YAACD,OAAO,CAAC,aAAa,EAAEN,MAAM,wBAAwB,CAAC;QAAA;IAChE;IACA,OAAO;QAACQ,WAAWP,KAAKQ,WAAW;IAAE;AACvC;AAEA;;;;;;CAMC,GACD,OAAO,SAASC,aAAaC,IAAY;IACvC,OAAO,IAAIT,KAAKA,KAAKK,GAAG,KAAKI,OAAOb,YAAYW,WAAW;AAC7D"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/actions/tokens/types.ts"],"sourcesContent":["interface
|
|
1
|
+
{"version":3,"sources":["../../../src/actions/tokens/types.ts"],"sourcesContent":["export interface Role {\n appliesToRobots: boolean\n appliesToUsers: boolean\n description: string\n isCustom: boolean\n name: string\n resourceId: string\n resourceType: string\n title: string\n}\n\nexport type SelectedTokenRole = Pick<Role, 'name' | 'title'>\n\nexport interface Membership {\n resourceId: string\n resourceType: string\n roleNames: string[]\n\n addedAt?: string\n lastSeenAt?: string | null\n resourceUserId?: string | null\n}\n\nexport interface Robot {\n createdAt: string\n id: string\n label: string\n memberships: Membership[]\n\n expiresAt?: string | null\n managedBy?: {\n resourceId: string\n resourceType: string\n }\n tokenId?: string\n}\n\nexport interface RobotWithToken extends Robot {\n token: string\n}\n"],"names":[],"mappings":"AAqCA,WAEC"}
|
|
@@ -5,7 +5,7 @@ import { getTokenRoles } from '../../services/tokens.js';
|
|
|
5
5
|
* @param roleName - The role name to validate
|
|
6
6
|
* @param projectId - The project ID
|
|
7
7
|
* @param output - Output to raise the error through the calling command
|
|
8
|
-
* @returns A promise that resolves to the validated role
|
|
8
|
+
* @returns A promise that resolves to the validated role
|
|
9
9
|
*
|
|
10
10
|
* @internal
|
|
11
11
|
*/ export async function validateRole(roleName, projectId, output) {
|
|
@@ -13,7 +13,10 @@ import { getTokenRoles } from '../../services/tokens.js';
|
|
|
13
13
|
const robotRoles = roles.filter((role)=>role.appliesToRobots);
|
|
14
14
|
const role = robotRoles.find((r)=>r.name === roleName);
|
|
15
15
|
if (role) {
|
|
16
|
-
return
|
|
16
|
+
return {
|
|
17
|
+
name: role.name,
|
|
18
|
+
title: role.title
|
|
19
|
+
};
|
|
17
20
|
}
|
|
18
21
|
const availableRoles = robotRoles.map((r)=>r.name).join(', ');
|
|
19
22
|
return output.error(`Invalid role "${roleName}". Available roles: ${availableRoles}`, {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/actions/tokens/validateRole.ts"],"sourcesContent":["import {exitCodes, type Output} from '@sanity/cli-core'\n\nimport {getTokenRoles} from '../../services/tokens.js'\n\n/**\n * Validate a role name\n * @param roleName - The role name to validate\n * @param projectId - The project ID\n * @param output - Output to raise the error through the calling command\n * @returns A promise that resolves to the validated role
|
|
1
|
+
{"version":3,"sources":["../../../src/actions/tokens/validateRole.ts"],"sourcesContent":["import {exitCodes, type Output} from '@sanity/cli-core'\n\nimport {getTokenRoles} from '../../services/tokens.js'\nimport {type SelectedTokenRole} from './types.js'\n\n/**\n * Validate a role name\n * @param roleName - The role name to validate\n * @param projectId - The project ID\n * @param output - Output to raise the error through the calling command\n * @returns A promise that resolves to the validated role\n *\n * @internal\n */\nexport async function validateRole(\n roleName: string,\n projectId: string,\n output: Output,\n): Promise<SelectedTokenRole> {\n const roles = await getTokenRoles(projectId)\n const robotRoles = roles.filter((role) => role.appliesToRobots)\n\n const role = robotRoles.find((r) => r.name === roleName)\n if (role) {\n return {name: role.name, title: role.title}\n }\n\n const availableRoles = robotRoles.map((r) => r.name).join(', ')\n return output.error(`Invalid role \"${roleName}\". Available roles: ${availableRoles}`, {\n exit: exitCodes.USAGE_ERROR,\n })\n}\n"],"names":["exitCodes","getTokenRoles","validateRole","roleName","projectId","output","roles","robotRoles","filter","role","appliesToRobots","find","r","name","title","availableRoles","map","join","error","exit","USAGE_ERROR"],"mappings":"AAAA,SAAQA,SAAS,QAAoB,mBAAkB;AAEvD,SAAQC,aAAa,QAAO,2BAA0B;AAGtD;;;;;;;;CAQC,GACD,OAAO,eAAeC,aACpBC,QAAgB,EAChBC,SAAiB,EACjBC,MAAc;IAEd,MAAMC,QAAQ,MAAML,cAAcG;IAClC,MAAMG,aAAaD,MAAME,MAAM,CAAC,CAACC,OAASA,KAAKC,eAAe;IAE9D,MAAMD,OAAOF,WAAWI,IAAI,CAAC,CAACC,IAAMA,EAAEC,IAAI,KAAKV;IAC/C,IAAIM,MAAM;QACR,OAAO;YAACI,MAAMJ,KAAKI,IAAI;YAAEC,OAAOL,KAAKK,KAAK;QAAA;IAC5C;IAEA,MAAMC,iBAAiBR,WAAWS,GAAG,CAAC,CAACJ,IAAMA,EAAEC,IAAI,EAAEI,IAAI,CAAC;IAC1D,OAAOZ,OAAOa,KAAK,CAAC,CAAC,cAAc,EAAEf,SAAS,oBAAoB,EAAEY,gBAAgB,EAAE;QACpFI,MAAMnB,UAAUoB,WAAW;IAC7B;AACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/actions/typegen/count.ts"],"sourcesContent":["export const count = (\n amount: number,\n plural: string = '',\n singular: string = plural.slice(0, Math.max(0, plural.length - 1)),\n): string =>\n [amount.toLocaleString('en-US'), amount === 1 ? singular : plural].filter(Boolean).join(' ')\n"],"names":["count","amount","plural","singular","slice","Math","max","length","toLocaleString","filter","Boolean","join"],"mappings":"AAAA,OAAO,MAAMA,QAAQ,CACnBC,QACAC,SAAiB,EAAE,EACnBC,WAAmBD,OAAOE,KAAK,CAAC,GAAGC,KAAKC,GAAG,CAAC,GAAGJ,OAAOK,MAAM,GAAG,GAAG,GAElE;QAACN,OAAOO,cAAc,CAAC;QAAUP,WAAW,IAAIE,WAAWD;KAAO,CAACO,MAAM,CAACC,SAASC,IAAI,CAAC,KAAI"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/actions/typegen/formatPath.ts"],"sourcesContent":["/** Formats a path so it is the same in Windows and Unix. */\nexport function formatPath(path: string): string {\n return path.replaceAll('\\\\', '/')\n}\n"],"names":["formatPath","path","replaceAll"],"mappings":"AAAA,0DAA0D,GAC1D,OAAO,SAASA,WAAWC,IAAY;IACrC,OAAOA,KAAKC,UAAU,CAAC,MAAM;AAC/B"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/actions/typegen/percent.ts"],"sourcesContent":["const formatter = new Intl.NumberFormat('en-US', {\n maximumFractionDigits: 1,\n minimumFractionDigits: 1,\n style: 'percent',\n})\n\nexport const percent = (value: number): string => formatter.format(Math.min(value, 1))\n"],"names":["formatter","Intl","NumberFormat","maximumFractionDigits","minimumFractionDigits","style","percent","value","format","Math","min"],"mappings":"AAAA,MAAMA,YAAY,IAAIC,KAAKC,YAAY,CAAC,SAAS;IAC/CC,uBAAuB;IACvBC,uBAAuB;IACvBC,OAAO;AACT;AAEA,OAAO,MAAMC,UAAU,CAACC,QAA0BP,UAAUQ,MAAM,CAACC,KAAKC,GAAG,CAACH,OAAO,IAAG"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { count } from './count.js';
|
|
2
|
+
import { formatPath } from './formatPath.js';
|
|
3
|
+
import { percent } from './percent.js';
|
|
4
|
+
/**
|
|
5
|
+
* Builds an onProgress handler that renders typegen progress to a spinner,
|
|
6
|
+
* matching the output the command produced before the library was decoupled.
|
|
7
|
+
*/ export function createTypegenProgressRenderer(spin, context) {
|
|
8
|
+
const { formatGeneratedCode, generates, schema } = context;
|
|
9
|
+
// Track cross-event data needed for the final success message.
|
|
10
|
+
let evaluatedFiles = 0;
|
|
11
|
+
let queriesCount = 0;
|
|
12
|
+
let queryFilesCount = 0;
|
|
13
|
+
let schemaTypesCount = 0;
|
|
14
|
+
let formatterName;
|
|
15
|
+
let formattingError = false;
|
|
16
|
+
return (event)=>{
|
|
17
|
+
switch(event.type){
|
|
18
|
+
case 'complete':
|
|
19
|
+
{
|
|
20
|
+
const { result } = event;
|
|
21
|
+
if (result.filesWithErrors > 0) {
|
|
22
|
+
spin.warn(`Encountered errors in ${count(result.filesWithErrors, 'files')} while generating types`);
|
|
23
|
+
}
|
|
24
|
+
let successText = `Successfully generated types to ${formatPath(generates)} in ${Number(result.duration).toFixed(0)}ms` + `\n └─ ${count(queriesCount, 'queries', 'query')} and ${count(schemaTypesCount, 'schema types', 'schema type')}` + `\n └─ found queries in ${count(queryFilesCount, 'files', 'file')} after evaluating ${count(evaluatedFiles, 'files', 'file')}`;
|
|
25
|
+
// formatGeneratedCode !== false means a formatter was attempted.
|
|
26
|
+
if (formatGeneratedCode !== false && formatterName) {
|
|
27
|
+
successText += `\n └─ ${formattingError ? 'an error occurred during formatting' : `formatted the generated code with ${formatterName}`}`;
|
|
28
|
+
}
|
|
29
|
+
spin.succeed(successText);
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
case 'formatFailed':
|
|
33
|
+
{
|
|
34
|
+
formatterName = event.formatterName;
|
|
35
|
+
formattingError = true;
|
|
36
|
+
spin.warn(`Failed to format generated types with ${event.formatterName}: ${event.message}`);
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
case 'formatting':
|
|
40
|
+
{
|
|
41
|
+
formatterName = event.formatterName;
|
|
42
|
+
spin.text = `Formatting generated types with ${event.formatterName}…`;
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
case 'moduleEvaluated':
|
|
46
|
+
{
|
|
47
|
+
evaluatedFiles = event.evaluatedFiles;
|
|
48
|
+
queriesCount = event.queriesCount;
|
|
49
|
+
queryFilesCount = event.queryFilesCount;
|
|
50
|
+
// `fail` stops the spinner, so it has to be restarted to keep rendering
|
|
51
|
+
// progress. Restarting only after a failure (rather than whenever the
|
|
52
|
+
// spinner reports it is not spinning) keeps non-interactive output
|
|
53
|
+
// quiet: a disabled spinner never reports itself as spinning, and each
|
|
54
|
+
// `start` writes a line, which would emit progress once per source file.
|
|
55
|
+
for (const message of event.errors){
|
|
56
|
+
spin.fail(message);
|
|
57
|
+
}
|
|
58
|
+
if (event.errors.length > 0) {
|
|
59
|
+
spin.start();
|
|
60
|
+
}
|
|
61
|
+
spin.text = `Generating query types… (${percent(event.evaluatedFiles / event.expectedFileCount)})\n` + ` └─ Processed ${count(event.evaluatedFiles)} of ${count(event.expectedFileCount, 'files')}. ` + `Found ${count(event.queriesCount, 'queries', 'query')} from ${count(event.queryFilesCount, 'files')}.`;
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
case 'schemaLoaded':
|
|
65
|
+
{
|
|
66
|
+
spin.succeed(`Schema loaded from ${formatPath(schema)}`);
|
|
67
|
+
spin.start('Generating schema types…');
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
case 'schemaTypesGenerated':
|
|
71
|
+
{
|
|
72
|
+
schemaTypesCount = event.schemaTypesCount;
|
|
73
|
+
spin.text = 'Generating query types…';
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
case 'typegenStarted':
|
|
77
|
+
{
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
default:
|
|
81
|
+
{
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
//# sourceMappingURL=renderTypegenProgress.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/actions/typegen/renderTypegenProgress.ts"],"sourcesContent":["import {type TypeGenConfig, type TypegenProgressEvent} from '@sanity/codegen'\n\nimport {count} from './count.js'\nimport {formatPath} from './formatPath.js'\nimport {percent} from './percent.js'\n\n/**\n * Minimal structural shape of the spinner the renderer depends on.\n *\n * The `@sanity/cli-core/ux` `spinner` factory returns an instance whose\n * methods return `this` (for chaining), which is assignable to this\n * `void`-returning interface. This is deliberately narrower than the real\n * spinner type so that test doubles (plain object literals) can satisfy it\n * structurally without a type assertion.\n */\nexport interface TypegenSpinner {\n fail(text?: string): void\n start(text?: string): void\n succeed(text?: string): void\n text: string\n warn(text?: string): void\n}\n\ninterface RendererContext {\n // Indexed access avoids needing a dedicated FormatGeneratedCode export from @sanity/codegen.\n formatGeneratedCode: TypeGenConfig['formatGeneratedCode']\n generates: string\n schema: string\n}\n\n/**\n * Builds an onProgress handler that renders typegen progress to a spinner,\n * matching the output the command produced before the library was decoupled.\n */\nexport function createTypegenProgressRenderer(\n spin: TypegenSpinner,\n context: RendererContext,\n): (event: TypegenProgressEvent) => void {\n const {formatGeneratedCode, generates, schema} = context\n\n // Track cross-event data needed for the final success message.\n let evaluatedFiles = 0\n let queriesCount = 0\n let queryFilesCount = 0\n let schemaTypesCount = 0\n let formatterName: string | undefined\n let formattingError = false\n\n return (event) => {\n switch (event.type) {\n case 'complete': {\n const {result} = event\n if (result.filesWithErrors > 0) {\n spin.warn(\n `Encountered errors in ${count(result.filesWithErrors, 'files')} while generating types`,\n )\n }\n\n let successText =\n `Successfully generated types to ${formatPath(generates)} in ${Number(result.duration).toFixed(0)}ms` +\n `\\n └─ ${count(queriesCount, 'queries', 'query')} and ${count(schemaTypesCount, 'schema types', 'schema type')}` +\n `\\n └─ found queries in ${count(queryFilesCount, 'files', 'file')} after evaluating ${count(evaluatedFiles, 'files', 'file')}`\n\n // formatGeneratedCode !== false means a formatter was attempted.\n if (formatGeneratedCode !== false && formatterName) {\n successText += `\\n └─ ${formattingError ? 'an error occurred during formatting' : `formatted the generated code with ${formatterName}`}`\n }\n\n spin.succeed(successText)\n return\n }\n case 'formatFailed': {\n formatterName = event.formatterName\n formattingError = true\n spin.warn(`Failed to format generated types with ${event.formatterName}: ${event.message}`)\n return\n }\n case 'formatting': {\n formatterName = event.formatterName\n spin.text = `Formatting generated types with ${event.formatterName}…`\n return\n }\n case 'moduleEvaluated': {\n evaluatedFiles = event.evaluatedFiles\n queriesCount = event.queriesCount\n queryFilesCount = event.queryFilesCount\n\n // `fail` stops the spinner, so it has to be restarted to keep rendering\n // progress. Restarting only after a failure (rather than whenever the\n // spinner reports it is not spinning) keeps non-interactive output\n // quiet: a disabled spinner never reports itself as spinning, and each\n // `start` writes a line, which would emit progress once per source file.\n for (const message of event.errors) {\n spin.fail(message)\n }\n if (event.errors.length > 0) {\n spin.start()\n }\n\n spin.text =\n `Generating query types… (${percent(event.evaluatedFiles / event.expectedFileCount)})\\n` +\n ` └─ Processed ${count(event.evaluatedFiles)} of ${count(event.expectedFileCount, 'files')}. ` +\n `Found ${count(event.queriesCount, 'queries', 'query')} from ${count(event.queryFilesCount, 'files')}.`\n return\n }\n case 'schemaLoaded': {\n spin.succeed(`Schema loaded from ${formatPath(schema)}`)\n spin.start('Generating schema types…')\n return\n }\n case 'schemaTypesGenerated': {\n schemaTypesCount = event.schemaTypesCount\n spin.text = 'Generating query types…'\n return\n }\n case 'typegenStarted': {\n return\n }\n default: {\n return\n }\n }\n }\n}\n"],"names":["count","formatPath","percent","createTypegenProgressRenderer","spin","context","formatGeneratedCode","generates","schema","evaluatedFiles","queriesCount","queryFilesCount","schemaTypesCount","formatterName","formattingError","event","type","result","filesWithErrors","warn","successText","Number","duration","toFixed","succeed","message","text","errors","fail","length","start","expectedFileCount"],"mappings":"AAEA,SAAQA,KAAK,QAAO,aAAY;AAChC,SAAQC,UAAU,QAAO,kBAAiB;AAC1C,SAAQC,OAAO,QAAO,eAAc;AA0BpC;;;CAGC,GACD,OAAO,SAASC,8BACdC,IAAoB,EACpBC,OAAwB;IAExB,MAAM,EAACC,mBAAmB,EAAEC,SAAS,EAAEC,MAAM,EAAC,GAAGH;IAEjD,+DAA+D;IAC/D,IAAII,iBAAiB;IACrB,IAAIC,eAAe;IACnB,IAAIC,kBAAkB;IACtB,IAAIC,mBAAmB;IACvB,IAAIC;IACJ,IAAIC,kBAAkB;IAEtB,OAAO,CAACC;QACN,OAAQA,MAAMC,IAAI;YAChB,KAAK;gBAAY;oBACf,MAAM,EAACC,MAAM,EAAC,GAAGF;oBACjB,IAAIE,OAAOC,eAAe,GAAG,GAAG;wBAC9Bd,KAAKe,IAAI,CACP,CAAC,sBAAsB,EAAEnB,MAAMiB,OAAOC,eAAe,EAAE,SAAS,uBAAuB,CAAC;oBAE5F;oBAEA,IAAIE,cACF,CAAC,gCAAgC,EAAEnB,WAAWM,WAAW,IAAI,EAAEc,OAAOJ,OAAOK,QAAQ,EAAEC,OAAO,CAAC,GAAG,EAAE,CAAC,GACrG,CAAC,OAAO,EAAEvB,MAAMU,cAAc,WAAW,SAAS,KAAK,EAAEV,MAAMY,kBAAkB,gBAAgB,gBAAgB,GACjH,CAAC,wBAAwB,EAAEZ,MAAMW,iBAAiB,SAAS,QAAQ,kBAAkB,EAAEX,MAAMS,gBAAgB,SAAS,SAAS;oBAEjI,iEAAiE;oBACjE,IAAIH,wBAAwB,SAASO,eAAe;wBAClDO,eAAe,CAAC,OAAO,EAAEN,kBAAkB,wCAAwC,CAAC,kCAAkC,EAAED,eAAe,EAAE;oBAC3I;oBAEAT,KAAKoB,OAAO,CAACJ;oBACb;gBACF;YACA,KAAK;gBAAgB;oBACnBP,gBAAgBE,MAAMF,aAAa;oBACnCC,kBAAkB;oBAClBV,KAAKe,IAAI,CAAC,CAAC,sCAAsC,EAAEJ,MAAMF,aAAa,CAAC,EAAE,EAAEE,MAAMU,OAAO,EAAE;oBAC1F;gBACF;YACA,KAAK;gBAAc;oBACjBZ,gBAAgBE,MAAMF,aAAa;oBACnCT,KAAKsB,IAAI,GAAG,CAAC,gCAAgC,EAAEX,MAAMF,aAAa,CAAC,CAAC,CAAC;oBACrE;gBACF;YACA,KAAK;gBAAmB;oBACtBJ,iBAAiBM,MAAMN,cAAc;oBACrCC,eAAeK,MAAML,YAAY;oBACjCC,kBAAkBI,MAAMJ,eAAe;oBAEvC,wEAAwE;oBACxE,sEAAsE;oBACtE,mEAAmE;oBACnE,uEAAuE;oBACvE,yEAAyE;oBACzE,KAAK,MAAMc,WAAWV,MAAMY,MAAM,CAAE;wBAClCvB,KAAKwB,IAAI,CAACH;oBACZ;oBACA,IAAIV,MAAMY,MAAM,CAACE,MAAM,GAAG,GAAG;wBAC3BzB,KAAK0B,KAAK;oBACZ;oBAEA1B,KAAKsB,IAAI,GACP,CAAC,yBAAyB,EAAExB,QAAQa,MAAMN,cAAc,GAAGM,MAAMgB,iBAAiB,EAAE,GAAG,CAAC,GACxF,CAAC,eAAe,EAAE/B,MAAMe,MAAMN,cAAc,EAAE,IAAI,EAAET,MAAMe,MAAMgB,iBAAiB,EAAE,SAAS,EAAE,CAAC,GAC/F,CAAC,MAAM,EAAE/B,MAAMe,MAAML,YAAY,EAAE,WAAW,SAAS,MAAM,EAAEV,MAAMe,MAAMJ,eAAe,EAAE,SAAS,CAAC,CAAC;oBACzG;gBACF;YACA,KAAK;gBAAgB;oBACnBP,KAAKoB,OAAO,CAAC,CAAC,mBAAmB,EAAEvB,WAAWO,SAAS;oBACvDJ,KAAK0B,KAAK,CAAC;oBACX;gBACF;YACA,KAAK;gBAAwB;oBAC3BlB,mBAAmBG,MAAMH,gBAAgB;oBACzCR,KAAKsB,IAAI,GAAG;oBACZ;gBACF;YACA,KAAK;gBAAkB;oBACrB;gBACF;YACA;gBAAS;oBACP;gBACF;QACF;IACF;AACF"}
|
|
@@ -75,17 +75,14 @@ export function createStudioUndeployAdapter(cliConfig) {
|
|
|
75
75
|
}
|
|
76
76
|
function toUndeployTarget(application, type) {
|
|
77
77
|
return {
|
|
78
|
-
|
|
79
|
-
deployedAt: application.activeDeployment.deployedAt,
|
|
80
|
-
deployedBy: application.activeDeployment.deployedBy
|
|
81
|
-
} : null,
|
|
82
|
-
appHost: application.appHost ?? null,
|
|
83
|
-
createdAt: application.createdAt ?? null,
|
|
78
|
+
application,
|
|
84
79
|
deletes: 'application',
|
|
85
80
|
id: application.id,
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
81
|
+
payload: {
|
|
82
|
+
appId: application.id,
|
|
83
|
+
type
|
|
84
|
+
},
|
|
85
|
+
title: application.title,
|
|
89
86
|
type,
|
|
90
87
|
url: resolveTargetUrl(application, type)
|
|
91
88
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/actions/undeploy/adapters.ts"],"sourcesContent":["import {type CliConfig} from '@sanity/cli-core'\nimport {
|
|
1
|
+
{"version":3,"sources":["../../../src/actions/undeploy/adapters.ts"],"sourcesContent":["import {type CliConfig} from '@sanity/cli-core'\nimport {type UndeployAdapter, type UndeployApplicationTarget} from '@sanity/cli-core/undeploy'\nimport {getCoreAppUrl} from '@sanity/cli-core/util'\n\nimport {\n deleteUserApplication,\n getUserApplication,\n type UserApplication,\n} from '../../services/userApplications.js'\nimport {getAppId} from '../../util/appId.js'\nimport {NO_PROJECT_ID} from '../../util/errorMessages.js'\n\nexport function createAppUndeployAdapter(\n cliConfig: CliConfig,\n): UndeployAdapter<UndeployApplicationTarget> {\n return {\n async resolveTarget() {\n const appId = getAppId(cliConfig)\n if (!appId) {\n return {\n message: 'No `deployment.appId` configured',\n solution: 'Add `deployment.appId` to sanity.cli.ts',\n type: 'none',\n }\n }\n\n const application = await getUserApplication({appId, isSdkApp: true})\n if (!application) {\n return {message: 'Application with the given ID does not exist', type: 'none'}\n }\n\n return {target: toUndeployTarget(application, 'coreApp'), type: 'found'}\n },\n type: 'coreApp',\n undeploy: ({id}) => deleteUserApplication({applicationId: id, appType: 'coreApp'}),\n }\n}\n\nexport function createStudioUndeployAdapter(\n cliConfig: CliConfig,\n): UndeployAdapter<UndeployApplicationTarget> {\n return {\n async resolveTarget() {\n const appId = cliConfig.deployment?.appId\n const studioHost = cliConfig.studioHost\n if (!appId && !studioHost) {\n return {\n message: 'No studio hostname configured',\n solution: 'Set `studioHost` in sanity.cli.ts',\n type: 'none',\n }\n }\n\n const projectId = cliConfig.api?.projectId\n if (!projectId) throw new Error(NO_PROJECT_ID)\n\n const application = await getUserApplication({\n appHost: studioHost,\n appId,\n isSdkApp: false,\n projectId,\n })\n if (!application) {\n return {\n message:\n 'Your project has not been assigned an app ID or a studio hostname, or the `appId` or `studioHost` provided does not exist',\n type: 'none',\n }\n }\n\n return {target: toUndeployTarget(application, 'studio'), type: 'found'}\n },\n type: 'studio',\n undeploy: ({id}) => deleteUserApplication({applicationId: id, appType: 'studio'}),\n }\n}\n\nfunction toUndeployTarget(\n application: UserApplication,\n type: UndeployApplicationTarget['type'],\n): UndeployApplicationTarget {\n return {\n application,\n deletes: 'application',\n id: application.id,\n payload: {appId: application.id, type},\n title: application.title,\n type,\n url: resolveTargetUrl(application, type),\n }\n}\n\nfunction resolveTargetUrl(\n application: UserApplication,\n type: UndeployApplicationTarget['type'],\n): string | null {\n if (type === 'coreApp') {\n return application.organizationId\n ? getCoreAppUrl(application.organizationId, application.id)\n : null\n }\n if (!application.appHost) return null\n return application.urlType === 'external'\n ? application.appHost\n : `https://${application.appHost}.sanity.studio`\n}\n"],"names":["getCoreAppUrl","deleteUserApplication","getUserApplication","getAppId","NO_PROJECT_ID","createAppUndeployAdapter","cliConfig","resolveTarget","appId","message","solution","type","application","isSdkApp","target","toUndeployTarget","undeploy","id","applicationId","appType","createStudioUndeployAdapter","deployment","studioHost","projectId","api","Error","appHost","deletes","payload","title","url","resolveTargetUrl","organizationId","urlType"],"mappings":"AAEA,SAAQA,aAAa,QAAO,wBAAuB;AAEnD,SACEC,qBAAqB,EACrBC,kBAAkB,QAEb,qCAAoC;AAC3C,SAAQC,QAAQ,QAAO,sBAAqB;AAC5C,SAAQC,aAAa,QAAO,8BAA6B;AAEzD,OAAO,SAASC,yBACdC,SAAoB;IAEpB,OAAO;QACL,MAAMC;YACJ,MAAMC,QAAQL,SAASG;YACvB,IAAI,CAACE,OAAO;gBACV,OAAO;oBACLC,SAAS;oBACTC,UAAU;oBACVC,MAAM;gBACR;YACF;YAEA,MAAMC,cAAc,MAAMV,mBAAmB;gBAACM;gBAAOK,UAAU;YAAI;YACnE,IAAI,CAACD,aAAa;gBAChB,OAAO;oBAACH,SAAS;oBAAgDE,MAAM;gBAAM;YAC/E;YAEA,OAAO;gBAACG,QAAQC,iBAAiBH,aAAa;gBAAYD,MAAM;YAAO;QACzE;QACAA,MAAM;QACNK,UAAU,CAAC,EAACC,EAAE,EAAC,GAAKhB,sBAAsB;gBAACiB,eAAeD;gBAAIE,SAAS;YAAS;IAClF;AACF;AAEA,OAAO,SAASC,4BACdd,SAAoB;IAEpB,OAAO;QACL,MAAMC;YACJ,MAAMC,QAAQF,UAAUe,UAAU,EAAEb;YACpC,MAAMc,aAAahB,UAAUgB,UAAU;YACvC,IAAI,CAACd,SAAS,CAACc,YAAY;gBACzB,OAAO;oBACLb,SAAS;oBACTC,UAAU;oBACVC,MAAM;gBACR;YACF;YAEA,MAAMY,YAAYjB,UAAUkB,GAAG,EAAED;YACjC,IAAI,CAACA,WAAW,MAAM,IAAIE,MAAMrB;YAEhC,MAAMQ,cAAc,MAAMV,mBAAmB;gBAC3CwB,SAASJ;gBACTd;gBACAK,UAAU;gBACVU;YACF;YACA,IAAI,CAACX,aAAa;gBAChB,OAAO;oBACLH,SACE;oBACFE,MAAM;gBACR;YACF;YAEA,OAAO;gBAACG,QAAQC,iBAAiBH,aAAa;gBAAWD,MAAM;YAAO;QACxE;QACAA,MAAM;QACNK,UAAU,CAAC,EAACC,EAAE,EAAC,GAAKhB,sBAAsB;gBAACiB,eAAeD;gBAAIE,SAAS;YAAQ;IACjF;AACF;AAEA,SAASJ,iBACPH,WAA4B,EAC5BD,IAAuC;IAEvC,OAAO;QACLC;QACAe,SAAS;QACTV,IAAIL,YAAYK,EAAE;QAClBW,SAAS;YAACpB,OAAOI,YAAYK,EAAE;YAAEN;QAAI;QACrCkB,OAAOjB,YAAYiB,KAAK;QACxBlB;QACAmB,KAAKC,iBAAiBnB,aAAaD;IACrC;AACF;AAEA,SAASoB,iBACPnB,WAA4B,EAC5BD,IAAuC;IAEvC,IAAIA,SAAS,WAAW;QACtB,OAAOC,YAAYoB,cAAc,GAC7BhC,cAAcY,YAAYoB,cAAc,EAAEpB,YAAYK,EAAE,IACxD;IACN;IACA,IAAI,CAACL,YAAYc,OAAO,EAAE,OAAO;IACjC,OAAOd,YAAYqB,OAAO,KAAK,aAC3BrB,YAAYc,OAAO,GACnB,CAAC,QAAQ,EAAEd,YAAYc,OAAO,CAAC,cAAc,CAAC;AACpD"}
|
|
@@ -15,8 +15,7 @@ const undeployDebug = subdebug('undeploy');
|
|
|
15
15
|
*/ export async function runUndeploy(options, adapter) {
|
|
16
16
|
const { flags, output } = options;
|
|
17
17
|
const json = !!flags.json;
|
|
18
|
-
|
|
19
|
-
const emitJson = (payload)=>output.log(JSON.stringify(payload, (key, value)=>key === 'summary' ? undefined : value, 2));
|
|
18
|
+
const emitJson = (payload)=>output.log(JSON.stringify(payload, null, 2));
|
|
20
19
|
// The JSON payload owns stdout, so the run's progress logs go to stderr; only
|
|
21
20
|
// the final JSON.stringify writes to stdout.
|
|
22
21
|
const runOptions = json ? {
|
|
@@ -50,9 +49,12 @@ const undeployDebug = subdebug('undeploy');
|
|
|
50
49
|
// printed its plan, so only a real undeploy adds the {undeployed: false} envelope.
|
|
51
50
|
if (json && !flags['dry-run']) {
|
|
52
51
|
emitJson({
|
|
52
|
+
application: null,
|
|
53
53
|
error: {
|
|
54
54
|
message: failure.message
|
|
55
55
|
},
|
|
56
|
+
payload: null,
|
|
57
|
+
reason: failure.message,
|
|
56
58
|
undeployed: false
|
|
57
59
|
});
|
|
58
60
|
}
|
|
@@ -71,6 +73,8 @@ const undeployDebug = subdebug('undeploy');
|
|
|
71
73
|
if (resolution.solution) output.log(`${resolution.solution}.`);
|
|
72
74
|
output.log('Nothing to undeploy.');
|
|
73
75
|
return {
|
|
76
|
+
application: null,
|
|
77
|
+
payload: null,
|
|
74
78
|
reason: resolution.message,
|
|
75
79
|
undeployed: false
|
|
76
80
|
};
|
|
@@ -107,8 +111,12 @@ const undeployDebug = subdebug('undeploy');
|
|
|
107
111
|
spin.succeed();
|
|
108
112
|
printUndeployed(target, output);
|
|
109
113
|
return {
|
|
110
|
-
application: target,
|
|
111
|
-
|
|
114
|
+
application: target.application ?? null,
|
|
115
|
+
deletes: target.deletes,
|
|
116
|
+
payload: target.payload,
|
|
117
|
+
reason: null,
|
|
118
|
+
undeployed: true,
|
|
119
|
+
url: target.url
|
|
112
120
|
};
|
|
113
121
|
}
|
|
114
122
|
/**
|