@sanity/cli 6.4.0 → 6.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (99) hide show
  1. package/README.md +14 -8
  2. package/dist/actions/build/buildApp.js +12 -4
  3. package/dist/actions/build/buildApp.js.map +1 -1
  4. package/dist/actions/build/buildStaticFiles.js +3 -1
  5. package/dist/actions/build/buildStaticFiles.js.map +1 -1
  6. package/dist/actions/build/buildStudio.js +29 -7
  7. package/dist/actions/build/buildStudio.js.map +1 -1
  8. package/dist/actions/build/buildVendorDependencies.js +7 -7
  9. package/dist/actions/build/buildVendorDependencies.js.map +1 -1
  10. package/dist/actions/build/checkRequiredDependencies.js +4 -4
  11. package/dist/actions/build/checkRequiredDependencies.js.map +1 -1
  12. package/dist/actions/build/checkStudioDependencyVersions.js +9 -9
  13. package/dist/actions/build/checkStudioDependencyVersions.js.map +1 -1
  14. package/dist/actions/build/getAutoUpdatesImportMap.js +9 -0
  15. package/dist/actions/build/getAutoUpdatesImportMap.js.map +1 -1
  16. package/dist/actions/build/getViteConfig.js +2 -1
  17. package/dist/actions/build/getViteConfig.js.map +1 -1
  18. package/dist/actions/build/renderDocument.js.map +1 -1
  19. package/dist/actions/build/renderDocumentWorker/addTimestampImportMapScriptToHtml.js +34 -14
  20. package/dist/actions/build/renderDocumentWorker/addTimestampImportMapScriptToHtml.js.map +1 -1
  21. package/dist/actions/build/renderDocumentWorker/getDocumentHtml.js +2 -2
  22. package/dist/actions/build/renderDocumentWorker/getDocumentHtml.js.map +1 -1
  23. package/dist/actions/build/renderDocumentWorker/renderDocumentWorker.js +2 -2
  24. package/dist/actions/build/renderDocumentWorker/renderDocumentWorker.js.map +1 -1
  25. package/dist/actions/codemods/reactIconsV3.js +2 -2
  26. package/dist/actions/codemods/reactIconsV3.js.map +1 -1
  27. package/dist/actions/dev/startStudioDevServer.js +2 -2
  28. package/dist/actions/dev/startStudioDevServer.js.map +1 -1
  29. package/dist/actions/doctor/types.js.map +1 -1
  30. package/dist/actions/graphql/resolveGraphQLApisFromWorkspaces.js.map +1 -1
  31. package/dist/actions/init/bootstrapTemplate.js.map +1 -1
  32. package/dist/actions/init/checkNextJsReactCompatibility.js +3 -3
  33. package/dist/actions/init/checkNextJsReactCompatibility.js.map +1 -1
  34. package/dist/actions/init/initAction.js +287 -0
  35. package/dist/actions/init/initAction.js.map +1 -0
  36. package/dist/actions/init/initApp.js +7 -16
  37. package/dist/actions/init/initApp.js.map +1 -1
  38. package/dist/actions/init/initError.js +10 -0
  39. package/dist/actions/init/initError.js.map +1 -0
  40. package/dist/actions/init/initHelpers.js +3 -12
  41. package/dist/actions/init/initHelpers.js.map +1 -1
  42. package/dist/actions/init/initNextJs.js +17 -20
  43. package/dist/actions/init/initNextJs.js.map +1 -1
  44. package/dist/actions/init/initStudio.js +11 -20
  45. package/dist/actions/init/initStudio.js.map +1 -1
  46. package/dist/actions/init/plan/getPlan.js +15 -0
  47. package/dist/actions/init/plan/getPlan.js.map +1 -0
  48. package/dist/actions/init/plan/verifyCoupon.js +35 -0
  49. package/dist/actions/init/plan/verifyCoupon.js.map +1 -0
  50. package/dist/actions/init/plan/verifyPlan.js +34 -0
  51. package/dist/actions/init/plan/verifyPlan.js.map +1 -0
  52. package/dist/actions/init/project/createProjectFromName.js +44 -0
  53. package/dist/actions/init/project/createProjectFromName.js.map +1 -0
  54. package/dist/actions/init/project/getOrCreateDataset.js +126 -0
  55. package/dist/actions/init/project/getOrCreateDataset.js.map +1 -0
  56. package/dist/actions/init/project/getOrCreateProject.js +128 -0
  57. package/dist/actions/init/project/getOrCreateProject.js.map +1 -0
  58. package/dist/actions/init/project/getProjectDetails.js +87 -0
  59. package/dist/actions/init/project/getProjectDetails.js.map +1 -0
  60. package/dist/actions/init/project/getProjectOutputPath.js +17 -0
  61. package/dist/actions/init/project/getProjectOutputPath.js.map +1 -0
  62. package/dist/actions/init/project/promptForAppTemplateSetup.js +112 -0
  63. package/dist/actions/init/project/promptForAppTemplateSetup.js.map +1 -0
  64. package/dist/actions/init/project/promptForProjectCreation.js +40 -0
  65. package/dist/actions/init/project/promptForProjectCreation.js.map +1 -0
  66. package/dist/actions/init/project/promptUserForNewOrganization.js +12 -0
  67. package/dist/actions/init/project/promptUserForNewOrganization.js.map +1 -0
  68. package/dist/actions/init/project/promptUserForOrganization.js +38 -0
  69. package/dist/actions/init/project/promptUserForOrganization.js.map +1 -0
  70. package/dist/actions/init/scaffoldTemplate.js +23 -29
  71. package/dist/actions/init/scaffoldTemplate.js.map +1 -1
  72. package/dist/actions/init/types.js +47 -1
  73. package/dist/actions/init/types.js.map +1 -1
  74. package/dist/actions/manifest/types.js +0 -1
  75. package/dist/actions/manifest/types.js.map +1 -1
  76. package/dist/actions/versions/buildPackageArray.js +2 -2
  77. package/dist/actions/versions/buildPackageArray.js.map +1 -1
  78. package/dist/actions/versions/findSanityModulesVersions.js +3 -3
  79. package/dist/actions/versions/findSanityModulesVersions.js.map +1 -1
  80. package/dist/commands/datasets/copy.js.map +1 -1
  81. package/dist/commands/init.js +11 -911
  82. package/dist/commands/init.js.map +1 -1
  83. package/dist/server/vite/plugin-sanity-build-entries.js +2 -1
  84. package/dist/server/vite/plugin-sanity-build-entries.js.map +1 -1
  85. package/dist/services/datasets.js.map +1 -1
  86. package/dist/telemetry/init.telemetry.js.map +1 -1
  87. package/dist/util/compareDependencyVersions.js +4 -4
  88. package/dist/util/compareDependencyVersions.js.map +1 -1
  89. package/dist/util/createExpiringConfig.js +1 -1
  90. package/dist/util/createExpiringConfig.js.map +1 -1
  91. package/dist/util/packageManager/installationInfo/analyzeIssues.js +7 -7
  92. package/dist/util/packageManager/installationInfo/analyzeIssues.js.map +1 -1
  93. package/dist/util/packageManager/installationInfo/types.js.map +1 -1
  94. package/dist/util/packageManager/packageManagerChoice.js +2 -2
  95. package/dist/util/packageManager/packageManagerChoice.js.map +1 -1
  96. package/dist/util/packageManager/preferredPm.js +106 -0
  97. package/dist/util/packageManager/preferredPm.js.map +1 -0
  98. package/oclif.manifest.json +526 -526
  99. package/package.json +23 -22
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/commands/init.ts"],"sourcesContent":["import path from 'node:path'\nimport {styleText} from 'node:util'\n\nimport {Args, Command, Flags} from '@oclif/core'\nimport {CLIError} from '@oclif/core/errors'\nimport {\n SanityCommand,\n type SanityOrgUser,\n subdebug,\n type TelemetryUserProperties,\n} from '@sanity/cli-core'\nimport {confirm, input, logSymbols, select, Separator, spinner} from '@sanity/cli-core/ux'\nimport {type DatasetAclMode, isHttpError} from '@sanity/client'\nimport {type TelemetryTrace} from '@sanity/telemetry'\nimport {type Framework, frameworks} from '@vercel/frameworks'\nimport deburr from 'lodash-es/deburr.js'\n\nimport {validateSession} from '../actions/auth/ensureAuthenticated.js'\nimport {getProviderName} from '../actions/auth/getProviderName.js'\nimport {login} from '../actions/auth/login/login.js'\nimport {createDataset} from '../actions/dataset/create.js'\nimport {checkNextJsReactCompatibility} from '../actions/init/checkNextJsReactCompatibility.js'\nimport {determineAppTemplate} from '../actions/init/determineAppTemplate.js'\nimport {createOrAppendEnvVars} from '../actions/init/env/createOrAppendEnvVars.js'\nimport {initApp} from '../actions/init/initApp.js'\nimport {flagOrDefault, shouldPrompt, writeStagingEnvIfNeeded} from '../actions/init/initHelpers.js'\nimport {initNextJs} from '../actions/init/initNextJs.js'\nimport {initStudio} from '../actions/init/initStudio.js'\nimport {\n checkIsRemoteTemplate,\n getGitHubRepoInfo,\n type RepoInfo,\n} from '../actions/init/remoteTemplate.js'\nimport {setupMCP} from '../actions/mcp/setupMCP.js'\nimport {findOrganizationByUserName} from '../actions/organizations/findOrganizationByUserName.js'\nimport {getOrganizationChoices} from '../actions/organizations/getOrganizationChoices.js'\nimport {getOrganizationsWithAttachGrantInfo} from '../actions/organizations/getOrganizationsWithAttachGrantInfo.js'\nimport {hasProjectAttachGrant} from '../actions/organizations/hasProjectAttachGrant.js'\nimport {type OrganizationChoices} from '../actions/organizations/types.js'\nimport {promptForConfigFiles} from '../prompts/init/nextjs.js'\nimport {promptForDatasetName} from '../prompts/promptForDatasetName.js'\nimport {promptForDefaultConfig} from '../prompts/promptForDefaultConfig.js'\nimport {promptForOrganizationName} from '../prompts/promptForOrganizationName.js'\nimport {createDataset as createDatasetService, listDatasets} from '../services/datasets.js'\nimport {getProjectFeatures} from '../services/getProjectFeatures.js'\nimport {\n createOrganization,\n listOrganizations,\n type OrganizationCreateResponse,\n type ProjectOrganization,\n} from '../services/organizations.js'\nimport {getPlanId, getPlanIdFromCoupon} from '../services/plans.js'\nimport {createProject, listProjects} from '../services/projects.js'\nimport {getCliUser} from '../services/user.js'\nimport {CLIInitStepCompleted, type InitStepResult} from '../telemetry/init.telemetry.js'\nimport {detectFrameworkRecord} from '../util/detectFramework.js'\nimport {absolutify, validateEmptyPath} from '../util/fsUtils.js'\nimport {getProjectDefaults} from '../util/getProjectDefaults.js'\nimport {getSanityEnv} from '../util/getSanityEnv.js'\n\nconst debug = subdebug('init')\n\nexport class InitCommand extends SanityCommand<typeof InitCommand> {\n static override args = {type: Args.string({hidden: true})}\n static override description = 'Initialize a new Sanity Studio, project and/or app'\n static override enableJsonFlag = true\n\n static override examples = [\n '<%= config.bin %> <%= command.id %>',\n {\n command: '<%= config.bin %> <%= command.id %> --dataset-default',\n description: 'Initialize a new project with a public dataset named \"production\"',\n },\n {\n command:\n '<%= config.bin %> <%= command.id %> -y --project abc123 --dataset production --output-path ~/myproj',\n description: 'Initialize a project with the given project ID and dataset to the given path',\n },\n {\n command:\n '<%= config.bin %> <%= command.id %> -y --project abc123 --dataset staging --template moviedb --output-path .',\n description:\n 'Initialize a project with the given project ID and dataset using the moviedb template to the given path',\n },\n {\n command:\n '<%= config.bin %> <%= command.id %> -y --project-name \"Movies Unlimited\" --dataset moviedb --visibility private --template moviedb --output-path /Users/espenh/movies-unlimited',\n description: 'Create a brand new project with name \"Movies Unlimited\"',\n },\n ] satisfies Array<Command.Example>\n\n static override flags = {\n 'auto-updates': Flags.boolean({\n allowNo: true,\n default: true,\n description: 'Enable auto updates of studio versions',\n exclusive: ['bare'],\n }),\n bare: Flags.boolean({\n description:\n 'Skip the Studio initialization and only print the selected project ID and dataset name to stdout',\n }),\n coupon: Flags.string({\n description:\n 'Optionally select a coupon for a new project (cannot be used with --project-plan)',\n exclusive: ['project-plan'],\n helpValue: '<code>',\n }),\n 'create-project': Flags.string({\n deprecated: {message: 'Use --project-name instead'},\n description: 'Create a new project with the given name',\n helpValue: '<name>',\n hidden: true,\n }),\n dataset: Flags.string({\n description: 'Dataset name for the studio',\n exclusive: ['dataset-default'],\n helpValue: '<name>',\n }),\n 'dataset-default': Flags.boolean({\n description: 'Set up a project with a public dataset named \"production\"',\n }),\n env: Flags.string({\n description: 'Write environment variables to file',\n exclusive: ['bare'],\n helpValue: '<filename>',\n parse: async (input) => {\n if (!input.startsWith('.env')) {\n throw new CLIError('Env filename (`--env`) must start with `.env`')\n }\n return input\n },\n }),\n 'from-create': Flags.boolean({\n description: 'Internal flag to indicate that the command is run from create-sanity',\n hidden: true,\n }),\n git: Flags.string({\n default: undefined,\n description: 'Specify a commit message for initial commit, or disable git init',\n exclusive: ['bare'],\n // oclif doesn't indent correctly with custom help labels, thus leading space :/\n helpLabel: ' --[no-]git',\n helpValue: '<message>',\n }),\n 'import-dataset': Flags.boolean({\n allowNo: true,\n default: undefined,\n description: 'Import template sample dataset',\n }),\n mcp: Flags.boolean({\n allowNo: true,\n default: true,\n description: 'Enable AI editor integration (MCP) setup',\n }),\n 'nextjs-add-config-files': Flags.boolean({\n allowNo: true,\n default: undefined,\n description: 'Add config files to Next.js project',\n helpGroup: 'Next.js',\n }),\n 'nextjs-append-env': Flags.boolean({\n allowNo: true,\n default: undefined,\n description: 'Append project ID and dataset to .env file',\n helpGroup: 'Next.js',\n }),\n 'nextjs-embed-studio': Flags.boolean({\n allowNo: true,\n default: undefined,\n description: 'Embed the Studio in Next.js application',\n helpGroup: 'Next.js',\n }),\n // oclif doesn't support a boolean/string flag combination, but listing both a\n // `--git` and a `--no-git` flag in help breaks conventions, so we hide this one,\n // but use it to \"combine\" the two in the actual logic.\n 'no-git': Flags.boolean({\n description: 'Disable git initialization',\n exclusive: ['git'],\n hidden: true,\n }),\n organization: Flags.string({\n description: 'Organization ID to use for the project',\n helpValue: '<id>',\n }),\n 'output-path': Flags.string({\n description: 'Path to write studio project to',\n exclusive: ['bare'],\n helpValue: '<path>',\n }),\n 'overwrite-files': Flags.boolean({\n allowNo: true,\n default: undefined,\n description: 'Overwrite existing files',\n }),\n 'package-manager': Flags.string({\n description: 'Specify which package manager to use [allowed: npm, yarn, pnpm]',\n exclusive: ['bare'],\n helpValue: '<manager>',\n options: ['npm', 'yarn', 'pnpm'],\n }),\n project: Flags.string({\n aliases: ['project-id'],\n description: 'Project ID to use for the studio',\n exclusive: ['create-project', 'project-name'],\n helpValue: '<id>',\n }),\n 'project-name': Flags.string({\n description: 'Create a new project with the given name',\n exclusive: ['project', 'create-project'],\n helpValue: '<name>',\n }),\n 'project-plan': Flags.string({\n description: 'Optionally select a plan for a new project',\n helpValue: '<name>',\n }),\n provider: Flags.string({\n description: 'Login provider to use',\n helpValue: '<provider>',\n }),\n quickstart: Flags.boolean({\n deprecated: true,\n description:\n 'Used for initializing a project from a server schema that is saved in the Journey API',\n hidden: true,\n }),\n reconfigure: Flags.boolean({\n deprecated: {\n message: 'This flag is no longer supported',\n version: '3.0.0',\n },\n description: 'Reconfigure an existing project',\n hidden: true,\n }),\n template: Flags.string({\n description: 'Project template to use [default: \"clean\"]',\n exclusive: ['bare'],\n helpValue: '<template>',\n }),\n // Porting over a beta flag\n // Oclif doesn't seem to support something in beta so hiding for now\n 'template-token': Flags.string({\n description: 'Used for accessing private GitHub repo templates',\n hidden: true,\n }),\n typescript: Flags.boolean({\n allowNo: true,\n default: undefined,\n description: 'Enable TypeScript support',\n exclusive: ['bare'],\n }),\n visibility: Flags.string({\n description: 'Visibility mode for dataset',\n helpValue: '<mode>',\n options: ['public', 'private'],\n }),\n yes: Flags.boolean({\n char: 'y',\n default: false,\n description:\n 'Unattended mode, answers \"yes\" to any \"yes/no\" prompt and otherwise uses defaults',\n }),\n }\n\n _trace!: TelemetryTrace<TelemetryUserProperties, InitStepResult>\n\n public async run(): Promise<void> {\n const workDir = process.cwd()\n\n const createProjectName = this.flags['project-name'] ?? this.flags['create-project']\n // For backwards \"compatibility\" - we used to allow `sanity init plugin`,\n // and no longer do - but instead of printing an error about an unknown\n // _command_, we want to acknowledge that the user is trying to do something\n // that no longer exists but might have at some point in the past.\n if (this.args.type) {\n this.error(\n this.args.type === 'plugin'\n ? 'Initializing plugins through the CLI is no longer supported'\n : `Unknown init type \"${this.args.type}\"`,\n {exit: 1},\n )\n }\n\n this._trace = this.telemetry.trace(CLIInitStepCompleted)\n\n // Slightly more helpful message for removed flags rather than just saying the flag\n // does not exist.\n if (this.flags.reconfigure) {\n this.error('--reconfigure is deprecated - manual configuration is now required', {exit: 1})\n }\n\n // Oclif doesn't support custom exclusive error messaging\n if (this.flags.project && this.flags.organization) {\n this.error(\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 {exit: 1},\n )\n }\n\n const defaultConfig = this.flags['dataset-default']\n let showDefaultConfigPrompt = !defaultConfig\n if (\n this.flags.dataset ||\n this.flags.visibility ||\n this.flags['dataset-default'] ||\n this.isUnattended()\n ) {\n showDefaultConfigPrompt = false\n }\n\n const detectedFramework = await detectFrameworkRecord({\n frameworkList: frameworks as readonly Framework[],\n rootPath: process.cwd(),\n })\n const isNextJs = detectedFramework?.slug === 'nextjs'\n\n let remoteTemplateInfo: RepoInfo | undefined\n if (this.flags.template && checkIsRemoteTemplate(this.flags.template)) {\n remoteTemplateInfo = await getGitHubRepoInfo(\n this.flags.template,\n this.flags['template-token'],\n )\n }\n\n if (detectedFramework && detectedFramework.slug !== 'sanity' && remoteTemplateInfo) {\n this.error(\n `A remote template cannot be used with a detected framework. Detected: ${detectedFramework.name}`,\n {exit: 1},\n )\n }\n\n const isAppTemplate = this.flags.template ? determineAppTemplate(this.flags.template) : false // Default to false\n\n // Checks flags are present when in unattended mode\n if (this.isUnattended()) {\n this.checkFlagsInUnattendedMode({createProjectName, isAppTemplate, isNextJs})\n }\n\n this._trace.start()\n this._trace.log({\n flags: {\n bare: this.flags.bare,\n coupon: this.flags.coupon,\n defaultConfig,\n env: this.flags.env,\n git: this.flags.git,\n plan: this.flags['project-plan'],\n reconfigure: this.flags.reconfigure,\n unattended: this.isUnattended(),\n },\n step: 'start',\n })\n\n // Plan can be set through `--project-plan`, or implied through `--coupon`.\n // As coupons can expire and project plans might change/be removed, we need to\n // verify that the passed flags are valid. The complexity of this is hidden in the\n // below plan methods, eventually returning a plan ID or undefined if we are told to\n // use the default plan.\n\n const planId = await this.getPlan()\n\n let envFilenameDefault = '.env'\n if (detectedFramework && detectedFramework.slug === 'nextjs') {\n envFilenameDefault = '.env.local'\n }\n const envFilename = typeof this.flags.env === 'string' ? this.flags.env : envFilenameDefault\n\n // If the user isn't already autenticated, make it so\n const {user} = await this.ensureAuthenticated()\n if (!isAppTemplate) {\n this.log(`${logSymbols.success} Fetching existing projects`)\n this.log('')\n }\n\n let newProject: string | undefined\n if (createProjectName) {\n newProject = await this.createProjectFromName({\n createProjectName,\n planId,\n user,\n })\n }\n\n const {datasetName, displayName, isFirstProject, organizationId, projectId} =\n await this.getProjectDetails({\n isAppTemplate,\n newProject,\n planId,\n showDefaultConfigPrompt,\n user,\n })\n\n // If user doesn't want to output any template code\n if (this.flags.bare) {\n this.log(`${logSymbols.success} Below are your project details`)\n this.log('')\n this.log(`Project ID: ${styleText('cyan', projectId)}`)\n this.log(`Dataset: ${styleText('cyan', datasetName)}`)\n this.log(\n `\\nYou can find your project on Sanity Manage — https://www.sanity.io/manage/project/${projectId}\\n`,\n )\n return\n }\n\n let initNext = flagOrDefault(this.flags['nextjs-add-config-files'], false)\n if (isNextJs && shouldPrompt(this.isUnattended(), this.flags['nextjs-add-config-files'])) {\n initNext = await promptForConfigFiles()\n }\n\n this._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 // add more frameworks to this as we add support for them\n // this is used to skip the getProjectInfo prompt\n const initFramework = initNext\n\n // Gather project defaults based on environment\n const defaults = await getProjectDefaults({isPlugin: false, workDir})\n\n // Prompt the user for required information\n const outputPath = await this.getProjectOutputPath({\n initFramework,\n sluggedName,\n workDir,\n })\n\n // Set up MCP integration (skip in non-production environments)\n let mcpMode: 'auto' | 'prompt' | 'skip' = 'prompt'\n if (!this.flags.mcp || !this.resolveIsInteractive() || getSanityEnv() !== 'production') {\n mcpMode = 'skip'\n } else if (this.flags.yes) {\n mcpMode = 'auto'\n }\n const mcpResult = await setupMCP({mode: mcpMode})\n\n this._trace.log({\n configuredEditors: mcpResult.configuredEditors,\n detectedEditors: mcpResult.detectedEditors,\n skipped: mcpResult.skipped,\n step: 'mcpSetup',\n })\n if (mcpResult.error) {\n this._trace.error(mcpResult.error)\n }\n const mcpConfigured = mcpResult.configuredEditors\n\n // Show checkmark for editors that were already configured\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 if (isNextJs) {\n await checkNextJsReactCompatibility({\n detectedFramework,\n output: this.output,\n outputPath,\n })\n }\n\n if (initNext) {\n await initNextJs({\n datasetName,\n detectedFramework,\n envFilename,\n mcpConfigured,\n nextjsAppendEnv: this.flags['nextjs-append-env'],\n nextjsEmbedStudio: this.flags['nextjs-embed-studio'],\n output: this.output,\n overwriteFiles: this.flags['overwrite-files'],\n packageManager: this.flags['package-manager'],\n projectId,\n template: this.flags.template,\n trace: this._trace,\n typescript: this.flags.typescript,\n unattended: this.isUnattended(),\n workDir,\n })\n this._trace.complete()\n return\n }\n\n // user wants to write environment variables to file\n if (this.flags.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: this.output,\n outputPath,\n })\n await writeStagingEnvIfNeeded(this.output, outputPath)\n this.exit(0)\n }\n\n const sharedParams = {\n autoUpdates: this.flags['auto-updates'],\n defaults,\n error: this.error.bind(this) as typeof this.error,\n git: this.flags.git,\n mcpConfigured,\n noGit: this.flags['no-git'],\n organizationId,\n output: this.output,\n outputPath,\n overwriteFiles: this.flags['overwrite-files'],\n packageManager: this.flags['package-manager'],\n remoteTemplateInfo,\n sluggedName,\n template: this.flags.template,\n templateToken: this.flags['template-token'],\n trace: this._trace,\n typescript: this.flags.typescript,\n unattended: this.isUnattended(),\n workDir,\n }\n\n await (isAppTemplate\n ? initApp({...sharedParams, datasetName, projectId})\n : initStudio({\n ...sharedParams,\n datasetName,\n displayName,\n importDataset: this.flags['import-dataset'],\n isFirstProject,\n projectId,\n }))\n\n this._trace.complete()\n }\n\n private checkFlagsInUnattendedMode({\n createProjectName,\n isAppTemplate,\n isNextJs,\n }: {\n createProjectName: string | undefined\n isAppTemplate: boolean\n isNextJs: boolean\n }) {\n debug('Unattended mode, validating required options')\n\n // App templates only require --organization and --output-path\n if (isAppTemplate) {\n if (!this.flags['output-path']) {\n this.error('`--output-path` must be specified in unattended mode', {\n exit: 1,\n })\n }\n\n if (!this.flags.organization) {\n this.error(\n 'The --organization flag is required for app templates in unattended mode. ' +\n 'Use --organization <id> to specify which organization to use.',\n {exit: 1},\n )\n }\n\n return\n }\n\n // output-path is required in unattended mode when not using nextjs or bare\n if (!isNextJs && !this.flags.bare && !this.flags['output-path']) {\n this.error(`\\`--output-path\\` must be specified in unattended mode`, {\n exit: 1,\n })\n }\n\n if (!this.flags.project && !createProjectName) {\n this.error(\n '`--project <id>` or `--project-name <name>` must be specified in unattended mode',\n {exit: 1},\n )\n }\n\n if (createProjectName && !this.flags.organization) {\n this.error('`--project-name` requires `--organization <id>` in unattended mode', {exit: 1})\n }\n }\n\n private async createProjectFromName({\n createProjectName,\n planId,\n user,\n }: {\n createProjectName: string\n planId: string | undefined\n user: SanityOrgUser\n }) {\n debug('--project-name specified, creating a new project')\n\n let orgForCreateProjectFlag = this.flags.organization\n\n if (!orgForCreateProjectFlag) {\n debug('no organization specified, selecting one')\n const organizations = await listOrganizations()\n orgForCreateProjectFlag = await this.promptUserForOrganization({\n organizations,\n user,\n })\n }\n\n debug('creating a new project')\n const createdProject = await createProject({\n displayName: createProjectName.trim(),\n metadata: {coupon: this.flags.coupon},\n organizationId: orgForCreateProjectFlag,\n subscription: planId ? {planId} : undefined,\n })\n\n debug('Project with ID %s created', createdProject.projectId)\n if (this.flags.dataset) {\n debug('--dataset specified, creating dataset (%s)', this.flags.dataset)\n const spin = spinner('Creating dataset').start()\n await createDatasetService({\n aclMode: this.flags.visibility as DatasetAclMode,\n datasetName: this.flags.dataset,\n projectId: createdProject.projectId,\n })\n spin.succeed()\n }\n\n return createdProject.projectId\n }\n\n // @todo do we actually need to be authenticated for init? check flags and determine.\n private async ensureAuthenticated(): Promise<{user: SanityOrgUser}> {\n const user = await validateSession()\n\n if (user) {\n this._trace.log({alreadyLoggedIn: true, step: 'login'})\n this.log(\n `${logSymbols.success} You are logged in as ${user.email} using ${getProviderName(user.provider)}`,\n )\n return {user}\n }\n\n if (this.isUnattended()) {\n this.error('Must be logged in to run this command in unattended mode, run `sanity login`', {\n exit: 1,\n })\n }\n\n this._trace.log({step: 'login'})\n\n try {\n await login({\n output: this.output,\n telemetry: this._trace.newContext('login'),\n })\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error)\n this.error(`Login failed: ${message}`, {exit: 1})\n }\n\n const loggedInUser = await getCliUser()\n\n this.log(\n `${logSymbols.success} You are logged in as ${loggedInUser.email} using ${getProviderName(loggedInUser.provider)}`,\n )\n return {user: loggedInUser}\n }\n\n private async getOrCreateDataset(opts: {\n displayName: string\n projectId: string\n showDefaultConfigPrompt: boolean\n }): Promise<{\n datasetName: string\n userAction: 'create' | 'none' | 'select'\n }> {\n const visibility = this.flags.visibility\n const dataset = this.flags.dataset\n let defaultConfig = this.flags['dataset-default']\n\n if (dataset && this.isUnattended()) {\n return {datasetName: dataset, userAction: 'none'}\n }\n\n const [datasets, projectFeatures] = await Promise.all([\n listDatasets(opts.projectId),\n getProjectFeatures(opts.projectId),\n ])\n\n if (dataset) {\n debug('User has specified dataset through a flag (%s)', dataset)\n const existing = datasets.find((ds) => ds.name === dataset)\n if (!existing) {\n debug('Specified dataset not found, creating it')\n await createDataset({\n datasetName: dataset,\n forcePublic: defaultConfig,\n output: this.output,\n projectFeatures,\n projectId: opts.projectId,\n visibility,\n })\n }\n\n return {datasetName: dataset, userAction: 'none'}\n }\n\n // In unattended mode without --dataset, default to \"production\" with public visibility\n // (same behavior as --dataset-default)\n if (this.isUnattended()) {\n debug('Unattended mode without --dataset, defaulting to \"production\" dataset')\n const datasetName = 'production'\n const existing = datasets.find((ds) => ds.name === datasetName)\n if (!existing) {\n await createDataset({\n datasetName,\n forcePublic: visibility === undefined,\n isUnattended: true,\n output: this.output,\n projectFeatures,\n projectId: opts.projectId,\n visibility,\n })\n }\n return {datasetName, userAction: existing ? 'none' : 'create'}\n }\n\n if (datasets.length === 0) {\n debug('No datasets found for project, prompting for name')\n if (opts.showDefaultConfigPrompt) {\n defaultConfig = await promptForDefaultConfig()\n }\n const name = defaultConfig\n ? 'production'\n : await promptForDatasetName({\n message: 'Name of your first dataset:',\n })\n await createDataset({\n datasetName: name,\n forcePublic: defaultConfig,\n output: this.output,\n projectFeatures,\n projectId: opts.projectId,\n visibility,\n })\n return {datasetName: name, userAction: 'create'}\n }\n\n debug(`User has ${datasets.length} dataset(s) already, showing list of choices`)\n const datasetChoices = datasets.map((dataset) => ({value: dataset.name}))\n\n const selected = await select({\n choices: [{name: 'Create new dataset', value: 'new'}, new Separator(), ...datasetChoices],\n message: 'Select dataset to use',\n })\n\n if (selected === 'new') {\n const existingDatasetNames = datasets.map((ds) => ds.name)\n debug('User wants to create a new dataset, prompting for name')\n if (opts.showDefaultConfigPrompt && !existingDatasetNames.includes('production')) {\n defaultConfig = await promptForDefaultConfig()\n }\n\n const newDatasetName = defaultConfig\n ? 'production'\n : await promptForDatasetName(\n {\n message: 'Dataset name:',\n },\n existingDatasetNames,\n )\n await createDataset({\n datasetName: newDatasetName,\n forcePublic: defaultConfig,\n output: this.output,\n projectFeatures,\n projectId: opts.projectId,\n visibility,\n })\n return {datasetName: newDatasetName, userAction: 'create'}\n }\n\n debug(`Returning selected dataset (${selected})`)\n return {datasetName: selected, userAction: 'select'}\n }\n\n private async getOrCreateProject({\n newProject,\n planId,\n user,\n }: {\n newProject: string | undefined\n planId: string | undefined\n user: SanityOrgUser\n }): Promise<{\n displayName: string\n isFirstProject: boolean\n projectId: string\n userAction: 'create' | 'select'\n }> {\n const projectId = this.flags.project || newProject\n const organizationId = this.flags.organization\n let projects\n let organizations: ProjectOrganization[]\n\n try {\n const [allProjects, allOrgs] = await Promise.all([listProjects(), listOrganizations()])\n projects = allProjects.toSorted((a, b) => b.createdAt.localeCompare(a.createdAt))\n organizations = allOrgs\n } catch (err) {\n if (this.isUnattended() && projectId) {\n return {\n displayName: 'Unknown project',\n isFirstProject: false,\n projectId,\n userAction: 'select',\n }\n }\n this.error(`Failed to communicate with the Sanity API:\\n${err.message}`, {\n exit: 1,\n })\n }\n\n if (projects.length === 0 && this.isUnattended()) {\n this.error('No projects found for current user', {exit: 1})\n }\n\n if (projectId) {\n const project = projects.find((proj) => proj.id === projectId)\n if (!project && !this.isUnattended()) {\n this.error(`Given project ID (${projectId}) not found, or you do not have access to it`, {\n exit: 1,\n })\n }\n\n return {\n displayName: project ? project.displayName : 'Unknown project',\n isFirstProject: false,\n projectId,\n userAction: 'select',\n }\n }\n\n if (organizationId) {\n const organization =\n organizations.find((org) => org.id === organizationId) ||\n organizations.find((org) => org.slug === organizationId)\n\n if (!organization) {\n this.error(\n `Given organization ID (${organizationId}) not found, or you do not have access to it`,\n {exit: 1},\n )\n }\n\n if (!(await hasProjectAttachGrant(organizationId))) {\n this.error('You lack the necessary permissions to attach a project to this organization', {\n exit: 1,\n })\n }\n }\n\n // If the user has no projects or is using a coupon (which can only be applied to new projects)\n // just ask for project details instead of showing a list of projects\n const isUsersFirstProject = projects.length === 0\n if (isUsersFirstProject || this.flags.coupon) {\n debug(\n isUsersFirstProject\n ? 'No projects found for user, prompting for name'\n : 'Using a coupon - skipping project selection',\n )\n\n const newProject = await this.promptForProjectCreation({\n isUsersFirstProject,\n organizationId,\n organizations,\n planId,\n user,\n })\n\n return {\n ...newProject,\n isFirstProject: isUsersFirstProject,\n userAction: 'create',\n }\n }\n\n debug(`User has ${projects.length} project(s) already, showing list of choices`)\n\n const projectChoices = projects.map((project) => ({\n name: `${project.displayName} (${project.id})`,\n value: project.id,\n }))\n\n const selected = await select({\n choices: [{name: 'Create new project', value: 'new'}, new Separator(), ...projectChoices],\n message: 'Create a new project or select an existing one',\n })\n\n if (selected === 'new') {\n debug('User wants to create a new project, prompting for name')\n\n const newProject = await this.promptForProjectCreation({\n isUsersFirstProject,\n organizationId,\n organizations,\n planId,\n user,\n })\n\n return {\n ...newProject,\n isFirstProject: isUsersFirstProject,\n userAction: 'create',\n }\n }\n\n debug(`Returning selected project (${selected})`)\n return {\n displayName: projects.find((proj) => proj.id === selected)?.displayName || '',\n isFirstProject: isUsersFirstProject,\n projectId: selected,\n userAction: 'select',\n }\n }\n\n private async getPlan(): Promise<string | undefined> {\n const intendedPlan = this.flags['project-plan']\n const intendedCoupon = this.flags.coupon\n\n if (intendedCoupon) {\n return this.verifyCoupon(intendedCoupon)\n } else if (intendedPlan) {\n return this.verifyPlan(intendedPlan)\n } else {\n return undefined\n }\n }\n\n private async getProjectDetails({\n isAppTemplate,\n newProject,\n planId,\n showDefaultConfigPrompt,\n user,\n }: {\n isAppTemplate: boolean\n newProject: string | undefined\n planId: string | undefined\n showDefaultConfigPrompt: boolean\n user: SanityOrgUser\n }): Promise<{\n datasetName: string\n displayName: string\n isFirstProject: boolean\n organizationId?: string\n projectId: string\n schemaUrl?: string\n }> {\n if (isAppTemplate) {\n let organizationId: string | undefined = this.flags.organization\n if (!organizationId) {\n let organizations: ProjectOrganization[]\n try {\n organizations = await listOrganizations()\n } catch (err) {\n this.error(`Failed to communicate with the Sanity API:\\n${err.message}`, {\n exit: 1,\n })\n }\n organizationId = await this.promptUserForOrganization({\n isAppTemplate: true,\n organizations,\n user,\n })\n }\n\n const {datasetName, displayName, projectId} = await this.promptForAppTemplateSetup({\n newProject,\n organizationId,\n planId,\n user,\n })\n\n return {\n datasetName,\n displayName,\n isFirstProject: false,\n organizationId,\n projectId,\n }\n }\n\n debug('Prompting user to select or create a project')\n const project = await this.getOrCreateProject({newProject, planId, user})\n debug(`Project with name ${project.displayName} selected`)\n\n // Now let's pick or create a dataset\n debug('Prompting user to select or create a dataset')\n const dataset = await this.getOrCreateDataset({\n displayName: project.displayName,\n projectId: project.projectId,\n showDefaultConfigPrompt,\n })\n debug(`Dataset with name ${dataset.datasetName} selected`)\n\n this._trace.log({\n datasetName: dataset.datasetName,\n selectedOption: dataset.userAction,\n step: 'createOrSelectDataset',\n visibility: this.flags.visibility as 'private' | 'public',\n })\n\n return {\n datasetName: dataset.datasetName,\n displayName: project.displayName,\n isFirstProject: project.isFirstProject,\n projectId: project.projectId,\n }\n }\n\n private async getProjectOutputPath({\n initFramework,\n sluggedName,\n workDir,\n }: {\n initFramework: boolean\n sluggedName: string\n workDir: string\n }): Promise<string> {\n const outputPath = this.flags['output-path']\n const specifiedPath = outputPath && path.resolve(outputPath)\n if (this.isUnattended() || specifiedPath || this.flags.env || initFramework) {\n return specifiedPath || workDir\n }\n\n const inputPath = await input({\n default: path.join(workDir, sluggedName),\n message: 'Project output path:',\n validate: validateEmptyPath,\n })\n\n return absolutify(inputPath)\n }\n\n private async promptForAppTemplateSetup({\n newProject,\n organizationId,\n planId,\n user,\n }: {\n newProject: string | undefined\n organizationId: string | undefined\n planId: string | undefined\n user: SanityOrgUser\n }): Promise<{datasetName: string; displayName: string; projectId: string}> {\n if (this.isUnattended()) {\n if (!this.flags.project && !newProject) {\n return {datasetName: '', displayName: '', projectId: ''}\n }\n const project = await this.getOrCreateProject({newProject, planId, user})\n const dataset = await this.getOrCreateDataset({\n displayName: project.displayName,\n projectId: project.projectId,\n showDefaultConfigPrompt: false,\n })\n return {\n datasetName: dataset.datasetName,\n displayName: project.displayName,\n projectId: project.projectId,\n }\n }\n\n const projects = (await listProjects()).toSorted((a, b) =>\n b.createdAt.localeCompare(a.createdAt),\n )\n\n const projectChoices = projects.map((project) => ({\n name: `${project.displayName} (${project.id})`,\n value: project.id,\n }))\n\n const SKIP_PROJECT = '__skip__'\n const NEW_PROJECT = '__new__'\n\n const selected = await select({\n choices: [\n {name: \"Skip — I'll configure later\", value: SKIP_PROJECT},\n {name: 'Create new project', value: NEW_PROJECT},\n ...(projectChoices.length > 0 ? [new Separator(), ...projectChoices] : []),\n ],\n message: 'Configure a project for this app?',\n })\n\n if (selected === SKIP_PROJECT) {\n this._trace.log({selectedOption: 'skip', step: 'configureAppProject'})\n return {datasetName: '', displayName: '', projectId: ''}\n }\n\n this._trace.log({\n selectedOption: selected === NEW_PROJECT ? 'create' : 'existing',\n step: 'configureAppProject',\n })\n\n const project =\n selected === NEW_PROJECT\n ? await this.promptForProjectCreation({\n isUsersFirstProject: projects.length === 0,\n organizationId,\n organizations: [],\n planId,\n user,\n })\n : {\n displayName: projects.find((p) => p.id === selected)?.displayName ?? '',\n projectId: selected,\n }\n\n const dataset = await this.getOrCreateDataset({\n displayName: project.displayName,\n projectId: project.projectId,\n showDefaultConfigPrompt: false,\n })\n return {\n datasetName: dataset.datasetName,\n displayName: project.displayName,\n projectId: project.projectId,\n }\n }\n\n private async promptForProjectCreation({\n isUsersFirstProject,\n organizationId,\n organizations,\n planId,\n user,\n }: {\n isUsersFirstProject: boolean\n organizationId: string | undefined\n organizations: ProjectOrganization[]\n planId: string | undefined\n user: SanityOrgUser\n }) {\n const projectName = await input({\n default: 'My Sanity Project',\n message: 'Project name:',\n validate(input) {\n if (!input || input.trim() === '') {\n return 'Project name cannot be empty'\n }\n\n if (input.length > 80) {\n return 'Project name cannot be longer than 80 characters'\n }\n\n return true\n },\n })\n\n const organization =\n organizationId || (await this.promptUserForOrganization({organizations, user}))\n\n const newProject = await createProject({\n displayName: projectName,\n metadata: {coupon: this.flags.coupon},\n organizationId: organization,\n subscription: planId ? {planId} : undefined,\n })\n\n return {\n ...newProject,\n isFirstProject: isUsersFirstProject,\n userAction: 'create',\n }\n }\n\n private async promptUserForNewOrganization(\n user: SanityOrgUser,\n ): Promise<OrganizationCreateResponse> {\n const name = await promptForOrganizationName(user)\n\n const spin = spinner('Creating organization').start()\n const organization = await createOrganization(name)\n spin.succeed()\n\n return organization\n }\n\n private async promptUserForOrganization({\n isAppTemplate = false,\n organizations,\n user,\n }: {\n isAppTemplate?: boolean\n organizations: ProjectOrganization[]\n user: SanityOrgUser\n }) {\n // If the user has no organizations, prompt them to create one with the same name as\n // their user, but allow them to customize it if they want\n if (organizations.length === 0) {\n const newOrganization = await this.promptUserForNewOrganization(user)\n return newOrganization.id\n }\n\n let organizationChoices: OrganizationChoices\n let defaultOrganizationId: string | undefined\n\n if (isAppTemplate) {\n // For app templates, all organizations are valid — no attach grant check needed\n organizationChoices = getOrganizationChoices(organizations)\n defaultOrganizationId =\n organizations.length === 1\n ? organizations[0].id\n : findOrganizationByUserName(organizations, user)\n } else {\n // For studio projects, check which organizations the user can attach projects to\n debug(`User has ${organizations.length} organization(s), checking attach access`)\n const withGrantInfo = await getOrganizationsWithAttachGrantInfo(organizations)\n const withAttach = withGrantInfo.filter(({hasAttachGrant}) => hasAttachGrant)\n\n debug('User has attach access to %d organizations.', withAttach.length)\n organizationChoices = getOrganizationChoices(withGrantInfo)\n defaultOrganizationId =\n withAttach.length === 1\n ? withAttach[0].organization.id\n : findOrganizationByUserName(organizations, user)\n }\n\n const chosenOrg = await select({\n choices: organizationChoices,\n default: defaultOrganizationId || undefined,\n message: 'Select organization:',\n })\n\n if (chosenOrg === '-new-') {\n const newOrganization = await this.promptUserForNewOrganization(user)\n return newOrganization.id\n }\n\n return chosenOrg || undefined\n }\n\n private async verifyCoupon(intendedCoupon: string): Promise<string | undefined> {\n try {\n const planId = await getPlanIdFromCoupon(intendedCoupon)\n this.log(`Coupon \"${intendedCoupon}\" validated!\\n`)\n return planId\n } catch (err: unknown) {\n if (!isHttpError(err) || err.statusCode !== 404) {\n const message = err instanceof Error ? err.message : `${err}`\n this.error(`Unable to validate coupon, please try again later:\\n\\n${message}`, {exit: 1})\n }\n\n const useDefaultPlan =\n this.isUnattended() ||\n (await confirm({\n default: true,\n message: `Coupon \"${intendedCoupon}\" is not available, use default plan instead?`,\n }))\n\n if (this.isUnattended()) {\n this.warn(`Coupon \"${intendedCoupon}\" is not available - using default plan`)\n }\n\n this._trace.log({\n coupon: intendedCoupon,\n selectedOption: useDefaultPlan ? 'yes' : 'no',\n step: 'useDefaultPlanCoupon',\n })\n\n if (useDefaultPlan) {\n this.log('Using default plan.')\n } else {\n this.error(`Coupon \"${intendedCoupon}\" does not exist`, {exit: 1})\n }\n }\n }\n\n private async verifyPlan(intendedPlan: string): Promise<string | undefined> {\n try {\n const planId = await getPlanId(intendedPlan)\n return planId\n } catch (err: unknown) {\n if (!isHttpError(err) || err.statusCode !== 404) {\n const message = err instanceof Error ? err.message : `${err}`\n this.error(`Unable to validate plan, please try again later:\\n\\n${message}`, {exit: 1})\n }\n\n const useDefaultPlan =\n this.isUnattended() ||\n (await confirm({\n default: true,\n message: `Project plan \"${intendedPlan}\" does not exist, use default plan instead?`,\n }))\n\n if (this.isUnattended()) {\n this.warn(`Project plan \"${intendedPlan}\" does not exist - using default plan`)\n }\n\n this._trace.log({\n planId: intendedPlan,\n selectedOption: useDefaultPlan ? 'yes' : 'no',\n step: 'useDefaultPlanId',\n })\n\n if (useDefaultPlan) {\n this.log('Using default plan.')\n } else {\n this.error(`Plan id \"${intendedPlan}\" does not exist`, {exit: 1})\n }\n }\n }\n}\n"],"names":["path","styleText","Args","Flags","CLIError","SanityCommand","subdebug","confirm","input","logSymbols","select","Separator","spinner","isHttpError","frameworks","deburr","validateSession","getProviderName","login","createDataset","checkNextJsReactCompatibility","determineAppTemplate","createOrAppendEnvVars","initApp","flagOrDefault","shouldPrompt","writeStagingEnvIfNeeded","initNextJs","initStudio","checkIsRemoteTemplate","getGitHubRepoInfo","setupMCP","findOrganizationByUserName","getOrganizationChoices","getOrganizationsWithAttachGrantInfo","hasProjectAttachGrant","promptForConfigFiles","promptForDatasetName","promptForDefaultConfig","promptForOrganizationName","createDatasetService","listDatasets","getProjectFeatures","createOrganization","listOrganizations","getPlanId","getPlanIdFromCoupon","createProject","listProjects","getCliUser","CLIInitStepCompleted","detectFrameworkRecord","absolutify","validateEmptyPath","getProjectDefaults","getSanityEnv","debug","InitCommand","args","type","string","hidden","description","enableJsonFlag","examples","command","flags","boolean","allowNo","default","exclusive","bare","coupon","helpValue","deprecated","message","dataset","env","parse","startsWith","git","undefined","helpLabel","mcp","helpGroup","organization","options","project","aliases","provider","quickstart","reconfigure","version","template","typescript","visibility","yes","char","_trace","run","workDir","process","cwd","createProjectName","error","exit","telemetry","trace","defaultConfig","showDefaultConfigPrompt","isUnattended","detectedFramework","frameworkList","rootPath","isNextJs","slug","remoteTemplateInfo","name","isAppTemplate","checkFlagsInUnattendedMode","start","log","plan","unattended","step","planId","getPlan","envFilenameDefault","envFilename","user","ensureAuthenticated","success","newProject","createProjectFromName","datasetName","displayName","isFirstProject","organizationId","projectId","getProjectDetails","initNext","selectedOption","sluggedName","toLowerCase","replaceAll","initFramework","defaults","isPlugin","outputPath","getProjectOutputPath","mcpMode","resolveIsInteractive","mcpResult","mode","configuredEditors","detectedEditors","skipped","mcpConfigured","alreadyConfiguredEditors","length","label","succeed","output","nextjsAppendEnv","nextjsEmbedStudio","overwriteFiles","packageManager","complete","envVars","DATASET","PROJECT_ID","filename","framework","sharedParams","autoUpdates","bind","noGit","templateToken","importDataset","orgForCreateProjectFlag","organizations","promptUserForOrganization","createdProject","trim","metadata","subscription","spin","aclMode","alreadyLoggedIn","email","newContext","Error","String","loggedInUser","getOrCreateDataset","opts","userAction","datasets","projectFeatures","Promise","all","existing","find","ds","forcePublic","datasetChoices","map","value","selected","choices","existingDatasetNames","includes","newDatasetName","getOrCreateProject","projects","allProjects","allOrgs","toSorted","a","b","createdAt","localeCompare","err","proj","id","org","isUsersFirstProject","promptForProjectCreation","projectChoices","intendedPlan","intendedCoupon","verifyCoupon","verifyPlan","promptForAppTemplateSetup","specifiedPath","resolve","inputPath","join","validate","SKIP_PROJECT","NEW_PROJECT","p","projectName","promptUserForNewOrganization","newOrganization","organizationChoices","defaultOrganizationId","withGrantInfo","withAttach","filter","hasAttachGrant","chosenOrg","statusCode","useDefaultPlan","warn"],"mappings":"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"}
1
+ {"version":3,"sources":["../../src/commands/init.ts"],"sourcesContent":["import {Args, Command, Flags} from '@oclif/core'\nimport {CLIError} from '@oclif/core/errors'\nimport {SanityCommand} from '@sanity/cli-core'\n\nimport {initAction} from '../actions/init/initAction.js'\nimport {InitError} from '../actions/init/initError.js'\nimport {flagsToInitOptions} from '../actions/init/types.js'\nimport {getSanityEnv} from '../util/getSanityEnv.js'\n\nexport class InitCommand extends SanityCommand<typeof InitCommand> {\n static override args = {type: Args.string({hidden: true})}\n static override description = 'Initialize a new Sanity Studio, project and/or app'\n static override enableJsonFlag = true\n\n static override examples = [\n '<%= config.bin %> <%= command.id %>',\n {\n command: '<%= config.bin %> <%= command.id %> --dataset-default',\n description: 'Initialize a new project with a public dataset named \"production\"',\n },\n {\n command:\n '<%= config.bin %> <%= command.id %> -y --project abc123 --dataset production --output-path ~/myproj',\n description: 'Initialize a project with the given project ID and dataset to the given path',\n },\n {\n command:\n '<%= config.bin %> <%= command.id %> -y --project abc123 --dataset staging --template moviedb --output-path .',\n description:\n 'Initialize a project with the given project ID and dataset using the moviedb template to the given path',\n },\n {\n command:\n '<%= config.bin %> <%= command.id %> -y --project-name \"Movies Unlimited\" --dataset moviedb --visibility private --template moviedb --output-path /Users/espenh/movies-unlimited',\n description: 'Create a brand new project with name \"Movies Unlimited\"',\n },\n ] satisfies Array<Command.Example>\n\n static override flags = {\n 'auto-updates': Flags.boolean({\n allowNo: true,\n default: true,\n description: 'Enable auto updates of studio versions',\n exclusive: ['bare'],\n }),\n bare: Flags.boolean({\n description:\n 'Skip the Studio initialization and only print the selected project ID and dataset name to stdout',\n }),\n coupon: Flags.string({\n description:\n 'Optionally select a coupon for a new project (cannot be used with --project-plan)',\n exclusive: ['project-plan'],\n helpValue: '<code>',\n }),\n 'create-project': Flags.string({\n deprecated: {message: 'Use --project-name instead'},\n description: 'Create a new project with the given name',\n helpValue: '<name>',\n hidden: true,\n }),\n dataset: Flags.string({\n description: 'Dataset name for the studio',\n exclusive: ['dataset-default'],\n helpValue: '<name>',\n }),\n 'dataset-default': Flags.boolean({\n description: 'Set up a project with a public dataset named \"production\"',\n }),\n env: Flags.string({\n description: 'Write environment variables to file',\n exclusive: ['bare'],\n helpValue: '<filename>',\n parse: async (input) => {\n if (!input.startsWith('.env')) {\n throw new CLIError('Env filename (`--env`) must start with `.env`')\n }\n return input\n },\n }),\n 'from-create': Flags.boolean({\n description: 'Internal flag to indicate that the command is run from create-sanity',\n hidden: true,\n }),\n git: Flags.string({\n default: undefined,\n description: 'Specify a commit message for initial commit, or disable git init',\n exclusive: ['bare'],\n // oclif doesn't indent correctly with custom help labels, thus leading space :/\n helpLabel: ' --[no-]git',\n helpValue: '<message>',\n }),\n 'import-dataset': Flags.boolean({\n allowNo: true,\n default: undefined,\n description: 'Import template sample dataset',\n }),\n mcp: Flags.boolean({\n allowNo: true,\n default: true,\n description: 'Enable AI editor integration (MCP) setup',\n }),\n 'nextjs-add-config-files': Flags.boolean({\n allowNo: true,\n default: undefined,\n description: 'Add config files to Next.js project',\n helpGroup: 'Next.js',\n }),\n 'nextjs-append-env': Flags.boolean({\n allowNo: true,\n default: undefined,\n description: 'Append project ID and dataset to .env file',\n helpGroup: 'Next.js',\n }),\n 'nextjs-embed-studio': Flags.boolean({\n allowNo: true,\n default: undefined,\n description: 'Embed the Studio in Next.js application',\n helpGroup: 'Next.js',\n }),\n // oclif doesn't support a boolean/string flag combination, but listing both a\n // `--git` and a `--no-git` flag in help breaks conventions, so we hide this one,\n // but use it to \"combine\" the two in the actual logic.\n 'no-git': Flags.boolean({\n description: 'Disable git initialization',\n exclusive: ['git'],\n hidden: true,\n }),\n organization: Flags.string({\n description: 'Organization ID to use for the project',\n helpValue: '<id>',\n }),\n 'output-path': Flags.string({\n description: 'Path to write studio project to',\n exclusive: ['bare'],\n helpValue: '<path>',\n }),\n 'overwrite-files': Flags.boolean({\n allowNo: true,\n default: undefined,\n description: 'Overwrite existing files',\n }),\n 'package-manager': Flags.string({\n description: 'Specify which package manager to use [allowed: npm, yarn, pnpm]',\n exclusive: ['bare'],\n helpValue: '<manager>',\n options: ['npm', 'yarn', 'pnpm'],\n }),\n project: Flags.string({\n aliases: ['project-id'],\n description: 'Project ID to use for the studio',\n exclusive: ['create-project', 'project-name'],\n helpValue: '<id>',\n }),\n 'project-name': Flags.string({\n description: 'Create a new project with the given name',\n exclusive: ['project', 'create-project'],\n helpValue: '<name>',\n }),\n 'project-plan': Flags.string({\n description: 'Optionally select a plan for a new project',\n helpValue: '<name>',\n }),\n provider: Flags.string({\n description: 'Login provider to use',\n helpValue: '<provider>',\n }),\n quickstart: Flags.boolean({\n deprecated: true,\n description:\n 'Used for initializing a project from a server schema that is saved in the Journey API',\n hidden: true,\n }),\n reconfigure: Flags.boolean({\n deprecated: {\n message: 'This flag is no longer supported',\n version: '3.0.0',\n },\n description: 'Reconfigure an existing project',\n hidden: true,\n }),\n template: Flags.string({\n description: 'Project template to use [default: \"clean\"]',\n exclusive: ['bare'],\n helpValue: '<template>',\n }),\n // Porting over a beta flag\n // Oclif doesn't seem to support something in beta so hiding for now\n 'template-token': Flags.string({\n description: 'Used for accessing private GitHub repo templates',\n hidden: true,\n }),\n typescript: Flags.boolean({\n allowNo: true,\n default: undefined,\n description: 'Enable TypeScript support',\n exclusive: ['bare'],\n }),\n visibility: Flags.string({\n description: 'Visibility mode for dataset',\n helpValue: '<mode>',\n options: ['public', 'private'],\n }),\n yes: Flags.boolean({\n char: 'y',\n default: false,\n description:\n 'Unattended mode, answers \"yes\" to any \"yes/no\" prompt and otherwise uses defaults',\n }),\n }\n\n public async run(): Promise<void> {\n let mcpMode: 'auto' | 'prompt' | 'skip' = 'prompt'\n if (!this.flags.mcp || !this.resolveIsInteractive() || getSanityEnv() !== 'production') {\n mcpMode = 'skip'\n } else if (this.flags.yes) {\n mcpMode = 'auto'\n }\n\n try {\n await initAction(flagsToInitOptions(this.flags, this.isUnattended(), this.args, mcpMode), {\n output: this.output,\n telemetry: this.telemetry,\n workDir: process.cwd(),\n })\n } catch (error) {\n if (error instanceof InitError) {\n this.error(error.message, {exit: error.exitCode})\n }\n throw error\n }\n }\n}\n"],"names":["Args","Flags","CLIError","SanityCommand","initAction","InitError","flagsToInitOptions","getSanityEnv","InitCommand","args","type","string","hidden","description","enableJsonFlag","examples","command","flags","boolean","allowNo","default","exclusive","bare","coupon","helpValue","deprecated","message","dataset","env","parse","input","startsWith","git","undefined","helpLabel","mcp","helpGroup","organization","options","project","aliases","provider","quickstart","reconfigure","version","template","typescript","visibility","yes","char","run","mcpMode","resolveIsInteractive","isUnattended","output","telemetry","workDir","process","cwd","error","exit","exitCode"],"mappings":"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"}
@@ -3,7 +3,7 @@ import { decorateIndexWithStagingScript } from '../../actions/build/decorateInde
3
3
  import { renderDocument } from '../../actions/build/renderDocument.js';
4
4
  const entryChunkId = '.sanity/runtime/app.js';
5
5
  export function sanityBuildEntries(options) {
6
- const { basePath, cwd, importMap, isApp } = options;
6
+ const { autoUpdatesCssUrls, basePath, cwd, importMap, isApp } = options;
7
7
  return {
8
8
  apply: 'build',
9
9
  name: 'sanity/server/build-entries',
@@ -48,6 +48,7 @@ export function sanityBuildEntries(options) {
48
48
  this.emitFile({
49
49
  fileName: 'index.html',
50
50
  source: decorateIndexWithStagingScript(decorateIndexWithBridgeScript(await renderDocument({
51
+ autoUpdatesCssUrls,
51
52
  importMap,
52
53
  isApp,
53
54
  props: {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/server/vite/plugin-sanity-build-entries.ts"],"sourcesContent":["import {type ChunkMetadata, type Plugin} from 'vite'\n\nimport {decorateIndexWithBridgeScript} from '../../actions/build/decorateIndexWithBridgeScript.js'\nimport {decorateIndexWithStagingScript} from '../../actions/build/decorateIndexWithStagingScript.js'\nimport {renderDocument} from '../../actions/build/renderDocument.js'\n\ninterface ViteOutputBundle {\n [fileName: string]: ViteRenderedAsset | ViteRenderedChunk\n}\n\ninterface ViteRenderedAsset {\n type: 'asset'\n}\n\ninterface ViteRenderedChunk {\n code: string\n facadeModuleId: string | null\n fileName: string\n imports: string[]\n isEntry: boolean\n name: string\n type: 'chunk'\n viteMetadata: ChunkMetadata\n}\n\nconst entryChunkId = '.sanity/runtime/app.js'\n\nexport function sanityBuildEntries(options: {\n basePath: string\n cwd: string\n importMap?: {imports?: Record<string, string>}\n isApp?: boolean\n}): Plugin {\n const {basePath, cwd, importMap, isApp} = options\n\n return {\n apply: 'build',\n name: 'sanity/server/build-entries',\n\n buildStart() {\n this.emitFile({\n id: entryChunkId,\n name: 'sanity',\n type: 'chunk',\n })\n },\n\n async generateBundle(_options, outputBundle) {\n const bundle = outputBundle as unknown as ViteOutputBundle\n const entryFile = Object.values(bundle).find(\n (file) =>\n file.type === 'chunk' &&\n file.name === 'sanity' &&\n file.facadeModuleId?.endsWith(entryChunkId),\n )\n\n if (!entryFile) {\n throw new Error(`Failed to find entry file in bundle (${entryChunkId})`)\n }\n\n if (entryFile.type !== 'chunk') {\n throw new Error('Entry file is not a chunk')\n }\n\n const entryFileName = entryFile.fileName\n const entryPath = [basePath.replace(/\\/+$/, ''), entryFileName].join('/')\n\n let css: string[] = []\n if (entryFile.viteMetadata?.importedCss) {\n // Check all the top-level imports of the entryPoint to see if they have\n // static CSS assets that need loading\n css = [...entryFile.viteMetadata.importedCss]\n for (const key of entryFile.imports) {\n // Traverse all CSS assets that isn't loaded by the runtime and\n // need <link> tags in the HTML template\n const entry = bundle[key]\n const importedCss =\n entry && entry.type === 'chunk' ? entry.viteMetadata.importedCss : undefined\n\n if (importedCss) {\n css.push(...importedCss)\n }\n }\n }\n\n this.emitFile({\n fileName: 'index.html',\n source: decorateIndexWithStagingScript(\n decorateIndexWithBridgeScript(\n await renderDocument({\n importMap,\n isApp,\n props: {\n basePath,\n css,\n entryPath,\n },\n studioRootPath: cwd,\n }),\n ),\n ),\n type: 'asset',\n })\n },\n }\n}\n"],"names":["decorateIndexWithBridgeScript","decorateIndexWithStagingScript","renderDocument","entryChunkId","sanityBuildEntries","options","basePath","cwd","importMap","isApp","apply","name","buildStart","emitFile","id","type","generateBundle","_options","outputBundle","bundle","entryFile","Object","values","find","file","facadeModuleId","endsWith","Error","entryFileName","fileName","entryPath","replace","join","css","viteMetadata","importedCss","key","imports","entry","undefined","push","source","props","studioRootPath"],"mappings":"AAEA,SAAQA,6BAA6B,QAAO,uDAAsD;AAClG,SAAQC,8BAA8B,QAAO,wDAAuD;AACpG,SAAQC,cAAc,QAAO,wCAAuC;AAqBpE,MAAMC,eAAe;AAErB,OAAO,SAASC,mBAAmBC,OAKlC;IACC,MAAM,EAACC,QAAQ,EAAEC,GAAG,EAAEC,SAAS,EAAEC,KAAK,EAAC,GAAGJ;IAE1C,OAAO;QACLK,OAAO;QACPC,MAAM;QAENC;YACE,IAAI,CAACC,QAAQ,CAAC;gBACZC,IAAIX;gBACJQ,MAAM;gBACNI,MAAM;YACR;QACF;QAEA,MAAMC,gBAAeC,QAAQ,EAAEC,YAAY;YACzC,MAAMC,SAASD;YACf,MAAME,YAAYC,OAAOC,MAAM,CAACH,QAAQI,IAAI,CAC1C,CAACC,OACCA,KAAKT,IAAI,KAAK,WACdS,KAAKb,IAAI,KAAK,YACda,KAAKC,cAAc,EAAEC,SAASvB;YAGlC,IAAI,CAACiB,WAAW;gBACd,MAAM,IAAIO,MAAM,CAAC,qCAAqC,EAAExB,aAAa,CAAC,CAAC;YACzE;YAEA,IAAIiB,UAAUL,IAAI,KAAK,SAAS;gBAC9B,MAAM,IAAIY,MAAM;YAClB;YAEA,MAAMC,gBAAgBR,UAAUS,QAAQ;YACxC,MAAMC,YAAY;gBAACxB,SAASyB,OAAO,CAAC,QAAQ;gBAAKH;aAAc,CAACI,IAAI,CAAC;YAErE,IAAIC,MAAgB,EAAE;YACtB,IAAIb,UAAUc,YAAY,EAAEC,aAAa;gBACvC,wEAAwE;gBACxE,sCAAsC;gBACtCF,MAAM;uBAAIb,UAAUc,YAAY,CAACC,WAAW;iBAAC;gBAC7C,KAAK,MAAMC,OAAOhB,UAAUiB,OAAO,CAAE;oBACnC,+DAA+D;oBAC/D,wCAAwC;oBACxC,MAAMC,QAAQnB,MAAM,CAACiB,IAAI;oBACzB,MAAMD,cACJG,SAASA,MAAMvB,IAAI,KAAK,UAAUuB,MAAMJ,YAAY,CAACC,WAAW,GAAGI;oBAErE,IAAIJ,aAAa;wBACfF,IAAIO,IAAI,IAAIL;oBACd;gBACF;YACF;YAEA,IAAI,CAACtB,QAAQ,CAAC;gBACZgB,UAAU;gBACVY,QAAQxC,+BACND,8BACE,MAAME,eAAe;oBACnBM;oBACAC;oBACAiC,OAAO;wBACLpC;wBACA2B;wBACAH;oBACF;oBACAa,gBAAgBpC;gBAClB;gBAGJQ,MAAM;YACR;QACF;IACF;AACF"}
1
+ {"version":3,"sources":["../../../src/server/vite/plugin-sanity-build-entries.ts"],"sourcesContent":["import {type ChunkMetadata, type Plugin} from 'vite'\n\nimport {decorateIndexWithBridgeScript} from '../../actions/build/decorateIndexWithBridgeScript.js'\nimport {decorateIndexWithStagingScript} from '../../actions/build/decorateIndexWithStagingScript.js'\nimport {renderDocument} from '../../actions/build/renderDocument.js'\n\ninterface ViteOutputBundle {\n [fileName: string]: ViteRenderedAsset | ViteRenderedChunk\n}\n\ninterface ViteRenderedAsset {\n type: 'asset'\n}\n\ninterface ViteRenderedChunk {\n code: string\n facadeModuleId: string | null\n fileName: string\n imports: string[]\n isEntry: boolean\n name: string\n type: 'chunk'\n viteMetadata: ChunkMetadata\n}\n\nconst entryChunkId = '.sanity/runtime/app.js'\n\nexport function sanityBuildEntries(options: {\n autoUpdatesCssUrls?: string[]\n basePath: string\n cwd: string\n importMap?: {imports?: Record<string, string>}\n isApp?: boolean\n}): Plugin {\n const {autoUpdatesCssUrls, basePath, cwd, importMap, isApp} = options\n\n return {\n apply: 'build',\n name: 'sanity/server/build-entries',\n\n buildStart() {\n this.emitFile({\n id: entryChunkId,\n name: 'sanity',\n type: 'chunk',\n })\n },\n\n async generateBundle(_options, outputBundle) {\n const bundle = outputBundle as unknown as ViteOutputBundle\n const entryFile = Object.values(bundle).find(\n (file) =>\n file.type === 'chunk' &&\n file.name === 'sanity' &&\n file.facadeModuleId?.endsWith(entryChunkId),\n )\n\n if (!entryFile) {\n throw new Error(`Failed to find entry file in bundle (${entryChunkId})`)\n }\n\n if (entryFile.type !== 'chunk') {\n throw new Error('Entry file is not a chunk')\n }\n\n const entryFileName = entryFile.fileName\n const entryPath = [basePath.replace(/\\/+$/, ''), entryFileName].join('/')\n\n let css: string[] = []\n if (entryFile.viteMetadata?.importedCss) {\n // Check all the top-level imports of the entryPoint to see if they have\n // static CSS assets that need loading\n css = [...entryFile.viteMetadata.importedCss]\n for (const key of entryFile.imports) {\n // Traverse all CSS assets that isn't loaded by the runtime and\n // need <link> tags in the HTML template\n const entry = bundle[key]\n const importedCss =\n entry && entry.type === 'chunk' ? entry.viteMetadata.importedCss : undefined\n\n if (importedCss) {\n css.push(...importedCss)\n }\n }\n }\n\n this.emitFile({\n fileName: 'index.html',\n source: decorateIndexWithStagingScript(\n decorateIndexWithBridgeScript(\n await renderDocument({\n autoUpdatesCssUrls,\n importMap,\n isApp,\n props: {\n basePath,\n css,\n entryPath,\n },\n studioRootPath: cwd,\n }),\n ),\n ),\n type: 'asset',\n })\n },\n }\n}\n"],"names":["decorateIndexWithBridgeScript","decorateIndexWithStagingScript","renderDocument","entryChunkId","sanityBuildEntries","options","autoUpdatesCssUrls","basePath","cwd","importMap","isApp","apply","name","buildStart","emitFile","id","type","generateBundle","_options","outputBundle","bundle","entryFile","Object","values","find","file","facadeModuleId","endsWith","Error","entryFileName","fileName","entryPath","replace","join","css","viteMetadata","importedCss","key","imports","entry","undefined","push","source","props","studioRootPath"],"mappings":"AAEA,SAAQA,6BAA6B,QAAO,uDAAsD;AAClG,SAAQC,8BAA8B,QAAO,wDAAuD;AACpG,SAAQC,cAAc,QAAO,wCAAuC;AAqBpE,MAAMC,eAAe;AAErB,OAAO,SAASC,mBAAmBC,OAMlC;IACC,MAAM,EAACC,kBAAkB,EAAEC,QAAQ,EAAEC,GAAG,EAAEC,SAAS,EAAEC,KAAK,EAAC,GAAGL;IAE9D,OAAO;QACLM,OAAO;QACPC,MAAM;QAENC;YACE,IAAI,CAACC,QAAQ,CAAC;gBACZC,IAAIZ;gBACJS,MAAM;gBACNI,MAAM;YACR;QACF;QAEA,MAAMC,gBAAeC,QAAQ,EAAEC,YAAY;YACzC,MAAMC,SAASD;YACf,MAAME,YAAYC,OAAOC,MAAM,CAACH,QAAQI,IAAI,CAC1C,CAACC,OACCA,KAAKT,IAAI,KAAK,WACdS,KAAKb,IAAI,KAAK,YACda,KAAKC,cAAc,EAAEC,SAASxB;YAGlC,IAAI,CAACkB,WAAW;gBACd,MAAM,IAAIO,MAAM,CAAC,qCAAqC,EAAEzB,aAAa,CAAC,CAAC;YACzE;YAEA,IAAIkB,UAAUL,IAAI,KAAK,SAAS;gBAC9B,MAAM,IAAIY,MAAM;YAClB;YAEA,MAAMC,gBAAgBR,UAAUS,QAAQ;YACxC,MAAMC,YAAY;gBAACxB,SAASyB,OAAO,CAAC,QAAQ;gBAAKH;aAAc,CAACI,IAAI,CAAC;YAErE,IAAIC,MAAgB,EAAE;YACtB,IAAIb,UAAUc,YAAY,EAAEC,aAAa;gBACvC,wEAAwE;gBACxE,sCAAsC;gBACtCF,MAAM;uBAAIb,UAAUc,YAAY,CAACC,WAAW;iBAAC;gBAC7C,KAAK,MAAMC,OAAOhB,UAAUiB,OAAO,CAAE;oBACnC,+DAA+D;oBAC/D,wCAAwC;oBACxC,MAAMC,QAAQnB,MAAM,CAACiB,IAAI;oBACzB,MAAMD,cACJG,SAASA,MAAMvB,IAAI,KAAK,UAAUuB,MAAMJ,YAAY,CAACC,WAAW,GAAGI;oBAErE,IAAIJ,aAAa;wBACfF,IAAIO,IAAI,IAAIL;oBACd;gBACF;YACF;YAEA,IAAI,CAACtB,QAAQ,CAAC;gBACZgB,UAAU;gBACVY,QAAQzC,+BACND,8BACE,MAAME,eAAe;oBACnBI;oBACAG;oBACAC;oBACAiC,OAAO;wBACLpC;wBACA2B;wBACAH;oBACF;oBACAa,gBAAgBpC;gBAClB;gBAGJQ,MAAM;YACR;QACF;IACF;AACF"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/services/datasets.ts"],"sourcesContent":["import {getProjectCliClient} from '@sanity/cli-core'\nimport {\n type DatasetCreateOptions as ClientCreateOptions,\n type DatasetAclMode,\n type EmbeddingsSettingsBody,\n} from '@sanity/client'\nimport {EventSource} from 'eventsource'\nimport {Observable} from 'rxjs'\n\nexport const DATASET_API_VERSION = 'v2025-09-16'\n\nfunction getDatasetClient(projectId: string) {\n return getProjectCliClient({\n apiVersion: DATASET_API_VERSION,\n projectId,\n requireUser: true,\n })\n}\n\nexport async function listDatasets(projectId: string) {\n const client = await getDatasetClient(projectId)\n return client.datasets.list()\n}\n\nexport interface DatasetAliasDefinition {\n datasetName: string | null\n name: string\n}\n\nexport async function listDatasetAliases(projectId: string): Promise<DatasetAliasDefinition[]> {\n const client = await getDatasetClient(projectId)\n return client.request<DatasetAliasDefinition[]>({uri: '/aliases'})\n}\n\ninterface DeleteDatasetOptions {\n datasetName: string\n projectId: string\n}\n\nexport async function deleteDataset({datasetName, projectId}: DeleteDatasetOptions) {\n const client = await getDatasetClient(projectId)\n return client.datasets.delete(datasetName)\n}\n\ninterface EditDatasetAclOptions {\n aclMode: 'private' | 'public'\n datasetName: string\n projectId: string\n}\n\nexport async function editDatasetAcl({aclMode, datasetName, projectId}: EditDatasetAclOptions) {\n const client = await getDatasetClient(projectId)\n return client.datasets.edit(datasetName, {aclMode})\n}\n\ninterface CreateDatasetOptions {\n datasetName: string\n projectId: string\n\n aclMode?: DatasetAclMode\n embeddings?: EmbeddingsSettingsBody\n}\n\nexport async function createDataset({\n aclMode,\n datasetName,\n embeddings,\n projectId,\n}: CreateDatasetOptions) {\n const client = await getDatasetClient(projectId)\n const options: ClientCreateOptions = {}\n\n if (aclMode) {\n options.aclMode = aclMode\n }\n if (embeddings) {\n options.embeddings = embeddings\n }\n\n return client.datasets.create(datasetName, options)\n}\n\ninterface CopyDatasetOptions {\n projectId: string\n skipContentReleases?: boolean\n skipHistory: boolean\n sourceDataset: string\n targetDataset: string\n}\n\ninterface CopyDatasetResponse {\n jobId: string\n}\n\nexport async function copyDataset({\n projectId,\n skipContentReleases,\n skipHistory,\n sourceDataset,\n targetDataset,\n}: CopyDatasetOptions): Promise<CopyDatasetResponse> {\n const client = await getDatasetClient(projectId)\n return client.request<CopyDatasetResponse>({\n body: {\n skipContentReleases,\n skipHistory,\n targetDataset,\n },\n method: 'PUT',\n uri: `/datasets/${sourceDataset}/copy`,\n })\n}\n\ninterface ListDatasetCopyJobsOptions {\n projectId: string\n\n limit?: number\n offset?: number\n}\n\nexport interface DatasetCopyJob {\n createdAt: string\n id: string\n sourceDataset: string\n state: string\n targetDataset: string\n updatedAt: string\n withHistory: boolean\n}\n\nexport async function listDatasetCopyJobs({\n limit,\n offset,\n projectId,\n}: ListDatasetCopyJobsOptions): Promise<DatasetCopyJob[]> {\n const client = await getDatasetClient(projectId)\n const query: {limit?: string; offset?: string} = {}\n\n if (offset !== undefined && offset >= 0) {\n query.offset = `${offset}`\n }\n if (limit !== undefined && limit > 0) {\n query.limit = `${limit}`\n }\n\n return client.request<DatasetCopyJob[]>({\n method: 'GET',\n query,\n uri: `/projects/${projectId}/datasets/copy`,\n })\n}\n\nexport interface CopyJobProgressEvent {\n type: 'reconnect' | string\n\n progress?: number\n state?: 'completed' | 'failed' | 'pending' | 'processing'\n}\n\ninterface FollowCopyJobProgressOptions {\n jobId: string\n projectId: string\n}\n\nasync function getJobListenUrl(projectId: string, jobId: string): Promise<string> {\n const client = await getDatasetClient(projectId)\n const baseUrl = client.config().url || 'https://api.sanity.io'\n return `${baseUrl}/jobs/${jobId}/listen`\n}\n\nexport function followCopyJobProgress({\n jobId,\n projectId,\n}: FollowCopyJobProgressOptions): Observable<CopyJobProgressEvent> {\n return new Observable<CopyJobProgressEvent>((observer) => {\n let progressSource: InstanceType<typeof EventSource> | null = null\n let stopped = false\n\n getJobListenUrl(projectId, jobId)\n .then((url) => {\n progressSource = new EventSource(url)\n\n function onError() {\n if (progressSource) {\n progressSource.close()\n progressSource = null\n }\n\n if (stopped) {\n return\n }\n\n observer.next({type: 'reconnect'})\n progressSource = new EventSource(url)\n attachListeners()\n }\n\n function onChannelError(error: MessageEvent) {\n stopped = true\n if (progressSource) {\n progressSource.close()\n progressSource = null\n }\n const errorMessage = error.data\n ? `Copy job failed: ${error.data}`\n : 'Copy job failed: Connection to server lost. Please check the job status using --list and retry if needed.'\n observer.error(new Error(errorMessage))\n }\n\n function onMessage(event: MessageEvent) {\n let data\n try {\n data = JSON.parse(event.data)\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Unknown error'\n observer.error(new Error(`Invalid JSON received from server: ${message}`))\n return\n }\n\n if (data.state === 'failed') {\n const failureReason = data.message || data.error || 'Unknown reason'\n observer.error(new Error(`Copy job failed: ${failureReason}`))\n } else if (data.state === 'completed') {\n onComplete()\n } else {\n observer.next(data)\n }\n }\n\n function onComplete() {\n if (progressSource) {\n progressSource.removeEventListener('error', onError)\n progressSource.removeEventListener('channel_error', onChannelError)\n progressSource.removeEventListener('job', onMessage)\n progressSource.removeEventListener('done', onComplete)\n progressSource.close()\n progressSource = null\n }\n observer.complete()\n }\n\n function attachListeners() {\n if (progressSource) {\n progressSource.addEventListener('error', onError)\n progressSource.addEventListener('channel_error', onChannelError)\n progressSource.addEventListener('job', onMessage)\n progressSource.addEventListener('done', onComplete)\n }\n }\n\n attachListeners()\n })\n .catch((error) => {\n observer.error(error)\n })\n\n return () => {\n if (stopped) return\n stopped = true\n if (progressSource) {\n progressSource.close()\n progressSource = null\n }\n }\n })\n}\n"],"names":["getProjectCliClient","EventSource","Observable","DATASET_API_VERSION","getDatasetClient","projectId","apiVersion","requireUser","listDatasets","client","datasets","list","listDatasetAliases","request","uri","deleteDataset","datasetName","delete","editDatasetAcl","aclMode","edit","createDataset","embeddings","options","create","copyDataset","skipContentReleases","skipHistory","sourceDataset","targetDataset","body","method","listDatasetCopyJobs","limit","offset","query","undefined","getJobListenUrl","jobId","baseUrl","config","url","followCopyJobProgress","observer","progressSource","stopped","then","onError","close","next","type","attachListeners","onChannelError","error","errorMessage","data","Error","onMessage","event","JSON","parse","message","state","failureReason","onComplete","removeEventListener","complete","addEventListener","catch"],"mappings":"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"}
1
+ {"version":3,"sources":["../../src/services/datasets.ts"],"sourcesContent":["import {getProjectCliClient} from '@sanity/cli-core'\nimport {\n type DatasetCreateOptions as ClientCreateOptions,\n type DatasetAclMode,\n type EmbeddingsSettingsBody,\n} from '@sanity/client'\nimport {EventSource} from 'eventsource'\nimport {Observable} from 'rxjs'\n\nexport const DATASET_API_VERSION = 'v2025-09-16'\n\nfunction getDatasetClient(projectId: string) {\n return getProjectCliClient({\n apiVersion: DATASET_API_VERSION,\n projectId,\n requireUser: true,\n })\n}\n\nexport async function listDatasets(projectId: string) {\n const client = await getDatasetClient(projectId)\n return client.datasets.list()\n}\n\nexport interface DatasetAliasDefinition {\n datasetName: string | null\n name: string\n}\n\nexport async function listDatasetAliases(projectId: string): Promise<DatasetAliasDefinition[]> {\n const client = await getDatasetClient(projectId)\n return client.request<DatasetAliasDefinition[]>({uri: '/aliases'})\n}\n\ninterface DeleteDatasetOptions {\n datasetName: string\n projectId: string\n}\n\nexport async function deleteDataset({datasetName, projectId}: DeleteDatasetOptions) {\n const client = await getDatasetClient(projectId)\n return client.datasets.delete(datasetName)\n}\n\ninterface EditDatasetAclOptions {\n aclMode: 'private' | 'public'\n datasetName: string\n projectId: string\n}\n\nexport async function editDatasetAcl({aclMode, datasetName, projectId}: EditDatasetAclOptions) {\n const client = await getDatasetClient(projectId)\n return client.datasets.edit(datasetName, {aclMode})\n}\n\ninterface CreateDatasetOptions {\n datasetName: string\n projectId: string\n\n aclMode?: DatasetAclMode\n embeddings?: EmbeddingsSettingsBody\n}\n\nexport async function createDataset({\n aclMode,\n datasetName,\n embeddings,\n projectId,\n}: CreateDatasetOptions) {\n const client = await getDatasetClient(projectId)\n const options: ClientCreateOptions = {}\n\n if (aclMode) {\n options.aclMode = aclMode\n }\n if (embeddings) {\n options.embeddings = embeddings\n }\n\n return client.datasets.create(datasetName, options)\n}\n\ninterface CopyDatasetOptions {\n projectId: string\n skipHistory: boolean\n sourceDataset: string\n targetDataset: string\n\n skipContentReleases?: boolean\n}\n\ninterface CopyDatasetResponse {\n jobId: string\n}\n\nexport async function copyDataset({\n projectId,\n skipContentReleases,\n skipHistory,\n sourceDataset,\n targetDataset,\n}: CopyDatasetOptions): Promise<CopyDatasetResponse> {\n const client = await getDatasetClient(projectId)\n return client.request<CopyDatasetResponse>({\n body: {\n skipContentReleases,\n skipHistory,\n targetDataset,\n },\n method: 'PUT',\n uri: `/datasets/${sourceDataset}/copy`,\n })\n}\n\ninterface ListDatasetCopyJobsOptions {\n projectId: string\n\n limit?: number\n offset?: number\n}\n\nexport interface DatasetCopyJob {\n createdAt: string\n id: string\n sourceDataset: string\n state: string\n targetDataset: string\n updatedAt: string\n withHistory: boolean\n}\n\nexport async function listDatasetCopyJobs({\n limit,\n offset,\n projectId,\n}: ListDatasetCopyJobsOptions): Promise<DatasetCopyJob[]> {\n const client = await getDatasetClient(projectId)\n const query: {limit?: string; offset?: string} = {}\n\n if (offset !== undefined && offset >= 0) {\n query.offset = `${offset}`\n }\n if (limit !== undefined && limit > 0) {\n query.limit = `${limit}`\n }\n\n return client.request<DatasetCopyJob[]>({\n method: 'GET',\n query,\n uri: `/projects/${projectId}/datasets/copy`,\n })\n}\n\nexport interface CopyJobProgressEvent {\n type: 'reconnect' | string\n\n progress?: number\n state?: 'completed' | 'failed' | 'pending' | 'processing'\n}\n\ninterface FollowCopyJobProgressOptions {\n jobId: string\n projectId: string\n}\n\nasync function getJobListenUrl(projectId: string, jobId: string): Promise<string> {\n const client = await getDatasetClient(projectId)\n const baseUrl = client.config().url || 'https://api.sanity.io'\n return `${baseUrl}/jobs/${jobId}/listen`\n}\n\nexport function followCopyJobProgress({\n jobId,\n projectId,\n}: FollowCopyJobProgressOptions): Observable<CopyJobProgressEvent> {\n return new Observable<CopyJobProgressEvent>((observer) => {\n let progressSource: InstanceType<typeof EventSource> | null = null\n let stopped = false\n\n getJobListenUrl(projectId, jobId)\n .then((url) => {\n progressSource = new EventSource(url)\n\n function onError() {\n if (progressSource) {\n progressSource.close()\n progressSource = null\n }\n\n if (stopped) {\n return\n }\n\n observer.next({type: 'reconnect'})\n progressSource = new EventSource(url)\n attachListeners()\n }\n\n function onChannelError(error: MessageEvent) {\n stopped = true\n if (progressSource) {\n progressSource.close()\n progressSource = null\n }\n const errorMessage = error.data\n ? `Copy job failed: ${error.data}`\n : 'Copy job failed: Connection to server lost. Please check the job status using --list and retry if needed.'\n observer.error(new Error(errorMessage))\n }\n\n function onMessage(event: MessageEvent) {\n let data\n try {\n data = JSON.parse(event.data)\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Unknown error'\n observer.error(new Error(`Invalid JSON received from server: ${message}`))\n return\n }\n\n if (data.state === 'failed') {\n const failureReason = data.message || data.error || 'Unknown reason'\n observer.error(new Error(`Copy job failed: ${failureReason}`))\n } else if (data.state === 'completed') {\n onComplete()\n } else {\n observer.next(data)\n }\n }\n\n function onComplete() {\n if (progressSource) {\n progressSource.removeEventListener('error', onError)\n progressSource.removeEventListener('channel_error', onChannelError)\n progressSource.removeEventListener('job', onMessage)\n progressSource.removeEventListener('done', onComplete)\n progressSource.close()\n progressSource = null\n }\n observer.complete()\n }\n\n function attachListeners() {\n if (progressSource) {\n progressSource.addEventListener('error', onError)\n progressSource.addEventListener('channel_error', onChannelError)\n progressSource.addEventListener('job', onMessage)\n progressSource.addEventListener('done', onComplete)\n }\n }\n\n attachListeners()\n })\n .catch((error) => {\n observer.error(error)\n })\n\n return () => {\n if (stopped) return\n stopped = true\n if (progressSource) {\n progressSource.close()\n progressSource = null\n }\n }\n })\n}\n"],"names":["getProjectCliClient","EventSource","Observable","DATASET_API_VERSION","getDatasetClient","projectId","apiVersion","requireUser","listDatasets","client","datasets","list","listDatasetAliases","request","uri","deleteDataset","datasetName","delete","editDatasetAcl","aclMode","edit","createDataset","embeddings","options","create","copyDataset","skipContentReleases","skipHistory","sourceDataset","targetDataset","body","method","listDatasetCopyJobs","limit","offset","query","undefined","getJobListenUrl","jobId","baseUrl","config","url","followCopyJobProgress","observer","progressSource","stopped","then","onError","close","next","type","attachListeners","onChannelError","error","errorMessage","data","Error","onMessage","event","JSON","parse","message","state","failureReason","onComplete","removeEventListener","complete","addEventListener","catch"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/telemetry/init.telemetry.ts"],"sourcesContent":["import {defineTrace} from '@sanity/telemetry'\n\nimport {type EditorName} from '../actions/mcp/editorConfigs.js'\n\ninterface StartStep {\n flags: Record<string, boolean | number | string | undefined>\n step: 'start'\n}\n\ninterface LoginStep {\n step: 'login'\n\n alreadyLoggedIn?: boolean\n}\n\ninterface FetchJourneyConfigStep {\n datasetName: string\n displayName: string\n isFirstProject: boolean\n projectId: string\n step: 'fetchJourneyConfig'\n}\n\ninterface CreateOrSelectProjectStep {\n projectId: string\n selectedOption: 'create' | 'none' | 'select'\n step: 'createOrSelectProject'\n}\n\ninterface CreateOrSelectDatasetStep {\n datasetName: string\n selectedOption: 'create' | 'none' | 'select'\n step: 'createOrSelectDataset'\n visibility: 'private' | 'public'\n}\n\ninterface UseDefaultPlanCoupon {\n selectedOption: 'no' | 'yes'\n step: 'useDefaultPlanCoupon'\n\n coupon?: string\n}\n\ninterface UseDefaultPlanId {\n selectedOption: 'no' | 'yes'\n step: 'useDefaultPlanId'\n\n planId?: string\n}\n\ninterface UseDetectedFrameworkStep {\n selectedOption: 'no' | 'yes'\n step: 'useDetectedFramework'\n\n detectedFramework?: string\n}\n\ninterface UseTypeScriptStep {\n selectedOption: 'no' | 'yes'\n step: 'useTypeScript'\n}\n\ninterface SelectTemplateStep {\n selectedOption: string\n step: 'selectProjectTemplate'\n}\ninterface ImportTemplateDatasetStep {\n selectedOption: 'no' | 'yes'\n step: 'importTemplateDataset'\n}\n\ninterface SendCommunityInviteStep {\n selectedOption: 'no' | 'yes'\n step: 'sendCommunityInvite'\n}\n\ninterface SelectPackageManagerStep {\n selectedOption: string\n step: 'selectPackageManager'\n}\n\ninterface MCPSetupStep {\n configuredEditors: EditorName[]\n detectedEditors: EditorName[]\n skipped: boolean\n step: 'mcpSetup'\n}\n\ninterface ConfigureAppProjectStep {\n selectedOption: 'create' | 'existing' | 'skip'\n step: 'configureAppProject'\n}\n\nexport type InitStepResult =\n | ConfigureAppProjectStep\n | CreateOrSelectDatasetStep\n | CreateOrSelectProjectStep\n | FetchJourneyConfigStep\n | ImportTemplateDatasetStep\n | LoginStep\n | MCPSetupStep\n | SelectPackageManagerStep\n | SelectTemplateStep\n | SendCommunityInviteStep\n | StartStep\n | UseDefaultPlanCoupon\n | UseDefaultPlanId\n | UseDetectedFrameworkStep\n | UseTypeScriptStep\n\nexport const CLIInitStepCompleted = defineTrace<InitStepResult>({\n description: 'User completed a step in the CLI init flow',\n name: 'CLI Init Step Completed',\n version: 1,\n})\n"],"names":["defineTrace","CLIInitStepCompleted","description","name","version"],"mappings":"AAAA,SAAQA,WAAW,QAAO,oBAAmB;AA8G7C,OAAO,MAAMC,uBAAuBD,YAA4B;IAC9DE,aAAa;IACbC,MAAM;IACNC,SAAS;AACX,GAAE"}
1
+ {"version":3,"sources":["../../src/telemetry/init.telemetry.ts"],"sourcesContent":["import {defineTrace} from '@sanity/telemetry'\n\nimport {type EditorName} from '../actions/mcp/editorConfigs.js'\n\ninterface StartStep {\n flags: Record<string, boolean | number | string | undefined>\n step: 'start'\n}\n\ninterface LoginStep {\n step: 'login'\n\n alreadyLoggedIn?: boolean\n}\n\ninterface FetchJourneyConfigStep {\n datasetName: string\n displayName: string\n isFirstProject: boolean\n projectId: string\n step: 'fetchJourneyConfig'\n}\n\ninterface CreateOrSelectProjectStep {\n projectId: string\n selectedOption: 'create' | 'none' | 'select'\n step: 'createOrSelectProject'\n}\n\ninterface CreateOrSelectDatasetStep {\n datasetName: string\n selectedOption: 'create' | 'none' | 'select'\n step: 'createOrSelectDataset'\n\n visibility?: 'private' | 'public'\n}\n\ninterface UseDefaultPlanCoupon {\n selectedOption: 'no' | 'yes'\n step: 'useDefaultPlanCoupon'\n\n coupon?: string\n}\n\ninterface UseDefaultPlanId {\n selectedOption: 'no' | 'yes'\n step: 'useDefaultPlanId'\n\n planId?: string\n}\n\ninterface UseDetectedFrameworkStep {\n selectedOption: 'no' | 'yes'\n step: 'useDetectedFramework'\n\n detectedFramework?: string\n}\n\ninterface UseTypeScriptStep {\n selectedOption: 'no' | 'yes'\n step: 'useTypeScript'\n}\n\ninterface SelectTemplateStep {\n selectedOption: string\n step: 'selectProjectTemplate'\n}\ninterface ImportTemplateDatasetStep {\n selectedOption: 'no' | 'yes'\n step: 'importTemplateDataset'\n}\n\ninterface SendCommunityInviteStep {\n selectedOption: 'no' | 'yes'\n step: 'sendCommunityInvite'\n}\n\ninterface SelectPackageManagerStep {\n selectedOption: string\n step: 'selectPackageManager'\n}\n\ninterface MCPSetupStep {\n configuredEditors: EditorName[]\n detectedEditors: EditorName[]\n skipped: boolean\n step: 'mcpSetup'\n}\n\ninterface ConfigureAppProjectStep {\n selectedOption: 'create' | 'existing' | 'skip'\n step: 'configureAppProject'\n}\n\nexport type InitStepResult =\n | ConfigureAppProjectStep\n | CreateOrSelectDatasetStep\n | CreateOrSelectProjectStep\n | FetchJourneyConfigStep\n | ImportTemplateDatasetStep\n | LoginStep\n | MCPSetupStep\n | SelectPackageManagerStep\n | SelectTemplateStep\n | SendCommunityInviteStep\n | StartStep\n | UseDefaultPlanCoupon\n | UseDefaultPlanId\n | UseDetectedFrameworkStep\n | UseTypeScriptStep\n\nexport const CLIInitStepCompleted = defineTrace<InitStepResult>({\n description: 'User completed a step in the CLI init flow',\n name: 'CLI Init Step Completed',\n version: 1,\n})\n"],"names":["defineTrace","CLIInitStepCompleted","description","name","version"],"mappings":"AAAA,SAAQA,WAAW,QAAO,oBAAmB;AA+G7C,OAAO,MAAMC,uBAAuBD,YAA4B;IAC9DE,aAAa;IACbC,MAAM;IACNC,SAAS;AACX,GAAE"}
@@ -1,7 +1,7 @@
1
1
  import path from 'node:path';
2
2
  import { readPackageJson } from '@sanity/cli-core';
3
3
  import { createRequester } from '@sanity/cli-core/request';
4
- import semver from 'semver';
4
+ import { coerce, eq, prerelease, parse as semverParse } from 'semver';
5
5
  import { getModuleUrl } from '../actions/build/getAutoUpdatesImportMap.js';
6
6
  import { getLocalPackageVersion } from './getLocalPackageVersion.js';
7
7
  const defaultRequester = createRequester({
@@ -52,7 +52,7 @@ const defaultRequester = createRequester({
52
52
  appId
53
53
  }), requester);
54
54
  if (resolvedVersion === null) {
55
- if (semver.prerelease(pkg.version)) {
55
+ if (prerelease(pkg.version)) {
56
56
  unresolvedPrerelease.push({
57
57
  pkg: pkg.name,
58
58
  version: pkg.version
@@ -63,11 +63,11 @@ const defaultRequester = createRequester({
63
63
  }
64
64
  const packageVersion = await getLocalPackageVersion(pkg.name, workDir);
65
65
  const manifestVersion = dependencies[pkg.name];
66
- const installed = semver.coerce(packageVersion ? semver.parse(packageVersion) : semver.coerce(manifestVersion));
66
+ const installed = coerce(packageVersion ? semverParse(packageVersion) : coerce(manifestVersion));
67
67
  if (!installed) {
68
68
  throw new Error(`Failed to parse installed version for ${pkg.name}`);
69
69
  }
70
- if (!semver.eq(resolvedVersion, installed.version)) {
70
+ if (!eq(resolvedVersion, installed.version)) {
71
71
  mismatched.push({
72
72
  installed: installed.version,
73
73
  pkg: pkg.name,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/util/compareDependencyVersions.ts"],"sourcesContent":["import path from 'node:path'\n\nimport {readPackageJson} from '@sanity/cli-core'\nimport {createRequester} from '@sanity/cli-core/request'\nimport semver from 'semver'\n\nimport {getModuleUrl} from '../actions/build/getAutoUpdatesImportMap.js'\nimport {getLocalPackageVersion} from './getLocalPackageVersion.js'\n\nconst defaultRequester = createRequester({\n middleware: {httpErrors: false, promise: {onlyBody: false}},\n})\n\ninterface CompareDependencyVersions {\n installed: string\n pkg: string\n remote: string\n}\n\nexport interface UnresolvedPrerelease {\n pkg: string\n version: string\n}\n\ninterface CompareDependencyVersionsResult {\n mismatched: Array<CompareDependencyVersions>\n unresolvedPrerelease: Array<UnresolvedPrerelease>\n}\n\ninterface CompareDependencyVersionsOptions {\n /** When provided, uses the app-specific module endpoint instead of the default endpoint. */\n appId?: string\n /** Optional requester for dependency injection (primarily for testing). */\n requester?: typeof defaultRequester\n}\n\n/**\n * @internal\n *\n * Compares the versions of dependencies in the studio or app with their remote versions.\n *\n * This function reads the package.json file in the provided working directory, and compares the versions of the dependencies\n * specified in the `autoUpdatesImports` parameter with their remote versions. If the versions do not match, the dependency is\n * added to a list of failed dependencies, which is returned by the function.\n *\n * The failed dependencies are anything that does not strictly match the remote version.\n * This means that if a version is lower or greater by even a patch it will be marked as failed.\n *\n * @param packages - An array of packages with their name and version to compare against remote.\n * @param workDir - The path to the working directory containing the package.json file.\n * @param options - Optional configuration for version comparison.\n *\n * @returns A promise that resolves to an object containing `mismatched` (packages whose local and remote versions differ)\n * and `unresolvedPrerelease` (packages with prerelease versions that could not be resolved remotely).\n *\n * @throws Throws an error if the remote version of a non-prerelease package cannot be fetched, or if the local version\n * of a package cannot be parsed.\n */\nexport async function compareDependencyVersions(\n packages: {name: string; version: string}[],\n workDir: string,\n {appId, requester = defaultRequester}: CompareDependencyVersionsOptions = {},\n): Promise<CompareDependencyVersionsResult> {\n const manifest = await readPackageJson(path.join(workDir, 'package.json'), {\n skipSchemaValidation: true,\n })\n const dependencies = {...manifest?.dependencies, ...manifest?.devDependencies}\n\n const mismatched: Array<CompareDependencyVersions> = []\n const unresolvedPrerelease: Array<UnresolvedPrerelease> = []\n\n for (const pkg of packages) {\n // Skip packages that are not declared in the local package.json\n if (!dependencies[pkg.name]) {\n continue\n }\n\n const resolvedVersion = await getRemoteResolvedVersion(getModuleUrl(pkg, {appId}), requester)\n\n if (resolvedVersion === null) {\n if (semver.prerelease(pkg.version)) {\n unresolvedPrerelease.push({pkg: pkg.name, version: pkg.version})\n continue\n }\n throw new Error(\n `Failed to resolve remote version for ${pkg.name}@${pkg.version}: package not found`,\n )\n }\n\n const packageVersion = await getLocalPackageVersion(pkg.name, workDir)\n\n const manifestVersion = dependencies[pkg.name]\n\n const installed = semver.coerce(\n packageVersion ? semver.parse(packageVersion) : semver.coerce(manifestVersion),\n )\n\n if (!installed) {\n throw new Error(`Failed to parse installed version for ${pkg.name}`)\n }\n\n if (!semver.eq(resolvedVersion, installed.version)) {\n mismatched.push({\n installed: installed.version,\n pkg: pkg.name,\n remote: resolvedVersion,\n })\n }\n }\n\n return {mismatched, unresolvedPrerelease}\n}\n\nasync function getRemoteResolvedVersion(\n url: string,\n request: typeof defaultRequester,\n): Promise<string | null> {\n let response\n try {\n response = await request({\n maxRedirects: 0,\n method: 'HEAD',\n url,\n })\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err)\n throw new Error(`Failed to fetch remote version for ${url}: ${message}`, {cause: err})\n }\n\n // 302 is expected, but lets also handle 2xx\n if (response.statusCode < 400) {\n const resolved = response.headers['x-resolved-version']\n if (!resolved) {\n throw new Error(`Missing 'x-resolved-version' header on response from HEAD ${url}`)\n }\n return resolved\n }\n\n if (response.statusCode === 404) {\n return null\n }\n\n throw new Error(`Unexpected HTTP response: ${response.statusCode} ${response.statusMessage}`)\n}\n"],"names":["path","readPackageJson","createRequester","semver","getModuleUrl","getLocalPackageVersion","defaultRequester","middleware","httpErrors","promise","onlyBody","compareDependencyVersions","packages","workDir","appId","requester","manifest","join","skipSchemaValidation","dependencies","devDependencies","mismatched","unresolvedPrerelease","pkg","name","resolvedVersion","getRemoteResolvedVersion","prerelease","version","push","Error","packageVersion","manifestVersion","installed","coerce","parse","eq","remote","url","request","response","maxRedirects","method","err","message","String","cause","statusCode","resolved","headers","statusMessage"],"mappings":"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"}
1
+ {"version":3,"sources":["../../src/util/compareDependencyVersions.ts"],"sourcesContent":["import path from 'node:path'\n\nimport {readPackageJson} from '@sanity/cli-core'\nimport {createRequester} from '@sanity/cli-core/request'\nimport {coerce, eq, prerelease, parse as semverParse} from 'semver'\n\nimport {getModuleUrl} from '../actions/build/getAutoUpdatesImportMap.js'\nimport {getLocalPackageVersion} from './getLocalPackageVersion.js'\n\nconst defaultRequester = createRequester({\n middleware: {httpErrors: false, promise: {onlyBody: false}},\n})\n\ninterface CompareDependencyVersions {\n installed: string\n pkg: string\n remote: string\n}\n\nexport interface UnresolvedPrerelease {\n pkg: string\n version: string\n}\n\ninterface CompareDependencyVersionsResult {\n mismatched: Array<CompareDependencyVersions>\n unresolvedPrerelease: Array<UnresolvedPrerelease>\n}\n\ninterface CompareDependencyVersionsOptions {\n /** When provided, uses the app-specific module endpoint instead of the default endpoint. */\n appId?: string\n /** Optional requester for dependency injection (primarily for testing). */\n requester?: typeof defaultRequester\n}\n\n/**\n * @internal\n *\n * Compares the versions of dependencies in the studio or app with their remote versions.\n *\n * This function reads the package.json file in the provided working directory, and compares the versions of the dependencies\n * specified in the `autoUpdatesImports` parameter with their remote versions. If the versions do not match, the dependency is\n * added to a list of failed dependencies, which is returned by the function.\n *\n * The failed dependencies are anything that does not strictly match the remote version.\n * This means that if a version is lower or greater by even a patch it will be marked as failed.\n *\n * @param packages - An array of packages with their name and version to compare against remote.\n * @param workDir - The path to the working directory containing the package.json file.\n * @param options - Optional configuration for version comparison.\n *\n * @returns A promise that resolves to an object containing `mismatched` (packages whose local and remote versions differ)\n * and `unresolvedPrerelease` (packages with prerelease versions that could not be resolved remotely).\n *\n * @throws Throws an error if the remote version of a non-prerelease package cannot be fetched, or if the local version\n * of a package cannot be parsed.\n */\nexport async function compareDependencyVersions(\n packages: {name: string; version: string}[],\n workDir: string,\n {appId, requester = defaultRequester}: CompareDependencyVersionsOptions = {},\n): Promise<CompareDependencyVersionsResult> {\n const manifest = await readPackageJson(path.join(workDir, 'package.json'), {\n skipSchemaValidation: true,\n })\n const dependencies = {...manifest?.dependencies, ...manifest?.devDependencies}\n\n const mismatched: Array<CompareDependencyVersions> = []\n const unresolvedPrerelease: Array<UnresolvedPrerelease> = []\n\n for (const pkg of packages) {\n // Skip packages that are not declared in the local package.json\n if (!dependencies[pkg.name]) {\n continue\n }\n\n const resolvedVersion = await getRemoteResolvedVersion(getModuleUrl(pkg, {appId}), requester)\n\n if (resolvedVersion === null) {\n if (prerelease(pkg.version)) {\n unresolvedPrerelease.push({pkg: pkg.name, version: pkg.version})\n continue\n }\n throw new Error(\n `Failed to resolve remote version for ${pkg.name}@${pkg.version}: package not found`,\n )\n }\n\n const packageVersion = await getLocalPackageVersion(pkg.name, workDir)\n\n const manifestVersion = dependencies[pkg.name]\n\n const installed = coerce(packageVersion ? semverParse(packageVersion) : coerce(manifestVersion))\n\n if (!installed) {\n throw new Error(`Failed to parse installed version for ${pkg.name}`)\n }\n\n if (!eq(resolvedVersion, installed.version)) {\n mismatched.push({\n installed: installed.version,\n pkg: pkg.name,\n remote: resolvedVersion,\n })\n }\n }\n\n return {mismatched, unresolvedPrerelease}\n}\n\nasync function getRemoteResolvedVersion(\n url: string,\n request: typeof defaultRequester,\n): Promise<string | null> {\n let response\n try {\n response = await request({\n maxRedirects: 0,\n method: 'HEAD',\n url,\n })\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err)\n throw new Error(`Failed to fetch remote version for ${url}: ${message}`, {cause: err})\n }\n\n // 302 is expected, but lets also handle 2xx\n if (response.statusCode < 400) {\n const resolved = response.headers['x-resolved-version']\n if (!resolved) {\n throw new Error(`Missing 'x-resolved-version' header on response from HEAD ${url}`)\n }\n return resolved\n }\n\n if (response.statusCode === 404) {\n return null\n }\n\n throw new Error(`Unexpected HTTP response: ${response.statusCode} ${response.statusMessage}`)\n}\n"],"names":["path","readPackageJson","createRequester","coerce","eq","prerelease","parse","semverParse","getModuleUrl","getLocalPackageVersion","defaultRequester","middleware","httpErrors","promise","onlyBody","compareDependencyVersions","packages","workDir","appId","requester","manifest","join","skipSchemaValidation","dependencies","devDependencies","mismatched","unresolvedPrerelease","pkg","name","resolvedVersion","getRemoteResolvedVersion","version","push","Error","packageVersion","manifestVersion","installed","remote","url","request","response","maxRedirects","method","err","message","String","cause","statusCode","resolved","headers","statusMessage"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Create a config in the provided config store that expires after the provided TTL.
3
- */ export function createExpiringConfig({ fetchValue, key, onCacheHit = ()=>null, onFetch = ()=>null, onRevalidate = ()=>null, store, ttl, validateValue = (value)=>true }) {
3
+ */ export function createExpiringConfig({ fetchValue, key, onCacheHit = ()=>null, onFetch = ()=>null, onRevalidate = ()=>null, store, ttl, validateValue = (_value)=>true }) {
4
4
  let currentFetch = null;
5
5
  return {
6
6
  delete () {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/util/createExpiringConfig.ts"],"sourcesContent":["import {type ConfigStore} from '@sanity/cli-core'\n\ninterface ExpiringConfigValue {\n updatedAt: number\n value: unknown\n}\n\ninterface ExpiringConfigOptions<Type> {\n /** Fetch value */\n fetchValue: () => Promise<Type> | Type\n /** Config key */\n key: string\n /** Config store */\n store: ConfigStore\n /** TTL (milliseconds) */\n ttl: number\n\n /** Subscribe to cache hit event */\n onCacheHit?: () => void\n /** Subscribe to fetch event */\n onFetch?: () => void\n /** Subscribe to revalidate event */\n onRevalidate?: () => void\n\n /**\n * Assert the fetched value is valid, or throw if invalid.\n * If none is provided, it will always accept the fetched value.\n */\n validateValue?: (value: unknown) => value is Type\n}\n\ninterface ExpiringConfigApi<Type> {\n /**\n * Delete the cached value.\n */\n delete: () => void\n /**\n * Attempt to get the cached value. If there is no cached value, or the cached value has expired,\n * fetch, cache, and return the value.\n */\n get: () => Promise<Type>\n}\n\n/**\n * Create a config in the provided config store that expires after the provided TTL.\n */\nexport function createExpiringConfig<Type>({\n fetchValue,\n key,\n onCacheHit = () => null,\n onFetch = () => null,\n onRevalidate = () => null,\n store,\n ttl,\n validateValue = (value: unknown): value is Type => true,\n}: ExpiringConfigOptions<Type>): ExpiringConfigApi<Type> {\n let currentFetch: Promise<Type> | null = null\n return {\n delete() {\n store.delete(key)\n },\n async get(): Promise<Type> {\n const stored = store.get(key)\n\n if (isExpiringValue(stored)) {\n const {updatedAt, value} = stored\n if (!validateValue(value)) {\n throw new Error('Stored value is invalid')\n }\n\n const hasExpired = Date.now() - updatedAt > ttl\n\n if (!hasExpired) {\n onCacheHit()\n return value\n }\n\n onRevalidate()\n }\n\n // Return existing fetch if one is already in progress\n if (currentFetch) {\n return currentFetch\n }\n\n onFetch()\n\n currentFetch = Promise.resolve(fetchValue())\n const nextValue = await currentFetch\n if (!validateValue(nextValue)) {\n throw new Error('Fetched value is invalid')\n }\n\n currentFetch = null\n\n store.set(key, {\n updatedAt: Date.now(),\n value: nextValue,\n })\n\n return nextValue\n },\n }\n}\n\n/**\n * Checks if the given stored value is valid (does not check if expired, only verified shape)\n *\n * @param stored - The stored value to check\n * @returns True if the stored value is valid\n * @internal\n */\nfunction isExpiringValue(stored: unknown): stored is ExpiringConfigValue {\n if (typeof stored !== 'object' || stored === null || Array.isArray(stored)) {\n return false\n }\n\n if (!('updatedAt' in stored) || typeof stored.updatedAt !== 'number') {\n return false\n }\n\n if (!('value' in stored)) {\n return false\n }\n\n return true\n}\n"],"names":["createExpiringConfig","fetchValue","key","onCacheHit","onFetch","onRevalidate","store","ttl","validateValue","value","currentFetch","delete","get","stored","isExpiringValue","updatedAt","Error","hasExpired","Date","now","Promise","resolve","nextValue","set","Array","isArray"],"mappings":"AA2CA;;CAEC,GACD,OAAO,SAASA,qBAA2B,EACzCC,UAAU,EACVC,GAAG,EACHC,aAAa,IAAM,IAAI,EACvBC,UAAU,IAAM,IAAI,EACpBC,eAAe,IAAM,IAAI,EACzBC,KAAK,EACLC,GAAG,EACHC,gBAAgB,CAACC,QAAkC,IAAI,EAC3B;IAC5B,IAAIC,eAAqC;IACzC,OAAO;QACLC;YACEL,MAAMK,MAAM,CAACT;QACf;QACA,MAAMU;YACJ,MAAMC,SAASP,MAAMM,GAAG,CAACV;YAEzB,IAAIY,gBAAgBD,SAAS;gBAC3B,MAAM,EAACE,SAAS,EAAEN,KAAK,EAAC,GAAGI;gBAC3B,IAAI,CAACL,cAAcC,QAAQ;oBACzB,MAAM,IAAIO,MAAM;gBAClB;gBAEA,MAAMC,aAAaC,KAAKC,GAAG,KAAKJ,YAAYR;gBAE5C,IAAI,CAACU,YAAY;oBACfd;oBACA,OAAOM;gBACT;gBAEAJ;YACF;YAEA,sDAAsD;YACtD,IAAIK,cAAc;gBAChB,OAAOA;YACT;YAEAN;YAEAM,eAAeU,QAAQC,OAAO,CAACpB;YAC/B,MAAMqB,YAAY,MAAMZ;YACxB,IAAI,CAACF,cAAcc,YAAY;gBAC7B,MAAM,IAAIN,MAAM;YAClB;YAEAN,eAAe;YAEfJ,MAAMiB,GAAG,CAACrB,KAAK;gBACba,WAAWG,KAAKC,GAAG;gBACnBV,OAAOa;YACT;YAEA,OAAOA;QACT;IACF;AACF;AAEA;;;;;;CAMC,GACD,SAASR,gBAAgBD,MAAe;IACtC,IAAI,OAAOA,WAAW,YAAYA,WAAW,QAAQW,MAAMC,OAAO,CAACZ,SAAS;QAC1E,OAAO;IACT;IAEA,IAAI,CAAE,CAAA,eAAeA,MAAK,KAAM,OAAOA,OAAOE,SAAS,KAAK,UAAU;QACpE,OAAO;IACT;IAEA,IAAI,CAAE,CAAA,WAAWF,MAAK,GAAI;QACxB,OAAO;IACT;IAEA,OAAO;AACT"}
1
+ {"version":3,"sources":["../../src/util/createExpiringConfig.ts"],"sourcesContent":["import {type ConfigStore} from '@sanity/cli-core'\n\ninterface ExpiringConfigValue {\n updatedAt: number\n value: unknown\n}\n\ninterface ExpiringConfigOptions<Type> {\n /** Fetch value */\n fetchValue: () => Promise<Type> | Type\n /** Config key */\n key: string\n /** Config store */\n store: ConfigStore\n /** TTL (milliseconds) */\n ttl: number\n\n /** Subscribe to cache hit event */\n onCacheHit?: () => void\n /** Subscribe to fetch event */\n onFetch?: () => void\n /** Subscribe to revalidate event */\n onRevalidate?: () => void\n\n /**\n * Assert the fetched value is valid, or throw if invalid.\n * If none is provided, it will always accept the fetched value.\n */\n validateValue?: (value: unknown) => value is Type\n}\n\ninterface ExpiringConfigApi<Type> {\n /**\n * Delete the cached value.\n */\n delete: () => void\n /**\n * Attempt to get the cached value. If there is no cached value, or the cached value has expired,\n * fetch, cache, and return the value.\n */\n get: () => Promise<Type>\n}\n\n/**\n * Create a config in the provided config store that expires after the provided TTL.\n */\nexport function createExpiringConfig<Type>({\n fetchValue,\n key,\n onCacheHit = () => null,\n onFetch = () => null,\n onRevalidate = () => null,\n store,\n ttl,\n validateValue = (_value: unknown): _value is Type => true,\n}: ExpiringConfigOptions<Type>): ExpiringConfigApi<Type> {\n let currentFetch: Promise<Type> | null = null\n return {\n delete() {\n store.delete(key)\n },\n async get(): Promise<Type> {\n const stored = store.get(key)\n\n if (isExpiringValue(stored)) {\n const {updatedAt, value} = stored\n if (!validateValue(value)) {\n throw new Error('Stored value is invalid')\n }\n\n const hasExpired = Date.now() - updatedAt > ttl\n\n if (!hasExpired) {\n onCacheHit()\n return value\n }\n\n onRevalidate()\n }\n\n // Return existing fetch if one is already in progress\n if (currentFetch) {\n return currentFetch\n }\n\n onFetch()\n\n currentFetch = Promise.resolve(fetchValue())\n const nextValue = await currentFetch\n if (!validateValue(nextValue)) {\n throw new Error('Fetched value is invalid')\n }\n\n currentFetch = null\n\n store.set(key, {\n updatedAt: Date.now(),\n value: nextValue,\n })\n\n return nextValue\n },\n }\n}\n\n/**\n * Checks if the given stored value is valid (does not check if expired, only verified shape)\n *\n * @param stored - The stored value to check\n * @returns True if the stored value is valid\n * @internal\n */\nfunction isExpiringValue(stored: unknown): stored is ExpiringConfigValue {\n if (typeof stored !== 'object' || stored === null || Array.isArray(stored)) {\n return false\n }\n\n if (!('updatedAt' in stored) || typeof stored.updatedAt !== 'number') {\n return false\n }\n\n if (!('value' in stored)) {\n return false\n }\n\n return true\n}\n"],"names":["createExpiringConfig","fetchValue","key","onCacheHit","onFetch","onRevalidate","store","ttl","validateValue","_value","currentFetch","delete","get","stored","isExpiringValue","updatedAt","value","Error","hasExpired","Date","now","Promise","resolve","nextValue","set","Array","isArray"],"mappings":"AA2CA;;CAEC,GACD,OAAO,SAASA,qBAA2B,EACzCC,UAAU,EACVC,GAAG,EACHC,aAAa,IAAM,IAAI,EACvBC,UAAU,IAAM,IAAI,EACpBC,eAAe,IAAM,IAAI,EACzBC,KAAK,EACLC,GAAG,EACHC,gBAAgB,CAACC,SAAoC,IAAI,EAC7B;IAC5B,IAAIC,eAAqC;IACzC,OAAO;QACLC;YACEL,MAAMK,MAAM,CAACT;QACf;QACA,MAAMU;YACJ,MAAMC,SAASP,MAAMM,GAAG,CAACV;YAEzB,IAAIY,gBAAgBD,SAAS;gBAC3B,MAAM,EAACE,SAAS,EAAEC,KAAK,EAAC,GAAGH;gBAC3B,IAAI,CAACL,cAAcQ,QAAQ;oBACzB,MAAM,IAAIC,MAAM;gBAClB;gBAEA,MAAMC,aAAaC,KAAKC,GAAG,KAAKL,YAAYR;gBAE5C,IAAI,CAACW,YAAY;oBACff;oBACA,OAAOa;gBACT;gBAEAX;YACF;YAEA,sDAAsD;YACtD,IAAIK,cAAc;gBAChB,OAAOA;YACT;YAEAN;YAEAM,eAAeW,QAAQC,OAAO,CAACrB;YAC/B,MAAMsB,YAAY,MAAMb;YACxB,IAAI,CAACF,cAAce,YAAY;gBAC7B,MAAM,IAAIN,MAAM;YAClB;YAEAP,eAAe;YAEfJ,MAAMkB,GAAG,CAACtB,KAAK;gBACba,WAAWI,KAAKC,GAAG;gBACnBJ,OAAOO;YACT;YAEA,OAAOA;QACT;IACF;AACF;AAEA;;;;;;CAMC,GACD,SAAST,gBAAgBD,MAAe;IACtC,IAAI,OAAOA,WAAW,YAAYA,WAAW,QAAQY,MAAMC,OAAO,CAACb,SAAS;QAC1E,OAAO;IACT;IAEA,IAAI,CAAE,CAAA,eAAeA,MAAK,KAAM,OAAOA,OAAOE,SAAS,KAAK,UAAU;QACpE,OAAO;IACT;IAEA,IAAI,CAAE,CAAA,WAAWF,MAAK,GAAI;QACxB,OAAO;IACT;IAEA,OAAO;AACT"}
@@ -1,4 +1,4 @@
1
- import semver from 'semver';
1
+ import { satisfies, parse as semverParse, subset, valid } from 'semver';
2
2
  import { getGlobalUninstallCommand, getLocalRemoveCommand, getLocalUpdateCommand } from './commands.js';
3
3
  /**
4
4
  * Analyzes package information and workspace configuration to detect potential issues.
@@ -52,10 +52,10 @@ import { getGlobalUninstallCommand, getLocalRemoveCommand, getLocalUpdateCommand
52
52
  // Skip @sanity/cli here — global-cli-incompatible (below) handles it with
53
53
  // better context by checking against sanity's actual required range.
54
54
  if (info.installed && name !== '@sanity/cli') {
55
- const localMajor = semver.parse(info.installed.version)?.major;
55
+ const localMajor = semverParse(info.installed.version)?.major;
56
56
  if (localMajor !== undefined) {
57
57
  for (const globalMatch of globals.filter((g)=>g.packageName === name)){
58
- const globalMajor = semver.parse(globalMatch.version)?.major;
58
+ const globalMajor = semverParse(globalMatch.version)?.major;
59
59
  if (globalMajor !== undefined && globalMajor !== localMajor) {
60
60
  issues.push({
61
61
  message: `${name} version mismatch: global ${globalMatch.version} (${globalMatch.packageManager}) vs local ${info.installed.version}.`,
@@ -86,7 +86,7 @@ import { getGlobalUninstallCommand, getLocalRemoveCommand, getLocalUpdateCommand
86
86
  if (cliInfo?.declared && !isNonSemverProtocol(cliInfo.declared.versionRange)) {
87
87
  const declaredRange = cliInfo.declared.versionRange;
88
88
  // Only flag as redundant when every version in the declared range also
89
- // satisfies the required range. semver.subset('^5.0.0', '^5.33.0') → false,
89
+ // satisfies the required range. subset('^5.0.0', '^5.33.0') → false,
90
90
  // so a too-wide range is correctly classified as conflicting.
91
91
  if (safeSubset(declaredRange, expectedCliRange)) {
92
92
  issues.push({
@@ -190,7 +190,7 @@ function isNonSemverProtocol(range) {
190
190
  * correctly matched against caret ranges like ^5.0.0-rc.1.
191
191
  */ function safeSatisfies(version, range) {
192
192
  try {
193
- return semver.satisfies(version, range, {
193
+ return satisfies(version, range, {
194
194
  includePrerelease: true
195
195
  });
196
196
  } catch {
@@ -202,7 +202,7 @@ function isNonSemverProtocol(range) {
202
202
  * like workspace:*, catalog:, file:, or git URLs instead of throwing.
203
203
  */ function safeSubset(sub, sup) {
204
204
  try {
205
- return semver.subset(sub, sup) ?? false;
205
+ return subset(sub, sup) ?? false;
206
206
  } catch {
207
207
  return false;
208
208
  }
@@ -216,7 +216,7 @@ function isNonSemverProtocol(range) {
216
216
  return range;
217
217
  }
218
218
  // If it's a plain version like "5.33.0", treat as ^5.33.0
219
- if (semver.valid(range)) {
219
+ if (valid(range)) {
220
220
  return `^${range}`;
221
221
  }
222
222
  return range;