@sanity/cli 7.10.0 → 7.12.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 +31 -22
- package/dist/actions/auth/ensureAuthenticated.js +2 -0
- package/dist/actions/auth/ensureAuthenticated.js.map +1 -1
- package/dist/actions/auth/login/loginInstructions.js +19 -0
- package/dist/actions/auth/login/loginInstructions.js.map +1 -0
- package/dist/actions/build/buildApp.js +10 -7
- package/dist/actions/build/buildApp.js.map +1 -1
- package/dist/actions/build/buildStudio.js +9 -6
- package/dist/actions/build/buildStudio.js.map +1 -1
- package/dist/actions/build/types.js.map +1 -1
- package/dist/actions/dataset/resolveDataset.js +7 -1
- package/dist/actions/dataset/resolveDataset.js.map +1 -1
- package/dist/actions/deploy/deployApp.js +205 -157
- package/dist/actions/deploy/deployApp.js.map +1 -1
- package/dist/actions/deploy/deployChecks.js +1 -1
- package/dist/actions/deploy/deployChecks.js.map +1 -1
- package/dist/actions/deploy/deployStudio.js +127 -86
- package/dist/actions/deploy/deployStudio.js.map +1 -1
- package/dist/actions/deploy/resolveDeployTarget.js +5 -9
- package/dist/actions/deploy/resolveDeployTarget.js.map +1 -1
- package/dist/actions/dev/devAction.js +1 -2
- package/dist/actions/dev/devAction.js.map +1 -1
- package/dist/actions/dev/servers/getDevServerConfig.js +8 -2
- package/dist/actions/dev/servers/getDevServerConfig.js.map +1 -1
- package/dist/actions/graphql/resolveApiGeneration.js +9 -6
- package/dist/actions/graphql/resolveApiGeneration.js.map +1 -1
- package/dist/actions/init/bootstrapLocalTemplate.js +18 -9
- package/dist/actions/init/bootstrapLocalTemplate.js.map +1 -1
- package/dist/actions/init/createAppCliConfig.js.map +1 -1
- package/dist/actions/init/createCliConfig.js.map +1 -1
- package/dist/actions/init/initAction.js +23 -15
- package/dist/actions/init/initAction.js.map +1 -1
- package/dist/actions/manifest/extractCoreAppManifest.js +5 -3
- package/dist/actions/manifest/extractCoreAppManifest.js.map +1 -1
- package/dist/actions/migration/constants.js +10 -0
- package/dist/actions/migration/constants.js.map +1 -0
- package/dist/actions/migration/ensureApiVersionFormat.js +16 -0
- package/dist/actions/migration/ensureApiVersionFormat.js.map +1 -0
- package/dist/actions/migration/fileExists.js +13 -0
- package/dist/actions/migration/fileExists.js.map +1 -0
- package/dist/actions/migration/prettyMutationFormatter.js +155 -0
- package/dist/actions/migration/prettyMutationFormatter.js.map +1 -0
- package/dist/actions/migration/resolveMigrationScript.js +75 -0
- package/dist/actions/migration/resolveMigrationScript.js.map +1 -0
- package/dist/actions/migration/resolveMigrations.js +50 -0
- package/dist/actions/migration/resolveMigrations.js.map +1 -0
- package/dist/actions/migration/templates/index.js +7 -0
- package/dist/actions/migration/templates/index.js.map +1 -0
- package/dist/actions/migration/templates/minimalAdvanced.js +21 -0
- package/dist/actions/migration/templates/minimalAdvanced.js.map +1 -0
- package/dist/actions/migration/templates/minimalSimple.js +61 -0
- package/dist/actions/migration/templates/minimalSimple.js.map +1 -0
- package/dist/actions/migration/templates/renameField.js +20 -0
- package/dist/actions/migration/templates/renameField.js.map +1 -0
- package/dist/actions/migration/templates/renameType.js +19 -0
- package/dist/actions/migration/templates/renameType.js.map +1 -0
- package/dist/actions/migration/templates/stringToPTE.js +32 -0
- package/dist/actions/migration/templates/stringToPTE.js.map +1 -0
- package/dist/actions/migration/tree.js +111 -0
- package/dist/actions/migration/tree.js.map +1 -0
- package/dist/actions/preview/previewAction.js +33 -1
- package/dist/actions/preview/previewAction.js.map +1 -1
- package/dist/actions/schema/listSchemas.js +6 -4
- package/dist/actions/schema/listSchemas.js.map +1 -1
- package/dist/actions/tokens/validateRole.js +2 -1
- package/dist/actions/tokens/validateRole.js.map +1 -1
- package/dist/actions/undeploy/runUndeploy.js +13 -4
- package/dist/actions/undeploy/runUndeploy.js.map +1 -1
- package/dist/commands/backups/disable.js +5 -1
- package/dist/commands/backups/disable.js.map +1 -1
- package/dist/commands/backups/download.js +30 -6
- package/dist/commands/backups/download.js.map +1 -1
- package/dist/commands/backups/enable.js +5 -1
- package/dist/commands/backups/enable.js.map +1 -1
- package/dist/commands/backups/list.js +5 -1
- package/dist/commands/backups/list.js.map +1 -1
- package/dist/commands/cors/add.js +15 -7
- package/dist/commands/cors/add.js.map +1 -1
- package/dist/commands/cors/delete.js +6 -1
- package/dist/commands/cors/delete.js.map +1 -1
- package/dist/commands/datasets/alias/create.js +25 -18
- package/dist/commands/datasets/alias/create.js.map +1 -1
- package/dist/commands/datasets/alias/delete.js +15 -8
- package/dist/commands/datasets/alias/delete.js.map +1 -1
- package/dist/commands/datasets/alias/link.js +39 -17
- package/dist/commands/datasets/alias/link.js.map +1 -1
- package/dist/commands/datasets/alias/unlink.js +23 -2
- package/dist/commands/datasets/alias/unlink.js.map +1 -1
- package/dist/commands/datasets/copy.js +18 -2
- package/dist/commands/datasets/copy.js.map +1 -1
- package/dist/commands/datasets/create.js +8 -2
- package/dist/commands/datasets/create.js.map +1 -1
- package/dist/commands/datasets/delete.js +14 -17
- package/dist/commands/datasets/delete.js.map +1 -1
- package/dist/commands/datasets/embeddings/disable.js +3 -0
- package/dist/commands/datasets/embeddings/disable.js.map +1 -1
- package/dist/commands/datasets/embeddings/enable.js +5 -2
- package/dist/commands/datasets/embeddings/enable.js.map +1 -1
- package/dist/commands/datasets/embeddings/status.js +3 -0
- package/dist/commands/datasets/embeddings/status.js.map +1 -1
- package/dist/commands/datasets/export.js +27 -15
- package/dist/commands/datasets/export.js.map +1 -1
- package/dist/commands/datasets/import.js +3 -3
- package/dist/commands/datasets/import.js.map +1 -1
- package/dist/commands/datasets/visibility/get.js +2 -2
- package/dist/commands/datasets/visibility/get.js.map +1 -1
- package/dist/commands/datasets/visibility/set.js +2 -2
- package/dist/commands/datasets/visibility/set.js.map +1 -1
- package/dist/commands/docs/read.js +3 -3
- package/dist/commands/docs/read.js.map +1 -1
- package/dist/commands/documents/create.js +18 -13
- package/dist/commands/documents/create.js.map +1 -1
- package/dist/commands/documents/delete.js +3 -3
- package/dist/commands/documents/delete.js.map +1 -1
- package/dist/commands/documents/get.js +3 -3
- package/dist/commands/documents/get.js.map +1 -1
- package/dist/commands/documents/query.js +3 -3
- package/dist/commands/documents/query.js.map +1 -1
- package/dist/commands/documents/validate.js +29 -26
- package/dist/commands/documents/validate.js.map +1 -1
- package/dist/commands/graphql/deploy.js +20 -16
- package/dist/commands/graphql/deploy.js.map +1 -1
- package/dist/commands/graphql/undeploy.js +15 -18
- package/dist/commands/graphql/undeploy.js.map +1 -1
- package/dist/commands/hooks/delete.js +2 -2
- package/dist/commands/hooks/delete.js.map +1 -1
- package/dist/commands/hooks/logs.js +2 -2
- package/dist/commands/hooks/logs.js.map +1 -1
- package/dist/commands/login.js +2 -1
- package/dist/commands/login.js.map +1 -1
- package/dist/commands/media/create-aspect.js +20 -8
- package/dist/commands/media/create-aspect.js.map +1 -1
- package/dist/commands/media/delete-aspect.js +31 -16
- package/dist/commands/media/delete-aspect.js.map +1 -1
- package/dist/commands/media/deploy-aspect.js +10 -5
- package/dist/commands/media/deploy-aspect.js.map +1 -1
- package/dist/commands/media/export.js +9 -4
- package/dist/commands/media/export.js.map +1 -1
- package/dist/commands/media/import.js +6 -1
- package/dist/commands/media/import.js.map +1 -1
- package/dist/commands/migrations/create.js +150 -0
- package/dist/commands/migrations/create.js.map +1 -0
- package/dist/commands/migrations/list.js +64 -0
- package/dist/commands/migrations/list.js.map +1 -0
- package/dist/commands/migrations/run.js +306 -0
- package/dist/commands/migrations/run.js.map +1 -0
- package/dist/commands/preview.js +1 -0
- package/dist/commands/preview.js.map +1 -1
- package/dist/commands/projects/create.js +2 -1
- package/dist/commands/projects/create.js.map +1 -1
- package/dist/commands/schemas/delete.js +23 -2
- package/dist/commands/schemas/delete.js.map +1 -1
- package/dist/commands/schemas/deploy.js +6 -4
- package/dist/commands/schemas/deploy.js.map +1 -1
- package/dist/commands/schemas/extract.js +22 -1
- package/dist/commands/schemas/extract.js.map +1 -1
- package/dist/commands/schemas/list.js +8 -8
- package/dist/commands/schemas/list.js.map +1 -1
- package/dist/commands/tokens/{add.js → create.js} +25 -18
- package/dist/commands/tokens/create.js.map +1 -0
- package/dist/commands/tokens/delete.js +41 -23
- package/dist/commands/tokens/delete.js.map +1 -1
- package/dist/commands/undeploy.js +2 -7
- package/dist/commands/undeploy.js.map +1 -1
- package/dist/commands/users/invite.js +25 -3
- package/dist/commands/users/invite.js.map +1 -1
- package/dist/topicAliases.js +3 -0
- package/dist/topicAliases.js.map +1 -1
- package/dist/util/formatCliErrorMessages.js +5 -0
- package/dist/util/formatCliErrorMessages.js.map +1 -0
- package/oclif.config.js +5 -1
- package/oclif.manifest.json +579 -374
- package/package.json +7 -7
- package/dist/commands/tokens/add.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/actions/dev/devAction.ts"],"sourcesContent":["import {SANITY_CACHE_DIR} from '@sanity/cli-build/_internal/build'\nimport {type CliConfig} from '@sanity/cli-core'\nimport {isWorkbenchApp} from '@sanity/workbench-cli'\n\nimport {checkForDeprecatedAppId
|
|
1
|
+
{"version":3,"sources":["../../../src/actions/dev/devAction.ts"],"sourcesContent":["import {SANITY_CACHE_DIR} from '@sanity/cli-build/_internal/build'\nimport {type CliConfig} from '@sanity/cli-core'\nimport {isWorkbenchApp} from '@sanity/workbench-cli'\n\nimport {checkForDeprecatedAppId} from '../../util/appId.js'\nimport {getSharedServerConfig} from '../../util/getSharedServerConfig.js'\nimport {resolveReactStrictMode} from '../../util/resolveReactStrictMode.js'\nimport {extractCoreAppManifest} from '../manifest/extractCoreAppManifest.js'\nimport {extractStudioManifest} from '../manifest/extractStudioManifest.js'\nimport {startAppDevServer} from './servers/startAppDevServer.js'\nimport {startStudioDevServer} from './servers/startStudioDevServer.js'\nimport {type DevActionOptions} from './types.js'\n\nconst noop = async () => {}\n\n/**\n * Entry point for `sanity dev`. A plain studio/app starts a single dev server, as\n * before workbench existed. A workbench app (via `unstable_defineApp`) delegates to\n * `@sanity/workbench-cli`, injecting the CLI-domain pieces (app server, manifest\n * extraction, app id) and loading the package lazily so plain projects never do.\n */\nexport async function devAction(options: DevActionOptions): Promise<{close: () => Promise<void>}> {\n const {cliConfig, flags, isApp, output, workDir} = options\n\n const {httpHost, httpPort} = getSharedServerConfig({\n cliConfig,\n flags: {host: flags.host, port: flags.port},\n workDir,\n })\n\n // The app/studio server, parameterized per call; `announceUrl` is false when\n // the workbench announces the URL on its behalf.\n const startAppServer = (params: {announceUrl: boolean; cliConfig: CliConfig; httpPort: number}) =>\n (isApp ? startAppDevServer : startStudioDevServer)({\n ...options,\n announceUrl: params.announceUrl,\n cliConfig: params.cliConfig,\n httpPort: params.httpPort,\n })\n\n if (isWorkbenchApp(cliConfig?.app)) {\n // Lazy so a non-workbench `sanity dev` never loads the package. `doImport`\n // is path-based and doesn't apply to a bare specifier.\n // eslint-disable-next-line no-restricted-syntax\n const {startWorkbenchDev} = await import('@sanity/workbench-cli/dev')\n return startWorkbenchDev({\n cacheDir: `${SANITY_CACHE_DIR}/vite`,\n checkForDeprecatedAppId: () => checkForDeprecatedAppId({cliConfig, output}),\n cliConfig,\n extractManifest: isApp\n ? ({workDir: wd}) => extractCoreAppManifest({workDir: wd})\n : (params) => extractStudioManifest(params),\n httpHost,\n httpPort,\n isApp,\n output,\n // Runtime template needs a concrete boolean; collapse an unset config to off.\n reactStrictMode: resolveReactStrictMode(cliConfig) ?? false,\n startAppServer,\n workDir,\n })\n }\n\n // Plain non-workbench studio/app: one dev server announcing its own URL.\n const result = await startAppServer({announceUrl: true, cliConfig, httpPort})\n return {close: result.started ? result.close : noop}\n}\n"],"names":["SANITY_CACHE_DIR","isWorkbenchApp","checkForDeprecatedAppId","getSharedServerConfig","resolveReactStrictMode","extractCoreAppManifest","extractStudioManifest","startAppDevServer","startStudioDevServer","noop","devAction","options","cliConfig","flags","isApp","output","workDir","httpHost","httpPort","host","port","startAppServer","params","announceUrl","app","startWorkbenchDev","cacheDir","extractManifest","wd","reactStrictMode","result","close","started"],"mappings":"AAAA,SAAQA,gBAAgB,QAAO,oCAAmC;AAElE,SAAQC,cAAc,QAAO,wBAAuB;AAEpD,SAAQC,uBAAuB,QAAO,sBAAqB;AAC3D,SAAQC,qBAAqB,QAAO,sCAAqC;AACzE,SAAQC,sBAAsB,QAAO,uCAAsC;AAC3E,SAAQC,sBAAsB,QAAO,wCAAuC;AAC5E,SAAQC,qBAAqB,QAAO,uCAAsC;AAC1E,SAAQC,iBAAiB,QAAO,iCAAgC;AAChE,SAAQC,oBAAoB,QAAO,oCAAmC;AAGtE,MAAMC,OAAO,WAAa;AAE1B;;;;;CAKC,GACD,OAAO,eAAeC,UAAUC,OAAyB;IACvD,MAAM,EAACC,SAAS,EAAEC,KAAK,EAAEC,KAAK,EAAEC,MAAM,EAAEC,OAAO,EAAC,GAAGL;IAEnD,MAAM,EAACM,QAAQ,EAAEC,QAAQ,EAAC,GAAGf,sBAAsB;QACjDS;QACAC,OAAO;YAACM,MAAMN,MAAMM,IAAI;YAAEC,MAAMP,MAAMO,IAAI;QAAA;QAC1CJ;IACF;IAEA,6EAA6E;IAC7E,iDAAiD;IACjD,MAAMK,iBAAiB,CAACC,SACtB,AAACR,CAAAA,QAAQP,oBAAoBC,oBAAmB,EAAG;YACjD,GAAGG,OAAO;YACVY,aAAaD,OAAOC,WAAW;YAC/BX,WAAWU,OAAOV,SAAS;YAC3BM,UAAUI,OAAOJ,QAAQ;QAC3B;IAEF,IAAIjB,eAAeW,WAAWY,MAAM;QAClC,2EAA2E;QAC3E,uDAAuD;QACvD,gDAAgD;QAChD,MAAM,EAACC,iBAAiB,EAAC,GAAG,MAAM,MAAM,CAAC;QACzC,OAAOA,kBAAkB;YACvBC,UAAU,GAAG1B,iBAAiB,KAAK,CAAC;YACpCE,yBAAyB,IAAMA,wBAAwB;oBAACU;oBAAWG;gBAAM;YACzEH;YACAe,iBAAiBb,QACb,CAAC,EAACE,SAASY,EAAE,EAAC,GAAKvB,uBAAuB;oBAACW,SAASY;gBAAE,KACtD,CAACN,SAAWhB,sBAAsBgB;YACtCL;YACAC;YACAJ;YACAC;YACA,8EAA8E;YAC9Ec,iBAAiBzB,uBAAuBQ,cAAc;YACtDS;YACAL;QACF;IACF;IAEA,yEAAyE;IACzE,MAAMc,SAAS,MAAMT,eAAe;QAACE,aAAa;QAAMX;QAAWM;IAAQ;IAC3E,OAAO;QAACa,OAAOD,OAAOE,OAAO,GAAGF,OAAOC,KAAK,GAAGtB;IAAI;AACrD"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import path from 'node:path';
|
|
2
2
|
import { getSanityEnvVar } from '@sanity/cli-core';
|
|
3
3
|
import { logSymbols, spinner } from '@sanity/cli-core/ux';
|
|
4
|
-
import { isWorkbenchApp } from '@sanity/workbench-cli';
|
|
4
|
+
import { isWorkbenchApp, resolveAppId } from '@sanity/workbench-cli';
|
|
5
5
|
import { determineIsApp } from '../../../util/determineIsApp.js';
|
|
6
6
|
import { getSharedServerConfig } from '../../../util/getSharedServerConfig.js';
|
|
7
7
|
import { resolveReactStrictMode } from '../../../util/resolveReactStrictMode.js';
|
|
@@ -50,7 +50,13 @@ export function getDevServerConfig({ cliConfig, flags, httpPort, output, workDir
|
|
|
50
50
|
reactStrictMode,
|
|
51
51
|
staticPath: path.join(workDir, 'static'),
|
|
52
52
|
typegen: cliConfig?.typegen,
|
|
53
|
-
|
|
53
|
+
// Inline the same id the dev registry advertises so the app's bus identity
|
|
54
|
+
// matches how the workbench addresses it. The registry re-reads the bound
|
|
55
|
+
// port if a non-strict shift moves it.
|
|
56
|
+
workbenchAppId: isWorkbenchApp(app) ? resolveAppId({
|
|
57
|
+
host: baseConfig.httpHost,
|
|
58
|
+
port: httpPort ?? baseConfig.httpPort
|
|
59
|
+
}) : undefined
|
|
54
60
|
};
|
|
55
61
|
}
|
|
56
62
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/actions/dev/servers/getDevServerConfig.ts"],"sourcesContent":["import path from 'node:path'\n\nimport {type CliConfig, getSanityEnvVar, type Output} from '@sanity/cli-core'\nimport {logSymbols, spinner} from '@sanity/cli-core/ux'\nimport {isWorkbenchApp} from '@sanity/workbench-cli'\n\nimport {type DevServerOptions} from '../../../server/devServer.js'\nimport {determineIsApp} from '../../../util/determineIsApp.js'\nimport {getSharedServerConfig} from '../../../util/getSharedServerConfig.js'\nimport {resolveReactStrictMode} from '../../../util/resolveReactStrictMode.js'\nimport {type DevFlags} from '../types.js'\n\nexport function getDevServerConfig({\n cliConfig,\n flags,\n httpPort,\n output,\n workDir,\n}: {\n cliConfig?: CliConfig\n flags: DevFlags\n httpPort?: number\n output: Output\n workDir: string\n}): Omit<DevServerOptions, 'spinner'> {\n const configSpinner = spinner('Checking configuration files...')\n\n const baseConfig = getSharedServerConfig({\n cliConfig,\n flags: {\n host: flags.host,\n port: flags.port,\n },\n workDir,\n })\n\n configSpinner.succeed()\n\n const isApp = cliConfig ? determineIsApp(cliConfig) : false\n const reactStrictMode = resolveReactStrictMode(cliConfig)\n // `views`/`services` are declared via `unstable_defineApp`, so read them off\n // the branded app result rather than the legacy `app` config type.\n const app = cliConfig?.app\n\n const envBasePath = getSanityEnvVar('BASEPATH', isApp ?? false)\n if (envBasePath && cliConfig?.project?.basePath) {\n output.warn(\n `Overriding configured base path (${cliConfig.project.basePath}) with value from environment variable (${envBasePath})`,\n )\n }\n\n // Unstable opt-in to Vite's experimental bundled dev mode, via\n // `unstable_bundledDev` in sanity.cli.ts. Defaults to off.\n const bundledDev = cliConfig?.unstable_bundledDev ?? false\n if (bundledDev) {\n output.log(`${logSymbols.info} Running dev server with experimental Vite bundled dev mode`)\n }\n\n return {\n ...baseConfig,\n bundledDev,\n // The app's navigable entry. A branded app that omits `entry` has no app\n // view: the runtime/federation skip the `./App` render path entirely.\n entry: app?.entry,\n exposes: isWorkbenchApp(app)\n ? {config: app.config, services: app.services, views: app.views}\n : undefined,\n // `devAction` passes an explicit port when a running workbench claimed the\n // configured one; otherwise the shared resolution stands.\n httpPort: httpPort ?? baseConfig.httpPort,\n isWorkbenchApp: isWorkbenchApp(app),\n reactCompiler: cliConfig && 'reactCompiler' in cliConfig ? cliConfig.reactCompiler : undefined,\n reactStrictMode,\n staticPath: path.join(workDir, 'static'),\n typegen: cliConfig?.typegen,\n workbenchAppId: isWorkbenchApp(app)
|
|
1
|
+
{"version":3,"sources":["../../../../src/actions/dev/servers/getDevServerConfig.ts"],"sourcesContent":["import path from 'node:path'\n\nimport {type CliConfig, getSanityEnvVar, type Output} from '@sanity/cli-core'\nimport {logSymbols, spinner} from '@sanity/cli-core/ux'\nimport {isWorkbenchApp, resolveAppId} from '@sanity/workbench-cli'\n\nimport {type DevServerOptions} from '../../../server/devServer.js'\nimport {determineIsApp} from '../../../util/determineIsApp.js'\nimport {getSharedServerConfig} from '../../../util/getSharedServerConfig.js'\nimport {resolveReactStrictMode} from '../../../util/resolveReactStrictMode.js'\nimport {type DevFlags} from '../types.js'\n\nexport function getDevServerConfig({\n cliConfig,\n flags,\n httpPort,\n output,\n workDir,\n}: {\n cliConfig?: CliConfig\n flags: DevFlags\n httpPort?: number\n output: Output\n workDir: string\n}): Omit<DevServerOptions, 'spinner'> {\n const configSpinner = spinner('Checking configuration files...')\n\n const baseConfig = getSharedServerConfig({\n cliConfig,\n flags: {\n host: flags.host,\n port: flags.port,\n },\n workDir,\n })\n\n configSpinner.succeed()\n\n const isApp = cliConfig ? determineIsApp(cliConfig) : false\n const reactStrictMode = resolveReactStrictMode(cliConfig)\n // `views`/`services` are declared via `unstable_defineApp`, so read them off\n // the branded app result rather than the legacy `app` config type.\n const app = cliConfig?.app\n\n const envBasePath = getSanityEnvVar('BASEPATH', isApp ?? false)\n if (envBasePath && cliConfig?.project?.basePath) {\n output.warn(\n `Overriding configured base path (${cliConfig.project.basePath}) with value from environment variable (${envBasePath})`,\n )\n }\n\n // Unstable opt-in to Vite's experimental bundled dev mode, via\n // `unstable_bundledDev` in sanity.cli.ts. Defaults to off.\n const bundledDev = cliConfig?.unstable_bundledDev ?? false\n if (bundledDev) {\n output.log(`${logSymbols.info} Running dev server with experimental Vite bundled dev mode`)\n }\n\n return {\n ...baseConfig,\n bundledDev,\n // The app's navigable entry. A branded app that omits `entry` has no app\n // view: the runtime/federation skip the `./App` render path entirely.\n entry: app?.entry,\n exposes: isWorkbenchApp(app)\n ? {config: app.config, services: app.services, views: app.views}\n : undefined,\n // `devAction` passes an explicit port when a running workbench claimed the\n // configured one; otherwise the shared resolution stands.\n httpPort: httpPort ?? baseConfig.httpPort,\n isWorkbenchApp: isWorkbenchApp(app),\n reactCompiler: cliConfig && 'reactCompiler' in cliConfig ? cliConfig.reactCompiler : undefined,\n reactStrictMode,\n staticPath: path.join(workDir, 'static'),\n typegen: cliConfig?.typegen,\n // Inline the same id the dev registry advertises so the app's bus identity\n // matches how the workbench addresses it. The registry re-reads the bound\n // port if a non-strict shift moves it.\n workbenchAppId: isWorkbenchApp(app)\n ? resolveAppId({host: baseConfig.httpHost, port: httpPort ?? baseConfig.httpPort})\n : undefined,\n }\n}\n"],"names":["path","getSanityEnvVar","logSymbols","spinner","isWorkbenchApp","resolveAppId","determineIsApp","getSharedServerConfig","resolveReactStrictMode","getDevServerConfig","cliConfig","flags","httpPort","output","workDir","configSpinner","baseConfig","host","port","succeed","isApp","reactStrictMode","app","envBasePath","project","basePath","warn","bundledDev","unstable_bundledDev","log","info","entry","exposes","config","services","views","undefined","reactCompiler","staticPath","join","typegen","workbenchAppId","httpHost"],"mappings":"AAAA,OAAOA,UAAU,YAAW;AAE5B,SAAwBC,eAAe,QAAoB,mBAAkB;AAC7E,SAAQC,UAAU,EAAEC,OAAO,QAAO,sBAAqB;AACvD,SAAQC,cAAc,EAAEC,YAAY,QAAO,wBAAuB;AAGlE,SAAQC,cAAc,QAAO,kCAAiC;AAC9D,SAAQC,qBAAqB,QAAO,yCAAwC;AAC5E,SAAQC,sBAAsB,QAAO,0CAAyC;AAG9E,OAAO,SAASC,mBAAmB,EACjCC,SAAS,EACTC,KAAK,EACLC,QAAQ,EACRC,MAAM,EACNC,OAAO,EAOR;IACC,MAAMC,gBAAgBZ,QAAQ;IAE9B,MAAMa,aAAaT,sBAAsB;QACvCG;QACAC,OAAO;YACLM,MAAMN,MAAMM,IAAI;YAChBC,MAAMP,MAAMO,IAAI;QAClB;QACAJ;IACF;IAEAC,cAAcI,OAAO;IAErB,MAAMC,QAAQV,YAAYJ,eAAeI,aAAa;IACtD,MAAMW,kBAAkBb,uBAAuBE;IAC/C,6EAA6E;IAC7E,mEAAmE;IACnE,MAAMY,MAAMZ,WAAWY;IAEvB,MAAMC,cAActB,gBAAgB,YAAYmB,SAAS;IACzD,IAAIG,eAAeb,WAAWc,SAASC,UAAU;QAC/CZ,OAAOa,IAAI,CACT,CAAC,iCAAiC,EAAEhB,UAAUc,OAAO,CAACC,QAAQ,CAAC,wCAAwC,EAAEF,YAAY,CAAC,CAAC;IAE3H;IAEA,+DAA+D;IAC/D,2DAA2D;IAC3D,MAAMI,aAAajB,WAAWkB,uBAAuB;IACrD,IAAID,YAAY;QACdd,OAAOgB,GAAG,CAAC,GAAG3B,WAAW4B,IAAI,CAAC,2DAA2D,CAAC;IAC5F;IAEA,OAAO;QACL,GAAGd,UAAU;QACbW;QACA,yEAAyE;QACzE,sEAAsE;QACtEI,OAAOT,KAAKS;QACZC,SAAS5B,eAAekB,OACpB;YAACW,QAAQX,IAAIW,MAAM;YAAEC,UAAUZ,IAAIY,QAAQ;YAAEC,OAAOb,IAAIa,KAAK;QAAA,IAC7DC;QACJ,2EAA2E;QAC3E,0DAA0D;QAC1DxB,UAAUA,YAAYI,WAAWJ,QAAQ;QACzCR,gBAAgBA,eAAekB;QAC/Be,eAAe3B,aAAa,mBAAmBA,YAAYA,UAAU2B,aAAa,GAAGD;QACrFf;QACAiB,YAAYtC,KAAKuC,IAAI,CAACzB,SAAS;QAC/B0B,SAAS9B,WAAW8B;QACpB,2EAA2E;QAC3E,0EAA0E;QAC1E,uCAAuC;QACvCC,gBAAgBrC,eAAekB,OAC3BjB,aAAa;YAACY,MAAMD,WAAW0B,QAAQ;YAAExB,MAAMN,YAAYI,WAAWJ,QAAQ;QAAA,KAC9EwB;IACN;AACF"}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { CLIError } from '@oclif/core/errors';
|
|
2
|
-
import {
|
|
2
|
+
import { exitCodes } from '@sanity/cli-core';
|
|
3
3
|
import { confirm } from '@sanity/cli-core/ux';
|
|
4
4
|
import { oneline } from 'oneline';
|
|
5
5
|
import { graphqlDebug } from './graphqlDebug.js';
|
|
6
6
|
const LATEST_GENERATION = 'gen3';
|
|
7
|
-
export async function resolveApiGeneration({ currentGeneration, force, index, output, specifiedGeneration }) {
|
|
7
|
+
export async function resolveApiGeneration({ currentGeneration, force, index, output, specifiedGeneration, unattended }) {
|
|
8
8
|
// a) If no API is currently deployed:
|
|
9
9
|
// use the specificed one from config, or use whichever generation is the latest
|
|
10
10
|
// b) If an API generation is specified explicitly:
|
|
@@ -17,12 +17,12 @@ export async function resolveApiGeneration({ currentGeneration, force, index, ou
|
|
|
17
17
|
return generation;
|
|
18
18
|
}
|
|
19
19
|
if (specifiedGeneration && specifiedGeneration !== currentGeneration) {
|
|
20
|
-
if (!force &&
|
|
20
|
+
if (!force && unattended) {
|
|
21
21
|
throw new CLIError(oneline`
|
|
22
22
|
Specified generation (${specifiedGeneration}) for API at index ${index} differs from the one currently deployed (${currentGeneration}).
|
|
23
|
-
|
|
23
|
+
Pass \`--force\` to continue.
|
|
24
24
|
`, {
|
|
25
|
-
exit:
|
|
25
|
+
exit: exitCodes.USAGE_ERROR
|
|
26
26
|
});
|
|
27
27
|
}
|
|
28
28
|
output.warn(`Specified generation (${specifiedGeneration}) for API at index ${index} differs from the one currently deployed (${currentGeneration}).`);
|
|
@@ -30,7 +30,10 @@ export async function resolveApiGeneration({ currentGeneration, force, index, ou
|
|
|
30
30
|
default: false,
|
|
31
31
|
message: 'Are you sure you want to deploy?'
|
|
32
32
|
});
|
|
33
|
-
|
|
33
|
+
if (!confirmDeploy) {
|
|
34
|
+
return undefined;
|
|
35
|
+
}
|
|
36
|
+
return specifiedGeneration;
|
|
34
37
|
}
|
|
35
38
|
if (specifiedGeneration) {
|
|
36
39
|
graphqlDebug('Using specified (%s) generation', specifiedGeneration);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/actions/graphql/resolveApiGeneration.ts"],"sourcesContent":["import {CLIError} from '@oclif/core/errors'\nimport {
|
|
1
|
+
{"version":3,"sources":["../../../src/actions/graphql/resolveApiGeneration.ts"],"sourcesContent":["import {CLIError} from '@oclif/core/errors'\nimport {exitCodes, type Output} from '@sanity/cli-core'\nimport {confirm} from '@sanity/cli-core/ux'\nimport {oneline} from 'oneline'\n\nimport {graphqlDebug} from './graphqlDebug.js'\n\nconst LATEST_GENERATION = 'gen3'\n\nexport async function resolveApiGeneration({\n currentGeneration,\n force,\n index,\n output,\n specifiedGeneration,\n unattended,\n}: {\n currentGeneration?: string\n force?: boolean\n index: number\n output: Output\n specifiedGeneration?: string\n unattended: boolean\n}): Promise<string | undefined> {\n // a) If no API is currently deployed:\n // use the specificed one from config, or use whichever generation is the latest\n // b) If an API generation is specified explicitly:\n // use the given one, but _prompt_ if it differs from the current one\n // c) If no API generation is specified explicitly:\n // use whichever is already deployed, but warn if differs from latest\n if (!currentGeneration) {\n const generation = specifiedGeneration || LATEST_GENERATION\n graphqlDebug(\n 'There is no current generation deployed, using %s (%s)',\n generation,\n specifiedGeneration ? 'specified' : 'default',\n )\n return generation\n }\n\n if (specifiedGeneration && specifiedGeneration !== currentGeneration) {\n if (!force && unattended) {\n throw new CLIError(\n oneline`\n Specified generation (${specifiedGeneration}) for API at index ${index} differs from the one currently deployed (${currentGeneration}).\n Pass \\`--force\\` to continue.\n `,\n {exit: exitCodes.USAGE_ERROR},\n )\n }\n\n output.warn(\n `Specified generation (${specifiedGeneration}) for API at index ${index} differs from the one currently deployed (${currentGeneration}).`,\n )\n\n const confirmDeploy =\n force ||\n (await confirm({\n default: false,\n message: 'Are you sure you want to deploy?',\n }))\n\n if (!confirmDeploy) {\n return undefined\n }\n\n return specifiedGeneration\n }\n\n if (specifiedGeneration) {\n graphqlDebug('Using specified (%s) generation', specifiedGeneration)\n return specifiedGeneration\n }\n\n graphqlDebug('Using the currently deployed version (%s)', currentGeneration)\n return currentGeneration\n}\n"],"names":["CLIError","exitCodes","confirm","oneline","graphqlDebug","LATEST_GENERATION","resolveApiGeneration","currentGeneration","force","index","output","specifiedGeneration","unattended","generation","exit","USAGE_ERROR","warn","confirmDeploy","default","message","undefined"],"mappings":"AAAA,SAAQA,QAAQ,QAAO,qBAAoB;AAC3C,SAAQC,SAAS,QAAoB,mBAAkB;AACvD,SAAQC,OAAO,QAAO,sBAAqB;AAC3C,SAAQC,OAAO,QAAO,UAAS;AAE/B,SAAQC,YAAY,QAAO,oBAAmB;AAE9C,MAAMC,oBAAoB;AAE1B,OAAO,eAAeC,qBAAqB,EACzCC,iBAAiB,EACjBC,KAAK,EACLC,KAAK,EACLC,MAAM,EACNC,mBAAmB,EACnBC,UAAU,EAQX;IACC,sCAAsC;IACtC,mFAAmF;IACnF,mDAAmD;IACnD,wEAAwE;IACxE,mDAAmD;IACnD,wEAAwE;IACxE,IAAI,CAACL,mBAAmB;QACtB,MAAMM,aAAaF,uBAAuBN;QAC1CD,aACE,0DACAS,YACAF,sBAAsB,cAAc;QAEtC,OAAOE;IACT;IAEA,IAAIF,uBAAuBA,wBAAwBJ,mBAAmB;QACpE,IAAI,CAACC,SAASI,YAAY;YACxB,MAAM,IAAIZ,SACRG,OAAO,CAAC;8BACc,EAAEQ,oBAAoB,mBAAmB,EAAEF,MAAM,0CAA0C,EAAEF,kBAAkB;;MAEvI,CAAC,EACC;gBAACO,MAAMb,UAAUc,WAAW;YAAA;QAEhC;QAEAL,OAAOM,IAAI,CACT,CAAC,sBAAsB,EAAEL,oBAAoB,mBAAmB,EAAEF,MAAM,0CAA0C,EAAEF,kBAAkB,EAAE,CAAC;QAG3I,MAAMU,gBACJT,SACC,MAAMN,QAAQ;YACbgB,SAAS;YACTC,SAAS;QACX;QAEF,IAAI,CAACF,eAAe;YAClB,OAAOG;QACT;QAEA,OAAOT;IACT;IAEA,IAAIA,qBAAqB;QACvBP,aAAa,mCAAmCO;QAChD,OAAOA;IACT;IAEAP,aAAa,6CAA6CG;IAC1D,OAAOA;AACT"}
|
|
@@ -64,12 +64,7 @@ export async function bootstrapLocalTemplate(opts) {
|
|
|
64
64
|
...isAppTemplate ? sdkAppDependencies.dependencies : studioDependencies.dependencies,
|
|
65
65
|
...isAppTemplate ? sdkAppDependencies.devDependencies : studioDependencies.devDependencies,
|
|
66
66
|
...template.dependencies,
|
|
67
|
-
...template.devDependencies
|
|
68
|
-
// `unstable_defineApp` (re-exported via `sanity/cli`) only exists on the
|
|
69
|
-
// workbench dist-tag of `sanity`.
|
|
70
|
-
...variables.workbench && {
|
|
71
|
-
sanity: 'workbench'
|
|
72
|
-
}
|
|
67
|
+
...template.devDependencies
|
|
73
68
|
});
|
|
74
69
|
spin.succeed();
|
|
75
70
|
// Use the resolved version for the given dependency
|
|
@@ -91,8 +86,17 @@ export async function bootstrapLocalTemplate(opts) {
|
|
|
91
86
|
/**
|
|
92
87
|
* Currently app init doesn't ask for a name, so we use the last part of the path
|
|
93
88
|
*/ if (isAppTemplate) {
|
|
94
|
-
packageJsonName =
|
|
89
|
+
packageJsonName = slugify(path.basename(outputPath));
|
|
95
90
|
}
|
|
91
|
+
const title = variables.projectName || packageJsonName;
|
|
92
|
+
// Default the workbench app `slug` (the hostname the application is created
|
|
93
|
+
// at on deploy). App init never asks for a name (`variables.projectName` is
|
|
94
|
+
// just the cwd basename there), so apps follow their identity — the
|
|
95
|
+
// output-path basename (`packageJsonName`) — while studios slug the entered
|
|
96
|
+
// project name. Fall back to a constant when the source slugifies to
|
|
97
|
+
// nothing (e.g. a fully non-latin name): an empty `slug` fails app config
|
|
98
|
+
// validation, which is exactly what pre-filling it is meant to avoid.
|
|
99
|
+
const slug = (isAppTemplate ? packageJsonName : slugify(title)) || 'sanity-app';
|
|
96
100
|
// Now create a package manifest (`package.json`) with the merged dependencies
|
|
97
101
|
spin = spinner('Creating default project files').start();
|
|
98
102
|
const packageManifest = createPackageManifest({
|
|
@@ -114,7 +118,8 @@ export async function bootstrapLocalTemplate(opts) {
|
|
|
114
118
|
isWorkbenchApp: variables.workbench,
|
|
115
119
|
name: packageJsonName,
|
|
116
120
|
organizationId: variables.organizationId,
|
|
117
|
-
|
|
121
|
+
slug,
|
|
122
|
+
title
|
|
118
123
|
}) : createCliConfig({
|
|
119
124
|
autoUpdates: variables.autoUpdates,
|
|
120
125
|
dataset: variables.dataset,
|
|
@@ -122,7 +127,8 @@ export async function bootstrapLocalTemplate(opts) {
|
|
|
122
127
|
name: packageJsonName,
|
|
123
128
|
organizationId: variables.organizationId,
|
|
124
129
|
projectId: variables.projectId,
|
|
125
|
-
|
|
130
|
+
slug,
|
|
131
|
+
title
|
|
126
132
|
});
|
|
127
133
|
// Write non-template files to disc
|
|
128
134
|
const codeExt = useTypeScript ? 'ts' : 'js';
|
|
@@ -162,5 +168,8 @@ export async function bootstrapLocalTemplate(opts) {
|
|
|
162
168
|
function toTypeScriptPath(originalPath) {
|
|
163
169
|
return originalPath.replace(/\.js$/, '.ts');
|
|
164
170
|
}
|
|
171
|
+
/** Lowercase, deburred, spaces to hyphens, everything else stripped. */ function slugify(value) {
|
|
172
|
+
return deburr(value.toLowerCase()).replaceAll(/\s+/g, '-').replaceAll(/[^a-z0-9-]/g, '');
|
|
173
|
+
}
|
|
165
174
|
|
|
166
175
|
//# sourceMappingURL=bootstrapLocalTemplate.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/actions/init/bootstrapLocalTemplate.ts"],"sourcesContent":["import fs from 'node:fs/promises'\nimport path from 'node:path'\nimport {styleText} from 'node:util'\n\nimport {Output, subdebug} from '@sanity/cli-core'\nimport {spinner} from '@sanity/cli-core/ux'\nimport deburr from 'lodash-es/deburr.js'\n\nimport {copy} from '../../util/copy.js'\nimport {resolveLatestVersions} from '../../util/resolveLatestVersions.js'\nimport {createAppCliConfig} from './createAppCliConfig.js'\nimport {createCliConfig} from './createCliConfig.js'\nimport {createPackageManifest} from './createPackageManifest.js'\nimport {createStudioConfig, type GenerateConfigOptions} from './createStudioConfig.js'\nimport {determineAppTemplate} from './determineAppTemplate.js'\nimport {processTemplate} from './processTemplate.js'\nimport {sdkAppDependencies} from './sdkAppDependencies.js'\nimport {studioDependencies} from './studioDependencies.js'\nimport templates from './templates/index.js'\nimport {type ProjectTemplate} from './types.js'\nimport {updateInitialTemplateMetadata} from './updateInitialTemplateMetadata.js'\n\nconst debug = subdebug('init:bootstrapRemoteTemplate')\n\ninterface BootstrapLocalOptions {\n output: Output\n outputPath: string\n packageName: string\n templateName: string\n useTypeScript: boolean\n variables: GenerateConfigOptions['variables']\n\n overwriteFiles?: boolean\n}\n\nexport async function bootstrapLocalTemplate(\n opts: BootstrapLocalOptions,\n): Promise<ProjectTemplate> {\n const {output, outputPath, packageName, templateName, useTypeScript, variables} = opts\n // packages/@sanity/cli/src/actions/init/ -> packages/@sanity/cli/src/action -> packages/@sanity/cli/src/\n const cliRoot = path.resolve(import.meta.dirname, '../../..')\n const templatesDir = path.join(cliRoot, 'templates')\n const sourceDir = path.join(templatesDir, templateName)\n const sharedDir = path.join(templatesDir, 'shared')\n const isAppTemplate = determineAppTemplate(templateName)\n\n // Check that we have a template info file (dependencies, plugins etc)\n const template = templates[templateName]\n if (!template) {\n throw new Error(`Template \"${templateName}\" not defined`)\n }\n\n // Copy template files\n debug('Copying files from template \"%s\" to \"%s\"', templateName, outputPath)\n let spin = spinner('Bootstrapping files from template').start()\n\n debug(`Copying template from : ${sourceDir}`)\n await copy(sourceDir, outputPath, {\n rename: useTypeScript ? toTypeScriptPath : undefined,\n })\n debug(`Copying shared template code from : ${sharedDir}`)\n await copy(path.join(sharedDir, 'gitignore.txt'), outputPath, {rename: () => '.gitignore'})\n\n if (useTypeScript) {\n await fs.copyFile(path.join(sharedDir, 'tsconfig.json'), path.join(outputPath, 'tsconfig.json'))\n }\n\n spin.succeed()\n\n if (isAppTemplate) {\n const appEntryPath = path.join(outputPath, 'src', 'App.tsx')\n const raw = await fs.readFile(appEntryPath, 'utf8')\n const rendered = processTemplate({\n template: raw,\n variables: {\n dataset: variables.dataset ?? '',\n projectId: variables.projectId ?? '',\n },\n })\n await fs.writeFile(appEntryPath, rendered)\n }\n\n // Merge global and template-specific plugins and dependencies\n\n // Resolve latest versions of Sanity-dependencies\n spin = spinner('Resolving latest module versions').start()\n const dependencyVersions = await resolveLatestVersions({\n ...(isAppTemplate ? sdkAppDependencies.dependencies : studioDependencies.dependencies),\n ...(isAppTemplate ? sdkAppDependencies.devDependencies : studioDependencies.devDependencies),\n ...template.dependencies,\n ...template.devDependencies,\n // `unstable_defineApp` (re-exported via `sanity/cli`) only exists on the\n // workbench dist-tag of `sanity`.\n ...(variables.workbench && {sanity: 'workbench'}),\n })\n spin.succeed()\n\n // Use the resolved version for the given dependency\n const dependencies: Record<string, string> = {}\n for (const dependency of Object.keys({\n ...(isAppTemplate ? sdkAppDependencies.dependencies : studioDependencies.dependencies),\n ...template.dependencies,\n })) {\n dependencies[dependency] = dependencyVersions[dependency]\n }\n\n const devDependencies: Record<string, string> = {}\n for (const dependency of Object.keys({\n ...(isAppTemplate ? sdkAppDependencies.devDependencies : studioDependencies.devDependencies),\n ...template.devDependencies,\n })) {\n devDependencies[dependency] = dependencyVersions[dependency]\n }\n\n let packageJsonName: string = packageName\n\n /**\n * Currently app init doesn't ask for a name, so we use the last part of the path\n */\n if (isAppTemplate) {\n packageJsonName = deburr(path.basename(outputPath).toLowerCase())\n .replaceAll(/\\s+/g, '-')\n .replaceAll(/[^a-z0-9-]/g, '')\n }\n\n // Now create a package manifest (`package.json`) with the merged dependencies\n spin = spinner('Creating default project files').start()\n const packageManifest = createPackageManifest({\n dependencies,\n devDependencies,\n isAppTemplate,\n name: packageJsonName,\n scripts: template.scripts,\n type: template.type,\n })\n\n // ...and a studio config (`sanity.config.[ts|js]`)\n const studioConfig = createStudioConfig({\n template: template.configTemplate,\n variables,\n })\n\n // ...and a CLI config (`sanity.cli.[ts|js]`)\n const cliConfig = isAppTemplate\n ? createAppCliConfig({\n entry: template.entry!,\n isWorkbenchApp: variables.workbench,\n name: packageJsonName,\n organizationId: variables.organizationId,\n title: variables.projectName || packageJsonName,\n })\n : createCliConfig({\n autoUpdates: variables.autoUpdates,\n dataset: variables.dataset,\n isWorkbenchApp: variables.workbench,\n name: packageJsonName,\n organizationId: variables.organizationId,\n projectId: variables.projectId,\n title: variables.projectName || packageJsonName,\n })\n\n // Write non-template files to disc\n const codeExt = useTypeScript ? 'ts' : 'js'\n await Promise.all(\n [\n isAppTemplate\n ? Promise.resolve(null)\n : writeFileIfNotExists(`sanity.config.${codeExt}`, studioConfig),\n writeFileIfNotExists(`sanity.cli.${codeExt}`, cliConfig),\n writeFileIfNotExists('package.json', packageManifest),\n\n writeFileIfNotExists(\n 'eslint.config.mjs',\n `import studio from '@sanity/eslint-config-studio'\\n\\nexport default [...studio]\\n`,\n ),\n ].filter(Boolean),\n )\n\n debug('Updating initial template metadata')\n if (variables.projectId) {\n await updateInitialTemplateMetadata(variables.projectId, `cli-${templateName}`)\n }\n\n // Finish up by providing init process with template-specific info\n spin.succeed()\n return template\n\n async function writeFileIfNotExists(fileName: string, content: string): Promise<void> {\n const filePath = path.join(outputPath, fileName)\n\n if (opts.overwriteFiles) {\n // If overwrite is enabled, just write the file\n await fs.writeFile(filePath, content)\n return\n }\n\n try {\n await fs.writeFile(filePath, content, {flag: 'wx'})\n } catch (err) {\n if (err.code === 'EEXIST') {\n output.warn(`\\n${styleText('yellow', '⚠')} File \"${filePath}\" already exists, skipping`)\n } else {\n throw err\n }\n }\n }\n}\n\nfunction toTypeScriptPath(originalPath: string): string {\n return originalPath.replace(/\\.js$/, '.ts')\n}\n"],"names":["fs","path","styleText","subdebug","spinner","deburr","copy","resolveLatestVersions","createAppCliConfig","createCliConfig","createPackageManifest","createStudioConfig","determineAppTemplate","processTemplate","sdkAppDependencies","studioDependencies","templates","updateInitialTemplateMetadata","debug","bootstrapLocalTemplate","opts","output","outputPath","packageName","templateName","useTypeScript","variables","cliRoot","resolve","dirname","templatesDir","join","sourceDir","sharedDir","isAppTemplate","template","Error","spin","start","rename","toTypeScriptPath","undefined","copyFile","succeed","appEntryPath","raw","readFile","rendered","dataset","projectId","writeFile","dependencyVersions","dependencies","devDependencies","workbench","sanity","dependency","Object","keys","packageJsonName","basename","toLowerCase","replaceAll","packageManifest","name","scripts","type","studioConfig","configTemplate","cliConfig","entry","isWorkbenchApp","organizationId","title","projectName","autoUpdates","codeExt","Promise","all","writeFileIfNotExists","filter","Boolean","fileName","content","filePath","overwriteFiles","flag","err","code","warn","originalPath","replace"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../src/actions/init/bootstrapLocalTemplate.ts"],"sourcesContent":["import fs from 'node:fs/promises'\nimport path from 'node:path'\nimport {styleText} from 'node:util'\n\nimport {Output, subdebug} from '@sanity/cli-core'\nimport {spinner} from '@sanity/cli-core/ux'\nimport deburr from 'lodash-es/deburr.js'\n\nimport {copy} from '../../util/copy.js'\nimport {resolveLatestVersions} from '../../util/resolveLatestVersions.js'\nimport {createAppCliConfig} from './createAppCliConfig.js'\nimport {createCliConfig} from './createCliConfig.js'\nimport {createPackageManifest} from './createPackageManifest.js'\nimport {createStudioConfig, type GenerateConfigOptions} from './createStudioConfig.js'\nimport {determineAppTemplate} from './determineAppTemplate.js'\nimport {processTemplate} from './processTemplate.js'\nimport {sdkAppDependencies} from './sdkAppDependencies.js'\nimport {studioDependencies} from './studioDependencies.js'\nimport templates from './templates/index.js'\nimport {type ProjectTemplate} from './types.js'\nimport {updateInitialTemplateMetadata} from './updateInitialTemplateMetadata.js'\n\nconst debug = subdebug('init:bootstrapRemoteTemplate')\n\ninterface BootstrapLocalOptions {\n output: Output\n outputPath: string\n packageName: string\n templateName: string\n useTypeScript: boolean\n variables: GenerateConfigOptions['variables']\n\n overwriteFiles?: boolean\n}\n\nexport async function bootstrapLocalTemplate(\n opts: BootstrapLocalOptions,\n): Promise<ProjectTemplate> {\n const {output, outputPath, packageName, templateName, useTypeScript, variables} = opts\n // packages/@sanity/cli/src/actions/init/ -> packages/@sanity/cli/src/action -> packages/@sanity/cli/src/\n const cliRoot = path.resolve(import.meta.dirname, '../../..')\n const templatesDir = path.join(cliRoot, 'templates')\n const sourceDir = path.join(templatesDir, templateName)\n const sharedDir = path.join(templatesDir, 'shared')\n const isAppTemplate = determineAppTemplate(templateName)\n\n // Check that we have a template info file (dependencies, plugins etc)\n const template = templates[templateName]\n if (!template) {\n throw new Error(`Template \"${templateName}\" not defined`)\n }\n\n // Copy template files\n debug('Copying files from template \"%s\" to \"%s\"', templateName, outputPath)\n let spin = spinner('Bootstrapping files from template').start()\n\n debug(`Copying template from : ${sourceDir}`)\n await copy(sourceDir, outputPath, {\n rename: useTypeScript ? toTypeScriptPath : undefined,\n })\n debug(`Copying shared template code from : ${sharedDir}`)\n await copy(path.join(sharedDir, 'gitignore.txt'), outputPath, {rename: () => '.gitignore'})\n\n if (useTypeScript) {\n await fs.copyFile(path.join(sharedDir, 'tsconfig.json'), path.join(outputPath, 'tsconfig.json'))\n }\n\n spin.succeed()\n\n if (isAppTemplate) {\n const appEntryPath = path.join(outputPath, 'src', 'App.tsx')\n const raw = await fs.readFile(appEntryPath, 'utf8')\n const rendered = processTemplate({\n template: raw,\n variables: {\n dataset: variables.dataset ?? '',\n projectId: variables.projectId ?? '',\n },\n })\n await fs.writeFile(appEntryPath, rendered)\n }\n\n // Merge global and template-specific plugins and dependencies\n\n // Resolve latest versions of Sanity-dependencies\n spin = spinner('Resolving latest module versions').start()\n const dependencyVersions = await resolveLatestVersions({\n ...(isAppTemplate ? sdkAppDependencies.dependencies : studioDependencies.dependencies),\n ...(isAppTemplate ? sdkAppDependencies.devDependencies : studioDependencies.devDependencies),\n ...template.dependencies,\n ...template.devDependencies,\n })\n spin.succeed()\n\n // Use the resolved version for the given dependency\n const dependencies: Record<string, string> = {}\n for (const dependency of Object.keys({\n ...(isAppTemplate ? sdkAppDependencies.dependencies : studioDependencies.dependencies),\n ...template.dependencies,\n })) {\n dependencies[dependency] = dependencyVersions[dependency]\n }\n\n const devDependencies: Record<string, string> = {}\n for (const dependency of Object.keys({\n ...(isAppTemplate ? sdkAppDependencies.devDependencies : studioDependencies.devDependencies),\n ...template.devDependencies,\n })) {\n devDependencies[dependency] = dependencyVersions[dependency]\n }\n\n let packageJsonName: string = packageName\n\n /**\n * Currently app init doesn't ask for a name, so we use the last part of the path\n */\n if (isAppTemplate) {\n packageJsonName = slugify(path.basename(outputPath))\n }\n\n const title = variables.projectName || packageJsonName\n // Default the workbench app `slug` (the hostname the application is created\n // at on deploy). App init never asks for a name (`variables.projectName` is\n // just the cwd basename there), so apps follow their identity — the\n // output-path basename (`packageJsonName`) — while studios slug the entered\n // project name. Fall back to a constant when the source slugifies to\n // nothing (e.g. a fully non-latin name): an empty `slug` fails app config\n // validation, which is exactly what pre-filling it is meant to avoid.\n const slug = (isAppTemplate ? packageJsonName : slugify(title)) || 'sanity-app'\n\n // Now create a package manifest (`package.json`) with the merged dependencies\n spin = spinner('Creating default project files').start()\n const packageManifest = createPackageManifest({\n dependencies,\n devDependencies,\n isAppTemplate,\n name: packageJsonName,\n scripts: template.scripts,\n type: template.type,\n })\n\n // ...and a studio config (`sanity.config.[ts|js]`)\n const studioConfig = createStudioConfig({\n template: template.configTemplate,\n variables,\n })\n\n // ...and a CLI config (`sanity.cli.[ts|js]`)\n const cliConfig = isAppTemplate\n ? createAppCliConfig({\n entry: template.entry!,\n isWorkbenchApp: variables.workbench,\n name: packageJsonName,\n organizationId: variables.organizationId,\n slug,\n title,\n })\n : createCliConfig({\n autoUpdates: variables.autoUpdates,\n dataset: variables.dataset,\n isWorkbenchApp: variables.workbench,\n name: packageJsonName,\n organizationId: variables.organizationId,\n projectId: variables.projectId,\n slug,\n title,\n })\n\n // Write non-template files to disc\n const codeExt = useTypeScript ? 'ts' : 'js'\n await Promise.all(\n [\n isAppTemplate\n ? Promise.resolve(null)\n : writeFileIfNotExists(`sanity.config.${codeExt}`, studioConfig),\n writeFileIfNotExists(`sanity.cli.${codeExt}`, cliConfig),\n writeFileIfNotExists('package.json', packageManifest),\n\n writeFileIfNotExists(\n 'eslint.config.mjs',\n `import studio from '@sanity/eslint-config-studio'\\n\\nexport default [...studio]\\n`,\n ),\n ].filter(Boolean),\n )\n\n debug('Updating initial template metadata')\n if (variables.projectId) {\n await updateInitialTemplateMetadata(variables.projectId, `cli-${templateName}`)\n }\n\n // Finish up by providing init process with template-specific info\n spin.succeed()\n return template\n\n async function writeFileIfNotExists(fileName: string, content: string): Promise<void> {\n const filePath = path.join(outputPath, fileName)\n\n if (opts.overwriteFiles) {\n // If overwrite is enabled, just write the file\n await fs.writeFile(filePath, content)\n return\n }\n\n try {\n await fs.writeFile(filePath, content, {flag: 'wx'})\n } catch (err) {\n if (err.code === 'EEXIST') {\n output.warn(`\\n${styleText('yellow', '⚠')} File \"${filePath}\" already exists, skipping`)\n } else {\n throw err\n }\n }\n }\n}\n\nfunction toTypeScriptPath(originalPath: string): string {\n return originalPath.replace(/\\.js$/, '.ts')\n}\n\n/** Lowercase, deburred, spaces to hyphens, everything else stripped. */\nfunction slugify(value: string): string {\n return deburr(value.toLowerCase())\n .replaceAll(/\\s+/g, '-')\n .replaceAll(/[^a-z0-9-]/g, '')\n}\n"],"names":["fs","path","styleText","subdebug","spinner","deburr","copy","resolveLatestVersions","createAppCliConfig","createCliConfig","createPackageManifest","createStudioConfig","determineAppTemplate","processTemplate","sdkAppDependencies","studioDependencies","templates","updateInitialTemplateMetadata","debug","bootstrapLocalTemplate","opts","output","outputPath","packageName","templateName","useTypeScript","variables","cliRoot","resolve","dirname","templatesDir","join","sourceDir","sharedDir","isAppTemplate","template","Error","spin","start","rename","toTypeScriptPath","undefined","copyFile","succeed","appEntryPath","raw","readFile","rendered","dataset","projectId","writeFile","dependencyVersions","dependencies","devDependencies","dependency","Object","keys","packageJsonName","slugify","basename","title","projectName","slug","packageManifest","name","scripts","type","studioConfig","configTemplate","cliConfig","entry","isWorkbenchApp","workbench","organizationId","autoUpdates","codeExt","Promise","all","writeFileIfNotExists","filter","Boolean","fileName","content","filePath","overwriteFiles","flag","err","code","warn","originalPath","replace","value","toLowerCase","replaceAll"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/actions/init/createAppCliConfig.ts"],"sourcesContent":["import {workbenchAppConfigTemplate} from '@sanity/workbench-cli/init'\n\nimport {processTemplate} from './processTemplate.js'\n\nconst defaultAppTemplate = `\nimport {defineCliConfig} from 'sanity/cli'\n\nexport default defineCliConfig({\n app: {\n organizationId: '%organizationId%',\n entry: '%entry%',\n },\n})\n`\n\ninterface GenerateCliConfigOptions {\n entry: string\n isWorkbenchApp: boolean\n name: string\n title: string\n\n organizationId?: string\n}\n\nexport function createAppCliConfig(options: GenerateCliConfigOptions): string {\n const {isWorkbenchApp, ...variables} = options\n return processTemplate({\n includeBooleanTransform: true,\n template: isWorkbenchApp ? workbenchAppConfigTemplate : defaultAppTemplate,\n variables,\n })\n}\n"],"names":["workbenchAppConfigTemplate","processTemplate","defaultAppTemplate","createAppCliConfig","options","isWorkbenchApp","variables","includeBooleanTransform","template"],"mappings":"AAAA,SAAQA,0BAA0B,QAAO,6BAA4B;AAErE,SAAQC,eAAe,QAAO,uBAAsB;AAEpD,MAAMC,qBAAqB,CAAC;;;;;;;;;AAS5B,CAAC;
|
|
1
|
+
{"version":3,"sources":["../../../src/actions/init/createAppCliConfig.ts"],"sourcesContent":["import {workbenchAppConfigTemplate} from '@sanity/workbench-cli/init'\n\nimport {processTemplate} from './processTemplate.js'\n\nconst defaultAppTemplate = `\nimport {defineCliConfig} from 'sanity/cli'\n\nexport default defineCliConfig({\n app: {\n organizationId: '%organizationId%',\n entry: '%entry%',\n },\n})\n`\n\ninterface GenerateCliConfigOptions {\n entry: string\n isWorkbenchApp: boolean\n name: string\n slug: string\n title: string\n\n organizationId?: string\n}\n\nexport function createAppCliConfig(options: GenerateCliConfigOptions): string {\n const {isWorkbenchApp, ...variables} = options\n return processTemplate({\n includeBooleanTransform: true,\n template: isWorkbenchApp ? workbenchAppConfigTemplate : defaultAppTemplate,\n variables,\n })\n}\n"],"names":["workbenchAppConfigTemplate","processTemplate","defaultAppTemplate","createAppCliConfig","options","isWorkbenchApp","variables","includeBooleanTransform","template"],"mappings":"AAAA,SAAQA,0BAA0B,QAAO,6BAA4B;AAErE,SAAQC,eAAe,QAAO,uBAAsB;AAEpD,MAAMC,qBAAqB,CAAC;;;;;;;;;AAS5B,CAAC;AAYD,OAAO,SAASC,mBAAmBC,OAAiC;IAClE,MAAM,EAACC,cAAc,EAAE,GAAGC,WAAU,GAAGF;IACvC,OAAOH,gBAAgB;QACrBM,yBAAyB;QACzBC,UAAUH,iBAAiBL,6BAA6BE;QACxDI;IACF;AACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/actions/init/createCliConfig.ts"],"sourcesContent":["import {workbenchStudioConfigTemplate} from '@sanity/workbench-cli/init'\n\nimport {processTemplate} from './processTemplate.js'\n\nconst defaultTemplate = `\nimport {defineCliConfig} from 'sanity/cli'\n\nexport default defineCliConfig({\n api: {\n projectId: '%projectId%',\n dataset: '%dataset%'\n },\n deployment: {\n /**\n * Enable auto-updates for studios.\n * Learn more at https://www.sanity.io/docs/studio/latest-version-of-sanity#k47faf43faf56\n */\n autoUpdates: __BOOL__autoUpdates__,\n },\n})\n`\n\ninterface GenerateCliConfigOptions {\n autoUpdates: boolean\n dataset: string\n isWorkbenchApp: boolean\n name: string\n projectId: string\n title: string\n\n organizationId?: string\n}\n\nexport function createCliConfig(options: GenerateCliConfigOptions): string {\n const {isWorkbenchApp, ...variables} = options\n return processTemplate({\n includeBooleanTransform: true,\n template: isWorkbenchApp ? workbenchStudioConfigTemplate : defaultTemplate,\n variables,\n })\n}\n"],"names":["workbenchStudioConfigTemplate","processTemplate","defaultTemplate","createCliConfig","options","isWorkbenchApp","variables","includeBooleanTransform","template"],"mappings":"AAAA,SAAQA,6BAA6B,QAAO,6BAA4B;AAExE,SAAQC,eAAe,QAAO,uBAAsB;AAEpD,MAAMC,kBAAkB,CAAC;;;;;;;;;;;;;;;;AAgBzB,CAAC;
|
|
1
|
+
{"version":3,"sources":["../../../src/actions/init/createCliConfig.ts"],"sourcesContent":["import {workbenchStudioConfigTemplate} from '@sanity/workbench-cli/init'\n\nimport {processTemplate} from './processTemplate.js'\n\nconst defaultTemplate = `\nimport {defineCliConfig} from 'sanity/cli'\n\nexport default defineCliConfig({\n api: {\n projectId: '%projectId%',\n dataset: '%dataset%'\n },\n deployment: {\n /**\n * Enable auto-updates for studios.\n * Learn more at https://www.sanity.io/docs/studio/latest-version-of-sanity#k47faf43faf56\n */\n autoUpdates: __BOOL__autoUpdates__,\n },\n})\n`\n\ninterface GenerateCliConfigOptions {\n autoUpdates: boolean\n dataset: string\n isWorkbenchApp: boolean\n name: string\n projectId: string\n slug: string\n title: string\n\n organizationId?: string\n}\n\nexport function createCliConfig(options: GenerateCliConfigOptions): string {\n const {isWorkbenchApp, ...variables} = options\n return processTemplate({\n includeBooleanTransform: true,\n template: isWorkbenchApp ? workbenchStudioConfigTemplate : defaultTemplate,\n variables,\n })\n}\n"],"names":["workbenchStudioConfigTemplate","processTemplate","defaultTemplate","createCliConfig","options","isWorkbenchApp","variables","includeBooleanTransform","template"],"mappings":"AAAA,SAAQA,6BAA6B,QAAO,6BAA4B;AAExE,SAAQC,eAAe,QAAO,uBAAsB;AAEpD,MAAMC,kBAAkB,CAAC;;;;;;;;;;;;;;;;AAgBzB,CAAC;AAcD,OAAO,SAASC,gBAAgBC,OAAiC;IAC/D,MAAM,EAACC,cAAc,EAAE,GAAGC,WAAU,GAAGF;IACvC,OAAOH,gBAAgB;QACrBM,yBAAyB;QACzBC,UAAUH,iBAAiBL,gCAAgCE;QAC3DI;IACF;AACF"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { styleText } from 'node:util';
|
|
2
|
-
import { subdebug } from '@sanity/cli-core';
|
|
2
|
+
import { exitCodes, subdebug } from '@sanity/cli-core';
|
|
3
3
|
import { logSymbols, spinner } from '@sanity/cli-core/ux';
|
|
4
4
|
import { frameworks } from '@vercel/frameworks';
|
|
5
5
|
import deburr from 'lodash-es/deburr.js';
|
|
@@ -7,10 +7,12 @@ import { promptForConfigFiles } from '../../prompts/init/nextjs.js';
|
|
|
7
7
|
import { getCliUser } from '../../services/user.js';
|
|
8
8
|
import { CLIInitStepCompleted } from '../../telemetry/init.telemetry.js';
|
|
9
9
|
import { detectFrameworkRecord } from '../../util/detectFramework.js';
|
|
10
|
+
import { formatCliErrorMessages } from '../../util/formatCliErrorMessages.js';
|
|
10
11
|
import { getProjectDefaults } from '../../util/getProjectDefaults.js';
|
|
11
12
|
import { validateSession } from '../auth/ensureAuthenticated.js';
|
|
12
13
|
import { getProviderName } from '../auth/getProviderName.js';
|
|
13
14
|
import { login } from '../auth/login/login.js';
|
|
15
|
+
import { LOGIN_REQUIRED_MESSAGE } from '../auth/login/loginInstructions.js';
|
|
14
16
|
import { detectAvailableEditors } from '../mcp/detectAvailableEditors.js';
|
|
15
17
|
import { setupMCP } from '../mcp/setupMCP.js';
|
|
16
18
|
import { setupSkills } from '../skills/setupSkills.js';
|
|
@@ -268,24 +270,29 @@ export async function initAction(options, context) {
|
|
|
268
270
|
}
|
|
269
271
|
function checkFlagsInUnattendedMode(options, { isAppTemplate, isNextJs }) {
|
|
270
272
|
debug('Unattended mode, validating required options');
|
|
271
|
-
|
|
272
|
-
throw new InitError('`--project-name` requires `--organization <id>` in unattended mode', 1);
|
|
273
|
-
}
|
|
273
|
+
const errors = [];
|
|
274
274
|
if (isAppTemplate) {
|
|
275
275
|
if (!options.outputPath) {
|
|
276
|
-
|
|
276
|
+
errors.push('Output path is required in unattended mode. Pass it with `--output-path <path>`.');
|
|
277
277
|
}
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
278
|
+
if (options.projectName && !options.organization) {
|
|
279
|
+
errors.push('Organization is required when creating a project in unattended mode. Pass it with `--organization <id>`.');
|
|
280
|
+
} else if (!options.project && !options.organization) {
|
|
281
|
+
errors.push('Project or organization is required for app templates in unattended mode. ' + 'Pass `--project <id>` or `--organization <id>`. To create a project, pass ' + '`--project-name <name>` with `--organization <id>`.');
|
|
282
|
+
}
|
|
283
|
+
} else {
|
|
284
|
+
if (!isNextJs && !options.bare && !options.outputPath) {
|
|
285
|
+
errors.push('Output path is required in unattended mode. Pass it with `--output-path <path>`.');
|
|
286
|
+
}
|
|
287
|
+
if (!options.project && !options.projectName) {
|
|
288
|
+
errors.push('Project is required in unattended mode. Pass it with `--project <id>` or `--project-name <name>`.');
|
|
289
|
+
}
|
|
290
|
+
if (!options.project && !options.organization) {
|
|
291
|
+
errors.push('Organization is required when creating a project in unattended mode. Pass it with `--organization <id>`.');
|
|
281
292
|
}
|
|
282
|
-
return;
|
|
283
|
-
}
|
|
284
|
-
if (!isNextJs && !options.bare && !options.outputPath) {
|
|
285
|
-
throw new InitError('`--output-path` must be specified in unattended mode', 1);
|
|
286
293
|
}
|
|
287
|
-
if (
|
|
288
|
-
throw new InitError(
|
|
294
|
+
if (errors.length > 0) {
|
|
295
|
+
throw new InitError(formatCliErrorMessages(errors), exitCodes.USAGE_ERROR);
|
|
289
296
|
}
|
|
290
297
|
}
|
|
291
298
|
async function ensureAuthenticated(options, output, trace) {
|
|
@@ -301,11 +308,12 @@ async function ensureAuthenticated(options, output, trace) {
|
|
|
301
308
|
};
|
|
302
309
|
}
|
|
303
310
|
if (options.unattended) {
|
|
304
|
-
throw new InitError(
|
|
311
|
+
throw new InitError(LOGIN_REQUIRED_MESSAGE, exitCodes.RUNTIME_ERROR);
|
|
305
312
|
}
|
|
306
313
|
trace.log({
|
|
307
314
|
step: 'login'
|
|
308
315
|
});
|
|
316
|
+
output.warn(LOGIN_REQUIRED_MESSAGE);
|
|
309
317
|
try {
|
|
310
318
|
await login({
|
|
311
319
|
output,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/actions/init/initAction.ts"],"sourcesContent":["import {styleText} from 'node:util'\n\nimport {type SanityOrgUser, subdebug, type TelemetryUserProperties} from '@sanity/cli-core'\nimport {logSymbols, spinner} from '@sanity/cli-core/ux'\nimport {type TelemetryTrace} from '@sanity/telemetry'\nimport {type Framework, frameworks} from '@vercel/frameworks'\nimport deburr from 'lodash-es/deburr.js'\n\nimport {promptForConfigFiles} from '../../prompts/init/nextjs.js'\nimport {getCliUser} from '../../services/user.js'\nimport {CLIInitStepCompleted, type InitStepResult} from '../../telemetry/init.telemetry.js'\nimport {detectFrameworkRecord} from '../../util/detectFramework.js'\nimport {getProjectDefaults} from '../../util/getProjectDefaults.js'\nimport {validateSession} from '../auth/ensureAuthenticated.js'\nimport {getProviderName} from '../auth/getProviderName.js'\nimport {login} from '../auth/login/login.js'\nimport {detectAvailableEditors} from '../mcp/detectAvailableEditors.js'\nimport {setupMCP} from '../mcp/setupMCP.js'\nimport {setupSkills} from '../skills/setupSkills.js'\nimport {checkNextJsReactCompatibility} from './checkNextJsReactCompatibility.js'\nimport {determineAppTemplate} from './determineAppTemplate.js'\nimport {createOrAppendEnvVars} from './env/createOrAppendEnvVars.js'\nimport {initApp} from './initApp.js'\nimport {InitError} from './initError.js'\nimport {flagOrDefault, shouldPrompt, writeStagingEnvIfNeeded} from './initHelpers.js'\nimport {initNextJs} from './initNextJs.js'\nimport {initStudio} from './initStudio.js'\nimport {getPlan} from './plan/getPlan.js'\nimport {createProjectFromName} from './project/createProjectFromName.js'\nimport {getProjectDetails} from './project/getProjectDetails.js'\nimport {getProjectOutputPath} from './project/getProjectOutputPath.js'\nimport {checkIsRemoteTemplate, getGitHubRepoInfo, type RepoInfo} from './remoteTemplate.js'\nimport {type InitContext, type InitOptions} from './types.js'\n\nconst debug = subdebug('init')\n\nexport async function initAction(options: InitOptions, context: InitContext): Promise<void> {\n const {output, workDir} = context\n\n if (options.argType) {\n throw new InitError(\n options.argType === 'plugin'\n ? 'Initializing plugins through the CLI is no longer supported'\n : `Unknown init type \"${options.argType}\"`,\n 1,\n )\n }\n\n const trace = context.telemetry.trace(CLIInitStepCompleted)\n\n if (options.reconfigure) {\n throw new InitError('--reconfigure is deprecated - manual configuration is now required', 1)\n }\n\n if (options.project && options.organization) {\n throw new InitError(\n 'You have specified both a project and an organization. To move a project to an organization please visit https://www.sanity.io/manage',\n 1,\n )\n }\n\n const defaultConfig = options.datasetDefault\n let showDefaultConfigPrompt = !defaultConfig\n if (options.dataset || options.visibility || options.datasetDefault || options.unattended) {\n showDefaultConfigPrompt = false\n }\n\n const detectedFramework = await detectFrameworkRecord({\n frameworkList: frameworks as readonly Framework[],\n rootPath: workDir,\n })\n const isNextJs = detectedFramework?.slug === 'nextjs'\n\n let remoteTemplateInfo: RepoInfo | undefined\n if (options.template && checkIsRemoteTemplate(options.template)) {\n remoteTemplateInfo = await getGitHubRepoInfo(options.template, options.templateToken)\n }\n\n if (detectedFramework && detectedFramework.slug !== 'sanity' && remoteTemplateInfo) {\n throw new InitError(\n `A remote template cannot be used with a detected framework. Detected: ${detectedFramework.name}`,\n 1,\n )\n }\n\n const isAppTemplate = options.template ? determineAppTemplate(options.template) : false\n\n if (options.unattended) {\n checkFlagsInUnattendedMode(options, {isAppTemplate, isNextJs})\n }\n\n trace.start()\n trace.log({\n flags: {\n bare: options.bare,\n coupon: options.coupon,\n defaultConfig,\n env: options.env,\n git: typeof options.git === 'string' ? options.git : undefined,\n plan: options.projectPlan,\n reconfigure: options.reconfigure,\n unattended: options.unattended,\n },\n step: 'start',\n })\n\n const planId = await getPlan(options, output, trace)\n\n let envFilenameDefault = '.env'\n if (detectedFramework && detectedFramework.slug === 'nextjs') {\n envFilenameDefault = '.env.local'\n }\n const envFilename = typeof options.env === 'string' ? options.env : envFilenameDefault\n\n const {user} = await ensureAuthenticated(options, output, trace)\n if (!isAppTemplate) {\n output.log(`${logSymbols.success} Fetching existing projects`)\n output.log('')\n }\n\n let newProject: string | undefined\n if (options.projectName) {\n newProject = await createProjectFromName({\n coupon: options.coupon,\n createProjectName: options.projectName,\n dataset: options.dataset,\n organization: options.organization,\n planId,\n user,\n visibility: options.visibility,\n })\n }\n\n const {datasetName, displayName, isFirstProject, organizationId, projectId} =\n await getProjectDetails({\n coupon: options.coupon,\n dataset: options.dataset,\n datasetDefault: options.datasetDefault,\n isAppTemplate,\n newProject,\n organization: options.organization,\n output,\n planId,\n project: options.project,\n showDefaultConfigPrompt,\n trace,\n unattended: options.unattended,\n user,\n visibility: options.visibility,\n })\n\n if (options.bare) {\n output.log(`${logSymbols.success} Below are your project details`)\n output.log('')\n output.log(`Project ID: ${styleText('cyan', projectId)}`)\n output.log(`Dataset: ${styleText('cyan', datasetName)}`)\n output.log(\n `\\nYou can find your project on Sanity Manage — https://www.sanity.io/manage/project/${projectId}\\n`,\n )\n trace.complete()\n return\n }\n\n // Detect editors once, then share the result with MCP and skills setup so\n // we don't pay the detection cost (filesystem probes + CLI execa calls) twice.\n const detectedEditors =\n options.mcpMode === 'skip' && options.skillsMode === 'skip'\n ? []\n : await detectAvailableEditors()\n\n const mcpResult = await setupMCP({\n editors: detectedEditors,\n mode: options.mcpMode,\n output,\n skillsMode: options.skillsMode,\n })\n\n trace.log({\n configuredEditors: mcpResult.configuredEditors,\n detectedEditors: mcpResult.detectedEditors,\n skipped: mcpResult.skipped,\n step: 'mcpSetup',\n })\n if (mcpResult.error) {\n trace.error(mcpResult.error)\n }\n const mcpConfigured = mcpResult.configuredEditors\n\n async function installSkills(): Promise<void> {\n if (mcpResult.skillsToInstall.length === 0) return\n try {\n const skillsResult = await setupSkills({agents: mcpResult.skillsToInstall, output})\n trace.log({\n installedAgents: skillsResult.installedAgents,\n skipped: skillsResult.skipped,\n step: 'skillsSetup',\n })\n if (skillsResult.error) {\n trace.error(skillsResult.error)\n }\n } catch (error) {\n const err = error instanceof Error ? error : new Error(String(error))\n debug('Unexpected error from setupSkills %O', err)\n output.warn(`Could not install Sanity agent skills: ${err.message}`)\n trace.error(err)\n }\n }\n\n // Install skills right after the MCP/skills prompt so the progress + result\n // surface in sequence, rather than trailing the studio \"Success!\" output.\n await installSkills()\n\n const {alreadyConfiguredEditors} = mcpResult\n if (alreadyConfiguredEditors.length > 0) {\n const label =\n alreadyConfiguredEditors.length === 1\n ? `${alreadyConfiguredEditors[0]} already configured for Sanity MCP`\n : `${alreadyConfiguredEditors.length} editors already configured for Sanity MCP`\n spinner(label).start().succeed()\n }\n\n let initNext = flagOrDefault(options.nextjsAddConfigFiles, false)\n if (isNextJs && shouldPrompt(options.unattended, options.nextjsAddConfigFiles)) {\n initNext = await promptForConfigFiles()\n }\n\n trace.log({\n detectedFramework: detectedFramework?.name,\n selectedOption: initNext ? 'yes' : 'no',\n step: 'useDetectedFramework',\n })\n\n const sluggedName = deburr(displayName.toLowerCase())\n .replaceAll(/\\s+/g, '-')\n .replaceAll(/[^a-z0-9-]/g, '')\n\n const initFramework = initNext\n\n const defaults = await getProjectDefaults({isPlugin: false, workDir})\n\n const outputPath = await getProjectOutputPath({\n initFramework,\n outputPath: options.outputPath,\n sluggedName,\n unattended: options.unattended,\n useEnv: Boolean(options.env),\n workDir,\n })\n\n if (isNextJs) {\n await checkNextJsReactCompatibility({\n detectedFramework,\n output,\n outputPath,\n })\n }\n\n if (initNext) {\n await initNextJs({\n datasetName,\n detectedFramework,\n envFilename,\n mcpConfigured,\n options,\n output,\n projectId,\n trace,\n workDir,\n })\n trace.complete()\n return\n }\n\n if (options.env) {\n await createOrAppendEnvVars({\n envVars: {\n DATASET: datasetName,\n PROJECT_ID: projectId,\n },\n filename: envFilename,\n framework: detectedFramework,\n log: false,\n output,\n outputPath,\n })\n await writeStagingEnvIfNeeded(output, outputPath)\n trace.complete()\n return\n }\n\n // Workbench is opt-in (no prompt): the flag swaps the scaffolded\n // `sanity.cli.*` over to `unstable_defineApp` — the branded app is the sole\n // workbench opt-in.\n const workbench = flagOrDefault(options.unstableWorkbench, false)\n\n const sharedParams = {\n defaults,\n mcpConfigured,\n options,\n organizationId,\n output,\n outputPath,\n remoteTemplateInfo,\n sluggedName,\n trace,\n workbench,\n workDir,\n }\n\n await (isAppTemplate\n ? initApp({...sharedParams, datasetName, projectId})\n : initStudio({\n ...sharedParams,\n datasetName,\n displayName,\n isFirstProject,\n projectId,\n }))\n\n trace.complete()\n}\n\nfunction checkFlagsInUnattendedMode(\n options: InitOptions,\n {isAppTemplate, isNextJs}: {isAppTemplate: boolean; isNextJs: boolean},\n): void {\n debug('Unattended mode, validating required options')\n\n if (options.projectName && !options.organization) {\n throw new InitError('`--project-name` requires `--organization <id>` in unattended mode', 1)\n }\n\n if (isAppTemplate) {\n if (!options.outputPath) {\n throw new InitError('`--output-path` must be specified in unattended mode', 1)\n }\n\n const hasProjectFlag = Boolean(options.project || options.projectName)\n\n if (!hasProjectFlag && !options.organization) {\n throw new InitError(\n 'The --organization flag is required for app templates in unattended mode. ' +\n 'Use --organization <id>, or pass --project <id> / --project-name <name>.',\n 1,\n )\n }\n\n return\n }\n\n if (!isNextJs && !options.bare && !options.outputPath) {\n throw new InitError('`--output-path` must be specified in unattended mode', 1)\n }\n\n if (!options.project && !options.projectName) {\n throw new InitError(\n '`--project <id>` or `--project-name <name>` must be specified in unattended mode',\n 1,\n )\n }\n}\n\nasync function ensureAuthenticated(\n options: InitOptions,\n output: InitContext['output'],\n trace: TelemetryTrace<TelemetryUserProperties, InitStepResult>,\n): Promise<{user: SanityOrgUser}> {\n const user = await validateSession()\n\n if (user) {\n trace.log({alreadyLoggedIn: true, step: 'login'})\n output.log(\n `${logSymbols.success} You are logged in as ${user.email} using ${getProviderName(user.provider)}`,\n )\n return {user}\n }\n\n if (options.unattended) {\n throw new InitError(\n 'Must be logged in to run this command in unattended mode, run `sanity login`',\n 1,\n )\n }\n\n trace.log({step: 'login'})\n\n try {\n await login({\n output,\n telemetry: trace.newContext('login'),\n })\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n throw new InitError(`Login failed: ${message}`, 1)\n }\n\n const loggedInUser = await getCliUser()\n\n output.log(\n `${logSymbols.success} You are logged in as ${loggedInUser.email} using ${getProviderName(loggedInUser.provider)}`,\n )\n return {user: loggedInUser}\n}\n"],"names":["styleText","subdebug","logSymbols","spinner","frameworks","deburr","promptForConfigFiles","getCliUser","CLIInitStepCompleted","detectFrameworkRecord","getProjectDefaults","validateSession","getProviderName","login","detectAvailableEditors","setupMCP","setupSkills","checkNextJsReactCompatibility","determineAppTemplate","createOrAppendEnvVars","initApp","InitError","flagOrDefault","shouldPrompt","writeStagingEnvIfNeeded","initNextJs","initStudio","getPlan","createProjectFromName","getProjectDetails","getProjectOutputPath","checkIsRemoteTemplate","getGitHubRepoInfo","debug","initAction","options","context","output","workDir","argType","trace","telemetry","reconfigure","project","organization","defaultConfig","datasetDefault","showDefaultConfigPrompt","dataset","visibility","unattended","detectedFramework","frameworkList","rootPath","isNextJs","slug","remoteTemplateInfo","template","templateToken","name","isAppTemplate","checkFlagsInUnattendedMode","start","log","flags","bare","coupon","env","git","undefined","plan","projectPlan","step","planId","envFilenameDefault","envFilename","user","ensureAuthenticated","success","newProject","projectName","createProjectName","datasetName","displayName","isFirstProject","organizationId","projectId","complete","detectedEditors","mcpMode","skillsMode","mcpResult","editors","mode","configuredEditors","skipped","error","mcpConfigured","installSkills","skillsToInstall","length","skillsResult","agents","installedAgents","err","Error","String","warn","message","alreadyConfiguredEditors","label","succeed","initNext","nextjsAddConfigFiles","selectedOption","sluggedName","toLowerCase","replaceAll","initFramework","defaults","isPlugin","outputPath","useEnv","Boolean","envVars","DATASET","PROJECT_ID","filename","framework","workbench","unstableWorkbench","sharedParams","hasProjectFlag","alreadyLoggedIn","email","provider","newContext","loggedInUser"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../../src/actions/init/initAction.ts"],"sourcesContent":["import {styleText} from 'node:util'\n\nimport {\n exitCodes,\n type SanityOrgUser,\n subdebug,\n type TelemetryUserProperties,\n} from '@sanity/cli-core'\nimport {logSymbols, spinner} from '@sanity/cli-core/ux'\nimport {type TelemetryTrace} from '@sanity/telemetry'\nimport {type Framework, frameworks} from '@vercel/frameworks'\nimport deburr from 'lodash-es/deburr.js'\n\nimport {promptForConfigFiles} from '../../prompts/init/nextjs.js'\nimport {getCliUser} from '../../services/user.js'\nimport {CLIInitStepCompleted, type InitStepResult} from '../../telemetry/init.telemetry.js'\nimport {detectFrameworkRecord} from '../../util/detectFramework.js'\nimport {formatCliErrorMessages} from '../../util/formatCliErrorMessages.js'\nimport {getProjectDefaults} from '../../util/getProjectDefaults.js'\nimport {validateSession} from '../auth/ensureAuthenticated.js'\nimport {getProviderName} from '../auth/getProviderName.js'\nimport {login} from '../auth/login/login.js'\nimport {LOGIN_REQUIRED_MESSAGE} from '../auth/login/loginInstructions.js'\nimport {detectAvailableEditors} from '../mcp/detectAvailableEditors.js'\nimport {setupMCP} from '../mcp/setupMCP.js'\nimport {setupSkills} from '../skills/setupSkills.js'\nimport {checkNextJsReactCompatibility} from './checkNextJsReactCompatibility.js'\nimport {determineAppTemplate} from './determineAppTemplate.js'\nimport {createOrAppendEnvVars} from './env/createOrAppendEnvVars.js'\nimport {initApp} from './initApp.js'\nimport {InitError} from './initError.js'\nimport {flagOrDefault, shouldPrompt, writeStagingEnvIfNeeded} from './initHelpers.js'\nimport {initNextJs} from './initNextJs.js'\nimport {initStudio} from './initStudio.js'\nimport {getPlan} from './plan/getPlan.js'\nimport {createProjectFromName} from './project/createProjectFromName.js'\nimport {getProjectDetails} from './project/getProjectDetails.js'\nimport {getProjectOutputPath} from './project/getProjectOutputPath.js'\nimport {checkIsRemoteTemplate, getGitHubRepoInfo, type RepoInfo} from './remoteTemplate.js'\nimport {type InitContext, type InitOptions} from './types.js'\n\nconst debug = subdebug('init')\n\nexport async function initAction(options: InitOptions, context: InitContext): Promise<void> {\n const {output, workDir} = context\n\n if (options.argType) {\n throw new InitError(\n options.argType === 'plugin'\n ? 'Initializing plugins through the CLI is no longer supported'\n : `Unknown init type \"${options.argType}\"`,\n 1,\n )\n }\n\n const trace = context.telemetry.trace(CLIInitStepCompleted)\n\n if (options.reconfigure) {\n throw new InitError('--reconfigure is deprecated - manual configuration is now required', 1)\n }\n\n if (options.project && options.organization) {\n throw new InitError(\n 'You have specified both a project and an organization. To move a project to an organization please visit https://www.sanity.io/manage',\n 1,\n )\n }\n\n const defaultConfig = options.datasetDefault\n let showDefaultConfigPrompt = !defaultConfig\n if (options.dataset || options.visibility || options.datasetDefault || options.unattended) {\n showDefaultConfigPrompt = false\n }\n\n const detectedFramework = await detectFrameworkRecord({\n frameworkList: frameworks as readonly Framework[],\n rootPath: workDir,\n })\n const isNextJs = detectedFramework?.slug === 'nextjs'\n\n let remoteTemplateInfo: RepoInfo | undefined\n if (options.template && checkIsRemoteTemplate(options.template)) {\n remoteTemplateInfo = await getGitHubRepoInfo(options.template, options.templateToken)\n }\n\n if (detectedFramework && detectedFramework.slug !== 'sanity' && remoteTemplateInfo) {\n throw new InitError(\n `A remote template cannot be used with a detected framework. Detected: ${detectedFramework.name}`,\n 1,\n )\n }\n\n const isAppTemplate = options.template ? determineAppTemplate(options.template) : false\n\n if (options.unattended) {\n checkFlagsInUnattendedMode(options, {isAppTemplate, isNextJs})\n }\n\n trace.start()\n trace.log({\n flags: {\n bare: options.bare,\n coupon: options.coupon,\n defaultConfig,\n env: options.env,\n git: typeof options.git === 'string' ? options.git : undefined,\n plan: options.projectPlan,\n reconfigure: options.reconfigure,\n unattended: options.unattended,\n },\n step: 'start',\n })\n\n const planId = await getPlan(options, output, trace)\n\n let envFilenameDefault = '.env'\n if (detectedFramework && detectedFramework.slug === 'nextjs') {\n envFilenameDefault = '.env.local'\n }\n const envFilename = typeof options.env === 'string' ? options.env : envFilenameDefault\n\n const {user} = await ensureAuthenticated(options, output, trace)\n if (!isAppTemplate) {\n output.log(`${logSymbols.success} Fetching existing projects`)\n output.log('')\n }\n\n let newProject: string | undefined\n if (options.projectName) {\n newProject = await createProjectFromName({\n coupon: options.coupon,\n createProjectName: options.projectName,\n dataset: options.dataset,\n organization: options.organization,\n planId,\n user,\n visibility: options.visibility,\n })\n }\n\n const {datasetName, displayName, isFirstProject, organizationId, projectId} =\n await getProjectDetails({\n coupon: options.coupon,\n dataset: options.dataset,\n datasetDefault: options.datasetDefault,\n isAppTemplate,\n newProject,\n organization: options.organization,\n output,\n planId,\n project: options.project,\n showDefaultConfigPrompt,\n trace,\n unattended: options.unattended,\n user,\n visibility: options.visibility,\n })\n\n if (options.bare) {\n output.log(`${logSymbols.success} Below are your project details`)\n output.log('')\n output.log(`Project ID: ${styleText('cyan', projectId)}`)\n output.log(`Dataset: ${styleText('cyan', datasetName)}`)\n output.log(\n `\\nYou can find your project on Sanity Manage — https://www.sanity.io/manage/project/${projectId}\\n`,\n )\n trace.complete()\n return\n }\n\n // Detect editors once, then share the result with MCP and skills setup so\n // we don't pay the detection cost (filesystem probes + CLI execa calls) twice.\n const detectedEditors =\n options.mcpMode === 'skip' && options.skillsMode === 'skip'\n ? []\n : await detectAvailableEditors()\n\n const mcpResult = await setupMCP({\n editors: detectedEditors,\n mode: options.mcpMode,\n output,\n skillsMode: options.skillsMode,\n })\n\n trace.log({\n configuredEditors: mcpResult.configuredEditors,\n detectedEditors: mcpResult.detectedEditors,\n skipped: mcpResult.skipped,\n step: 'mcpSetup',\n })\n if (mcpResult.error) {\n trace.error(mcpResult.error)\n }\n const mcpConfigured = mcpResult.configuredEditors\n\n async function installSkills(): Promise<void> {\n if (mcpResult.skillsToInstall.length === 0) return\n try {\n const skillsResult = await setupSkills({\n agents: mcpResult.skillsToInstall,\n output,\n })\n trace.log({\n installedAgents: skillsResult.installedAgents,\n skipped: skillsResult.skipped,\n step: 'skillsSetup',\n })\n if (skillsResult.error) {\n trace.error(skillsResult.error)\n }\n } catch (error) {\n const err = error instanceof Error ? error : new Error(String(error))\n debug('Unexpected error from setupSkills %O', err)\n output.warn(`Could not install Sanity agent skills: ${err.message}`)\n trace.error(err)\n }\n }\n\n // Install skills right after the MCP/skills prompt so the progress + result\n // surface in sequence, rather than trailing the studio \"Success!\" output.\n await installSkills()\n\n const {alreadyConfiguredEditors} = mcpResult\n if (alreadyConfiguredEditors.length > 0) {\n const label =\n alreadyConfiguredEditors.length === 1\n ? `${alreadyConfiguredEditors[0]} already configured for Sanity MCP`\n : `${alreadyConfiguredEditors.length} editors already configured for Sanity MCP`\n spinner(label).start().succeed()\n }\n\n let initNext = flagOrDefault(options.nextjsAddConfigFiles, false)\n if (isNextJs && shouldPrompt(options.unattended, options.nextjsAddConfigFiles)) {\n initNext = await promptForConfigFiles()\n }\n\n trace.log({\n detectedFramework: detectedFramework?.name,\n selectedOption: initNext ? 'yes' : 'no',\n step: 'useDetectedFramework',\n })\n\n const sluggedName = deburr(displayName.toLowerCase())\n .replaceAll(/\\s+/g, '-')\n .replaceAll(/[^a-z0-9-]/g, '')\n\n const initFramework = initNext\n\n const defaults = await getProjectDefaults({isPlugin: false, workDir})\n\n const outputPath = await getProjectOutputPath({\n initFramework,\n outputPath: options.outputPath,\n sluggedName,\n unattended: options.unattended,\n useEnv: Boolean(options.env),\n workDir,\n })\n\n if (isNextJs) {\n await checkNextJsReactCompatibility({\n detectedFramework,\n output,\n outputPath,\n })\n }\n\n if (initNext) {\n await initNextJs({\n datasetName,\n detectedFramework,\n envFilename,\n mcpConfigured,\n options,\n output,\n projectId,\n trace,\n workDir,\n })\n trace.complete()\n return\n }\n\n if (options.env) {\n await createOrAppendEnvVars({\n envVars: {\n DATASET: datasetName,\n PROJECT_ID: projectId,\n },\n filename: envFilename,\n framework: detectedFramework,\n log: false,\n output,\n outputPath,\n })\n await writeStagingEnvIfNeeded(output, outputPath)\n trace.complete()\n return\n }\n\n // Workbench is opt-in (no prompt): the flag swaps the scaffolded\n // `sanity.cli.*` over to `unstable_defineApp` — the branded app is the sole\n // workbench opt-in.\n const workbench = flagOrDefault(options.unstableWorkbench, false)\n\n const sharedParams = {\n defaults,\n mcpConfigured,\n options,\n organizationId,\n output,\n outputPath,\n remoteTemplateInfo,\n sluggedName,\n trace,\n workbench,\n workDir,\n }\n\n await (isAppTemplate\n ? initApp({...sharedParams, datasetName, projectId})\n : initStudio({\n ...sharedParams,\n datasetName,\n displayName,\n isFirstProject,\n projectId,\n }))\n\n trace.complete()\n}\n\nfunction checkFlagsInUnattendedMode(\n options: InitOptions,\n {isAppTemplate, isNextJs}: {isAppTemplate: boolean; isNextJs: boolean},\n): void {\n debug('Unattended mode, validating required options')\n\n const errors: string[] = []\n\n if (isAppTemplate) {\n if (!options.outputPath) {\n errors.push(\n 'Output path is required in unattended mode. Pass it with `--output-path <path>`.',\n )\n }\n\n if (options.projectName && !options.organization) {\n errors.push(\n 'Organization is required when creating a project in unattended mode. Pass it with `--organization <id>`.',\n )\n } else if (!options.project && !options.organization) {\n errors.push(\n 'Project or organization is required for app templates in unattended mode. ' +\n 'Pass `--project <id>` or `--organization <id>`. To create a project, pass ' +\n '`--project-name <name>` with `--organization <id>`.',\n )\n }\n } else {\n if (!isNextJs && !options.bare && !options.outputPath) {\n errors.push(\n 'Output path is required in unattended mode. Pass it with `--output-path <path>`.',\n )\n }\n\n if (!options.project && !options.projectName) {\n errors.push(\n 'Project is required in unattended mode. Pass it with `--project <id>` or `--project-name <name>`.',\n )\n }\n\n if (!options.project && !options.organization) {\n errors.push(\n 'Organization is required when creating a project in unattended mode. Pass it with `--organization <id>`.',\n )\n }\n }\n\n if (errors.length > 0) {\n throw new InitError(formatCliErrorMessages(errors), exitCodes.USAGE_ERROR)\n }\n}\n\nasync function ensureAuthenticated(\n options: InitOptions,\n output: InitContext['output'],\n trace: TelemetryTrace<TelemetryUserProperties, InitStepResult>,\n): Promise<{user: SanityOrgUser}> {\n const user = await validateSession()\n\n if (user) {\n trace.log({alreadyLoggedIn: true, step: 'login'})\n output.log(\n `${logSymbols.success} You are logged in as ${user.email} using ${getProviderName(user.provider)}`,\n )\n return {user}\n }\n\n if (options.unattended) {\n throw new InitError(LOGIN_REQUIRED_MESSAGE, exitCodes.RUNTIME_ERROR)\n }\n\n trace.log({step: 'login'})\n output.warn(LOGIN_REQUIRED_MESSAGE)\n\n try {\n await login({\n output,\n telemetry: trace.newContext('login'),\n })\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n throw new InitError(`Login failed: ${message}`, 1)\n }\n\n const loggedInUser = await getCliUser()\n\n output.log(\n `${logSymbols.success} You are logged in as ${loggedInUser.email} using ${getProviderName(loggedInUser.provider)}`,\n )\n return {user: loggedInUser}\n}\n"],"names":["styleText","exitCodes","subdebug","logSymbols","spinner","frameworks","deburr","promptForConfigFiles","getCliUser","CLIInitStepCompleted","detectFrameworkRecord","formatCliErrorMessages","getProjectDefaults","validateSession","getProviderName","login","LOGIN_REQUIRED_MESSAGE","detectAvailableEditors","setupMCP","setupSkills","checkNextJsReactCompatibility","determineAppTemplate","createOrAppendEnvVars","initApp","InitError","flagOrDefault","shouldPrompt","writeStagingEnvIfNeeded","initNextJs","initStudio","getPlan","createProjectFromName","getProjectDetails","getProjectOutputPath","checkIsRemoteTemplate","getGitHubRepoInfo","debug","initAction","options","context","output","workDir","argType","trace","telemetry","reconfigure","project","organization","defaultConfig","datasetDefault","showDefaultConfigPrompt","dataset","visibility","unattended","detectedFramework","frameworkList","rootPath","isNextJs","slug","remoteTemplateInfo","template","templateToken","name","isAppTemplate","checkFlagsInUnattendedMode","start","log","flags","bare","coupon","env","git","undefined","plan","projectPlan","step","planId","envFilenameDefault","envFilename","user","ensureAuthenticated","success","newProject","projectName","createProjectName","datasetName","displayName","isFirstProject","organizationId","projectId","complete","detectedEditors","mcpMode","skillsMode","mcpResult","editors","mode","configuredEditors","skipped","error","mcpConfigured","installSkills","skillsToInstall","length","skillsResult","agents","installedAgents","err","Error","String","warn","message","alreadyConfiguredEditors","label","succeed","initNext","nextjsAddConfigFiles","selectedOption","sluggedName","toLowerCase","replaceAll","initFramework","defaults","isPlugin","outputPath","useEnv","Boolean","envVars","DATASET","PROJECT_ID","filename","framework","workbench","unstableWorkbench","sharedParams","errors","push","USAGE_ERROR","alreadyLoggedIn","email","provider","RUNTIME_ERROR","newContext","loggedInUser"],"mappings":"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"}
|
|
@@ -31,13 +31,15 @@ const sanitizeIconPath = new URL('sanitizeIcon.js', import.meta.url).href;
|
|
|
31
31
|
return mod.sanitizeIcon;
|
|
32
32
|
}
|
|
33
33
|
/**
|
|
34
|
-
* Resolves app.icon from config (a file path) to
|
|
35
|
-
*
|
|
34
|
+
* Resolves app.icon from config (a file path) to a sanitized SVG string. Used
|
|
35
|
+
* both for the manifest and, on deploy, for the icon shipped to Brett — the
|
|
36
|
+
* manifest expects the SVG inline, not a path.
|
|
36
37
|
*
|
|
37
38
|
* The file is sanitized through the same allowlist as the studio manifest's
|
|
38
39
|
* icon resolver (see {@link lazySanitizeIcon}) so both manifest paths inline the
|
|
39
40
|
* same trusted subset of SVG markup.
|
|
40
|
-
|
|
41
|
+
* @internal
|
|
42
|
+
*/ export async function readIconFromPath(workDir, iconPath) {
|
|
41
43
|
const resolvedPath = resolve(workDir, iconPath);
|
|
42
44
|
const pathRelativeToWorkDir = relative(workDir, resolvedPath);
|
|
43
45
|
if (pathRelativeToWorkDir.startsWith('..')) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/actions/manifest/extractCoreAppManifest.ts"],"sourcesContent":["import {readFile} from 'node:fs/promises'\nimport {relative, resolve} from 'node:path'\n\nimport {doImport, getCliConfigUncached} from '@sanity/cli-core'\nimport {getErrorMessage} from '@sanity/cli-core/errors'\nimport {spinner} from '@sanity/cli-core/ux'\nimport {isWorkbenchApp} from '@sanity/workbench-cli'\n\nimport {type sanitizeIcon as sanitizeIconFn} from './sanitizeIcon.js'\nimport {type CoreAppManifest, coreAppManifestSchema} from './types.js'\n\ninterface ExtractCoreAppManifestOptions {\n workDir: string\n}\n\n/**\n * The title change a deploy would sync from the manifest to the user\n * application, or null when the titles already match (or none is set).\n *\n * @internal\n */\nexport function resolveTitleUpdate(\n manifest: CoreAppManifest | undefined,\n application: {title: string | null},\n): {from: string | null; to: string} | null {\n if (manifest?.title === undefined || manifest.title === application.title) {\n return null\n }\n return {from: application.title, to: manifest.title}\n}\n\nconst sanitizeIconPath = new URL('sanitizeIcon.js', import.meta.url).href\n\n/**\n * Lazy-load {@link sanitizeIconFn} so `isomorphic-dompurify` (and its jsdom\n * dependency) stays out of the CLI's eager import graph. The studio manifest\n * resolver lazy-loads its icon machinery for the same reason; this path runs in\n * the main process (not the manifest worker), so only an app deploy that\n * actually has an icon pays the cost.\n */\nasync function lazySanitizeIcon(): Promise<typeof sanitizeIconFn> {\n const mod = await doImport(sanitizeIconPath)\n return mod.sanitizeIcon\n}\n\n/**\n * Resolves app.icon from config (a file path) to
|
|
1
|
+
{"version":3,"sources":["../../../src/actions/manifest/extractCoreAppManifest.ts"],"sourcesContent":["import {readFile} from 'node:fs/promises'\nimport {relative, resolve} from 'node:path'\n\nimport {doImport, getCliConfigUncached} from '@sanity/cli-core'\nimport {getErrorMessage} from '@sanity/cli-core/errors'\nimport {spinner} from '@sanity/cli-core/ux'\nimport {isWorkbenchApp} from '@sanity/workbench-cli'\n\nimport {type sanitizeIcon as sanitizeIconFn} from './sanitizeIcon.js'\nimport {type CoreAppManifest, coreAppManifestSchema} from './types.js'\n\ninterface ExtractCoreAppManifestOptions {\n workDir: string\n}\n\n/**\n * The title change a deploy would sync from the manifest to the user\n * application, or null when the titles already match (or none is set).\n *\n * @internal\n */\nexport function resolveTitleUpdate(\n manifest: CoreAppManifest | undefined,\n application: {title: string | null},\n): {from: string | null; to: string} | null {\n if (manifest?.title === undefined || manifest.title === application.title) {\n return null\n }\n return {from: application.title, to: manifest.title}\n}\n\nconst sanitizeIconPath = new URL('sanitizeIcon.js', import.meta.url).href\n\n/**\n * Lazy-load {@link sanitizeIconFn} so `isomorphic-dompurify` (and its jsdom\n * dependency) stays out of the CLI's eager import graph. The studio manifest\n * resolver lazy-loads its icon machinery for the same reason; this path runs in\n * the main process (not the manifest worker), so only an app deploy that\n * actually has an icon pays the cost.\n */\nasync function lazySanitizeIcon(): Promise<typeof sanitizeIconFn> {\n const mod = await doImport(sanitizeIconPath)\n return mod.sanitizeIcon\n}\n\n/**\n * Resolves app.icon from config (a file path) to a sanitized SVG string. Used\n * both for the manifest and, on deploy, for the icon shipped to Brett — the\n * manifest expects the SVG inline, not a path.\n *\n * The file is sanitized through the same allowlist as the studio manifest's\n * icon resolver (see {@link lazySanitizeIcon}) so both manifest paths inline the\n * same trusted subset of SVG markup.\n * @internal\n */\nexport async function readIconFromPath(workDir: string, iconPath: string): Promise<string> {\n const resolvedPath = resolve(workDir, iconPath)\n const pathRelativeToWorkDir = relative(workDir, resolvedPath)\n if (pathRelativeToWorkDir.startsWith('..')) {\n throw new Error(\n `Icon path \"${iconPath}\" resolves outside the project directory and is not allowed.`,\n )\n }\n\n let content: string\n try {\n content = await readFile(resolvedPath, 'utf8')\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err)\n throw new Error(\n `Could not read icon file at \"${iconPath}\" (resolved: ${resolvedPath}): ${message}`,\n {cause: err},\n )\n }\n\n const trimmed = content.trim()\n if (!/<svg[\\s>]/i.test(trimmed)) {\n throw new Error(\n `Icon file at \"${iconPath}\" does not contain an SVG element. App manifest icons must be SVG files.`,\n )\n }\n\n const sanitizeIcon = await lazySanitizeIcon()\n return sanitizeIcon(trimmed)\n}\n\n/**\n * Unlike studio manifest extraction, skips schema/tool parsing. The config's\n * `app.icon` is a file path; its content is read and inlined in the manifest.\n */\nexport async function extractCoreAppManifest(\n options: ExtractCoreAppManifestOptions,\n): Promise<CoreAppManifest | undefined> {\n const {workDir} = options\n const {app} = await getCliConfigUncached(workDir)\n if (!app) {\n return undefined\n }\n\n const spin = spinner('Extracting manifest').start()\n\n try {\n let icon: string | undefined\n if (app.icon) {\n icon = await readIconFromPath(workDir, app.icon)\n }\n\n if (!icon && !app.title) {\n spin.info('Manifest creation skipped: no icon or title found in app configuration')\n return undefined\n }\n\n const slug = isWorkbenchApp(app) ? app.slug : undefined\n\n const manifest: CoreAppManifest = coreAppManifestSchema.parse({\n version: '1',\n ...(icon ? {icon} : {}),\n ...(app.title ? {title: app.title} : {}),\n ...(app.group ? {group: app.group} : {}),\n ...(app.priority === undefined ? {} : {priority: app.priority}),\n ...(slug ? {slug} : {}),\n })\n\n spin.succeed(`Extracted manifest`)\n\n return manifest\n } catch (err) {\n const message = getErrorMessage(err)\n spin.fail(message)\n throw err\n }\n}\n"],"names":["readFile","relative","resolve","doImport","getCliConfigUncached","getErrorMessage","spinner","isWorkbenchApp","coreAppManifestSchema","resolveTitleUpdate","manifest","application","title","undefined","from","to","sanitizeIconPath","URL","url","href","lazySanitizeIcon","mod","sanitizeIcon","readIconFromPath","workDir","iconPath","resolvedPath","pathRelativeToWorkDir","startsWith","Error","content","err","message","String","cause","trimmed","trim","test","extractCoreAppManifest","options","app","spin","start","icon","info","slug","parse","version","group","priority","succeed","fail"],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/actions/migration/constants.ts"],"sourcesContent":["export const MIGRATIONS_DIRECTORY = 'migrations'\nexport const MIGRATION_SCRIPT_EXTENSIONS = ['mjs', 'js', 'ts', 'cjs']\nexport const DEFAULT_API_VERSION = 'v2024-01-29'\n"],"names":["MIGRATIONS_DIRECTORY","MIGRATION_SCRIPT_EXTENSIONS","DEFAULT_API_VERSION"],"mappings":"AAAA,OAAO,MAAMA,uBAAuB,aAAY;AAChD,OAAO,MAAMC,8BAA8B;IAAC;IAAO;IAAM;IAAM;CAAM,CAAA;AACrE,OAAO,MAAMC,sBAAsB,cAAa"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
const VERSION_PATTERN = /^v\d+-\d+-\d+$|^vX$/ // Matches version strings like vYYYY-MM-DD or vX
|
|
2
|
+
;
|
|
3
|
+
/**
|
|
4
|
+
* Ensures that the provided API version string is in the correct format.
|
|
5
|
+
* If the version does not start with 'v', it will be prefixed with 'v'.
|
|
6
|
+
* If the version does not match the expected pattern, an error will be thrown.
|
|
7
|
+
*/ export function ensureApiVersionFormat(version) {
|
|
8
|
+
const normalizedVersion = version.startsWith('v') ? version : `v${version}`;
|
|
9
|
+
// Check if the version matches the expected pattern
|
|
10
|
+
if (!VERSION_PATTERN.test(normalizedVersion)) {
|
|
11
|
+
throw new Error(`Invalid API version format: ${normalizedVersion}. Expected format: vYYYY-MM-DD or vX`);
|
|
12
|
+
}
|
|
13
|
+
return normalizedVersion;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
//# sourceMappingURL=ensureApiVersionFormat.js.map
|