@sanity/cli 6.0.0-alpha.9 → 6.1.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 (613) hide show
  1. package/README.md +602 -291
  2. package/bin/run.js +2 -0
  3. package/dist/SanityHelp.js +51 -23
  4. package/dist/SanityHelp.js.map +1 -1
  5. package/dist/actions/auth/authServer.js +28 -22
  6. package/dist/actions/auth/authServer.js.map +1 -1
  7. package/dist/actions/auth/login/getProvider.js +49 -38
  8. package/dist/actions/auth/login/getProvider.js.map +1 -1
  9. package/dist/actions/auth/login/getSSOProvider.js +25 -19
  10. package/dist/actions/auth/login/getSSOProvider.js.map +1 -1
  11. package/dist/actions/auth/login/login.js +12 -33
  12. package/dist/actions/auth/login/login.js.map +1 -1
  13. package/dist/actions/auth/types.js.map +1 -1
  14. package/dist/actions/backup/downloadAsset.js +9 -9
  15. package/dist/actions/backup/downloadAsset.js.map +1 -1
  16. package/dist/actions/backup/downloadDocument.js +8 -8
  17. package/dist/actions/backup/downloadDocument.js.map +1 -1
  18. package/dist/actions/build/buildApp.js +55 -18
  19. package/dist/actions/build/buildApp.js.map +1 -1
  20. package/dist/actions/build/buildStaticFiles.js +3 -2
  21. package/dist/actions/build/buildStaticFiles.js.map +1 -1
  22. package/dist/actions/build/buildStudio.js +72 -44
  23. package/dist/actions/build/buildStudio.js.map +1 -1
  24. package/dist/actions/build/buildVendorDependencies.js +18 -52
  25. package/dist/actions/build/buildVendorDependencies.js.map +1 -1
  26. package/dist/actions/build/checkRequiredDependencies.js +13 -8
  27. package/dist/actions/build/checkRequiredDependencies.js.map +1 -1
  28. package/dist/actions/build/checkStudioDependencyVersions.js +19 -17
  29. package/dist/actions/build/checkStudioDependencyVersions.js.map +1 -1
  30. package/dist/actions/build/createExternalFromImportMap.js +1 -1
  31. package/dist/actions/build/createExternalFromImportMap.js.map +1 -1
  32. package/dist/actions/build/determineBasePath.js +5 -2
  33. package/dist/actions/build/determineBasePath.js.map +1 -1
  34. package/dist/actions/build/getViteConfig.js +47 -4
  35. package/dist/actions/build/getViteConfig.js.map +1 -1
  36. package/dist/actions/build/handlePrereleaseVersions.js +44 -0
  37. package/dist/actions/build/handlePrereleaseVersions.js.map +1 -0
  38. package/dist/actions/build/renderDocument.js +6 -10
  39. package/dist/actions/build/renderDocument.js.map +1 -1
  40. package/dist/actions/build/renderDocumentWorker/components/BasicDocument.js +4 -4
  41. package/dist/actions/build/renderDocumentWorker/components/BasicDocument.js.map +1 -1
  42. package/dist/actions/build/renderDocumentWorker/components/DefaultDocument.js +3 -3
  43. package/dist/actions/build/renderDocumentWorker/components/DefaultDocument.js.map +1 -1
  44. package/dist/actions/build/renderDocumentWorker/components/GlobalErrorHandler.js +1 -0
  45. package/dist/actions/build/renderDocumentWorker/components/GlobalErrorHandler.js.map +1 -1
  46. package/dist/actions/build/renderDocumentWorker/getDocumentComponent.js +2 -2
  47. package/dist/actions/build/renderDocumentWorker/getDocumentComponent.js.map +1 -1
  48. package/dist/actions/build/renderDocumentWorker/renderDocumentWorker.js +1 -1
  49. package/dist/actions/build/renderDocumentWorker/renderDocumentWorker.js.map +1 -1
  50. package/dist/actions/build/shouldAutoUpdate.js +2 -0
  51. package/dist/actions/build/shouldAutoUpdate.js.map +1 -1
  52. package/dist/actions/build/types.js.map +1 -1
  53. package/dist/actions/build/writeFavicons.js +3 -5
  54. package/dist/actions/build/writeFavicons.js.map +1 -1
  55. package/dist/actions/build/writeSanityRuntime.js +4 -3
  56. package/dist/actions/build/writeSanityRuntime.js.map +1 -1
  57. package/dist/actions/codemods/reactIconsV3.js +2 -2
  58. package/dist/actions/codemods/reactIconsV3.js.map +1 -1
  59. package/dist/actions/dataset/create.js +7 -1
  60. package/dist/actions/dataset/create.js.map +1 -1
  61. package/dist/actions/dataset/determineDatasetAclMode.js.map +1 -1
  62. package/dist/actions/dataset/resolveDataset.js +26 -0
  63. package/dist/actions/dataset/resolveDataset.js.map +1 -0
  64. package/dist/actions/debug/formatters.js +22 -0
  65. package/dist/actions/debug/formatters.js.map +1 -0
  66. package/dist/actions/deploy/createStudioUserApplication.js +17 -4
  67. package/dist/actions/deploy/createStudioUserApplication.js.map +1 -1
  68. package/dist/actions/deploy/deployApp.js +41 -15
  69. package/dist/actions/deploy/deployApp.js.map +1 -1
  70. package/dist/actions/deploy/deployStudio.js +92 -44
  71. package/dist/actions/deploy/deployStudio.js.map +1 -1
  72. package/dist/actions/deploy/deployStudioSchemasAndManifests.js +55 -0
  73. package/dist/actions/deploy/deployStudioSchemasAndManifests.js.map +1 -0
  74. package/dist/actions/deploy/deployStudioSchemasAndManifests.worker.js +120 -0
  75. package/dist/actions/deploy/deployStudioSchemasAndManifests.worker.js.map +1 -0
  76. package/dist/actions/deploy/findUserApplicationForStudio.js +35 -12
  77. package/dist/actions/deploy/findUserApplicationForStudio.js.map +1 -1
  78. package/dist/actions/deploy/types.js +10 -1
  79. package/dist/actions/deploy/types.js.map +1 -1
  80. package/dist/actions/deploy/urlUtils.js +21 -0
  81. package/dist/actions/deploy/urlUtils.js.map +1 -0
  82. package/dist/actions/dev/getDashboardAppUrl.js +48 -0
  83. package/dist/actions/dev/getDashboardAppUrl.js.map +1 -0
  84. package/dist/actions/dev/getDevServerConfig.js +7 -3
  85. package/dist/actions/dev/getDevServerConfig.js.map +1 -1
  86. package/dist/actions/dev/startAppDevServer.js +3 -3
  87. package/dist/actions/dev/startAppDevServer.js.map +1 -1
  88. package/dist/actions/dev/startStudioDevServer.js +14 -14
  89. package/dist/actions/dev/startStudioDevServer.js.map +1 -1
  90. package/dist/actions/doctor/checks/cliInstallation.js +56 -0
  91. package/dist/actions/doctor/checks/cliInstallation.js.map +1 -0
  92. package/dist/actions/doctor/checks/index.js +16 -0
  93. package/dist/actions/doctor/checks/index.js.map +1 -0
  94. package/dist/actions/doctor/runDoctorChecks.js +56 -0
  95. package/dist/actions/doctor/runDoctorChecks.js.map +1 -0
  96. package/dist/actions/doctor/types.js +3 -0
  97. package/dist/actions/doctor/types.js.map +1 -0
  98. package/dist/actions/documents/types.js.map +1 -1
  99. package/dist/actions/documents/validate.js +11 -2
  100. package/dist/actions/documents/validate.js.map +1 -1
  101. package/dist/actions/documents/validateDocuments.worker.js +4 -4
  102. package/dist/actions/documents/validateDocuments.worker.js.map +1 -1
  103. package/dist/actions/documents/validation/reporters/jsonReporter.js +1 -1
  104. package/dist/actions/documents/validation/reporters/jsonReporter.js.map +1 -1
  105. package/dist/actions/documents/validation/reporters/ndjsonReporter.js +1 -1
  106. package/dist/actions/documents/validation/reporters/ndjsonReporter.js.map +1 -1
  107. package/dist/actions/documents/validation/reporters/prettyReporter/formatDocumentValidation.js +1 -1
  108. package/dist/actions/documents/validation/reporters/prettyReporter/formatDocumentValidation.js.map +1 -1
  109. package/dist/actions/documents/validation/reporters/prettyReporter/tree.js +108 -0
  110. package/dist/actions/documents/validation/reporters/prettyReporter/tree.js.map +1 -0
  111. package/dist/actions/graphql/SchemaError.js +4 -26
  112. package/dist/actions/graphql/SchemaError.js.map +1 -1
  113. package/dist/actions/graphql/__tests__/fixtures/many-self-refs.js +540 -0
  114. package/dist/actions/graphql/__tests__/fixtures/many-self-refs.js.map +1 -0
  115. package/dist/actions/graphql/__tests__/fixtures/test-studio.js +1143 -0
  116. package/dist/actions/graphql/__tests__/fixtures/test-studio.js.map +1 -0
  117. package/dist/actions/graphql/__tests__/fixtures/union-refs.js +591 -0
  118. package/dist/actions/graphql/__tests__/fixtures/union-refs.js.map +1 -0
  119. package/dist/actions/graphql/__tests__/helpers.js +23 -0
  120. package/dist/actions/graphql/__tests__/helpers.js.map +1 -0
  121. package/dist/actions/graphql/extractFromSanitySchema.js +5 -5
  122. package/dist/actions/graphql/extractFromSanitySchema.js.map +1 -1
  123. package/dist/actions/graphql/extractGraphQLAPIs.js +150 -0
  124. package/dist/actions/graphql/extractGraphQLAPIs.js.map +1 -0
  125. package/dist/actions/graphql/extractGraphQLAPIs.worker.js +12 -0
  126. package/dist/actions/graphql/extractGraphQLAPIs.worker.js.map +1 -0
  127. package/dist/actions/graphql/gen1/generateTypeFilters.js +1 -1
  128. package/dist/actions/graphql/gen1/generateTypeFilters.js.map +1 -1
  129. package/dist/actions/graphql/gen1/generateTypeQueries.js +2 -1
  130. package/dist/actions/graphql/gen1/generateTypeQueries.js.map +1 -1
  131. package/dist/actions/graphql/gen1/index.js +5 -5
  132. package/dist/actions/graphql/gen1/index.js.map +1 -1
  133. package/dist/actions/graphql/gen2/generateTypeQueries.js +1 -1
  134. package/dist/actions/graphql/gen2/generateTypeQueries.js.map +1 -1
  135. package/dist/actions/graphql/gen2/index.js +6 -6
  136. package/dist/actions/graphql/gen2/index.js.map +1 -1
  137. package/dist/actions/graphql/gen3/generateTypeQueries.js +3 -4
  138. package/dist/actions/graphql/gen3/generateTypeQueries.js.map +1 -1
  139. package/dist/actions/graphql/gen3/index.js +6 -7
  140. package/dist/actions/graphql/gen3/index.js.map +1 -1
  141. package/dist/actions/graphql/getGraphQLAPIs.js +15 -57
  142. package/dist/actions/graphql/getGraphQLAPIs.js.map +1 -1
  143. package/dist/actions/graphql/getGraphQLAPIs.worker.js +75 -106
  144. package/dist/actions/graphql/getGraphQLAPIs.worker.js.map +1 -1
  145. package/dist/actions/graphql/helpers.js +13 -0
  146. package/dist/actions/graphql/helpers.js.map +1 -1
  147. package/dist/actions/graphql/resolveGraphQLApisFromWorkspaces.js +187 -0
  148. package/dist/actions/graphql/resolveGraphQLApisFromWorkspaces.js.map +1 -0
  149. package/dist/actions/graphql/types.js +1 -1
  150. package/dist/actions/graphql/types.js.map +1 -1
  151. package/dist/actions/init/bootstrapLocalTemplate.js +10 -8
  152. package/dist/actions/init/bootstrapLocalTemplate.js.map +1 -1
  153. package/dist/actions/init/bootstrapRemoteTemplate.js +6 -5
  154. package/dist/actions/init/bootstrapRemoteTemplate.js.map +1 -1
  155. package/dist/actions/init/bootstrapTemplate.js.map +1 -1
  156. package/dist/actions/init/checkNextJsReactCompatibility.js +1 -1
  157. package/dist/actions/init/checkNextJsReactCompatibility.js.map +1 -1
  158. package/dist/actions/init/createAppCliConfig.js.map +1 -1
  159. package/dist/actions/init/createCliConfig.js.map +1 -1
  160. package/dist/actions/init/createPackageManifest.js +21 -9
  161. package/dist/actions/init/createPackageManifest.js.map +1 -1
  162. package/dist/actions/init/remoteTemplate.js +1 -2
  163. package/dist/actions/init/remoteTemplate.js.map +1 -1
  164. package/dist/actions/init/sdkAppDependencies.js +19 -0
  165. package/dist/actions/init/sdkAppDependencies.js.map +1 -0
  166. package/dist/actions/init/studioDependencies.js.map +1 -0
  167. package/dist/actions/init/templates/appQuickstart.js +1 -22
  168. package/dist/actions/init/templates/appQuickstart.js.map +1 -1
  169. package/dist/actions/init/templates/appSanityUi.js +3 -22
  170. package/dist/actions/init/templates/appSanityUi.js.map +1 -1
  171. package/dist/actions/init/types.js.map +1 -1
  172. package/dist/actions/manifest/SchemaIcon.js +6 -4
  173. package/dist/actions/manifest/SchemaIcon.js.map +1 -1
  174. package/dist/actions/manifest/blockTypeTransformer.js +67 -0
  175. package/dist/actions/manifest/blockTypeTransformer.js.map +1 -0
  176. package/dist/actions/manifest/debug.js +4 -0
  177. package/dist/actions/manifest/debug.js.map +1 -0
  178. package/dist/actions/manifest/extractAppManifest.js +39 -22
  179. package/dist/actions/manifest/extractAppManifest.js.map +1 -1
  180. package/dist/actions/manifest/extractManifest.js +27 -78
  181. package/dist/actions/manifest/extractManifest.js.map +1 -1
  182. package/dist/actions/manifest/extractManifest.worker.js +30 -0
  183. package/dist/actions/manifest/extractManifest.worker.js.map +1 -0
  184. package/dist/actions/manifest/extractWorkspaceManifest.js +31 -372
  185. package/dist/actions/manifest/extractWorkspaceManifest.js.map +1 -1
  186. package/dist/actions/manifest/iconResolver.js +30 -0
  187. package/dist/actions/manifest/iconResolver.js.map +1 -0
  188. package/dist/actions/manifest/referenceTransformer.js +51 -0
  189. package/dist/actions/manifest/referenceTransformer.js.map +1 -0
  190. package/dist/actions/manifest/schemaTypeHelpers.js +2 -2
  191. package/dist/actions/manifest/schemaTypeHelpers.js.map +1 -1
  192. package/dist/actions/manifest/schemaTypeTransformer.js +168 -0
  193. package/dist/actions/manifest/schemaTypeTransformer.js.map +1 -0
  194. package/dist/actions/manifest/transformerUtils.js +40 -0
  195. package/dist/actions/manifest/transformerUtils.js.map +1 -0
  196. package/dist/actions/manifest/types.js +5 -0
  197. package/dist/actions/manifest/types.js.map +1 -1
  198. package/dist/actions/manifest/validationTransformer.js +84 -0
  199. package/dist/actions/manifest/validationTransformer.js.map +1 -0
  200. package/dist/actions/manifest/writeManifestFile.js +30 -0
  201. package/dist/actions/manifest/writeManifestFile.js.map +1 -0
  202. package/dist/actions/manifest/writeWorkspaceFiles.js +30 -0
  203. package/dist/actions/manifest/writeWorkspaceFiles.js.map +1 -0
  204. package/dist/actions/mcp/detectAvailableEditors.js +34 -13
  205. package/dist/actions/mcp/detectAvailableEditors.js.map +1 -1
  206. package/dist/actions/mcp/editorConfigs.js +231 -109
  207. package/dist/actions/mcp/editorConfigs.js.map +1 -1
  208. package/dist/actions/mcp/promptForMCPSetup.js +16 -7
  209. package/dist/actions/mcp/promptForMCPSetup.js.map +1 -1
  210. package/dist/actions/mcp/setupMCP.js +62 -23
  211. package/dist/actions/mcp/setupMCP.js.map +1 -1
  212. package/dist/actions/mcp/types.js.map +1 -1
  213. package/dist/actions/mcp/validateEditorTokens.js +56 -0
  214. package/dist/actions/mcp/validateEditorTokens.js.map +1 -0
  215. package/dist/actions/mcp/writeMCPConfig.js +27 -15
  216. package/dist/actions/mcp/writeMCPConfig.js.map +1 -1
  217. package/dist/actions/media/buildNdjsonIndex.js +32 -0
  218. package/dist/actions/media/buildNdjsonIndex.js.map +1 -0
  219. package/dist/actions/media/importAspects.js +2 -11
  220. package/dist/actions/media/importAspects.js.map +1 -1
  221. package/dist/actions/media/importMedia.js +22 -18
  222. package/dist/actions/media/importMedia.js.map +1 -1
  223. package/dist/actions/organizations/findOrganizationByUserName.js +5 -0
  224. package/dist/actions/organizations/findOrganizationByUserName.js.map +1 -0
  225. package/dist/actions/organizations/getOrganization.js +3 -2
  226. package/dist/actions/organizations/getOrganization.js.map +1 -1
  227. package/dist/actions/organizations/getOrganizationChoices.js +27 -19
  228. package/dist/actions/organizations/getOrganizationChoices.js.map +1 -1
  229. package/dist/actions/organizations/types.js +3 -0
  230. package/dist/actions/organizations/types.js.map +1 -0
  231. package/dist/actions/projects/getManageUrl.js +1 -2
  232. package/dist/actions/projects/getManageUrl.js.map +1 -1
  233. package/dist/actions/schema/deleteSchemaAction.js +14 -30
  234. package/dist/actions/schema/deleteSchemaAction.js.map +1 -1
  235. package/dist/actions/schema/deploySchemas.js +22 -91
  236. package/dist/actions/schema/deploySchemas.js.map +1 -1
  237. package/dist/actions/schema/extractSanitySchema.worker.js +0 -5
  238. package/dist/actions/schema/extractSanitySchema.worker.js.map +1 -1
  239. package/dist/actions/schema/extractSanityWorkspace.worker.js +24 -0
  240. package/dist/actions/schema/extractSanityWorkspace.worker.js.map +1 -0
  241. package/dist/actions/schema/extractSchema.js +8 -40
  242. package/dist/actions/schema/extractSchema.js.map +1 -1
  243. package/dist/actions/schema/extractSchemaWatcher.js +128 -0
  244. package/dist/actions/schema/extractSchemaWatcher.js.map +1 -0
  245. package/dist/actions/schema/formatSchemaValidation.js +5 -1
  246. package/dist/actions/schema/formatSchemaValidation.js.map +1 -1
  247. package/dist/actions/schema/getExtractOptions.js +16 -0
  248. package/dist/actions/schema/getExtractOptions.js.map +1 -0
  249. package/dist/actions/schema/listSchemas.js +53 -56
  250. package/dist/actions/schema/listSchemas.js.map +1 -1
  251. package/dist/actions/schema/matchSchemaPattern.js +22 -0
  252. package/dist/actions/schema/matchSchemaPattern.js.map +1 -0
  253. package/dist/actions/schema/runSchemaExtraction.js +39 -0
  254. package/dist/actions/schema/runSchemaExtraction.js.map +1 -0
  255. package/dist/actions/schema/types.js +8 -0
  256. package/dist/actions/schema/types.js.map +1 -1
  257. package/dist/actions/schema/uniqueWorkspaces.worker.js +24 -0
  258. package/dist/actions/schema/uniqueWorkspaces.worker.js.map +1 -0
  259. package/dist/actions/schema/updateWorkspaceSchema.js +63 -0
  260. package/dist/actions/schema/updateWorkspaceSchema.js.map +1 -0
  261. package/dist/actions/schema/uploadSchemaToLexicon.js +87 -0
  262. package/dist/actions/schema/uploadSchemaToLexicon.js.map +1 -0
  263. package/dist/actions/schema/utils/SchemaExtractionError.js +10 -0
  264. package/dist/actions/schema/utils/SchemaExtractionError.js.map +1 -0
  265. package/dist/actions/schema/utils/schemaStoreValidation.js +1 -15
  266. package/dist/actions/schema/utils/schemaStoreValidation.js.map +1 -1
  267. package/dist/actions/schema/utils/uniqByProjectIdDataset.js +1 -1
  268. package/dist/actions/schema/utils/uniqByProjectIdDataset.js.map +1 -1
  269. package/dist/actions/schema/validateSchema.worker.js +1 -8
  270. package/dist/actions/schema/validateSchema.worker.js.map +1 -1
  271. package/dist/actions/schema/watchExtractSchema.js +72 -0
  272. package/dist/actions/schema/watchExtractSchema.js.map +1 -0
  273. package/dist/actions/telemetry/isTrueish.js +10 -0
  274. package/dist/actions/telemetry/isTrueish.js.map +1 -0
  275. package/dist/actions/telemetry/resolveConsent.js +2 -1
  276. package/dist/actions/telemetry/resolveConsent.js.map +1 -1
  277. package/dist/actions/telemetry/setConsent.js +2 -1
  278. package/dist/actions/telemetry/setConsent.js.map +1 -1
  279. package/dist/actions/telemetry/telemetryDebug.js +2 -2
  280. package/dist/actions/telemetry/telemetryDebug.js.map +1 -1
  281. package/dist/actions/users/getMembersForProject.js.map +1 -1
  282. package/dist/actions/users/getPendingInvitations.js +1 -1
  283. package/dist/actions/users/getPendingInvitations.js.map +1 -1
  284. package/dist/actions/users/types.js.map +1 -1
  285. package/dist/actions/versions/filterSanityModules.js.map +1 -1
  286. package/dist/actions/versions/findSanityModulesVersions.js +2 -3
  287. package/dist/actions/versions/findSanityModulesVersions.js.map +1 -1
  288. package/dist/actions/versions/getFormatters.js +1 -1
  289. package/dist/actions/versions/getFormatters.js.map +1 -1
  290. package/dist/actions/versions/tryFindLatestVersion.js +1 -1
  291. package/dist/actions/versions/tryFindLatestVersion.js.map +1 -1
  292. package/dist/commands/backup/disable.js +22 -7
  293. package/dist/commands/backup/disable.js.map +1 -1
  294. package/dist/commands/backup/download.js +19 -10
  295. package/dist/commands/backup/download.js.map +1 -1
  296. package/dist/commands/backup/enable.js +22 -7
  297. package/dist/commands/backup/enable.js.map +1 -1
  298. package/dist/commands/backup/list.js +20 -8
  299. package/dist/commands/backup/list.js.map +1 -1
  300. package/dist/commands/build.js +2 -5
  301. package/dist/commands/build.js.map +1 -1
  302. package/dist/commands/cors/add.js +20 -7
  303. package/dist/commands/cors/add.js.map +1 -1
  304. package/dist/commands/cors/delete.js +22 -7
  305. package/dist/commands/cors/delete.js.map +1 -1
  306. package/dist/commands/cors/list.js +22 -7
  307. package/dist/commands/cors/list.js.map +1 -1
  308. package/dist/commands/dataset/alias/create.js +26 -7
  309. package/dist/commands/dataset/alias/create.js.map +1 -1
  310. package/dist/commands/dataset/alias/delete.js +20 -7
  311. package/dist/commands/dataset/alias/delete.js.map +1 -1
  312. package/dist/commands/dataset/alias/link.js +20 -7
  313. package/dist/commands/dataset/alias/link.js.map +1 -1
  314. package/dist/commands/dataset/alias/unlink.js +20 -7
  315. package/dist/commands/dataset/alias/unlink.js.map +1 -1
  316. package/dist/commands/dataset/copy.js +45 -30
  317. package/dist/commands/dataset/copy.js.map +1 -1
  318. package/dist/commands/dataset/create.js +32 -7
  319. package/dist/commands/dataset/create.js.map +1 -1
  320. package/dist/commands/dataset/delete.js +16 -7
  321. package/dist/commands/dataset/delete.js.map +1 -1
  322. package/dist/commands/dataset/embeddings/disable.js +77 -0
  323. package/dist/commands/dataset/embeddings/disable.js.map +1 -0
  324. package/dist/commands/dataset/embeddings/enable.js +141 -0
  325. package/dist/commands/dataset/embeddings/enable.js.map +1 -0
  326. package/dist/commands/dataset/embeddings/status.js +72 -0
  327. package/dist/commands/dataset/embeddings/status.js.map +1 -0
  328. package/dist/commands/dataset/export.js +25 -16
  329. package/dist/commands/dataset/export.js.map +1 -1
  330. package/dist/commands/dataset/import.js +306 -1
  331. package/dist/commands/dataset/import.js.map +1 -1
  332. package/dist/commands/dataset/list.js +22 -7
  333. package/dist/commands/dataset/list.js.map +1 -1
  334. package/dist/commands/dataset/visibility/get.js +18 -7
  335. package/dist/commands/dataset/visibility/get.js.map +1 -1
  336. package/dist/commands/dataset/visibility/set.js +22 -7
  337. package/dist/commands/dataset/visibility/set.js.map +1 -1
  338. package/dist/commands/debug.js +4 -2
  339. package/dist/commands/debug.js.map +1 -1
  340. package/dist/commands/deploy.js +22 -11
  341. package/dist/commands/deploy.js.map +1 -1
  342. package/dist/commands/dev.js +2 -4
  343. package/dist/commands/dev.js.map +1 -1
  344. package/dist/commands/doctor.js +125 -0
  345. package/dist/commands/doctor.js.map +1 -0
  346. package/dist/commands/documents/create.js +19 -12
  347. package/dist/commands/documents/create.js.map +1 -1
  348. package/dist/commands/documents/delete.js +19 -12
  349. package/dist/commands/documents/delete.js.map +1 -1
  350. package/dist/commands/documents/get.js +17 -12
  351. package/dist/commands/documents/get.js.map +1 -1
  352. package/dist/commands/documents/query.js +26 -18
  353. package/dist/commands/documents/query.js.map +1 -1
  354. package/dist/commands/documents/validate.js +32 -10
  355. package/dist/commands/documents/validate.js.map +1 -1
  356. package/dist/commands/graphql/deploy.js +58 -30
  357. package/dist/commands/graphql/deploy.js.map +1 -1
  358. package/dist/commands/graphql/list.js +15 -7
  359. package/dist/commands/graphql/list.js.map +1 -1
  360. package/dist/commands/graphql/undeploy.js +37 -19
  361. package/dist/commands/graphql/undeploy.js.map +1 -1
  362. package/dist/commands/hook/attempt.js +22 -7
  363. package/dist/commands/hook/attempt.js.map +1 -1
  364. package/dist/commands/hook/create.js +23 -8
  365. package/dist/commands/hook/create.js.map +1 -1
  366. package/dist/commands/hook/delete.js +22 -7
  367. package/dist/commands/hook/delete.js.map +1 -1
  368. package/dist/commands/hook/list.js +22 -7
  369. package/dist/commands/hook/list.js.map +1 -1
  370. package/dist/commands/hook/logs.js +21 -8
  371. package/dist/commands/hook/logs.js.map +1 -1
  372. package/dist/commands/init.js +55 -32
  373. package/dist/commands/init.js.map +1 -1
  374. package/dist/commands/login.js +19 -6
  375. package/dist/commands/login.js.map +1 -1
  376. package/dist/commands/logout.js +8 -6
  377. package/dist/commands/logout.js.map +1 -1
  378. package/dist/commands/manage.js +0 -1
  379. package/dist/commands/manage.js.map +1 -1
  380. package/dist/commands/manifest/extract.js +14 -10
  381. package/dist/commands/manifest/extract.js.map +1 -1
  382. package/dist/commands/mcp/configure.js +4 -2
  383. package/dist/commands/mcp/configure.js.map +1 -1
  384. package/dist/commands/media/create-aspect.js +4 -4
  385. package/dist/commands/media/create-aspect.js.map +1 -1
  386. package/dist/commands/media/delete-aspect.js +9 -7
  387. package/dist/commands/media/delete-aspect.js.map +1 -1
  388. package/dist/commands/media/deploy-aspect.js +22 -9
  389. package/dist/commands/media/deploy-aspect.js.map +1 -1
  390. package/dist/commands/media/export.js +9 -7
  391. package/dist/commands/media/export.js.map +1 -1
  392. package/dist/commands/media/import.js +10 -8
  393. package/dist/commands/media/import.js.map +1 -1
  394. package/dist/commands/preview.js +5 -8
  395. package/dist/commands/preview.js.map +1 -1
  396. package/dist/commands/projects/list.js +2 -1
  397. package/dist/commands/projects/list.js.map +1 -1
  398. package/dist/commands/schema/delete.js +33 -34
  399. package/dist/commands/schema/delete.js.map +1 -1
  400. package/dist/commands/schema/deploy.js +19 -30
  401. package/dist/commands/schema/deploy.js.map +1 -1
  402. package/dist/commands/schema/extract.js +32 -4
  403. package/dist/commands/schema/extract.js.map +1 -1
  404. package/dist/commands/schema/list.js +10 -31
  405. package/dist/commands/schema/list.js.map +1 -1
  406. package/dist/commands/tokens/add.js +24 -7
  407. package/dist/commands/tokens/add.js.map +1 -1
  408. package/dist/commands/tokens/delete.js +20 -7
  409. package/dist/commands/tokens/delete.js.map +1 -1
  410. package/dist/commands/tokens/list.js +20 -7
  411. package/dist/commands/tokens/list.js.map +1 -1
  412. package/dist/commands/users/invite.js +24 -7
  413. package/dist/commands/users/invite.js.map +1 -1
  414. package/dist/commands/users/list.js +76 -33
  415. package/dist/commands/users/list.js.map +1 -1
  416. package/dist/commands/versions.js +1 -1
  417. package/dist/commands/versions.js.map +1 -1
  418. package/dist/config/createCliConfig.js +1 -2
  419. package/dist/config/createCliConfig.js.map +1 -1
  420. package/dist/exports/_internal.d.ts +132 -0
  421. package/dist/exports/_internal.js +4 -0
  422. package/dist/exports/_internal.js.map +1 -0
  423. package/dist/exports/index.d.ts +113 -0
  424. package/dist/exports/index.js +6 -0
  425. package/dist/exports/index.js.map +1 -0
  426. package/dist/hooks/init/checkForUpdates.js +14 -0
  427. package/dist/hooks/init/checkForUpdates.js.map +1 -0
  428. package/dist/hooks/prerun/flushTelemetry.worker.js +1 -1
  429. package/dist/hooks/prerun/flushTelemetry.worker.js.map +1 -1
  430. package/dist/hooks/prerun/injectEnvVariables.js +9 -1
  431. package/dist/hooks/prerun/injectEnvVariables.js.map +1 -1
  432. package/dist/hooks/prerun/setupTelemetry.js +16 -10
  433. package/dist/hooks/prerun/setupTelemetry.js.map +1 -1
  434. package/dist/prompts/promptForProject.js +64 -0
  435. package/dist/prompts/promptForProject.js.map +1 -0
  436. package/dist/{actions/auth/login/promptProviders.js → prompts/promptForProviders.js} +3 -3
  437. package/dist/prompts/promptForProviders.js.map +1 -0
  438. package/dist/prompts/selectMediaLibrary.js +1 -1
  439. package/dist/prompts/selectMediaLibrary.js.map +1 -1
  440. package/dist/server/devServer.js +4 -2
  441. package/dist/server/devServer.js.map +1 -1
  442. package/dist/server/previewServer.js +2 -2
  443. package/dist/server/previewServer.js.map +1 -1
  444. package/dist/server/vite/plugin-schema-extraction.js +201 -0
  445. package/dist/server/vite/plugin-schema-extraction.js.map +1 -0
  446. package/dist/server/vite/plugin-typegen.js +217 -0
  447. package/dist/server/vite/plugin-typegen.js.map +1 -0
  448. package/dist/services/auth.js +42 -3
  449. package/dist/services/auth.js.map +1 -1
  450. package/dist/services/datasets.js +7 -5
  451. package/dist/services/datasets.js.map +1 -1
  452. package/dist/services/docs.js +2 -2
  453. package/dist/services/docs.js.map +1 -1
  454. package/dist/services/embeddings.js +25 -0
  455. package/dist/services/embeddings.js.map +1 -0
  456. package/dist/services/getUrlHeaders.js +7 -18
  457. package/dist/services/getUrlHeaders.js.map +1 -1
  458. package/dist/services/grants.js +13 -0
  459. package/dist/services/grants.js.map +1 -0
  460. package/dist/services/graphql.js +1 -1
  461. package/dist/services/graphql.js.map +1 -1
  462. package/dist/services/mcp.js +55 -1
  463. package/dist/services/mcp.js.map +1 -1
  464. package/dist/services/projects.js +4 -2
  465. package/dist/services/projects.js.map +1 -1
  466. package/dist/services/schemas.js +1 -1
  467. package/dist/services/schemas.js.map +1 -1
  468. package/dist/services/telemetry.js +2 -1
  469. package/dist/services/telemetry.js.map +1 -1
  470. package/dist/services/userApplications.js +21 -6
  471. package/dist/services/userApplications.js.map +1 -1
  472. package/dist/telemetry/extractSchema.telemetry.js +10 -0
  473. package/dist/telemetry/extractSchema.telemetry.js.map +1 -1
  474. package/dist/types/grants.js +3 -0
  475. package/dist/types/grants.js.map +1 -0
  476. package/dist/types.js +3 -0
  477. package/dist/types.js.map +1 -1
  478. package/dist/util/checkProjectPermissions.js +21 -0
  479. package/dist/util/checkProjectPermissions.js.map +1 -0
  480. package/dist/util/cliClient.js +5 -3
  481. package/dist/util/cliClient.js.map +1 -1
  482. package/dist/util/compareDependencyVersions.js +74 -38
  483. package/dist/util/compareDependencyVersions.js.map +1 -1
  484. package/dist/util/createExpiringConfig.js +64 -0
  485. package/dist/util/createExpiringConfig.js.map +1 -0
  486. package/dist/util/detectFramework.js +135 -0
  487. package/dist/util/detectFramework.js.map +1 -0
  488. package/dist/util/errorMessages.js +0 -1
  489. package/dist/util/errorMessages.js.map +1 -1
  490. package/dist/util/extractDocumentsFromNdjsonOrTarball.js +1 -2
  491. package/dist/util/extractDocumentsFromNdjsonOrTarball.js.map +1 -1
  492. package/dist/util/getCliVersion.js +1 -1
  493. package/dist/util/getCliVersion.js.map +1 -1
  494. package/dist/util/getLocalPackageVersion.js +33 -23
  495. package/dist/util/getLocalPackageVersion.js.map +1 -1
  496. package/dist/util/getProjectDefaults.js +22 -28
  497. package/dist/util/getProjectDefaults.js.map +1 -1
  498. package/dist/util/getSharedServerConfig.js +1 -0
  499. package/dist/util/getSharedServerConfig.js.map +1 -1
  500. package/dist/util/getWorkspace.js +1 -1
  501. package/dist/util/getWorkspace.js.map +1 -1
  502. package/dist/util/gitConfig.js +45 -0
  503. package/dist/util/gitConfig.js.map +1 -0
  504. package/dist/util/isSchemaError.js +11 -0
  505. package/dist/util/isSchemaError.js.map +1 -0
  506. package/dist/util/isTar.js +8 -0
  507. package/dist/util/isTar.js.map +1 -0
  508. package/dist/util/packageManager/getPeerDependencies.js +44 -0
  509. package/dist/util/packageManager/getPeerDependencies.js.map +1 -0
  510. package/dist/util/packageManager/installationInfo/analyzeIssues.js +225 -0
  511. package/dist/util/packageManager/installationInfo/analyzeIssues.js.map +1 -0
  512. package/dist/util/packageManager/installationInfo/commands.js +73 -0
  513. package/dist/util/packageManager/installationInfo/commands.js.map +1 -0
  514. package/dist/util/packageManager/installationInfo/detectCliInstallation.js +66 -0
  515. package/dist/util/packageManager/installationInfo/detectCliInstallation.js.map +1 -0
  516. package/dist/util/packageManager/installationInfo/detectGlobals.js +295 -0
  517. package/dist/util/packageManager/installationInfo/detectGlobals.js.map +1 -0
  518. package/dist/util/packageManager/installationInfo/detectPackages.js +190 -0
  519. package/dist/util/packageManager/installationInfo/detectPackages.js.map +1 -0
  520. package/dist/util/packageManager/installationInfo/detectWorkspace.js +192 -0
  521. package/dist/util/packageManager/installationInfo/detectWorkspace.js.map +1 -0
  522. package/dist/util/packageManager/installationInfo/index.js +4 -0
  523. package/dist/util/packageManager/installationInfo/index.js.map +1 -0
  524. package/dist/util/packageManager/installationInfo/readJsonFile.js +14 -0
  525. package/dist/util/packageManager/installationInfo/readJsonFile.js.map +1 -0
  526. package/dist/util/packageManager/installationInfo/resolveVersionRange.js +42 -0
  527. package/dist/util/packageManager/installationInfo/resolveVersionRange.js.map +1 -0
  528. package/dist/util/packageManager/installationInfo/types.js +3 -0
  529. package/dist/util/packageManager/installationInfo/types.js.map +1 -0
  530. package/dist/util/packageManager/packageManagerChoice.js +1 -20
  531. package/dist/util/packageManager/packageManagerChoice.js.map +1 -1
  532. package/dist/util/packageManager/upgradePackages.js +4 -1
  533. package/dist/util/packageManager/upgradePackages.js.map +1 -1
  534. package/dist/util/promiseRaceWithTimeout.js +28 -0
  535. package/dist/util/promiseRaceWithTimeout.js.map +1 -0
  536. package/dist/util/readdirRecursive.js.map +1 -1
  537. package/dist/util/resolveLatestVersions.js +2 -2
  538. package/dist/util/resolveLatestVersions.js.map +1 -1
  539. package/dist/util/sharedFlags.js +54 -0
  540. package/dist/util/sharedFlags.js.map +1 -0
  541. package/dist/util/telemetry/cleanupOldTelemetryFiles.js +30 -0
  542. package/dist/util/telemetry/cleanupOldTelemetryFiles.js.map +1 -0
  543. package/dist/util/telemetry/createTelemetryStore.js +95 -0
  544. package/dist/util/telemetry/createTelemetryStore.js.map +1 -0
  545. package/dist/util/telemetry/createTraceId.js +10 -0
  546. package/dist/util/telemetry/createTraceId.js.map +1 -0
  547. package/dist/util/telemetry/findTelemetryFiles.js +35 -0
  548. package/dist/util/telemetry/findTelemetryFiles.js.map +1 -0
  549. package/dist/util/telemetry/flushTelemetryFiles.js +118 -0
  550. package/dist/util/telemetry/flushTelemetryFiles.js.map +1 -0
  551. package/dist/util/telemetry/generateTelemetryFilePath.js +30 -0
  552. package/dist/util/telemetry/generateTelemetryFilePath.js.map +1 -0
  553. package/dist/util/telemetry/logger.js +59 -0
  554. package/dist/util/telemetry/logger.js.map +1 -0
  555. package/dist/util/telemetry/readNDJSON.js +28 -0
  556. package/dist/util/telemetry/readNDJSON.js.map +1 -0
  557. package/dist/util/telemetry/telemetryStoreDebug.js +7 -0
  558. package/dist/util/telemetry/telemetryStoreDebug.js.map +1 -0
  559. package/dist/util/telemetry/trace.js +150 -0
  560. package/dist/util/telemetry/trace.js.map +1 -0
  561. package/dist/util/toForwardSlashes.js +8 -0
  562. package/dist/util/toForwardSlashes.js.map +1 -0
  563. package/dist/util/update/fetchLatestVersion.js +21 -0
  564. package/dist/util/update/fetchLatestVersion.js.map +1 -0
  565. package/dist/util/update/getUpdateCommand.js +20 -0
  566. package/dist/util/update/getUpdateCommand.js.map +1 -0
  567. package/dist/util/update/isInstalledUsingYarn.js +17 -0
  568. package/dist/util/update/isInstalledUsingYarn.js.map +1 -0
  569. package/dist/util/update/showNotificationUpdate.js +31 -0
  570. package/dist/util/update/showNotificationUpdate.js.map +1 -0
  571. package/dist/util/update/updateChecker.js +60 -0
  572. package/dist/util/update/updateChecker.js.map +1 -0
  573. package/dist/util/update/updateCheckerDebug.js +4 -0
  574. package/dist/util/update/updateCheckerDebug.js.map +1 -0
  575. package/oclif.config.js +1 -0
  576. package/oclif.manifest.json +1285 -492
  577. package/package.json +72 -73
  578. package/static/favicons/apple-touch-icon.png +0 -0
  579. package/static/favicons/favicon-192.png +0 -0
  580. package/static/favicons/favicon-512.png +0 -0
  581. package/static/favicons/favicon-96.png +0 -0
  582. package/static/favicons/favicon.ico +0 -0
  583. package/static/favicons/favicon.svg +12 -0
  584. package/dist/actions/auth/login/promptProviders.js.map +0 -1
  585. package/dist/actions/dev/getCoreAppUrl.js +0 -10
  586. package/dist/actions/dev/getCoreAppUrl.js.map +0 -1
  587. package/dist/actions/schema/schemaStoreTypes.js +0 -19
  588. package/dist/actions/schema/schemaStoreTypes.js.map +0 -1
  589. package/dist/actions/schema/utils/manifestExtractor.js +0 -33
  590. package/dist/actions/schema/utils/manifestExtractor.js.map +0 -1
  591. package/dist/actions/schema/utils/manifestReader.js +0 -71
  592. package/dist/actions/schema/utils/manifestReader.js.map +0 -1
  593. package/dist/index.d.ts +0 -2326
  594. package/dist/index.js +0 -6
  595. package/dist/index.js.map +0 -1
  596. package/dist/studioDependencies.js.map +0 -1
  597. package/dist/typings/deepSortObject.d.js +0 -2
  598. package/dist/typings/deepSortObject.d.js.map +0 -1
  599. package/dist/util/findNdjsonEntry.js +0 -21
  600. package/dist/util/findNdjsonEntry.js.map +0 -1
  601. package/dist/util/importStudioConfig.js +0 -40
  602. package/dist/util/importStudioConfig.js.map +0 -1
  603. package/dist/util/readModuleVersion.js +0 -15
  604. package/dist/util/readModuleVersion.js.map +0 -1
  605. package/dist/util/readPackageJson.js +0 -44
  606. package/dist/util/readPackageJson.js.map +0 -1
  607. package/dist/util/readPackageManifest.js +0 -46
  608. package/dist/util/readPackageManifest.js.map +0 -1
  609. package/dist/util/uniqBy.js +0 -14
  610. package/dist/util/uniqBy.js.map +0 -1
  611. package/dist/util/workerChannels.js +0 -172
  612. package/dist/util/workerChannels.js.map +0 -1
  613. /package/dist/{studioDependencies.js → actions/init/studioDependencies.js} +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/util/packageManager/installationInfo/analyzeIssues.ts"],"sourcesContent":["import semver from 'semver'\n\nimport {\n getGlobalUninstallCommand,\n getLocalRemoveCommand,\n getLocalUpdateCommand,\n} from './commands.js'\nimport {\n type GlobalInstallation,\n type Issue,\n type LockfileType,\n type PackageInfo,\n type SanityPackage,\n type WorkspaceInfo,\n} from './types.js'\n\n/**\n * Analyzes package information and workspace configuration to detect potential issues.\n */\nexport function analyzeIssues(\n packages: Partial<Record<SanityPackage, PackageInfo>>,\n workspace: WorkspaceInfo,\n globals: GlobalInstallation[],\n): Issue[] {\n const issues: Issue[] = []\n // When multiple lockfiles exist, the \"winning\" lockfile is arbitrary (based on\n // detection priority order), so fall back to workspace-level signals instead.\n const pm: LockfileType =\n workspace.hasMultipleLockfiles || !workspace.lockfile\n ? inferPackageManager(workspace)\n : workspace.lockfile.type\n const updateOptions = {yarnBerry: workspace.yarnBerry}\n\n // Check for multiple lockfiles\n if (workspace.hasMultipleLockfiles) {\n issues.push({\n message: 'Multiple lockfiles found. This can cause inconsistent installations.',\n packageName: null,\n severity: 'warning',\n suggestion: 'Remove all but one lockfile and use a single package manager.',\n type: 'multiple-lockfiles',\n })\n }\n\n // Check each package for issues\n for (const [name, info] of Object.entries(packages) as [\n SanityPackage,\n PackageInfo | undefined,\n ][]) {\n if (!info) continue\n\n // override-in-effect\n if (info.override) {\n issues.push({\n message: `${name} has an override (${info.override.mechanism}) set to ${info.override.versionRange}.`,\n packageName: name,\n severity: 'info',\n suggestion: null,\n type: 'override-in-effect',\n })\n }\n\n // declared-not-installed — skip when an override is in effect, since the\n // override may explain the unusual state and the user already sees override-in-effect.\n // Also skip @sanity/cli when sanity is installed — the CLI-specific section below\n // produces more specific diagnostics (conflicting/redundant/cli-not-installed).\n const cliSectionWillHandle =\n name === '@sanity/cli' && Boolean(packages.sanity?.installed?.cliDependencyRange)\n if (info.declared && !info.installed && !info.override && !cliSectionWillHandle) {\n issues.push({\n message: `${name} is declared in package.json but not installed.`,\n packageName: name,\n severity: 'error',\n suggestion: `Run: ${pm} install`,\n type: 'declared-not-installed',\n })\n }\n\n // global-local-mismatch — only warn on major version differences\n // Check all global installations, not just the first match.\n // Skip @sanity/cli here — global-cli-incompatible (below) handles it with\n // better context by checking against sanity's actual required range.\n if (info.installed && name !== '@sanity/cli') {\n const localMajor = semver.parse(info.installed.version)?.major\n if (localMajor !== undefined) {\n for (const globalMatch of globals.filter((g) => g.packageName === name)) {\n const globalMajor = semver.parse(globalMatch.version)?.major\n if (globalMajor !== undefined && globalMajor !== localMajor) {\n issues.push({\n message: `${name} version mismatch: global ${globalMatch.version} (${globalMatch.packageManager}) vs local ${info.installed.version}.`,\n packageName: name,\n severity: globalMatch.isActive ? 'warning' : 'info',\n suggestion: `Run: ${getGlobalUninstallCommand(globalMatch.packageManager, name)}`,\n type: 'global-local-mismatch',\n })\n }\n }\n }\n }\n }\n\n // Check @sanity/cli compatibility with sanity\n const sanityInfo = packages.sanity\n const cliInfo = packages['@sanity/cli']\n\n if (sanityInfo?.installed?.cliDependencyRange) {\n const expectedCliRange = sanityInfo.installed.cliDependencyRange\n // Normalize pinned versions (e.g. \"5.33.0\" → \"^5.33.0\") for satisfies checks.\n // Already-ranged values like \"^5.33.0\" pass through unchanged.\n // Note: sanity always uses caret ranges in practice. The pinned→caret conversion\n // is a defensive fallback — if sanity ever pinned an exact version, caret semantics\n // (any compatible minor/patch) are the expected behavior for CLI compatibility.\n const compatRange = toCaretRange(expectedCliRange)\n\n // Check if @sanity/cli is explicitly declared with an incompatible version.\n // Skip when the declared range uses a non-semver protocol (workspace:*, file:,\n // portal:, link:) — these are local package references, not version conflicts.\n if (cliInfo?.declared && !isNonSemverProtocol(cliInfo.declared.versionRange)) {\n const declaredRange = cliInfo.declared.versionRange\n // Only flag as redundant when every version in the declared range also\n // satisfies the required range. semver.subset('^5.0.0', '^5.33.0') → false,\n // so a too-wide range is correctly classified as conflicting.\n if (safeSubset(declaredRange, expectedCliRange)) {\n issues.push({\n message: `@sanity/cli is listed as a dependency but is already provided by sanity. Remove it to avoid version conflicts.`,\n packageName: '@sanity/cli',\n severity: 'info',\n suggestion: `Run: ${getLocalRemoveCommand(pm, '@sanity/cli')}`,\n type: 'redundant-cli-dependency',\n })\n } else {\n issues.push({\n message: `@sanity/cli is declared as ${declaredRange} but sanity requires ${expectedCliRange}. Sanity provides @sanity/cli automatically — removing the explicit declaration lets sanity manage the correct version.`,\n packageName: '@sanity/cli',\n severity: 'error',\n suggestion: `Run: ${getLocalRemoveCommand(pm, '@sanity/cli')}`,\n type: 'conflicting-cli-dependency',\n })\n }\n }\n\n // Check if installed @sanity/cli satisfies sanity's requirement.\n // Skip if we already flagged a conflicting declaration — that's the root cause.\n // Skip if an override is in effect — the user already knows about it, and\n // suggesting an update would be misleading since the override controls the version.\n const hasConflictingDeclaration = issues.some((i) => i.type === 'conflicting-cli-dependency')\n if (cliInfo?.installed && !hasConflictingDeclaration && !cliInfo.override) {\n const installedVersion = cliInfo.installed.version\n if (!safeSatisfies(installedVersion, compatRange)) {\n issues.push({\n message: `Installed @sanity/cli@${installedVersion} does not satisfy sanity's requirement of ${compatRange}.`,\n packageName: '@sanity/cli',\n severity: 'error',\n suggestion: `Run: ${getLocalUpdateCommand(pm, '@sanity/cli', updateOptions)}`,\n type: 'cli-version-incompatible',\n })\n }\n }\n\n // Check if @sanity/cli is missing entirely (not declared, not installed)\n // This indicates a broken node_modules state since sanity depends on @sanity/cli.\n if (!cliInfo?.installed && !cliInfo?.declared && !cliInfo?.override) {\n issues.push({\n message: `@sanity/cli is not installed. It is required by sanity@${sanityInfo.installed.version}.`,\n packageName: '@sanity/cli',\n severity: 'error',\n suggestion: `Run: ${pm} install`,\n type: 'cli-not-installed',\n })\n }\n\n // Check global @sanity/cli compatibility with local sanity\n for (const global of globals) {\n if (global.packageName !== '@sanity/cli') continue\n\n if (!safeSatisfies(global.version, compatRange)) {\n issues.push({\n message: `Global @sanity/cli@${global.version} (installed via ${global.packageManager}) is incompatible with local sanity@${sanityInfo.installed.version} (requires @sanity/cli ${compatRange}).`,\n packageName: '@sanity/cli',\n severity: global.isActive ? 'warning' : 'info',\n suggestion: `Run: ${getGlobalUninstallCommand(global.packageManager, '@sanity/cli')}`,\n type: 'global-cli-incompatible',\n })\n }\n }\n }\n\n return issues\n}\n\n/**\n * Protocols and prefixes that are not semver ranges.\n * Includes local package references (workspace:, file:, portal:, link:),\n * catalog: which may appear as an unresolved range when pnpm catalog lookup fails,\n * and git/URL-based dependency specifiers.\n */\nconst NON_SEMVER_PROTOCOLS = [\n 'workspace:',\n 'file:',\n 'portal:',\n 'link:',\n 'catalog:',\n 'git+',\n 'git:',\n 'github:',\n 'https:',\n 'http:',\n]\n\nfunction isNonSemverProtocol(range: string): boolean {\n return NON_SEMVER_PROTOCOLS.some((p) => range.startsWith(p))\n}\n\n/**\n * Infers the package manager from workspace info when no lockfile is present.\n * Uses both the workspace type (which captures workspace config markers like\n * pnpm-workspace.yaml) and the yarnBerry flag (which captures .yarnrc.yml\n * even for standalone projects).\n */\nfunction inferPackageManager(workspace: WorkspaceInfo): LockfileType {\n if (workspace.type.startsWith('pnpm')) return 'pnpm'\n if (workspace.type.startsWith('yarn')) return 'yarn'\n if (workspace.type.startsWith('bun')) return 'bun'\n if (workspace.yarnBerry) return 'yarn'\n if (workspace.bunfig) return 'bun'\n return 'npm'\n}\n\n/**\n * Safe wrapper around semver.satisfies that returns false for non-semver\n * versions or ranges (workspace:*, catalog:, file:, git URLs) instead of throwing.\n * Uses includePrerelease so that pre-release versions (e.g. 5.0.0-rc.1) are\n * correctly matched against caret ranges like ^5.0.0-rc.1.\n */\nfunction safeSatisfies(version: string, range: string): boolean {\n try {\n return semver.satisfies(version, range, {includePrerelease: true})\n } catch {\n return false\n }\n}\n\n/**\n * Safe wrapper around semver.subset that returns false for non-semver ranges\n * like workspace:*, catalog:, file:, or git URLs instead of throwing.\n */\nfunction safeSubset(sub: string, sup: string): boolean {\n try {\n return semver.subset(sub, sup) ?? false\n } catch {\n return false\n }\n}\n\n/**\n * Converts a pinned version like \"5.33.0\" to \"^5.33.0\".\n * If it's already a range (^, ~, \\>=, etc.), returns as-is.\n */\nfunction toCaretRange(range: string): string {\n // If it's already a range operator, return as-is\n if (/^[\\^~><!=]/.test(range) || range.includes(' ')) {\n return range\n }\n // If it's a plain version like \"5.33.0\", treat as ^5.33.0\n if (semver.valid(range)) {\n return `^${range}`\n }\n return range\n}\n"],"names":["semver","getGlobalUninstallCommand","getLocalRemoveCommand","getLocalUpdateCommand","analyzeIssues","packages","workspace","globals","issues","pm","hasMultipleLockfiles","lockfile","inferPackageManager","type","updateOptions","yarnBerry","push","message","packageName","severity","suggestion","name","info","Object","entries","override","mechanism","versionRange","cliSectionWillHandle","Boolean","sanity","installed","cliDependencyRange","declared","localMajor","parse","version","major","undefined","globalMatch","filter","g","globalMajor","packageManager","isActive","sanityInfo","cliInfo","expectedCliRange","compatRange","toCaretRange","isNonSemverProtocol","declaredRange","safeSubset","hasConflictingDeclaration","some","i","installedVersion","safeSatisfies","global","NON_SEMVER_PROTOCOLS","range","p","startsWith","bunfig","satisfies","includePrerelease","sub","sup","subset","test","includes","valid"],"mappings":"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"}
@@ -0,0 +1,73 @@
1
+ import { getYarnMajorVersion } from '@sanity/cli-core/package-manager';
2
+ export function getGlobalUninstallCommand(pm, packageName) {
3
+ switch(pm){
4
+ case 'bun':
5
+ {
6
+ return `bun remove -g ${packageName}`;
7
+ }
8
+ case 'npm':
9
+ {
10
+ return `npm uninstall -g ${packageName}`;
11
+ }
12
+ case 'pnpm':
13
+ {
14
+ return `pnpm remove -g ${packageName}`;
15
+ }
16
+ case 'yarn':
17
+ {
18
+ // The pm is 'yarn' because queryYarnGlobals found the package, meaning
19
+ // it was installed with Yarn Classic (`yarn global add`). Only Yarn
20
+ // Classic can uninstall it — the project's yarn version is irrelevant.
21
+ return `yarn global remove ${packageName}`;
22
+ }
23
+ }
24
+ }
25
+ export function getLocalUpdateCommand(pm, packageName, options) {
26
+ switch(pm){
27
+ case 'bun':
28
+ {
29
+ return `bun update ${packageName}`;
30
+ }
31
+ case 'npm':
32
+ {
33
+ return `npm update ${packageName}`;
34
+ }
35
+ case 'pnpm':
36
+ {
37
+ return `pnpm update ${packageName}`;
38
+ }
39
+ case 'yarn':
40
+ {
41
+ // Prefer project-level detection (.yarnrc.yml) over process user-agent,
42
+ // since the doctor command may be invoked via a different package manager.
43
+ const isBerry = options?.yarnBerry ?? isYarnBerryFromProcess();
44
+ return `yarn ${isBerry ? 'up' : 'upgrade'} ${packageName}`;
45
+ }
46
+ }
47
+ }
48
+ function isYarnBerryFromProcess() {
49
+ const yarnMajor = getYarnMajorVersion();
50
+ return yarnMajor !== undefined && yarnMajor >= 2;
51
+ }
52
+ export function getLocalRemoveCommand(pm, packageName) {
53
+ switch(pm){
54
+ case 'bun':
55
+ {
56
+ return `bun remove ${packageName}`;
57
+ }
58
+ case 'npm':
59
+ {
60
+ return `npm uninstall ${packageName}`;
61
+ }
62
+ case 'pnpm':
63
+ {
64
+ return `pnpm remove ${packageName}`;
65
+ }
66
+ case 'yarn':
67
+ {
68
+ return `yarn remove ${packageName}`;
69
+ }
70
+ }
71
+ }
72
+
73
+ //# sourceMappingURL=commands.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/util/packageManager/installationInfo/commands.ts"],"sourcesContent":["import {getYarnMajorVersion} from '@sanity/cli-core/package-manager'\n\nimport {type LockfileType} from './types.js'\n\ninterface CommandOptions {\n /** Whether the project uses Yarn Berry (v2+), determined from .yarnrc.yml. */\n yarnBerry?: boolean\n}\n\nexport function getGlobalUninstallCommand(pm: LockfileType, packageName: string): string {\n switch (pm) {\n case 'bun': {\n return `bun remove -g ${packageName}`\n }\n case 'npm': {\n return `npm uninstall -g ${packageName}`\n }\n case 'pnpm': {\n return `pnpm remove -g ${packageName}`\n }\n case 'yarn': {\n // The pm is 'yarn' because queryYarnGlobals found the package, meaning\n // it was installed with Yarn Classic (`yarn global add`). Only Yarn\n // Classic can uninstall it — the project's yarn version is irrelevant.\n return `yarn global remove ${packageName}`\n }\n }\n}\n\nexport function getLocalUpdateCommand(\n pm: LockfileType,\n packageName: string,\n options?: CommandOptions,\n): string {\n switch (pm) {\n case 'bun': {\n return `bun update ${packageName}`\n }\n case 'npm': {\n return `npm update ${packageName}`\n }\n case 'pnpm': {\n return `pnpm update ${packageName}`\n }\n case 'yarn': {\n // Prefer project-level detection (.yarnrc.yml) over process user-agent,\n // since the doctor command may be invoked via a different package manager.\n const isBerry = options?.yarnBerry ?? isYarnBerryFromProcess()\n return `yarn ${isBerry ? 'up' : 'upgrade'} ${packageName}`\n }\n }\n}\n\nfunction isYarnBerryFromProcess(): boolean {\n const yarnMajor = getYarnMajorVersion()\n return yarnMajor !== undefined && yarnMajor >= 2\n}\n\nexport function getLocalRemoveCommand(pm: LockfileType, packageName: string): string {\n switch (pm) {\n case 'bun': {\n return `bun remove ${packageName}`\n }\n case 'npm': {\n return `npm uninstall ${packageName}`\n }\n case 'pnpm': {\n return `pnpm remove ${packageName}`\n }\n case 'yarn': {\n return `yarn remove ${packageName}`\n }\n }\n}\n"],"names":["getYarnMajorVersion","getGlobalUninstallCommand","pm","packageName","getLocalUpdateCommand","options","isBerry","yarnBerry","isYarnBerryFromProcess","yarnMajor","undefined","getLocalRemoveCommand"],"mappings":"AAAA,SAAQA,mBAAmB,QAAO,mCAAkC;AASpE,OAAO,SAASC,0BAA0BC,EAAgB,EAAEC,WAAmB;IAC7E,OAAQD;QACN,KAAK;YAAO;gBACV,OAAO,CAAC,cAAc,EAAEC,aAAa;YACvC;QACA,KAAK;YAAO;gBACV,OAAO,CAAC,iBAAiB,EAAEA,aAAa;YAC1C;QACA,KAAK;YAAQ;gBACX,OAAO,CAAC,eAAe,EAAEA,aAAa;YACxC;QACA,KAAK;YAAQ;gBACX,uEAAuE;gBACvE,oEAAoE;gBACpE,uEAAuE;gBACvE,OAAO,CAAC,mBAAmB,EAAEA,aAAa;YAC5C;IACF;AACF;AAEA,OAAO,SAASC,sBACdF,EAAgB,EAChBC,WAAmB,EACnBE,OAAwB;IAExB,OAAQH;QACN,KAAK;YAAO;gBACV,OAAO,CAAC,WAAW,EAAEC,aAAa;YACpC;QACA,KAAK;YAAO;gBACV,OAAO,CAAC,WAAW,EAAEA,aAAa;YACpC;QACA,KAAK;YAAQ;gBACX,OAAO,CAAC,YAAY,EAAEA,aAAa;YACrC;QACA,KAAK;YAAQ;gBACX,wEAAwE;gBACxE,2EAA2E;gBAC3E,MAAMG,UAAUD,SAASE,aAAaC;gBACtC,OAAO,CAAC,KAAK,EAAEF,UAAU,OAAO,UAAU,CAAC,EAAEH,aAAa;YAC5D;IACF;AACF;AAEA,SAASK;IACP,MAAMC,YAAYT;IAClB,OAAOS,cAAcC,aAAaD,aAAa;AACjD;AAEA,OAAO,SAASE,sBAAsBT,EAAgB,EAAEC,WAAmB;IACzE,OAAQD;QACN,KAAK;YAAO;gBACV,OAAO,CAAC,WAAW,EAAEC,aAAa;YACpC;QACA,KAAK;YAAO;gBACV,OAAO,CAAC,cAAc,EAAEA,aAAa;YACvC;QACA,KAAK;YAAQ;gBACX,OAAO,CAAC,YAAY,EAAEA,aAAa;YACrC;QACA,KAAK;YAAQ;gBACX,OAAO,CAAC,YAAY,EAAEA,aAAa;YACrC;IACF;AACF"}
@@ -0,0 +1,66 @@
1
+ import { getRunningPackageManager } from '@sanity/cli-core/package-manager';
2
+ import { analyzeIssues } from './analyzeIssues.js';
3
+ import { detectGlobalInstallations } from './detectGlobals.js';
4
+ import { collectPackageInfo } from './detectPackages.js';
5
+ import { detectWorkspace } from './detectWorkspace.js';
6
+ const SANITY_PACKAGES = [
7
+ 'sanity',
8
+ '@sanity/cli'
9
+ ];
10
+ /**
11
+ * Main entry point for detecting CLI installation status.
12
+ * Gathers information about workspace configuration, package declarations,
13
+ * installed versions, global installations, and potential issues.
14
+ */ export async function detectCliInstallation(options) {
15
+ const cwd = options?.cwd ?? process.cwd();
16
+ // Run detection in parallel where possible
17
+ const [workspace, globalInstallations] = await Promise.all([
18
+ detectWorkspace(cwd),
19
+ detectGlobalInstallations()
20
+ ]);
21
+ // Collect package info for both sanity packages
22
+ const packageInfoResults = await Promise.all(SANITY_PACKAGES.map(async (name)=>{
23
+ const info = await collectPackageInfo(name, cwd, workspace);
24
+ return [
25
+ name,
26
+ info
27
+ ];
28
+ }));
29
+ const packages = Object.fromEntries(packageInfoResults.filter(([, info])=>info.declared || info.override || info.installed));
30
+ // Detect execution context
31
+ const currentExecution = detectExecutionContext(globalInstallations);
32
+ // Analyze for issues
33
+ const issues = analyzeIssues(packages, workspace, globalInstallations);
34
+ return {
35
+ currentExecution,
36
+ globalInstallations,
37
+ issues,
38
+ packages,
39
+ workspace
40
+ };
41
+ }
42
+ function detectExecutionContext(globalInstallations) {
43
+ // Try to determine how we're running
44
+ const binaryPath = process.argv[1] ?? null;
45
+ // Check npm_config_user_agent for package manager
46
+ const packageManager = getRunningPackageManager() ?? null;
47
+ // Determine if we're running from global, local, or npx
48
+ let resolvedFrom = 'unknown';
49
+ if (binaryPath) {
50
+ // Check if running via npx
51
+ if (process.env.npm_execpath?.includes('npx') || binaryPath.includes('/_npx/') || binaryPath.includes('\\_npx\\')) {
52
+ resolvedFrom = 'npx';
53
+ } else if (binaryPath.includes('node_modules')) {
54
+ resolvedFrom = 'local';
55
+ } else if (globalInstallations.some((g)=>g.isActive)) {
56
+ resolvedFrom = 'global';
57
+ }
58
+ }
59
+ return {
60
+ binaryPath,
61
+ packageManager,
62
+ resolvedFrom
63
+ };
64
+ }
65
+
66
+ //# sourceMappingURL=detectCliInstallation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/util/packageManager/installationInfo/detectCliInstallation.ts"],"sourcesContent":["import {getRunningPackageManager} from '@sanity/cli-core/package-manager'\n\nimport {analyzeIssues} from './analyzeIssues.js'\nimport {detectGlobalInstallations} from './detectGlobals.js'\nimport {collectPackageInfo} from './detectPackages.js'\nimport {detectWorkspace} from './detectWorkspace.js'\nimport {type CliInstallationInfo, type ExecutionContext, type SanityPackage} from './types.js'\n\nconst SANITY_PACKAGES: SanityPackage[] = ['sanity', '@sanity/cli']\n\ninterface DetectCliInstallationOptions {\n cwd?: string\n}\n\n/**\n * Main entry point for detecting CLI installation status.\n * Gathers information about workspace configuration, package declarations,\n * installed versions, global installations, and potential issues.\n */\nexport async function detectCliInstallation(\n options?: DetectCliInstallationOptions,\n): Promise<CliInstallationInfo> {\n const cwd = options?.cwd ?? process.cwd()\n\n // Run detection in parallel where possible\n const [workspace, globalInstallations] = await Promise.all([\n detectWorkspace(cwd),\n detectGlobalInstallations(),\n ])\n\n // Collect package info for both sanity packages\n const packageInfoResults = await Promise.all(\n SANITY_PACKAGES.map(async (name) => {\n const info = await collectPackageInfo(name, cwd, workspace)\n return [name, info] as const\n }),\n )\n\n const packages: Partial<Record<SanityPackage, CliInstallationInfo['packages'][SanityPackage]>> =\n Object.fromEntries(\n packageInfoResults.filter(([, info]) => info.declared || info.override || info.installed),\n )\n\n // Detect execution context\n const currentExecution = detectExecutionContext(globalInstallations)\n\n // Analyze for issues\n const issues = analyzeIssues(packages, workspace, globalInstallations)\n\n return {\n currentExecution,\n globalInstallations,\n issues,\n packages,\n workspace,\n }\n}\n\nfunction detectExecutionContext(\n globalInstallations: CliInstallationInfo['globalInstallations'],\n): ExecutionContext {\n // Try to determine how we're running\n const binaryPath = process.argv[1] ?? null\n\n // Check npm_config_user_agent for package manager\n const packageManager: ExecutionContext['packageManager'] = getRunningPackageManager() ?? null\n\n // Determine if we're running from global, local, or npx\n let resolvedFrom: ExecutionContext['resolvedFrom'] = 'unknown'\n\n if (binaryPath) {\n // Check if running via npx\n if (\n process.env.npm_execpath?.includes('npx') ||\n binaryPath.includes('/_npx/') ||\n binaryPath.includes('\\\\_npx\\\\')\n ) {\n resolvedFrom = 'npx'\n }\n // Check if running from node_modules (local install).\n // process.argv[1] for npm globals is the symlink path (e.g. /usr/local/bin/sanity),\n // not the resolved target, so this won't match global installs.\n else if (binaryPath.includes('node_modules')) {\n resolvedFrom = 'local'\n }\n // Fallback: if there's an active global installation, classify as global.\n // This covers all PM-specific bin paths (npm, pnpm, yarn, bun) since\n // markActiveInstallation already identifies the active PM using bin dir checks.\n else if (globalInstallations.some((g) => g.isActive)) {\n resolvedFrom = 'global'\n }\n }\n\n return {\n binaryPath,\n packageManager,\n resolvedFrom,\n }\n}\n"],"names":["getRunningPackageManager","analyzeIssues","detectGlobalInstallations","collectPackageInfo","detectWorkspace","SANITY_PACKAGES","detectCliInstallation","options","cwd","process","workspace","globalInstallations","Promise","all","packageInfoResults","map","name","info","packages","Object","fromEntries","filter","declared","override","installed","currentExecution","detectExecutionContext","issues","binaryPath","argv","packageManager","resolvedFrom","env","npm_execpath","includes","some","g","isActive"],"mappings":"AAAA,SAAQA,wBAAwB,QAAO,mCAAkC;AAEzE,SAAQC,aAAa,QAAO,qBAAoB;AAChD,SAAQC,yBAAyB,QAAO,qBAAoB;AAC5D,SAAQC,kBAAkB,QAAO,sBAAqB;AACtD,SAAQC,eAAe,QAAO,uBAAsB;AAGpD,MAAMC,kBAAmC;IAAC;IAAU;CAAc;AAMlE;;;;CAIC,GACD,OAAO,eAAeC,sBACpBC,OAAsC;IAEtC,MAAMC,MAAMD,SAASC,OAAOC,QAAQD,GAAG;IAEvC,2CAA2C;IAC3C,MAAM,CAACE,WAAWC,oBAAoB,GAAG,MAAMC,QAAQC,GAAG,CAAC;QACzDT,gBAAgBI;QAChBN;KACD;IAED,gDAAgD;IAChD,MAAMY,qBAAqB,MAAMF,QAAQC,GAAG,CAC1CR,gBAAgBU,GAAG,CAAC,OAAOC;QACzB,MAAMC,OAAO,MAAMd,mBAAmBa,MAAMR,KAAKE;QACjD,OAAO;YAACM;YAAMC;SAAK;IACrB;IAGF,MAAMC,WACJC,OAAOC,WAAW,CAChBN,mBAAmBO,MAAM,CAAC,CAAC,GAAGJ,KAAK,GAAKA,KAAKK,QAAQ,IAAIL,KAAKM,QAAQ,IAAIN,KAAKO,SAAS;IAG5F,2BAA2B;IAC3B,MAAMC,mBAAmBC,uBAAuBf;IAEhD,qBAAqB;IACrB,MAAMgB,SAAS1B,cAAciB,UAAUR,WAAWC;IAElD,OAAO;QACLc;QACAd;QACAgB;QACAT;QACAR;IACF;AACF;AAEA,SAASgB,uBACPf,mBAA+D;IAE/D,qCAAqC;IACrC,MAAMiB,aAAanB,QAAQoB,IAAI,CAAC,EAAE,IAAI;IAEtC,kDAAkD;IAClD,MAAMC,iBAAqD9B,8BAA8B;IAEzF,wDAAwD;IACxD,IAAI+B,eAAiD;IAErD,IAAIH,YAAY;QACd,2BAA2B;QAC3B,IACEnB,QAAQuB,GAAG,CAACC,YAAY,EAAEC,SAAS,UACnCN,WAAWM,QAAQ,CAAC,aACpBN,WAAWM,QAAQ,CAAC,aACpB;YACAH,eAAe;QACjB,OAIK,IAAIH,WAAWM,QAAQ,CAAC,iBAAiB;YAC5CH,eAAe;QACjB,OAIK,IAAIpB,oBAAoBwB,IAAI,CAAC,CAACC,IAAMA,EAAEC,QAAQ,GAAG;YACpDN,eAAe;QACjB;IACF;IAEA,OAAO;QACLH;QACAE;QACAC;IACF;AACF"}
@@ -0,0 +1,295 @@
1
+ import path from 'node:path';
2
+ import { execa } from 'execa';
3
+ import which from 'which';
4
+ const SANITY_PACKAGES = [
5
+ 'sanity',
6
+ '@sanity/cli'
7
+ ];
8
+ /**
9
+ * Tries to parse JSON from command output that may contain non-JSON prefix lines
10
+ * (e.g. npm warnings printed before JSON). Returns null if parsing fails.
11
+ */ function tryParseJson(stdout) {
12
+ // First, try parsing the full output
13
+ try {
14
+ return JSON.parse(stdout);
15
+ } catch {
16
+ // Fall through
17
+ }
18
+ // Try to find the start of JSON content (first { or [)
19
+ const jsonStart = stdout.search(/[{[]/);
20
+ if (jsonStart > 0) {
21
+ try {
22
+ return JSON.parse(stdout.slice(jsonStart));
23
+ } catch {
24
+ // Fall through
25
+ }
26
+ }
27
+ return null;
28
+ }
29
+ /**
30
+ * Detects global installations of sanity and \@sanity/cli across all package managers.
31
+ * Runs queries in parallel for efficiency.
32
+ */ export async function detectGlobalInstallations() {
33
+ // Query all package managers in parallel
34
+ const [activeBinaryPath, npmResult, pnpmResult, yarnGlobals, bunGlobals] = await Promise.all([
35
+ // Find which binary is active in PATH
36
+ findActiveBinaryPath(),
37
+ queryNpmGlobals(),
38
+ queryPnpmGlobals(),
39
+ queryYarnGlobals(),
40
+ queryBunGlobals()
41
+ ]);
42
+ const allGlobals = [
43
+ ...npmResult.globals,
44
+ ...pnpmResult.globals,
45
+ ...yarnGlobals,
46
+ ...bunGlobals
47
+ ];
48
+ // Mark which installation is active
49
+ return markActiveInstallation(allGlobals, activeBinaryPath, npmResult.libDir, pnpmResult.binDir);
50
+ }
51
+ async function findActiveBinaryPath() {
52
+ try {
53
+ return await which('sanity');
54
+ } catch {
55
+ return null;
56
+ }
57
+ }
58
+ async function queryNpmGlobals() {
59
+ try {
60
+ const result = await execa('npm', [
61
+ 'list',
62
+ '-g',
63
+ '--depth=0',
64
+ '--json'
65
+ ], {
66
+ reject: false,
67
+ timeout: 10_000
68
+ });
69
+ if (!result.stdout) {
70
+ return {
71
+ globals: [],
72
+ libDir: null
73
+ };
74
+ }
75
+ const output = tryParseJson(result.stdout);
76
+ if (!output) {
77
+ return {
78
+ globals: [],
79
+ libDir: null
80
+ };
81
+ }
82
+ const globals = [];
83
+ for (const pkg of SANITY_PACKAGES){
84
+ const dep = output.dependencies?.[pkg];
85
+ if (dep) {
86
+ globals.push({
87
+ isActive: false,
88
+ packageManager: 'npm',
89
+ packageName: pkg,
90
+ // npm's `resolved` is a tarball URL, not a filesystem path.
91
+ path: null,
92
+ version: dep.version
93
+ });
94
+ }
95
+ }
96
+ return {
97
+ globals,
98
+ libDir: output.path ?? null
99
+ };
100
+ } catch {
101
+ return {
102
+ globals: [],
103
+ libDir: null
104
+ };
105
+ }
106
+ }
107
+ async function queryPnpmGlobals() {
108
+ try {
109
+ // Query pnpm global bin dir and global packages in parallel
110
+ const [binResult, listResult] = await Promise.all([
111
+ execa('pnpm', [
112
+ 'bin',
113
+ '-g'
114
+ ], {
115
+ reject: false,
116
+ timeout: 10_000
117
+ }),
118
+ execa('pnpm', [
119
+ 'list',
120
+ '-g',
121
+ '--depth=0',
122
+ '--json'
123
+ ], {
124
+ reject: false,
125
+ timeout: 10_000
126
+ })
127
+ ]);
128
+ const binDir = binResult.stdout?.trim() || null;
129
+ if (!listResult.stdout) {
130
+ return {
131
+ binDir,
132
+ globals: []
133
+ };
134
+ }
135
+ const output = tryParseJson(listResult.stdout);
136
+ if (!output) {
137
+ return {
138
+ binDir,
139
+ globals: []
140
+ };
141
+ }
142
+ const globals = [];
143
+ for (const project of output){
144
+ if (!project.dependencies) continue;
145
+ for (const pkg of SANITY_PACKAGES){
146
+ const dep = project.dependencies[pkg];
147
+ if (dep) {
148
+ globals.push({
149
+ isActive: false,
150
+ packageManager: 'pnpm',
151
+ packageName: pkg,
152
+ path: dep.path || null,
153
+ version: dep.version
154
+ });
155
+ }
156
+ }
157
+ }
158
+ return {
159
+ binDir,
160
+ globals
161
+ };
162
+ } catch {
163
+ return {
164
+ binDir: null,
165
+ globals: []
166
+ };
167
+ }
168
+ }
169
+ async function queryYarnGlobals() {
170
+ // `yarn global list` only works with Yarn Classic (v1).
171
+ // Yarn Berry (v2+) removed global installs entirely — the command errors or
172
+ // produces no output. Because `reject: false` is set, the call returns
173
+ // empty stdout and we gracefully return []. This means Yarn Berry global
174
+ // installations (if any exist via third-party plugins) are invisible here.
175
+ // A version check (via getYarnMajorVersion) could skip the call entirely,
176
+ // but since it already degrades gracefully the cost is just a failed exec.
177
+ try {
178
+ const result = await execa('yarn', [
179
+ 'global',
180
+ 'list',
181
+ '--json'
182
+ ], {
183
+ reject: false,
184
+ timeout: 10_000
185
+ });
186
+ if (!result.stdout) {
187
+ return [];
188
+ }
189
+ // Yarn outputs NDJSON - one JSON object per line
190
+ const globals = [];
191
+ const lines = result.stdout.split('\n').filter(Boolean);
192
+ for (const line of lines){
193
+ try {
194
+ const entry = JSON.parse(line);
195
+ if (entry.type === 'info' && entry.data) {
196
+ // Yarn classic emits: "\"sanity@3.67.0\" has binaries:\n - sanity"
197
+ // Extract the quoted "package@version" portion.
198
+ for (const pkg of SANITY_PACKAGES){
199
+ const prefix = `"${pkg}@`;
200
+ if (entry.data.startsWith(prefix)) {
201
+ const closingQuote = entry.data.indexOf('"', prefix.length);
202
+ if (closingQuote !== -1) {
203
+ globals.push({
204
+ isActive: false,
205
+ packageManager: 'yarn',
206
+ packageName: pkg,
207
+ path: null,
208
+ version: entry.data.slice(prefix.length, closingQuote)
209
+ });
210
+ }
211
+ }
212
+ }
213
+ }
214
+ } catch {
215
+ // Skip malformed lines
216
+ }
217
+ }
218
+ return globals;
219
+ } catch {
220
+ return [];
221
+ }
222
+ }
223
+ // As of Bun 1.2, `bun pm ls` does not support --json or -g flags.
224
+ // Skip the subprocess call entirely to avoid wasted latency on every run.
225
+ // Re-enable when bun implements JSON output (see oven-sh/bun#26222).
226
+ async function queryBunGlobals() {
227
+ return [];
228
+ }
229
+ function markActiveInstallation(globals, activeBinaryPath, npmLibDir, pnpmBinDir) {
230
+ if (!activeBinaryPath) {
231
+ return globals;
232
+ }
233
+ // Determine which package manager the active binary belongs to.
234
+ // For npm and pnpm, we verify against their actual reported directories
235
+ // rather than relying on path substring matching which breaks with
236
+ // custom install locations.
237
+ let activePackageManager = null;
238
+ // bun — check default ~/.bun/ path, then fall back to BUN_INSTALL env var
239
+ // for users with a custom installation directory.
240
+ if (isInBunDir(activeBinaryPath)) {
241
+ activePackageManager = 'bun';
242
+ } else if (pnpmBinDir && isInPnpmBinDir(activeBinaryPath, pnpmBinDir)) {
243
+ activePackageManager = 'pnpm';
244
+ } else if (activeBinaryPath.includes('/.yarn/') || activeBinaryPath.includes('\\.yarn\\') || activeBinaryPath.includes('/.config/yarn/')) {
245
+ activePackageManager = 'yarn';
246
+ } else if (npmLibDir && isInNpmBinDir(activeBinaryPath, npmLibDir)) {
247
+ activePackageManager = 'npm';
248
+ }
249
+ return globals.map((g)=>({
250
+ ...g,
251
+ // Mark as active if it's from the detected package manager.
252
+ // Both `sanity` and `@sanity/cli` provide a `sanity` binary,
253
+ // so either package from the active pm is considered active.
254
+ isActive: g.packageManager === activePackageManager
255
+ }));
256
+ }
257
+ /**
258
+ * Checks whether a binary path is inside pnpm's global bin directory.
259
+ * `pnpm bin -g` returns the directory where global binaries are linked.
260
+ */ function isInPnpmBinDir(binaryPath, pnpmBinDir) {
261
+ const binaryDir = path.dirname(path.normalize(binaryPath));
262
+ return binaryDir === path.normalize(pnpmBinDir);
263
+ }
264
+ /**
265
+ * Checks whether a binary path is inside npm's global bin directory.
266
+ * On Unix: lib is at `<prefix>/lib`, bins at `<prefix>/bin` (sibling dirs).
267
+ * On Windows: lib and bins share the same directory.
268
+ */ function isInBunDir(binaryPath) {
269
+ // Default ~/.bun/ location
270
+ if (binaryPath.includes('/.bun/') || binaryPath.includes('\\.bun\\')) {
271
+ return true;
272
+ }
273
+ // Custom BUN_INSTALL directory (e.g. BUN_INSTALL=/opt/bun)
274
+ const bunInstall = process.env.BUN_INSTALL;
275
+ if (bunInstall) {
276
+ const binaryDir = path.dirname(path.normalize(binaryPath));
277
+ const bunBinDir = path.join(path.normalize(bunInstall), 'bin');
278
+ if (binaryDir === bunBinDir) {
279
+ return true;
280
+ }
281
+ }
282
+ return false;
283
+ }
284
+ function isInNpmBinDir(binaryPath, npmLibDir) {
285
+ // Normalize paths first — on Windows, path.dirname preserves forward slashes
286
+ // but path.join converts to backslashes, causing mismatches without this.
287
+ const binaryDir = path.dirname(path.normalize(binaryPath));
288
+ const normalizedLibDir = path.normalize(npmLibDir);
289
+ // Unix: bins at <prefix>/bin, lib at <prefix>/lib → sibling directories
290
+ const unixBinDir = path.join(path.dirname(normalizedLibDir), 'bin');
291
+ // Windows: bins and lib share the same directory
292
+ return binaryDir === unixBinDir || binaryDir === normalizedLibDir;
293
+ }
294
+
295
+ //# sourceMappingURL=detectGlobals.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/util/packageManager/installationInfo/detectGlobals.ts"],"sourcesContent":["import path from 'node:path'\n\nimport {execa} from 'execa'\nimport which from 'which'\n\nimport {type GlobalInstallation, type LockfileType, type SanityPackage} from './types.js'\n\nconst SANITY_PACKAGES: SanityPackage[] = ['sanity', '@sanity/cli']\n\n/**\n * Tries to parse JSON from command output that may contain non-JSON prefix lines\n * (e.g. npm warnings printed before JSON). Returns null if parsing fails.\n */\nfunction tryParseJson<T>(stdout: string): T | null {\n // First, try parsing the full output\n try {\n return JSON.parse(stdout) as T\n } catch {\n // Fall through\n }\n\n // Try to find the start of JSON content (first { or [)\n const jsonStart = stdout.search(/[{[]/)\n if (jsonStart > 0) {\n try {\n return JSON.parse(stdout.slice(jsonStart)) as T\n } catch {\n // Fall through\n }\n }\n\n return null\n}\n\ninterface NpmListOutput {\n dependencies?: Record<\n string,\n {\n resolved?: string\n version: string\n }\n >\n /** Global lib directory (e.g. /usr/local/lib on Unix). */\n path?: string\n}\n\ninterface NpmGlobalsResult {\n globals: GlobalInstallation[]\n /** npm's global lib directory, used to verify the active binary belongs to npm. */\n libDir: string | null\n}\n\ninterface PnpmListProject {\n dependencies?: Record<string, {path?: string; version: string}>\n path?: string\n}\n\n/**\n * Detects global installations of sanity and \\@sanity/cli across all package managers.\n * Runs queries in parallel for efficiency.\n */\nexport async function detectGlobalInstallations(): Promise<GlobalInstallation[]> {\n // Query all package managers in parallel\n const [activeBinaryPath, npmResult, pnpmResult, yarnGlobals, bunGlobals] = await Promise.all([\n // Find which binary is active in PATH\n findActiveBinaryPath(),\n queryNpmGlobals(),\n queryPnpmGlobals(),\n queryYarnGlobals(),\n queryBunGlobals(),\n ])\n\n const allGlobals = [...npmResult.globals, ...pnpmResult.globals, ...yarnGlobals, ...bunGlobals]\n\n // Mark which installation is active\n return markActiveInstallation(allGlobals, activeBinaryPath, npmResult.libDir, pnpmResult.binDir)\n}\n\nasync function findActiveBinaryPath(): Promise<string | null> {\n try {\n return await which('sanity')\n } catch {\n return null\n }\n}\n\nasync function queryNpmGlobals(): Promise<NpmGlobalsResult> {\n try {\n const result = await execa('npm', ['list', '-g', '--depth=0', '--json'], {\n reject: false,\n timeout: 10_000,\n })\n\n if (!result.stdout) {\n return {globals: [], libDir: null}\n }\n\n const output = tryParseJson<NpmListOutput>(result.stdout)\n if (!output) {\n return {globals: [], libDir: null}\n }\n\n const globals: GlobalInstallation[] = []\n\n for (const pkg of SANITY_PACKAGES) {\n const dep = output.dependencies?.[pkg]\n if (dep) {\n globals.push({\n isActive: false, // Will be set later\n packageManager: 'npm',\n packageName: pkg,\n // npm's `resolved` is a tarball URL, not a filesystem path.\n path: null,\n version: dep.version,\n })\n }\n }\n\n return {globals, libDir: output.path ?? null}\n } catch {\n return {globals: [], libDir: null}\n }\n}\n\ninterface PnpmGlobalsResult {\n /** pnpm's global bin directory, used to verify the active binary belongs to pnpm. */\n binDir: string | null\n globals: GlobalInstallation[]\n}\n\nasync function queryPnpmGlobals(): Promise<PnpmGlobalsResult> {\n try {\n // Query pnpm global bin dir and global packages in parallel\n const [binResult, listResult] = await Promise.all([\n execa('pnpm', ['bin', '-g'], {reject: false, timeout: 10_000}),\n execa('pnpm', ['list', '-g', '--depth=0', '--json'], {reject: false, timeout: 10_000}),\n ])\n\n const binDir = binResult.stdout?.trim() || null\n\n if (!listResult.stdout) {\n return {binDir, globals: []}\n }\n\n const output = tryParseJson<PnpmListProject[]>(listResult.stdout)\n if (!output) {\n return {binDir, globals: []}\n }\n\n const globals: GlobalInstallation[] = []\n\n for (const project of output) {\n if (!project.dependencies) continue\n for (const pkg of SANITY_PACKAGES) {\n const dep = project.dependencies[pkg]\n if (dep) {\n globals.push({\n isActive: false,\n packageManager: 'pnpm',\n packageName: pkg,\n path: dep.path || null,\n version: dep.version,\n })\n }\n }\n }\n\n return {binDir, globals}\n } catch {\n return {binDir: null, globals: []}\n }\n}\n\nasync function queryYarnGlobals(): Promise<GlobalInstallation[]> {\n // `yarn global list` only works with Yarn Classic (v1).\n // Yarn Berry (v2+) removed global installs entirely — the command errors or\n // produces no output. Because `reject: false` is set, the call returns\n // empty stdout and we gracefully return []. This means Yarn Berry global\n // installations (if any exist via third-party plugins) are invisible here.\n // A version check (via getYarnMajorVersion) could skip the call entirely,\n // but since it already degrades gracefully the cost is just a failed exec.\n try {\n const result = await execa('yarn', ['global', 'list', '--json'], {\n reject: false,\n timeout: 10_000,\n })\n\n if (!result.stdout) {\n return []\n }\n\n // Yarn outputs NDJSON - one JSON object per line\n const globals: GlobalInstallation[] = []\n const lines = result.stdout.split('\\n').filter(Boolean)\n\n for (const line of lines) {\n try {\n const entry = JSON.parse(line) as {data: string; type: string}\n if (entry.type === 'info' && entry.data) {\n // Yarn classic emits: \"\\\"sanity@3.67.0\\\" has binaries:\\n - sanity\"\n // Extract the quoted \"package@version\" portion.\n for (const pkg of SANITY_PACKAGES) {\n const prefix = `\"${pkg}@`\n if (entry.data.startsWith(prefix)) {\n const closingQuote = entry.data.indexOf('\"', prefix.length)\n if (closingQuote !== -1) {\n globals.push({\n isActive: false,\n packageManager: 'yarn',\n packageName: pkg,\n path: null,\n version: entry.data.slice(prefix.length, closingQuote),\n })\n }\n }\n }\n }\n } catch {\n // Skip malformed lines\n }\n }\n\n return globals\n } catch {\n return []\n }\n}\n\n// As of Bun 1.2, `bun pm ls` does not support --json or -g flags.\n// Skip the subprocess call entirely to avoid wasted latency on every run.\n// Re-enable when bun implements JSON output (see oven-sh/bun#26222).\nasync function queryBunGlobals(): Promise<GlobalInstallation[]> {\n return []\n}\n\nfunction markActiveInstallation(\n globals: GlobalInstallation[],\n activeBinaryPath: string | null,\n npmLibDir: string | null,\n pnpmBinDir: string | null,\n): GlobalInstallation[] {\n if (!activeBinaryPath) {\n return globals\n }\n\n // Determine which package manager the active binary belongs to.\n // For npm and pnpm, we verify against their actual reported directories\n // rather than relying on path substring matching which breaks with\n // custom install locations.\n let activePackageManager: LockfileType | null = null\n\n // bun — check default ~/.bun/ path, then fall back to BUN_INSTALL env var\n // for users with a custom installation directory.\n if (isInBunDir(activeBinaryPath)) {\n activePackageManager = 'bun'\n }\n // pnpm — verify against pnpm's actual global bin dir from `pnpm bin -g`.\n // This works regardless of PNPM_HOME configuration.\n else if (pnpmBinDir && isInPnpmBinDir(activeBinaryPath, pnpmBinDir)) {\n activePackageManager = 'pnpm'\n }\n // yarn — unlike npm/pnpm, Yarn Classic has no reliable command to query its\n // global bin directory. `yarn global bin` exists but its output varies by\n // platform and configuration. Fall back to known path patterns.\n // TODO: Query `yarn global bin` for more accurate detection, similar to\n // how pnpm uses `pnpm bin -g`. Custom $YARN_DIR or non-standard install\n // locations will not be detected by these patterns.\n else if (\n activeBinaryPath.includes('/.yarn/') ||\n activeBinaryPath.includes('\\\\.yarn\\\\') ||\n activeBinaryPath.includes('/.config/yarn/')\n ) {\n activePackageManager = 'yarn'\n }\n // npm — verify the binary is actually in npm's global bin directory.\n // `npm list -g --json` reports a `path` (the global lib dir, e.g. /usr/local/lib).\n // On Unix, bins are at <prefix>/bin (sibling of lib). On Windows, bins are in\n // the same directory as lib. When npmLibDir is null (npm didn't report a path),\n // we can't verify — leave activePackageManager as null rather than guessing,\n // since incorrectly marking npm as active could misclassify local installs.\n else if (npmLibDir && isInNpmBinDir(activeBinaryPath, npmLibDir)) {\n activePackageManager = 'npm'\n }\n\n return globals.map((g) => ({\n ...g,\n // Mark as active if it's from the detected package manager.\n // Both `sanity` and `@sanity/cli` provide a `sanity` binary,\n // so either package from the active pm is considered active.\n isActive: g.packageManager === activePackageManager,\n }))\n}\n\n/**\n * Checks whether a binary path is inside pnpm's global bin directory.\n * `pnpm bin -g` returns the directory where global binaries are linked.\n */\nfunction isInPnpmBinDir(binaryPath: string, pnpmBinDir: string): boolean {\n const binaryDir = path.dirname(path.normalize(binaryPath))\n return binaryDir === path.normalize(pnpmBinDir)\n}\n\n/**\n * Checks whether a binary path is inside npm's global bin directory.\n * On Unix: lib is at `<prefix>/lib`, bins at `<prefix>/bin` (sibling dirs).\n * On Windows: lib and bins share the same directory.\n */\nfunction isInBunDir(binaryPath: string): boolean {\n // Default ~/.bun/ location\n if (binaryPath.includes('/.bun/') || binaryPath.includes('\\\\.bun\\\\')) {\n return true\n }\n // Custom BUN_INSTALL directory (e.g. BUN_INSTALL=/opt/bun)\n const bunInstall = process.env.BUN_INSTALL\n if (bunInstall) {\n const binaryDir = path.dirname(path.normalize(binaryPath))\n const bunBinDir = path.join(path.normalize(bunInstall), 'bin')\n if (binaryDir === bunBinDir) {\n return true\n }\n }\n return false\n}\n\nfunction isInNpmBinDir(binaryPath: string, npmLibDir: string): boolean {\n // Normalize paths first — on Windows, path.dirname preserves forward slashes\n // but path.join converts to backslashes, causing mismatches without this.\n const binaryDir = path.dirname(path.normalize(binaryPath))\n const normalizedLibDir = path.normalize(npmLibDir)\n // Unix: bins at <prefix>/bin, lib at <prefix>/lib → sibling directories\n const unixBinDir = path.join(path.dirname(normalizedLibDir), 'bin')\n // Windows: bins and lib share the same directory\n return binaryDir === unixBinDir || binaryDir === normalizedLibDir\n}\n"],"names":["path","execa","which","SANITY_PACKAGES","tryParseJson","stdout","JSON","parse","jsonStart","search","slice","detectGlobalInstallations","activeBinaryPath","npmResult","pnpmResult","yarnGlobals","bunGlobals","Promise","all","findActiveBinaryPath","queryNpmGlobals","queryPnpmGlobals","queryYarnGlobals","queryBunGlobals","allGlobals","globals","markActiveInstallation","libDir","binDir","result","reject","timeout","output","pkg","dep","dependencies","push","isActive","packageManager","packageName","version","binResult","listResult","trim","project","lines","split","filter","Boolean","line","entry","type","data","prefix","startsWith","closingQuote","indexOf","length","npmLibDir","pnpmBinDir","activePackageManager","isInBunDir","isInPnpmBinDir","includes","isInNpmBinDir","map","g","binaryPath","binaryDir","dirname","normalize","bunInstall","process","env","BUN_INSTALL","bunBinDir","join","normalizedLibDir","unixBinDir"],"mappings":"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"}