@sanity/cli 6.0.0-alpha.9 → 6.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (600) hide show
  1. package/README.md +602 -258
  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 +16 -4
  205. package/dist/actions/mcp/detectAvailableEditors.js.map +1 -1
  206. package/dist/actions/mcp/editorConfigs.js +64 -6
  207. package/dist/actions/mcp/editorConfigs.js.map +1 -1
  208. package/dist/actions/mcp/setupMCP.js.map +1 -1
  209. package/dist/actions/mcp/writeMCPConfig.js +27 -15
  210. package/dist/actions/mcp/writeMCPConfig.js.map +1 -1
  211. package/dist/actions/media/buildNdjsonIndex.js +32 -0
  212. package/dist/actions/media/buildNdjsonIndex.js.map +1 -0
  213. package/dist/actions/media/importAspects.js +2 -11
  214. package/dist/actions/media/importAspects.js.map +1 -1
  215. package/dist/actions/media/importMedia.js +22 -18
  216. package/dist/actions/media/importMedia.js.map +1 -1
  217. package/dist/actions/organizations/findOrganizationByUserName.js +5 -0
  218. package/dist/actions/organizations/findOrganizationByUserName.js.map +1 -0
  219. package/dist/actions/organizations/getOrganization.js +3 -2
  220. package/dist/actions/organizations/getOrganization.js.map +1 -1
  221. package/dist/actions/organizations/getOrganizationChoices.js +27 -19
  222. package/dist/actions/organizations/getOrganizationChoices.js.map +1 -1
  223. package/dist/actions/organizations/types.js +3 -0
  224. package/dist/actions/organizations/types.js.map +1 -0
  225. package/dist/actions/projects/getManageUrl.js +1 -2
  226. package/dist/actions/projects/getManageUrl.js.map +1 -1
  227. package/dist/actions/schema/deleteSchemaAction.js +14 -30
  228. package/dist/actions/schema/deleteSchemaAction.js.map +1 -1
  229. package/dist/actions/schema/deploySchemas.js +22 -91
  230. package/dist/actions/schema/deploySchemas.js.map +1 -1
  231. package/dist/actions/schema/extractSanitySchema.worker.js +0 -5
  232. package/dist/actions/schema/extractSanitySchema.worker.js.map +1 -1
  233. package/dist/actions/schema/extractSanityWorkspace.worker.js +24 -0
  234. package/dist/actions/schema/extractSanityWorkspace.worker.js.map +1 -0
  235. package/dist/actions/schema/extractSchema.js +8 -40
  236. package/dist/actions/schema/extractSchema.js.map +1 -1
  237. package/dist/actions/schema/extractSchemaWatcher.js +128 -0
  238. package/dist/actions/schema/extractSchemaWatcher.js.map +1 -0
  239. package/dist/actions/schema/formatSchemaValidation.js +5 -1
  240. package/dist/actions/schema/formatSchemaValidation.js.map +1 -1
  241. package/dist/actions/schema/getExtractOptions.js +16 -0
  242. package/dist/actions/schema/getExtractOptions.js.map +1 -0
  243. package/dist/actions/schema/listSchemas.js +53 -56
  244. package/dist/actions/schema/listSchemas.js.map +1 -1
  245. package/dist/actions/schema/matchSchemaPattern.js +22 -0
  246. package/dist/actions/schema/matchSchemaPattern.js.map +1 -0
  247. package/dist/actions/schema/runSchemaExtraction.js +39 -0
  248. package/dist/actions/schema/runSchemaExtraction.js.map +1 -0
  249. package/dist/actions/schema/types.js +8 -0
  250. package/dist/actions/schema/types.js.map +1 -1
  251. package/dist/actions/schema/uniqueWorkspaces.worker.js +24 -0
  252. package/dist/actions/schema/uniqueWorkspaces.worker.js.map +1 -0
  253. package/dist/actions/schema/updateWorkspaceSchema.js +63 -0
  254. package/dist/actions/schema/updateWorkspaceSchema.js.map +1 -0
  255. package/dist/actions/schema/uploadSchemaToLexicon.js +87 -0
  256. package/dist/actions/schema/uploadSchemaToLexicon.js.map +1 -0
  257. package/dist/actions/schema/utils/SchemaExtractionError.js +10 -0
  258. package/dist/actions/schema/utils/SchemaExtractionError.js.map +1 -0
  259. package/dist/actions/schema/utils/schemaStoreValidation.js +1 -15
  260. package/dist/actions/schema/utils/schemaStoreValidation.js.map +1 -1
  261. package/dist/actions/schema/utils/uniqByProjectIdDataset.js +1 -1
  262. package/dist/actions/schema/utils/uniqByProjectIdDataset.js.map +1 -1
  263. package/dist/actions/schema/validateSchema.worker.js +1 -8
  264. package/dist/actions/schema/validateSchema.worker.js.map +1 -1
  265. package/dist/actions/schema/watchExtractSchema.js +72 -0
  266. package/dist/actions/schema/watchExtractSchema.js.map +1 -0
  267. package/dist/actions/telemetry/isTrueish.js +10 -0
  268. package/dist/actions/telemetry/isTrueish.js.map +1 -0
  269. package/dist/actions/telemetry/resolveConsent.js +2 -1
  270. package/dist/actions/telemetry/resolveConsent.js.map +1 -1
  271. package/dist/actions/telemetry/setConsent.js +2 -1
  272. package/dist/actions/telemetry/setConsent.js.map +1 -1
  273. package/dist/actions/users/getMembersForProject.js.map +1 -1
  274. package/dist/actions/users/getPendingInvitations.js +1 -1
  275. package/dist/actions/users/getPendingInvitations.js.map +1 -1
  276. package/dist/actions/users/types.js.map +1 -1
  277. package/dist/actions/versions/filterSanityModules.js.map +1 -1
  278. package/dist/actions/versions/findSanityModulesVersions.js +2 -3
  279. package/dist/actions/versions/findSanityModulesVersions.js.map +1 -1
  280. package/dist/actions/versions/getFormatters.js +1 -1
  281. package/dist/actions/versions/getFormatters.js.map +1 -1
  282. package/dist/actions/versions/tryFindLatestVersion.js +1 -1
  283. package/dist/actions/versions/tryFindLatestVersion.js.map +1 -1
  284. package/dist/commands/backup/disable.js +22 -7
  285. package/dist/commands/backup/disable.js.map +1 -1
  286. package/dist/commands/backup/download.js +19 -10
  287. package/dist/commands/backup/download.js.map +1 -1
  288. package/dist/commands/backup/enable.js +22 -7
  289. package/dist/commands/backup/enable.js.map +1 -1
  290. package/dist/commands/backup/list.js +20 -8
  291. package/dist/commands/backup/list.js.map +1 -1
  292. package/dist/commands/build.js +2 -5
  293. package/dist/commands/build.js.map +1 -1
  294. package/dist/commands/cors/add.js +20 -7
  295. package/dist/commands/cors/add.js.map +1 -1
  296. package/dist/commands/cors/delete.js +22 -7
  297. package/dist/commands/cors/delete.js.map +1 -1
  298. package/dist/commands/cors/list.js +22 -7
  299. package/dist/commands/cors/list.js.map +1 -1
  300. package/dist/commands/dataset/alias/create.js +26 -7
  301. package/dist/commands/dataset/alias/create.js.map +1 -1
  302. package/dist/commands/dataset/alias/delete.js +20 -7
  303. package/dist/commands/dataset/alias/delete.js.map +1 -1
  304. package/dist/commands/dataset/alias/link.js +20 -7
  305. package/dist/commands/dataset/alias/link.js.map +1 -1
  306. package/dist/commands/dataset/alias/unlink.js +20 -7
  307. package/dist/commands/dataset/alias/unlink.js.map +1 -1
  308. package/dist/commands/dataset/copy.js +45 -30
  309. package/dist/commands/dataset/copy.js.map +1 -1
  310. package/dist/commands/dataset/create.js +32 -7
  311. package/dist/commands/dataset/create.js.map +1 -1
  312. package/dist/commands/dataset/delete.js +16 -7
  313. package/dist/commands/dataset/delete.js.map +1 -1
  314. package/dist/commands/dataset/embeddings/disable.js +77 -0
  315. package/dist/commands/dataset/embeddings/disable.js.map +1 -0
  316. package/dist/commands/dataset/embeddings/enable.js +141 -0
  317. package/dist/commands/dataset/embeddings/enable.js.map +1 -0
  318. package/dist/commands/dataset/embeddings/status.js +72 -0
  319. package/dist/commands/dataset/embeddings/status.js.map +1 -0
  320. package/dist/commands/dataset/export.js +25 -16
  321. package/dist/commands/dataset/export.js.map +1 -1
  322. package/dist/commands/dataset/import.js +306 -1
  323. package/dist/commands/dataset/import.js.map +1 -1
  324. package/dist/commands/dataset/list.js +22 -7
  325. package/dist/commands/dataset/list.js.map +1 -1
  326. package/dist/commands/dataset/visibility/get.js +18 -7
  327. package/dist/commands/dataset/visibility/get.js.map +1 -1
  328. package/dist/commands/dataset/visibility/set.js +22 -7
  329. package/dist/commands/dataset/visibility/set.js.map +1 -1
  330. package/dist/commands/debug.js +4 -2
  331. package/dist/commands/debug.js.map +1 -1
  332. package/dist/commands/deploy.js +22 -11
  333. package/dist/commands/deploy.js.map +1 -1
  334. package/dist/commands/dev.js +2 -4
  335. package/dist/commands/dev.js.map +1 -1
  336. package/dist/commands/doctor.js +125 -0
  337. package/dist/commands/doctor.js.map +1 -0
  338. package/dist/commands/documents/create.js +19 -12
  339. package/dist/commands/documents/create.js.map +1 -1
  340. package/dist/commands/documents/delete.js +19 -12
  341. package/dist/commands/documents/delete.js.map +1 -1
  342. package/dist/commands/documents/get.js +17 -12
  343. package/dist/commands/documents/get.js.map +1 -1
  344. package/dist/commands/documents/query.js +26 -18
  345. package/dist/commands/documents/query.js.map +1 -1
  346. package/dist/commands/documents/validate.js +32 -10
  347. package/dist/commands/documents/validate.js.map +1 -1
  348. package/dist/commands/graphql/deploy.js +58 -30
  349. package/dist/commands/graphql/deploy.js.map +1 -1
  350. package/dist/commands/graphql/list.js +15 -7
  351. package/dist/commands/graphql/list.js.map +1 -1
  352. package/dist/commands/graphql/undeploy.js +37 -19
  353. package/dist/commands/graphql/undeploy.js.map +1 -1
  354. package/dist/commands/hook/attempt.js +22 -7
  355. package/dist/commands/hook/attempt.js.map +1 -1
  356. package/dist/commands/hook/create.js +23 -8
  357. package/dist/commands/hook/create.js.map +1 -1
  358. package/dist/commands/hook/delete.js +22 -7
  359. package/dist/commands/hook/delete.js.map +1 -1
  360. package/dist/commands/hook/list.js +22 -7
  361. package/dist/commands/hook/list.js.map +1 -1
  362. package/dist/commands/hook/logs.js +21 -8
  363. package/dist/commands/hook/logs.js.map +1 -1
  364. package/dist/commands/init.js +46 -28
  365. package/dist/commands/init.js.map +1 -1
  366. package/dist/commands/login.js +19 -6
  367. package/dist/commands/login.js.map +1 -1
  368. package/dist/commands/logout.js +8 -6
  369. package/dist/commands/logout.js.map +1 -1
  370. package/dist/commands/manage.js +0 -1
  371. package/dist/commands/manage.js.map +1 -1
  372. package/dist/commands/manifest/extract.js +14 -10
  373. package/dist/commands/manifest/extract.js.map +1 -1
  374. package/dist/commands/mcp/configure.js +1 -1
  375. package/dist/commands/mcp/configure.js.map +1 -1
  376. package/dist/commands/media/create-aspect.js +4 -4
  377. package/dist/commands/media/create-aspect.js.map +1 -1
  378. package/dist/commands/media/delete-aspect.js +9 -7
  379. package/dist/commands/media/delete-aspect.js.map +1 -1
  380. package/dist/commands/media/deploy-aspect.js +22 -9
  381. package/dist/commands/media/deploy-aspect.js.map +1 -1
  382. package/dist/commands/media/export.js +9 -7
  383. package/dist/commands/media/export.js.map +1 -1
  384. package/dist/commands/media/import.js +10 -8
  385. package/dist/commands/media/import.js.map +1 -1
  386. package/dist/commands/preview.js +2 -4
  387. package/dist/commands/preview.js.map +1 -1
  388. package/dist/commands/projects/list.js +2 -1
  389. package/dist/commands/projects/list.js.map +1 -1
  390. package/dist/commands/schema/delete.js +33 -34
  391. package/dist/commands/schema/delete.js.map +1 -1
  392. package/dist/commands/schema/deploy.js +19 -30
  393. package/dist/commands/schema/deploy.js.map +1 -1
  394. package/dist/commands/schema/extract.js +32 -4
  395. package/dist/commands/schema/extract.js.map +1 -1
  396. package/dist/commands/schema/list.js +10 -31
  397. package/dist/commands/schema/list.js.map +1 -1
  398. package/dist/commands/tokens/add.js +24 -7
  399. package/dist/commands/tokens/add.js.map +1 -1
  400. package/dist/commands/tokens/delete.js +20 -7
  401. package/dist/commands/tokens/delete.js.map +1 -1
  402. package/dist/commands/tokens/list.js +20 -7
  403. package/dist/commands/tokens/list.js.map +1 -1
  404. package/dist/commands/users/invite.js +24 -7
  405. package/dist/commands/users/invite.js.map +1 -1
  406. package/dist/commands/users/list.js +76 -33
  407. package/dist/commands/users/list.js.map +1 -1
  408. package/dist/commands/versions.js +1 -1
  409. package/dist/commands/versions.js.map +1 -1
  410. package/dist/config/createCliConfig.js +1 -2
  411. package/dist/config/createCliConfig.js.map +1 -1
  412. package/dist/exports/_internal.d.ts +132 -0
  413. package/dist/exports/_internal.js +4 -0
  414. package/dist/exports/_internal.js.map +1 -0
  415. package/dist/exports/index.d.ts +113 -0
  416. package/dist/exports/index.js +6 -0
  417. package/dist/exports/index.js.map +1 -0
  418. package/dist/hooks/init/checkForUpdates.js +14 -0
  419. package/dist/hooks/init/checkForUpdates.js.map +1 -0
  420. package/dist/hooks/prerun/flushTelemetry.worker.js +1 -1
  421. package/dist/hooks/prerun/flushTelemetry.worker.js.map +1 -1
  422. package/dist/hooks/prerun/injectEnvVariables.js +9 -1
  423. package/dist/hooks/prerun/injectEnvVariables.js.map +1 -1
  424. package/dist/hooks/prerun/setupTelemetry.js +9 -3
  425. package/dist/hooks/prerun/setupTelemetry.js.map +1 -1
  426. package/dist/prompts/promptForProject.js +64 -0
  427. package/dist/prompts/promptForProject.js.map +1 -0
  428. package/dist/{actions/auth/login/promptProviders.js → prompts/promptForProviders.js} +3 -3
  429. package/dist/prompts/promptForProviders.js.map +1 -0
  430. package/dist/prompts/selectMediaLibrary.js +1 -1
  431. package/dist/prompts/selectMediaLibrary.js.map +1 -1
  432. package/dist/server/devServer.js +4 -2
  433. package/dist/server/devServer.js.map +1 -1
  434. package/dist/server/previewServer.js +2 -2
  435. package/dist/server/previewServer.js.map +1 -1
  436. package/dist/server/vite/plugin-schema-extraction.js +201 -0
  437. package/dist/server/vite/plugin-schema-extraction.js.map +1 -0
  438. package/dist/server/vite/plugin-typegen.js +217 -0
  439. package/dist/server/vite/plugin-typegen.js.map +1 -0
  440. package/dist/services/auth.js +42 -3
  441. package/dist/services/auth.js.map +1 -1
  442. package/dist/services/datasets.js +7 -5
  443. package/dist/services/datasets.js.map +1 -1
  444. package/dist/services/docs.js +2 -2
  445. package/dist/services/docs.js.map +1 -1
  446. package/dist/services/embeddings.js +25 -0
  447. package/dist/services/embeddings.js.map +1 -0
  448. package/dist/services/getUrlHeaders.js +7 -18
  449. package/dist/services/getUrlHeaders.js.map +1 -1
  450. package/dist/services/grants.js +13 -0
  451. package/dist/services/grants.js.map +1 -0
  452. package/dist/services/graphql.js +1 -1
  453. package/dist/services/graphql.js.map +1 -1
  454. package/dist/services/projects.js +4 -2
  455. package/dist/services/projects.js.map +1 -1
  456. package/dist/services/schemas.js +1 -1
  457. package/dist/services/schemas.js.map +1 -1
  458. package/dist/services/telemetry.js +2 -1
  459. package/dist/services/telemetry.js.map +1 -1
  460. package/dist/services/userApplications.js +21 -6
  461. package/dist/services/userApplications.js.map +1 -1
  462. package/dist/telemetry/extractSchema.telemetry.js +10 -0
  463. package/dist/telemetry/extractSchema.telemetry.js.map +1 -1
  464. package/dist/types/grants.js +3 -0
  465. package/dist/types/grants.js.map +1 -0
  466. package/dist/types.js +3 -0
  467. package/dist/types.js.map +1 -1
  468. package/dist/util/checkProjectPermissions.js +21 -0
  469. package/dist/util/checkProjectPermissions.js.map +1 -0
  470. package/dist/util/cliClient.js +5 -3
  471. package/dist/util/cliClient.js.map +1 -1
  472. package/dist/util/compareDependencyVersions.js +74 -38
  473. package/dist/util/compareDependencyVersions.js.map +1 -1
  474. package/dist/util/createExpiringConfig.js +64 -0
  475. package/dist/util/createExpiringConfig.js.map +1 -0
  476. package/dist/util/detectFramework.js +135 -0
  477. package/dist/util/detectFramework.js.map +1 -0
  478. package/dist/util/errorMessages.js +0 -1
  479. package/dist/util/errorMessages.js.map +1 -1
  480. package/dist/util/extractDocumentsFromNdjsonOrTarball.js +1 -2
  481. package/dist/util/extractDocumentsFromNdjsonOrTarball.js.map +1 -1
  482. package/dist/util/getCliVersion.js +1 -1
  483. package/dist/util/getCliVersion.js.map +1 -1
  484. package/dist/util/getLocalPackageVersion.js +31 -23
  485. package/dist/util/getLocalPackageVersion.js.map +1 -1
  486. package/dist/util/getProjectDefaults.js.map +1 -1
  487. package/dist/util/getSharedServerConfig.js +1 -0
  488. package/dist/util/getSharedServerConfig.js.map +1 -1
  489. package/dist/util/getWorkspace.js +1 -1
  490. package/dist/util/getWorkspace.js.map +1 -1
  491. package/dist/util/isSchemaError.js +11 -0
  492. package/dist/util/isSchemaError.js.map +1 -0
  493. package/dist/util/isTar.js +8 -0
  494. package/dist/util/isTar.js.map +1 -0
  495. package/dist/util/packageManager/getPeerDependencies.js +44 -0
  496. package/dist/util/packageManager/getPeerDependencies.js.map +1 -0
  497. package/dist/util/packageManager/installationInfo/analyzeIssues.js +225 -0
  498. package/dist/util/packageManager/installationInfo/analyzeIssues.js.map +1 -0
  499. package/dist/util/packageManager/installationInfo/commands.js +73 -0
  500. package/dist/util/packageManager/installationInfo/commands.js.map +1 -0
  501. package/dist/util/packageManager/installationInfo/detectCliInstallation.js +66 -0
  502. package/dist/util/packageManager/installationInfo/detectCliInstallation.js.map +1 -0
  503. package/dist/util/packageManager/installationInfo/detectGlobals.js +295 -0
  504. package/dist/util/packageManager/installationInfo/detectGlobals.js.map +1 -0
  505. package/dist/util/packageManager/installationInfo/detectPackages.js +190 -0
  506. package/dist/util/packageManager/installationInfo/detectPackages.js.map +1 -0
  507. package/dist/util/packageManager/installationInfo/detectWorkspace.js +192 -0
  508. package/dist/util/packageManager/installationInfo/detectWorkspace.js.map +1 -0
  509. package/dist/util/packageManager/installationInfo/index.js +4 -0
  510. package/dist/util/packageManager/installationInfo/index.js.map +1 -0
  511. package/dist/util/packageManager/installationInfo/readJsonFile.js +14 -0
  512. package/dist/util/packageManager/installationInfo/readJsonFile.js.map +1 -0
  513. package/dist/util/packageManager/installationInfo/resolveVersionRange.js +42 -0
  514. package/dist/util/packageManager/installationInfo/resolveVersionRange.js.map +1 -0
  515. package/dist/util/packageManager/installationInfo/types.js +3 -0
  516. package/dist/util/packageManager/installationInfo/types.js.map +1 -0
  517. package/dist/util/packageManager/packageManagerChoice.js +1 -20
  518. package/dist/util/packageManager/packageManagerChoice.js.map +1 -1
  519. package/dist/util/packageManager/upgradePackages.js +4 -1
  520. package/dist/util/packageManager/upgradePackages.js.map +1 -1
  521. package/dist/util/promiseRaceWithTimeout.js +28 -0
  522. package/dist/util/promiseRaceWithTimeout.js.map +1 -0
  523. package/dist/util/readdirRecursive.js.map +1 -1
  524. package/dist/util/resolveLatestVersions.js +2 -2
  525. package/dist/util/resolveLatestVersions.js.map +1 -1
  526. package/dist/util/sharedFlags.js +54 -0
  527. package/dist/util/sharedFlags.js.map +1 -0
  528. package/dist/util/telemetry/cleanupOldTelemetryFiles.js +30 -0
  529. package/dist/util/telemetry/cleanupOldTelemetryFiles.js.map +1 -0
  530. package/dist/util/telemetry/createTelemetryStore.js +95 -0
  531. package/dist/util/telemetry/createTelemetryStore.js.map +1 -0
  532. package/dist/util/telemetry/createTraceId.js +10 -0
  533. package/dist/util/telemetry/createTraceId.js.map +1 -0
  534. package/dist/util/telemetry/findTelemetryFiles.js +35 -0
  535. package/dist/util/telemetry/findTelemetryFiles.js.map +1 -0
  536. package/dist/util/telemetry/flushTelemetryFiles.js +118 -0
  537. package/dist/util/telemetry/flushTelemetryFiles.js.map +1 -0
  538. package/dist/util/telemetry/generateTelemetryFilePath.js +30 -0
  539. package/dist/util/telemetry/generateTelemetryFilePath.js.map +1 -0
  540. package/dist/util/telemetry/logger.js +59 -0
  541. package/dist/util/telemetry/logger.js.map +1 -0
  542. package/dist/util/telemetry/readNDJSON.js +28 -0
  543. package/dist/util/telemetry/readNDJSON.js.map +1 -0
  544. package/dist/util/telemetry/telemetryStoreDebug.js +7 -0
  545. package/dist/util/telemetry/telemetryStoreDebug.js.map +1 -0
  546. package/dist/util/telemetry/trace.js +150 -0
  547. package/dist/util/telemetry/trace.js.map +1 -0
  548. package/dist/util/toForwardSlashes.js +8 -0
  549. package/dist/util/toForwardSlashes.js.map +1 -0
  550. package/dist/util/update/fetchLatestVersion.js +21 -0
  551. package/dist/util/update/fetchLatestVersion.js.map +1 -0
  552. package/dist/util/update/getUpdateCommand.js +20 -0
  553. package/dist/util/update/getUpdateCommand.js.map +1 -0
  554. package/dist/util/update/isInstalledUsingYarn.js +17 -0
  555. package/dist/util/update/isInstalledUsingYarn.js.map +1 -0
  556. package/dist/util/update/showNotificationUpdate.js +31 -0
  557. package/dist/util/update/showNotificationUpdate.js.map +1 -0
  558. package/dist/util/update/updateChecker.js +60 -0
  559. package/dist/util/update/updateChecker.js.map +1 -0
  560. package/dist/util/update/updateCheckerDebug.js +4 -0
  561. package/dist/util/update/updateCheckerDebug.js.map +1 -0
  562. package/oclif.config.js +1 -0
  563. package/oclif.manifest.json +900 -107
  564. package/package.json +72 -71
  565. package/static/favicons/apple-touch-icon.png +0 -0
  566. package/static/favicons/favicon-192.png +0 -0
  567. package/static/favicons/favicon-512.png +0 -0
  568. package/static/favicons/favicon-96.png +0 -0
  569. package/static/favicons/favicon.ico +0 -0
  570. package/static/favicons/favicon.svg +12 -0
  571. package/dist/actions/auth/login/promptProviders.js.map +0 -1
  572. package/dist/actions/dev/getCoreAppUrl.js +0 -10
  573. package/dist/actions/dev/getCoreAppUrl.js.map +0 -1
  574. package/dist/actions/schema/schemaStoreTypes.js +0 -19
  575. package/dist/actions/schema/schemaStoreTypes.js.map +0 -1
  576. package/dist/actions/schema/utils/manifestExtractor.js +0 -33
  577. package/dist/actions/schema/utils/manifestExtractor.js.map +0 -1
  578. package/dist/actions/schema/utils/manifestReader.js +0 -71
  579. package/dist/actions/schema/utils/manifestReader.js.map +0 -1
  580. package/dist/index.d.ts +0 -2326
  581. package/dist/index.js +0 -6
  582. package/dist/index.js.map +0 -1
  583. package/dist/studioDependencies.js.map +0 -1
  584. package/dist/typings/deepSortObject.d.js +0 -2
  585. package/dist/typings/deepSortObject.d.js.map +0 -1
  586. package/dist/util/findNdjsonEntry.js +0 -21
  587. package/dist/util/findNdjsonEntry.js.map +0 -1
  588. package/dist/util/importStudioConfig.js +0 -40
  589. package/dist/util/importStudioConfig.js.map +0 -1
  590. package/dist/util/readModuleVersion.js +0 -15
  591. package/dist/util/readModuleVersion.js.map +0 -1
  592. package/dist/util/readPackageJson.js +0 -44
  593. package/dist/util/readPackageJson.js.map +0 -1
  594. package/dist/util/readPackageManifest.js +0 -46
  595. package/dist/util/readPackageManifest.js.map +0 -1
  596. package/dist/util/uniqBy.js +0 -14
  597. package/dist/util/uniqBy.js.map +0 -1
  598. package/dist/util/workerChannels.js +0 -172
  599. package/dist/util/workerChannels.js.map +0 -1
  600. /package/dist/{studioDependencies.js → actions/init/studioDependencies.js} +0 -0
@@ -0,0 +1,192 @@
1
+ import fs from 'node:fs/promises';
2
+ import path from 'node:path';
3
+ import { readJsonFile } from './readJsonFile.js';
4
+ const LOCKFILE_MAP = {
5
+ 'bun.lock': 'bun',
6
+ 'bun.lockb': 'bun',
7
+ 'package-lock.json': 'npm',
8
+ 'pnpm-lock.yaml': 'pnpm',
9
+ 'yarn.lock': 'yarn'
10
+ };
11
+ // Explicit detection order: determines which lockfile is preferred when multiple exist.
12
+ // pnpm > npm > yarn > bun — pnpm first because it's most common in Sanity projects.
13
+ const LOCKFILE_NAMES = [
14
+ 'pnpm-lock.yaml',
15
+ 'package-lock.json',
16
+ 'yarn.lock',
17
+ 'bun.lock',
18
+ 'bun.lockb'
19
+ ];
20
+ /**
21
+ * Detects workspace configuration by walking up from the given directory.
22
+ * Identifies workspace type, root, lockfile, and whether multiple lockfiles exist.
23
+ *
24
+ * The search stops when a lockfile is found, as this indicates a project root.
25
+ * This prevents accidentally detecting parent monorepo configurations when
26
+ * analyzing a standalone project.
27
+ */ export async function detectWorkspace(cwd) {
28
+ const nearestPackageJson = await findNearestPackageJson(cwd);
29
+ if (!nearestPackageJson) {
30
+ // No package.json found - return minimal info
31
+ return {
32
+ bunfig: false,
33
+ hasMultipleLockfiles: false,
34
+ lockfile: null,
35
+ nearestPackageJson: null,
36
+ root: cwd,
37
+ type: 'standalone',
38
+ yarnBerry: false
39
+ };
40
+ }
41
+ // Find workspace root and type by walking up
42
+ // This also finds lockfiles along the way
43
+ const { lockfiles, root, type } = await findWorkspaceRoot(path.dirname(nearestPackageJson));
44
+ // De-duplicate by package manager type: bun.lock + bun.lockb both map to 'bun'
45
+ // and should not trigger a false "multiple lockfiles" warning.
46
+ const uniquePmTypes = new Set(lockfiles.map((l)=>l.type));
47
+ const hasMultipleLockfiles = uniquePmTypes.size > 1;
48
+ // Use the first lockfile found (ordered by LOCKFILE_NAMES priority)
49
+ const lockfile = lockfiles.length > 0 ? lockfiles[0] : null;
50
+ // PM-specific config files that exist even in standalone (non-workspace) projects
51
+ const [yarnBerry, bunfig] = await Promise.all([
52
+ fileExists(path.join(root, '.yarnrc.yml')),
53
+ fileExists(path.join(root, 'bunfig.toml'))
54
+ ]);
55
+ return {
56
+ bunfig,
57
+ hasMultipleLockfiles,
58
+ lockfile,
59
+ nearestPackageJson,
60
+ root,
61
+ type,
62
+ yarnBerry
63
+ };
64
+ }
65
+ async function findNearestPackageJson(startDir) {
66
+ let currentDir = path.resolve(startDir);
67
+ const root = path.parse(currentDir).root;
68
+ // Intentionally stops before the filesystem root (/) to avoid false positives
69
+ // from system-level package.json files. This is consistent across all three
70
+ // walking functions (findNearestPackageJson, findWorkspaceRoot, findInstalledPackage).
71
+ while(currentDir !== root){
72
+ const packageJsonPath = path.join(currentDir, 'package.json');
73
+ if (await fileExists(packageJsonPath)) {
74
+ return packageJsonPath;
75
+ }
76
+ currentDir = path.dirname(currentDir);
77
+ }
78
+ return null;
79
+ }
80
+ async function findWorkspaceRoot(startDir) {
81
+ let currentDir = path.resolve(startDir);
82
+ const fsRoot = path.parse(currentDir).root;
83
+ while(currentDir !== fsRoot){
84
+ // Check for lockfiles at this level - if found, this is the project root
85
+ const lockfiles = await findLockfiles(currentDir);
86
+ if (lockfiles.length > 0) {
87
+ // Found lockfile(s), this is the project root
88
+ // Now determine workspace type
89
+ // Check for pnpm-workspace.yaml (definitive pnpm workspace marker)
90
+ const pnpmWorkspacePath = path.join(currentDir, 'pnpm-workspace.yaml');
91
+ if (await fileExists(pnpmWorkspacePath)) {
92
+ return {
93
+ lockfiles,
94
+ root: currentDir,
95
+ type: 'pnpm-workspaces'
96
+ };
97
+ }
98
+ // Check for package.json with workspaces field
99
+ const packageJson = await readJsonFile(path.join(currentDir, 'package.json'));
100
+ if (packageJson?.workspaces) {
101
+ return {
102
+ lockfiles,
103
+ root: currentDir,
104
+ type: getWorkspaceType(lockfiles)
105
+ };
106
+ }
107
+ // Has lockfile but no workspace config - standalone project
108
+ return {
109
+ lockfiles,
110
+ root: currentDir,
111
+ type: 'standalone'
112
+ };
113
+ }
114
+ // No lockfile at this level, check for workspace markers before going up.
115
+ // This handles the case where we're in a nested package that doesn't have
116
+ // its own lockfile, or a fresh checkout before `install` has been run.
117
+ // We already know lockfiles is [] for this dir, so don't re-query.
118
+ // Check for pnpm-workspace.yaml
119
+ const pnpmWorkspacePath = path.join(currentDir, 'pnpm-workspace.yaml');
120
+ if (await fileExists(pnpmWorkspacePath)) {
121
+ return {
122
+ lockfiles: [],
123
+ root: currentDir,
124
+ type: 'pnpm-workspaces'
125
+ };
126
+ }
127
+ // Check for package.json with workspaces field
128
+ const packageJson = await readJsonFile(path.join(currentDir, 'package.json'));
129
+ if (packageJson?.workspaces) {
130
+ // Without a lockfile we can't determine the workspace type from
131
+ // lockfile presence. Check for PM-specific config files to
132
+ // distinguish the workspace type before falling back to npm-workspaces.
133
+ if (await fileExists(path.join(currentDir, '.yarnrc.yml'))) {
134
+ return {
135
+ lockfiles: [],
136
+ root: currentDir,
137
+ type: 'yarn-workspaces'
138
+ };
139
+ }
140
+ if (await fileExists(path.join(currentDir, 'bunfig.toml'))) {
141
+ return {
142
+ lockfiles: [],
143
+ root: currentDir,
144
+ type: 'bun-workspaces'
145
+ };
146
+ }
147
+ return {
148
+ lockfiles: [],
149
+ root: currentDir,
150
+ type: 'npm-workspaces'
151
+ };
152
+ }
153
+ currentDir = path.dirname(currentDir);
154
+ }
155
+ // No workspace or lockfile found, use the starting directory as root
156
+ return {
157
+ lockfiles: [],
158
+ root: startDir,
159
+ type: 'standalone'
160
+ };
161
+ }
162
+ /**
163
+ * Determines the workspace type from the lockfiles found at the workspace root.
164
+ * Uses the same priority order as LOCKFILE_NAMES (pnpm, npm, yarn, bun)
165
+ * so that workspace.type and workspace.lockfile.type always agree.
166
+ */ function getWorkspaceType(lockfiles) {
167
+ if (lockfiles.some((l)=>l.type === 'pnpm')) return 'pnpm-workspaces';
168
+ if (lockfiles.some((l)=>l.type === 'npm')) return 'npm-workspaces';
169
+ if (lockfiles.some((l)=>l.type === 'yarn')) return 'yarn-workspaces';
170
+ if (lockfiles.some((l)=>l.type === 'bun')) return 'bun-workspaces';
171
+ return 'npm-workspaces';
172
+ }
173
+ async function findLockfiles(dir) {
174
+ const results = await Promise.all(LOCKFILE_NAMES.map(async (name)=>{
175
+ const lockfilePath = path.join(dir, name);
176
+ return await fileExists(lockfilePath) ? {
177
+ path: lockfilePath,
178
+ type: LOCKFILE_MAP[name]
179
+ } : null;
180
+ }));
181
+ return results.filter((r)=>r !== null);
182
+ }
183
+ async function fileExists(filePath) {
184
+ try {
185
+ await fs.access(filePath);
186
+ return true;
187
+ } catch {
188
+ return false;
189
+ }
190
+ }
191
+
192
+ //# sourceMappingURL=detectWorkspace.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/util/packageManager/installationInfo/detectWorkspace.ts"],"sourcesContent":["import fs from 'node:fs/promises'\nimport path from 'node:path'\n\nimport {readJsonFile} from './readJsonFile.js'\nimport {type LockfileType, type WorkspaceInfo, type WorkspaceType} from './types.js'\n\ninterface LockfileInfo {\n path: string\n type: LockfileType\n}\n\nconst LOCKFILE_MAP: Record<string, LockfileType> = {\n 'bun.lock': 'bun',\n 'bun.lockb': 'bun',\n 'package-lock.json': 'npm',\n 'pnpm-lock.yaml': 'pnpm',\n 'yarn.lock': 'yarn',\n}\n\n// Explicit detection order: determines which lockfile is preferred when multiple exist.\n// pnpm > npm > yarn > bun — pnpm first because it's most common in Sanity projects.\nconst LOCKFILE_NAMES = ['pnpm-lock.yaml', 'package-lock.json', 'yarn.lock', 'bun.lock', 'bun.lockb']\n\n/**\n * Detects workspace configuration by walking up from the given directory.\n * Identifies workspace type, root, lockfile, and whether multiple lockfiles exist.\n *\n * The search stops when a lockfile is found, as this indicates a project root.\n * This prevents accidentally detecting parent monorepo configurations when\n * analyzing a standalone project.\n */\nexport async function detectWorkspace(cwd: string): Promise<WorkspaceInfo> {\n const nearestPackageJson = await findNearestPackageJson(cwd)\n if (!nearestPackageJson) {\n // No package.json found - return minimal info\n return {\n bunfig: false,\n hasMultipleLockfiles: false,\n lockfile: null,\n nearestPackageJson: null,\n root: cwd,\n type: 'standalone',\n yarnBerry: false,\n }\n }\n\n // Find workspace root and type by walking up\n // This also finds lockfiles along the way\n const {lockfiles, root, type} = await findWorkspaceRoot(path.dirname(nearestPackageJson))\n\n // De-duplicate by package manager type: bun.lock + bun.lockb both map to 'bun'\n // and should not trigger a false \"multiple lockfiles\" warning.\n const uniquePmTypes = new Set(lockfiles.map((l) => l.type))\n const hasMultipleLockfiles = uniquePmTypes.size > 1\n\n // Use the first lockfile found (ordered by LOCKFILE_NAMES priority)\n const lockfile = lockfiles.length > 0 ? lockfiles[0] : null\n\n // PM-specific config files that exist even in standalone (non-workspace) projects\n const [yarnBerry, bunfig] = await Promise.all([\n fileExists(path.join(root, '.yarnrc.yml')),\n fileExists(path.join(root, 'bunfig.toml')),\n ])\n\n return {\n bunfig,\n hasMultipleLockfiles,\n lockfile,\n nearestPackageJson,\n root,\n type,\n yarnBerry,\n }\n}\n\nasync function findNearestPackageJson(startDir: string): Promise<string | null> {\n let currentDir = path.resolve(startDir)\n const root = path.parse(currentDir).root\n\n // Intentionally stops before the filesystem root (/) to avoid false positives\n // from system-level package.json files. This is consistent across all three\n // walking functions (findNearestPackageJson, findWorkspaceRoot, findInstalledPackage).\n while (currentDir !== root) {\n const packageJsonPath = path.join(currentDir, 'package.json')\n if (await fileExists(packageJsonPath)) {\n return packageJsonPath\n }\n currentDir = path.dirname(currentDir)\n }\n\n return null\n}\n\nasync function findWorkspaceRoot(\n startDir: string,\n): Promise<{lockfiles: LockfileInfo[]; root: string; type: WorkspaceType}> {\n let currentDir = path.resolve(startDir)\n const fsRoot = path.parse(currentDir).root\n\n while (currentDir !== fsRoot) {\n // Check for lockfiles at this level - if found, this is the project root\n const lockfiles = await findLockfiles(currentDir)\n\n if (lockfiles.length > 0) {\n // Found lockfile(s), this is the project root\n // Now determine workspace type\n\n // Check for pnpm-workspace.yaml (definitive pnpm workspace marker)\n const pnpmWorkspacePath = path.join(currentDir, 'pnpm-workspace.yaml')\n if (await fileExists(pnpmWorkspacePath)) {\n return {lockfiles, root: currentDir, type: 'pnpm-workspaces'}\n }\n\n // Check for package.json with workspaces field\n const packageJson = await readJsonFile(path.join(currentDir, 'package.json'))\n if (packageJson?.workspaces) {\n return {lockfiles, root: currentDir, type: getWorkspaceType(lockfiles)}\n }\n\n // Has lockfile but no workspace config - standalone project\n return {lockfiles, root: currentDir, type: 'standalone'}\n }\n\n // No lockfile at this level, check for workspace markers before going up.\n // This handles the case where we're in a nested package that doesn't have\n // its own lockfile, or a fresh checkout before `install` has been run.\n // We already know lockfiles is [] for this dir, so don't re-query.\n\n // Check for pnpm-workspace.yaml\n const pnpmWorkspacePath = path.join(currentDir, 'pnpm-workspace.yaml')\n if (await fileExists(pnpmWorkspacePath)) {\n return {lockfiles: [], root: currentDir, type: 'pnpm-workspaces'}\n }\n\n // Check for package.json with workspaces field\n const packageJson = await readJsonFile(path.join(currentDir, 'package.json'))\n if (packageJson?.workspaces) {\n // Without a lockfile we can't determine the workspace type from\n // lockfile presence. Check for PM-specific config files to\n // distinguish the workspace type before falling back to npm-workspaces.\n if (await fileExists(path.join(currentDir, '.yarnrc.yml'))) {\n return {lockfiles: [], root: currentDir, type: 'yarn-workspaces'}\n }\n if (await fileExists(path.join(currentDir, 'bunfig.toml'))) {\n return {lockfiles: [], root: currentDir, type: 'bun-workspaces'}\n }\n return {lockfiles: [], root: currentDir, type: 'npm-workspaces'}\n }\n\n currentDir = path.dirname(currentDir)\n }\n\n // No workspace or lockfile found, use the starting directory as root\n return {lockfiles: [], root: startDir, type: 'standalone'}\n}\n\n/**\n * Determines the workspace type from the lockfiles found at the workspace root.\n * Uses the same priority order as LOCKFILE_NAMES (pnpm, npm, yarn, bun)\n * so that workspace.type and workspace.lockfile.type always agree.\n */\nfunction getWorkspaceType(lockfiles: LockfileInfo[]): WorkspaceType {\n if (lockfiles.some((l) => l.type === 'pnpm')) return 'pnpm-workspaces'\n if (lockfiles.some((l) => l.type === 'npm')) return 'npm-workspaces'\n if (lockfiles.some((l) => l.type === 'yarn')) return 'yarn-workspaces'\n if (lockfiles.some((l) => l.type === 'bun')) return 'bun-workspaces'\n return 'npm-workspaces'\n}\n\nasync function findLockfiles(dir: string): Promise<LockfileInfo[]> {\n const results = await Promise.all(\n LOCKFILE_NAMES.map(async (name) => {\n const lockfilePath = path.join(dir, name)\n return (await fileExists(lockfilePath))\n ? {path: lockfilePath, type: LOCKFILE_MAP[name]}\n : null\n }),\n )\n return results.filter((r): r is LockfileInfo => r !== null)\n}\n\nasync function fileExists(filePath: string): Promise<boolean> {\n try {\n await fs.access(filePath)\n return true\n } catch {\n return false\n }\n}\n"],"names":["fs","path","readJsonFile","LOCKFILE_MAP","LOCKFILE_NAMES","detectWorkspace","cwd","nearestPackageJson","findNearestPackageJson","bunfig","hasMultipleLockfiles","lockfile","root","type","yarnBerry","lockfiles","findWorkspaceRoot","dirname","uniquePmTypes","Set","map","l","size","length","Promise","all","fileExists","join","startDir","currentDir","resolve","parse","packageJsonPath","fsRoot","findLockfiles","pnpmWorkspacePath","packageJson","workspaces","getWorkspaceType","some","dir","results","name","lockfilePath","filter","r","filePath","access"],"mappings":"AAAA,OAAOA,QAAQ,mBAAkB;AACjC,OAAOC,UAAU,YAAW;AAE5B,SAAQC,YAAY,QAAO,oBAAmB;AAQ9C,MAAMC,eAA6C;IACjD,YAAY;IACZ,aAAa;IACb,qBAAqB;IACrB,kBAAkB;IAClB,aAAa;AACf;AAEA,wFAAwF;AACxF,oFAAoF;AACpF,MAAMC,iBAAiB;IAAC;IAAkB;IAAqB;IAAa;IAAY;CAAY;AAEpG;;;;;;;CAOC,GACD,OAAO,eAAeC,gBAAgBC,GAAW;IAC/C,MAAMC,qBAAqB,MAAMC,uBAAuBF;IACxD,IAAI,CAACC,oBAAoB;QACvB,8CAA8C;QAC9C,OAAO;YACLE,QAAQ;YACRC,sBAAsB;YACtBC,UAAU;YACVJ,oBAAoB;YACpBK,MAAMN;YACNO,MAAM;YACNC,WAAW;QACb;IACF;IAEA,6CAA6C;IAC7C,0CAA0C;IAC1C,MAAM,EAACC,SAAS,EAAEH,IAAI,EAAEC,IAAI,EAAC,GAAG,MAAMG,kBAAkBf,KAAKgB,OAAO,CAACV;IAErE,+EAA+E;IAC/E,+DAA+D;IAC/D,MAAMW,gBAAgB,IAAIC,IAAIJ,UAAUK,GAAG,CAAC,CAACC,IAAMA,EAAER,IAAI;IACzD,MAAMH,uBAAuBQ,cAAcI,IAAI,GAAG;IAElD,oEAAoE;IACpE,MAAMX,WAAWI,UAAUQ,MAAM,GAAG,IAAIR,SAAS,CAAC,EAAE,GAAG;IAEvD,kFAAkF;IAClF,MAAM,CAACD,WAAWL,OAAO,GAAG,MAAMe,QAAQC,GAAG,CAAC;QAC5CC,WAAWzB,KAAK0B,IAAI,CAACf,MAAM;QAC3Bc,WAAWzB,KAAK0B,IAAI,CAACf,MAAM;KAC5B;IAED,OAAO;QACLH;QACAC;QACAC;QACAJ;QACAK;QACAC;QACAC;IACF;AACF;AAEA,eAAeN,uBAAuBoB,QAAgB;IACpD,IAAIC,aAAa5B,KAAK6B,OAAO,CAACF;IAC9B,MAAMhB,OAAOX,KAAK8B,KAAK,CAACF,YAAYjB,IAAI;IAExC,8EAA8E;IAC9E,4EAA4E;IAC5E,uFAAuF;IACvF,MAAOiB,eAAejB,KAAM;QAC1B,MAAMoB,kBAAkB/B,KAAK0B,IAAI,CAACE,YAAY;QAC9C,IAAI,MAAMH,WAAWM,kBAAkB;YACrC,OAAOA;QACT;QACAH,aAAa5B,KAAKgB,OAAO,CAACY;IAC5B;IAEA,OAAO;AACT;AAEA,eAAeb,kBACbY,QAAgB;IAEhB,IAAIC,aAAa5B,KAAK6B,OAAO,CAACF;IAC9B,MAAMK,SAAShC,KAAK8B,KAAK,CAACF,YAAYjB,IAAI;IAE1C,MAAOiB,eAAeI,OAAQ;QAC5B,yEAAyE;QACzE,MAAMlB,YAAY,MAAMmB,cAAcL;QAEtC,IAAId,UAAUQ,MAAM,GAAG,GAAG;YACxB,8CAA8C;YAC9C,+BAA+B;YAE/B,mEAAmE;YACnE,MAAMY,oBAAoBlC,KAAK0B,IAAI,CAACE,YAAY;YAChD,IAAI,MAAMH,WAAWS,oBAAoB;gBACvC,OAAO;oBAACpB;oBAAWH,MAAMiB;oBAAYhB,MAAM;gBAAiB;YAC9D;YAEA,+CAA+C;YAC/C,MAAMuB,cAAc,MAAMlC,aAAaD,KAAK0B,IAAI,CAACE,YAAY;YAC7D,IAAIO,aAAaC,YAAY;gBAC3B,OAAO;oBAACtB;oBAAWH,MAAMiB;oBAAYhB,MAAMyB,iBAAiBvB;gBAAU;YACxE;YAEA,4DAA4D;YAC5D,OAAO;gBAACA;gBAAWH,MAAMiB;gBAAYhB,MAAM;YAAY;QACzD;QAEA,0EAA0E;QAC1E,0EAA0E;QAC1E,uEAAuE;QACvE,mEAAmE;QAEnE,gCAAgC;QAChC,MAAMsB,oBAAoBlC,KAAK0B,IAAI,CAACE,YAAY;QAChD,IAAI,MAAMH,WAAWS,oBAAoB;YACvC,OAAO;gBAACpB,WAAW,EAAE;gBAAEH,MAAMiB;gBAAYhB,MAAM;YAAiB;QAClE;QAEA,+CAA+C;QAC/C,MAAMuB,cAAc,MAAMlC,aAAaD,KAAK0B,IAAI,CAACE,YAAY;QAC7D,IAAIO,aAAaC,YAAY;YAC3B,gEAAgE;YAChE,2DAA2D;YAC3D,wEAAwE;YACxE,IAAI,MAAMX,WAAWzB,KAAK0B,IAAI,CAACE,YAAY,iBAAiB;gBAC1D,OAAO;oBAACd,WAAW,EAAE;oBAAEH,MAAMiB;oBAAYhB,MAAM;gBAAiB;YAClE;YACA,IAAI,MAAMa,WAAWzB,KAAK0B,IAAI,CAACE,YAAY,iBAAiB;gBAC1D,OAAO;oBAACd,WAAW,EAAE;oBAAEH,MAAMiB;oBAAYhB,MAAM;gBAAgB;YACjE;YACA,OAAO;gBAACE,WAAW,EAAE;gBAAEH,MAAMiB;gBAAYhB,MAAM;YAAgB;QACjE;QAEAgB,aAAa5B,KAAKgB,OAAO,CAACY;IAC5B;IAEA,qEAAqE;IACrE,OAAO;QAACd,WAAW,EAAE;QAAEH,MAAMgB;QAAUf,MAAM;IAAY;AAC3D;AAEA;;;;CAIC,GACD,SAASyB,iBAAiBvB,SAAyB;IACjD,IAAIA,UAAUwB,IAAI,CAAC,CAAClB,IAAMA,EAAER,IAAI,KAAK,SAAS,OAAO;IACrD,IAAIE,UAAUwB,IAAI,CAAC,CAAClB,IAAMA,EAAER,IAAI,KAAK,QAAQ,OAAO;IACpD,IAAIE,UAAUwB,IAAI,CAAC,CAAClB,IAAMA,EAAER,IAAI,KAAK,SAAS,OAAO;IACrD,IAAIE,UAAUwB,IAAI,CAAC,CAAClB,IAAMA,EAAER,IAAI,KAAK,QAAQ,OAAO;IACpD,OAAO;AACT;AAEA,eAAeqB,cAAcM,GAAW;IACtC,MAAMC,UAAU,MAAMjB,QAAQC,GAAG,CAC/BrB,eAAegB,GAAG,CAAC,OAAOsB;QACxB,MAAMC,eAAe1C,KAAK0B,IAAI,CAACa,KAAKE;QACpC,OAAO,AAAC,MAAMhB,WAAWiB,gBACrB;YAAC1C,MAAM0C;YAAc9B,MAAMV,YAAY,CAACuC,KAAK;QAAA,IAC7C;IACN;IAEF,OAAOD,QAAQG,MAAM,CAAC,CAACC,IAAyBA,MAAM;AACxD;AAEA,eAAenB,WAAWoB,QAAgB;IACxC,IAAI;QACF,MAAM9C,GAAG+C,MAAM,CAACD;QAChB,OAAO;IACT,EAAE,OAAM;QACN,OAAO;IACT;AACF"}
@@ -0,0 +1,4 @@
1
+ // Main entry point
2
+ export { detectCliInstallation } from './detectCliInstallation.js';
3
+
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/util/packageManager/installationInfo/index.ts"],"sourcesContent":["// Main entry point\nexport {detectCliInstallation} from './detectCliInstallation.js'\n"],"names":["detectCliInstallation"],"mappings":"AAAA,mBAAmB;AACnB,SAAQA,qBAAqB,QAAO,6BAA4B"}
@@ -0,0 +1,14 @@
1
+ import fs from 'node:fs/promises';
2
+ /**
3
+ * Reads and parses a JSON file, returning null if the file doesn't exist
4
+ * or contains invalid JSON.
5
+ */ export async function readJsonFile(filePath) {
6
+ try {
7
+ const content = await fs.readFile(filePath, 'utf8');
8
+ return JSON.parse(content);
9
+ } catch {
10
+ return null;
11
+ }
12
+ }
13
+
14
+ //# sourceMappingURL=readJsonFile.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/util/packageManager/installationInfo/readJsonFile.ts"],"sourcesContent":["import fs from 'node:fs/promises'\n\n/**\n * Reads and parses a JSON file, returning null if the file doesn't exist\n * or contains invalid JSON.\n */\nexport async function readJsonFile<T = Record<string, unknown>>(\n filePath: string,\n): Promise<T | null> {\n try {\n const content = await fs.readFile(filePath, 'utf8')\n return JSON.parse(content) as T\n } catch {\n return null\n }\n}\n"],"names":["fs","readJsonFile","filePath","content","readFile","JSON","parse"],"mappings":"AAAA,OAAOA,QAAQ,mBAAkB;AAEjC;;;CAGC,GACD,OAAO,eAAeC,aACpBC,QAAgB;IAEhB,IAAI;QACF,MAAMC,UAAU,MAAMH,GAAGI,QAAQ,CAACF,UAAU;QAC5C,OAAOG,KAAKC,KAAK,CAACH;IACpB,EAAE,OAAM;QACN,OAAO;IACT;AACF"}
@@ -0,0 +1,42 @@
1
+ import fs from 'node:fs/promises';
2
+ import path from 'node:path';
3
+ import yaml from 'yaml';
4
+ /**
5
+ * Resolves a version range that may use special protocols like `catalog:` or `catalog:name`.
6
+ *
7
+ * @param declaredRange - The version range as declared in package.json
8
+ * @param packageName - The name of the package (needed for catalog lookup)
9
+ * @param workspaceInfo - Workspace configuration for finding catalog definitions
10
+ * @returns The resolved version range, or the original if it can't be resolved
11
+ */ export async function resolveVersionRange(declaredRange, packageName, workspaceInfo) {
12
+ // Handle catalog: protocol (pnpm workspaces)
13
+ if (declaredRange.startsWith('catalog:')) {
14
+ return resolveCatalogRange(declaredRange, packageName, workspaceInfo);
15
+ }
16
+ // Other protocols (workspace:*, etc.) are returned as-is
17
+ // They're handled differently in the dependency resolution
18
+ return declaredRange;
19
+ }
20
+ async function resolveCatalogRange(declaredRange, packageName, workspaceInfo) {
21
+ // Parse catalog name from "catalog:" or "catalog:name"
22
+ const catalogName = declaredRange.slice('catalog:'.length) || 'default';
23
+ // Read pnpm-workspace.yaml from workspace root
24
+ const pnpmWorkspacePath = path.join(workspaceInfo.root, 'pnpm-workspace.yaml');
25
+ try {
26
+ const content = await fs.readFile(pnpmWorkspacePath, 'utf8');
27
+ const config = yaml.parse(content);
28
+ // pnpm supports the default catalog in two places:
29
+ // 1. Top-level `catalog:` key
30
+ // 2. Under `catalogs: { default: { ... } }`
31
+ const version = catalogName === 'default' ? config.catalog?.[packageName] ?? config.catalogs?.['default']?.[packageName] : config.catalogs?.[catalogName]?.[packageName];
32
+ if (version) {
33
+ return version;
34
+ }
35
+ } catch {
36
+ // Failed to read or parse pnpm-workspace.yaml
37
+ }
38
+ // Couldn't resolve - return original
39
+ return declaredRange;
40
+ }
41
+
42
+ //# sourceMappingURL=resolveVersionRange.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/util/packageManager/installationInfo/resolveVersionRange.ts"],"sourcesContent":["import fs from 'node:fs/promises'\nimport path from 'node:path'\n\nimport yaml from 'yaml'\n\nimport {type WorkspaceInfo} from './types.js'\n\ninterface PnpmWorkspaceConfig {\n catalog?: Record<string, string>\n catalogs?: Record<string, Record<string, string>>\n packages?: string[]\n}\n\n/**\n * Resolves a version range that may use special protocols like `catalog:` or `catalog:name`.\n *\n * @param declaredRange - The version range as declared in package.json\n * @param packageName - The name of the package (needed for catalog lookup)\n * @param workspaceInfo - Workspace configuration for finding catalog definitions\n * @returns The resolved version range, or the original if it can't be resolved\n */\nexport async function resolveVersionRange(\n declaredRange: string,\n packageName: string,\n workspaceInfo: WorkspaceInfo,\n): Promise<string> {\n // Handle catalog: protocol (pnpm workspaces)\n if (declaredRange.startsWith('catalog:')) {\n return resolveCatalogRange(declaredRange, packageName, workspaceInfo)\n }\n\n // Other protocols (workspace:*, etc.) are returned as-is\n // They're handled differently in the dependency resolution\n return declaredRange\n}\n\nasync function resolveCatalogRange(\n declaredRange: string,\n packageName: string,\n workspaceInfo: WorkspaceInfo,\n): Promise<string> {\n // Parse catalog name from \"catalog:\" or \"catalog:name\"\n const catalogName = declaredRange.slice('catalog:'.length) || 'default'\n\n // Read pnpm-workspace.yaml from workspace root\n const pnpmWorkspacePath = path.join(workspaceInfo.root, 'pnpm-workspace.yaml')\n\n try {\n const content = await fs.readFile(pnpmWorkspacePath, 'utf8')\n const config = yaml.parse(content) as PnpmWorkspaceConfig\n\n // pnpm supports the default catalog in two places:\n // 1. Top-level `catalog:` key\n // 2. Under `catalogs: { default: { ... } }`\n const version =\n catalogName === 'default'\n ? (config.catalog?.[packageName] ?? config.catalogs?.['default']?.[packageName])\n : config.catalogs?.[catalogName]?.[packageName]\n\n if (version) {\n return version\n }\n } catch {\n // Failed to read or parse pnpm-workspace.yaml\n }\n\n // Couldn't resolve - return original\n return declaredRange\n}\n"],"names":["fs","path","yaml","resolveVersionRange","declaredRange","packageName","workspaceInfo","startsWith","resolveCatalogRange","catalogName","slice","length","pnpmWorkspacePath","join","root","content","readFile","config","parse","version","catalog","catalogs"],"mappings":"AAAA,OAAOA,QAAQ,mBAAkB;AACjC,OAAOC,UAAU,YAAW;AAE5B,OAAOC,UAAU,OAAM;AAUvB;;;;;;;CAOC,GACD,OAAO,eAAeC,oBACpBC,aAAqB,EACrBC,WAAmB,EACnBC,aAA4B;IAE5B,6CAA6C;IAC7C,IAAIF,cAAcG,UAAU,CAAC,aAAa;QACxC,OAAOC,oBAAoBJ,eAAeC,aAAaC;IACzD;IAEA,yDAAyD;IACzD,2DAA2D;IAC3D,OAAOF;AACT;AAEA,eAAeI,oBACbJ,aAAqB,EACrBC,WAAmB,EACnBC,aAA4B;IAE5B,uDAAuD;IACvD,MAAMG,cAAcL,cAAcM,KAAK,CAAC,WAAWC,MAAM,KAAK;IAE9D,+CAA+C;IAC/C,MAAMC,oBAAoBX,KAAKY,IAAI,CAACP,cAAcQ,IAAI,EAAE;IAExD,IAAI;QACF,MAAMC,UAAU,MAAMf,GAAGgB,QAAQ,CAACJ,mBAAmB;QACrD,MAAMK,SAASf,KAAKgB,KAAK,CAACH;QAE1B,mDAAmD;QACnD,8BAA8B;QAC9B,4CAA4C;QAC5C,MAAMI,UACJV,gBAAgB,YACXQ,OAAOG,OAAO,EAAE,CAACf,YAAY,IAAIY,OAAOI,QAAQ,EAAE,CAAC,UAAU,EAAE,CAAChB,YAAY,GAC7EY,OAAOI,QAAQ,EAAE,CAACZ,YAAY,EAAE,CAACJ,YAAY;QAEnD,IAAIc,SAAS;YACX,OAAOA;QACT;IACF,EAAE,OAAM;IACN,8CAA8C;IAChD;IAEA,qCAAqC;IACrC,OAAOf;AACT"}
@@ -0,0 +1,3 @@
1
+ export { };
2
+
3
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/util/packageManager/installationInfo/types.ts"],"sourcesContent":["import {type PackageManager} from '../packageManagerChoice.js'\n\n/** Lockfile types — excludes 'manual' since lockfiles always map to a real package manager. */\nexport type LockfileType = Exclude<PackageManager, 'manual'>\n\nexport type WorkspaceType =\n | 'bun-workspaces'\n | 'npm-workspaces'\n | 'pnpm-workspaces'\n | 'standalone'\n | 'yarn-workspaces'\n\nexport type SanityPackage = '@sanity/cli' | 'sanity'\n\nexport interface CliInstallationInfo {\n currentExecution: ExecutionContext\n globalInstallations: GlobalInstallation[]\n issues: Issue[]\n packages: Partial<Record<SanityPackage, PackageInfo>>\n workspace: WorkspaceInfo\n}\n\nexport interface ExecutionContext {\n binaryPath: string | null\n packageManager: PackageManager | null\n resolvedFrom: 'global' | 'local' | 'npx' | 'unknown'\n}\n\nexport interface WorkspaceInfo {\n /** True when bunfig.toml exists at workspace root (bun project marker). */\n bunfig: boolean\n hasMultipleLockfiles: boolean\n lockfile: {\n path: string\n type: LockfileType\n } | null\n nearestPackageJson: string | null\n root: string\n type: WorkspaceType\n /** True when .yarnrc.yml exists at workspace root (Yarn Berry / v2+). */\n yarnBerry: boolean\n}\n\nexport interface PackageInfo {\n declared: PackageDeclaration | null\n installed: InstalledPackage | null\n override: PackageOverride | null\n}\n\nexport interface PackageDeclaration {\n declaredVersionRange: string\n dependencyType: 'dependencies' | 'devDependencies'\n packageJsonPath: string\n versionRange: string\n}\n\nexport interface PackageOverride {\n mechanism: 'npm-overrides' | 'pnpm-overrides' | 'yarn-resolutions'\n packageJsonPath: string\n versionRange: string\n}\n\nexport interface InstalledPackage {\n cliDependencyRange: string | null\n path: string\n version: string\n}\n\nexport interface GlobalInstallation {\n isActive: boolean\n packageManager: LockfileType\n packageName: SanityPackage\n /** Filesystem path to the global installation, or null when it can't be determined. */\n path: string | null\n version: string\n}\n\nexport type IssueType =\n | 'cli-not-installed'\n | 'cli-version-incompatible'\n | 'conflicting-cli-dependency'\n | 'declared-not-installed'\n | 'global-cli-incompatible'\n | 'global-local-mismatch'\n | 'multiple-lockfiles'\n | 'override-in-effect'\n | 'redundant-cli-dependency'\n\nexport type IssueSeverity = 'error' | 'info' | 'warning'\n\nexport interface Issue {\n message: string\n packageName: SanityPackage | null\n severity: IssueSeverity\n suggestion: string | null\n type: IssueType\n}\n\nexport {type PackageManager} from '../packageManagerChoice.js'\n"],"names":[],"mappings":"AAkGA,WAA8D"}
@@ -1,5 +1,6 @@
1
1
  import path from 'node:path';
2
2
  import { isInteractive } from '@sanity/cli-core';
3
+ import { getRunningPackageManager } from '@sanity/cli-core/package-manager';
3
4
  import { select } from '@sanity/cli-core/ux';
4
5
  // eslint-disable-next-line unicorn/no-named-default
5
6
  import { default as preferredPM } from 'preferred-pm';
@@ -157,25 +158,5 @@ async function getMostLikelyInstalledPackageManager(rootDir) {
157
158
  const running = getRunningPackageManager();
158
159
  return running && installed.includes(running) ? running : undefined;
159
160
  }
160
- function getRunningPackageManager() {
161
- // Yes, the env var is lowercase - it is set by the package managers themselves
162
- const agent = process.env.npm_config_user_agent || '';
163
- if (agent.includes('yarn')) {
164
- return 'yarn';
165
- }
166
- if (agent.includes('pnpm')) {
167
- return 'pnpm';
168
- }
169
- if (agent.includes('bun')) {
170
- return 'bun';
171
- }
172
- // Both yarn and pnpm does a `npm/?` thing, thus the slightly different match here
173
- // Theoretically not needed since we check for yarn/pnpm above, but in case other
174
- // package managers do the same thing, we'll (hopefully) catch them here.
175
- if (/^npm\/\d/.test(agent)) {
176
- return 'npm';
177
- }
178
- return undefined;
179
- }
180
161
 
181
162
  //# sourceMappingURL=packageManagerChoice.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/util/packageManager/packageManagerChoice.ts"],"sourcesContent":["import path from 'node:path'\n\nimport {isInteractive} from '@sanity/cli-core'\nimport {select} from '@sanity/cli-core/ux'\n// eslint-disable-next-line unicorn/no-named-default\nimport {default as preferredPM} from 'preferred-pm'\nimport which from 'which'\n\nexport type PackageManager = 'bun' | 'manual' | 'npm' | 'pnpm' | 'yarn'\n\nconst EXPERIMENTAL = new Set(['bun'])\n\nexport const ALLOWED_PACKAGE_MANAGERS: readonly PackageManager[] = [\n 'npm',\n 'yarn',\n 'pnpm',\n 'bun',\n 'manual',\n] as const\n\nexport const allowedPackageManagersString = ALLOWED_PACKAGE_MANAGERS.join(' | ')\n\n/**\n * Attempts to resolve the most optimal package manager to use to install/upgrade\n * packages/dependencies at a given path. It does so by looking for package manager\n * specific lockfiles. If it finds a lockfile belonging to a certain package manager,\n * it prioritizes this one. However, if that package manager is not installed, it will\n * prompt the user for which one they want to use and hint at the most optimal one\n * not being installed.\n *\n * Note that this function also takes local npm binary paths into account - for instance,\n * `yarn` can be installed as a dependency of the project instead of globally, and it\n * will use that is available.\n *\n * The user can also select 'manual' to skip the process and run their preferred package\n * manager manually. Commands using this function must take this `manual` choice into\n * account and act accordingly if chosen.\n *\n * @param workDir - The working directory where a lockfile is most likely to be present\n * @param options - Pass `interactive: false` to fall back to npm if most optimal is\n * not available, instead of prompting\n * @returns Object of `chosen` and, if a lockfile is found, the `mostOptimal` choice\n */\nexport async function getPackageManagerChoice(\n workDir: string,\n options: {interactive: boolean},\n): Promise<{chosen: PackageManager; mostOptimal?: PackageManager}> {\n const rootDir = workDir || process.cwd()\n const preferred = (await preferredPM(rootDir))?.name\n\n if (preferred && (await hasCommand(preferred, rootDir))) {\n // There is an optimal/preferred package manager, and the user has it installed!\n return {chosen: preferred, mostOptimal: preferred}\n }\n\n const mostLikelyPM = await getMostLikelyInstalledPackageManager(rootDir)\n const interactive =\n typeof options.interactive === 'boolean' ? options.interactive : isInteractive()\n if (!interactive) {\n // We can't ask the user for their preference, so fall back to either the one that is being run\n // or whatever is installed on the system (npm being the preferred choice).\n // Note that the most optimal choice is already picked above if available.\n return {chosen: mostLikelyPM || (await getFallback(rootDir)), mostOptimal: preferred}\n }\n\n // We can ask the user for their preference, hurray!\n const messageSuffix = preferred ? ` (preferred is ${preferred}, but is not installed)` : ''\n const installed = await getAvailablePackageManagers(rootDir)\n const chosen = await select<PackageManager>({\n choices: installed.map((pm) => ({\n name: EXPERIMENTAL.has(pm) ? `${pm} (experimental)` : pm,\n value: pm,\n })),\n default: preferred || mostLikelyPM,\n message: `Package manager to use for installing dependencies?${messageSuffix}`,\n })\n\n return {chosen, mostOptimal: preferred}\n}\n\nasync function getFallback(cwd: string): Promise<PackageManager> {\n if (await hasNpmInstalled(cwd)) {\n return 'npm'\n }\n\n if (await hasYarnInstalled(cwd)) {\n return 'yarn'\n }\n\n if (await hasPnpmInstalled(cwd)) {\n return 'pnpm'\n }\n\n if (await hasBunInstalled(cwd)) {\n return 'bun'\n }\n\n return 'manual'\n}\n\nasync function getAvailablePackageManagers(cwd: string): Promise<PackageManager[]> {\n const [npm, yarn, pnpm, bun] = await Promise.all([\n hasNpmInstalled(cwd),\n hasYarnInstalled(cwd),\n hasPnpmInstalled(cwd),\n hasBunInstalled(cwd),\n ])\n\n const choices = [npm && 'npm', yarn && 'yarn', pnpm && 'pnpm', bun && 'bun', 'manual']\n return choices.filter((pm): pm is PackageManager => pm !== false)\n}\n\nfunction hasNpmInstalled(cwd?: string): Promise<boolean> {\n return hasCommand('npm', cwd)\n}\n\nfunction hasYarnInstalled(cwd?: string): Promise<boolean> {\n return hasCommand('yarn', cwd)\n}\n\nfunction hasPnpmInstalled(cwd?: string): Promise<boolean> {\n return hasCommand('pnpm', cwd)\n}\n\nfunction hasBunInstalled(cwd?: string): Promise<boolean> {\n return hasCommand('bun', cwd)\n}\n\nfunction getNpmRunPath(cwd: string): string {\n let previous\n let cwdPath = path.resolve(cwd)\n const result: string[] = []\n\n while (previous !== cwdPath) {\n result.push(path.join(cwdPath, 'node_modules', '.bin'))\n previous = cwdPath\n cwdPath = path.resolve(cwdPath, '..')\n }\n\n result.push(path.resolve(cwd, process.execPath, '..'))\n\n const pathEnv = process.env[getPathEnvVarKey()]\n return [...result, pathEnv].join(path.delimiter)\n}\n\nexport function getPartialEnvWithNpmPath(cwd: string): NodeJS.ProcessEnv {\n const key = getPathEnvVarKey()\n return {[key]: getNpmRunPath(cwd)}\n}\n\nfunction getPathEnvVarKey(): string {\n if (process.platform !== 'win32') {\n return 'PATH'\n }\n\n return (\n Object.keys(process.env)\n .toReversed()\n .find((key) => key.toUpperCase() === 'PATH') || 'Path'\n )\n}\n\nfunction getCommandPath(cmd: string, cwd?: string): Promise<string | null> {\n const options = cwd ? {path: getNpmRunPath(cwd)} : undefined\n return which(cmd, options).catch(() => null)\n}\n\nfunction hasCommand(cmd: string, cwd?: string): Promise<boolean> {\n return getCommandPath(cmd, cwd).then((cmdPath) => cmdPath !== null)\n}\n\nasync function getMostLikelyInstalledPackageManager(\n rootDir: string,\n): Promise<PackageManager | undefined> {\n const installed = await getAvailablePackageManagers(rootDir)\n const running = getRunningPackageManager()\n return running && installed.includes(running) ? running : undefined\n}\n\nfunction getRunningPackageManager(): PackageManager | undefined {\n // Yes, the env var is lowercase - it is set by the package managers themselves\n const agent = process.env.npm_config_user_agent || ''\n\n if (agent.includes('yarn')) {\n return 'yarn'\n }\n\n if (agent.includes('pnpm')) {\n return 'pnpm'\n }\n\n if (agent.includes('bun')) {\n return 'bun'\n }\n\n // Both yarn and pnpm does a `npm/?` thing, thus the slightly different match here\n // Theoretically not needed since we check for yarn/pnpm above, but in case other\n // package managers do the same thing, we'll (hopefully) catch them here.\n if (/^npm\\/\\d/.test(agent)) {\n return 'npm'\n }\n\n return undefined\n}\n"],"names":["path","isInteractive","select","default","preferredPM","which","EXPERIMENTAL","Set","ALLOWED_PACKAGE_MANAGERS","allowedPackageManagersString","join","getPackageManagerChoice","workDir","options","rootDir","process","cwd","preferred","name","hasCommand","chosen","mostOptimal","mostLikelyPM","getMostLikelyInstalledPackageManager","interactive","getFallback","messageSuffix","installed","getAvailablePackageManagers","choices","map","pm","has","value","message","hasNpmInstalled","hasYarnInstalled","hasPnpmInstalled","hasBunInstalled","npm","yarn","pnpm","bun","Promise","all","filter","getNpmRunPath","previous","cwdPath","resolve","result","push","execPath","pathEnv","env","getPathEnvVarKey","delimiter","getPartialEnvWithNpmPath","key","platform","Object","keys","toReversed","find","toUpperCase","getCommandPath","cmd","undefined","catch","then","cmdPath","running","getRunningPackageManager","includes","agent","npm_config_user_agent","test"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../src/util/packageManager/packageManagerChoice.ts"],"sourcesContent":["import path from 'node:path'\n\nimport {isInteractive} from '@sanity/cli-core'\nimport {getRunningPackageManager} from '@sanity/cli-core/package-manager'\nimport {select} from '@sanity/cli-core/ux'\n// eslint-disable-next-line unicorn/no-named-default\nimport {default as preferredPM} from 'preferred-pm'\nimport which from 'which'\n\nexport type PackageManager = 'bun' | 'manual' | 'npm' | 'pnpm' | 'yarn'\n\nconst EXPERIMENTAL = new Set(['bun'])\n\nexport const ALLOWED_PACKAGE_MANAGERS: readonly PackageManager[] = [\n 'npm',\n 'yarn',\n 'pnpm',\n 'bun',\n 'manual',\n] as const\n\nexport const allowedPackageManagersString = ALLOWED_PACKAGE_MANAGERS.join(' | ')\n\n/**\n * Attempts to resolve the most optimal package manager to use to install/upgrade\n * packages/dependencies at a given path. It does so by looking for package manager\n * specific lockfiles. If it finds a lockfile belonging to a certain package manager,\n * it prioritizes this one. However, if that package manager is not installed, it will\n * prompt the user for which one they want to use and hint at the most optimal one\n * not being installed.\n *\n * Note that this function also takes local npm binary paths into account - for instance,\n * `yarn` can be installed as a dependency of the project instead of globally, and it\n * will use that is available.\n *\n * The user can also select 'manual' to skip the process and run their preferred package\n * manager manually. Commands using this function must take this `manual` choice into\n * account and act accordingly if chosen.\n *\n * @param workDir - The working directory where a lockfile is most likely to be present\n * @param options - Pass `interactive: false` to fall back to npm if most optimal is\n * not available, instead of prompting\n * @returns Object of `chosen` and, if a lockfile is found, the `mostOptimal` choice\n */\nexport async function getPackageManagerChoice(\n workDir: string,\n options: {interactive: boolean},\n): Promise<{chosen: PackageManager; mostOptimal?: PackageManager}> {\n const rootDir = workDir || process.cwd()\n const preferred = (await preferredPM(rootDir))?.name\n\n if (preferred && (await hasCommand(preferred, rootDir))) {\n // There is an optimal/preferred package manager, and the user has it installed!\n return {chosen: preferred, mostOptimal: preferred}\n }\n\n const mostLikelyPM = await getMostLikelyInstalledPackageManager(rootDir)\n const interactive =\n typeof options.interactive === 'boolean' ? options.interactive : isInteractive()\n if (!interactive) {\n // We can't ask the user for their preference, so fall back to either the one that is being run\n // or whatever is installed on the system (npm being the preferred choice).\n // Note that the most optimal choice is already picked above if available.\n return {chosen: mostLikelyPM || (await getFallback(rootDir)), mostOptimal: preferred}\n }\n\n // We can ask the user for their preference, hurray!\n const messageSuffix = preferred ? ` (preferred is ${preferred}, but is not installed)` : ''\n const installed = await getAvailablePackageManagers(rootDir)\n const chosen = await select<PackageManager>({\n choices: installed.map((pm) => ({\n name: EXPERIMENTAL.has(pm) ? `${pm} (experimental)` : pm,\n value: pm,\n })),\n default: preferred || mostLikelyPM,\n message: `Package manager to use for installing dependencies?${messageSuffix}`,\n })\n\n return {chosen, mostOptimal: preferred}\n}\n\nasync function getFallback(cwd: string): Promise<PackageManager> {\n if (await hasNpmInstalled(cwd)) {\n return 'npm'\n }\n\n if (await hasYarnInstalled(cwd)) {\n return 'yarn'\n }\n\n if (await hasPnpmInstalled(cwd)) {\n return 'pnpm'\n }\n\n if (await hasBunInstalled(cwd)) {\n return 'bun'\n }\n\n return 'manual'\n}\n\nasync function getAvailablePackageManagers(cwd: string): Promise<PackageManager[]> {\n const [npm, yarn, pnpm, bun] = await Promise.all([\n hasNpmInstalled(cwd),\n hasYarnInstalled(cwd),\n hasPnpmInstalled(cwd),\n hasBunInstalled(cwd),\n ])\n\n const choices = [npm && 'npm', yarn && 'yarn', pnpm && 'pnpm', bun && 'bun', 'manual']\n return choices.filter((pm): pm is PackageManager => pm !== false)\n}\n\nfunction hasNpmInstalled(cwd?: string): Promise<boolean> {\n return hasCommand('npm', cwd)\n}\n\nfunction hasYarnInstalled(cwd?: string): Promise<boolean> {\n return hasCommand('yarn', cwd)\n}\n\nfunction hasPnpmInstalled(cwd?: string): Promise<boolean> {\n return hasCommand('pnpm', cwd)\n}\n\nfunction hasBunInstalled(cwd?: string): Promise<boolean> {\n return hasCommand('bun', cwd)\n}\n\nfunction getNpmRunPath(cwd: string): string {\n let previous\n let cwdPath = path.resolve(cwd)\n const result: string[] = []\n\n while (previous !== cwdPath) {\n result.push(path.join(cwdPath, 'node_modules', '.bin'))\n previous = cwdPath\n cwdPath = path.resolve(cwdPath, '..')\n }\n\n result.push(path.resolve(cwd, process.execPath, '..'))\n\n const pathEnv = process.env[getPathEnvVarKey()]\n return [...result, pathEnv].join(path.delimiter)\n}\n\nexport function getPartialEnvWithNpmPath(cwd: string): NodeJS.ProcessEnv {\n const key = getPathEnvVarKey()\n return {[key]: getNpmRunPath(cwd)}\n}\n\nfunction getPathEnvVarKey(): string {\n if (process.platform !== 'win32') {\n return 'PATH'\n }\n\n return (\n Object.keys(process.env)\n .toReversed()\n .find((key) => key.toUpperCase() === 'PATH') || 'Path'\n )\n}\n\nfunction getCommandPath(cmd: string, cwd?: string): Promise<string | null> {\n const options = cwd ? {path: getNpmRunPath(cwd)} : undefined\n return which(cmd, options).catch(() => null)\n}\n\nfunction hasCommand(cmd: string, cwd?: string): Promise<boolean> {\n return getCommandPath(cmd, cwd).then((cmdPath) => cmdPath !== null)\n}\n\nasync function getMostLikelyInstalledPackageManager(\n rootDir: string,\n): Promise<PackageManager | undefined> {\n const installed = await getAvailablePackageManagers(rootDir)\n const running = getRunningPackageManager()\n return running && installed.includes(running) ? running : undefined\n}\n"],"names":["path","isInteractive","getRunningPackageManager","select","default","preferredPM","which","EXPERIMENTAL","Set","ALLOWED_PACKAGE_MANAGERS","allowedPackageManagersString","join","getPackageManagerChoice","workDir","options","rootDir","process","cwd","preferred","name","hasCommand","chosen","mostOptimal","mostLikelyPM","getMostLikelyInstalledPackageManager","interactive","getFallback","messageSuffix","installed","getAvailablePackageManagers","choices","map","pm","has","value","message","hasNpmInstalled","hasYarnInstalled","hasPnpmInstalled","hasBunInstalled","npm","yarn","pnpm","bun","Promise","all","filter","getNpmRunPath","previous","cwdPath","resolve","result","push","execPath","pathEnv","env","getPathEnvVarKey","delimiter","getPartialEnvWithNpmPath","key","platform","Object","keys","toReversed","find","toUpperCase","getCommandPath","cmd","undefined","catch","then","cmdPath","running","includes"],"mappings":"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"}
@@ -1,3 +1,4 @@
1
+ import { getYarnMajorVersion } from '@sanity/cli-core/package-manager';
1
2
  import { execa } from 'execa';
2
3
  import { getPartialEnvWithNpmPath } from './packageManagerChoice.js';
3
4
  /**
@@ -52,8 +53,10 @@ import { getPartialEnvWithNpmPath } from './packageManagerChoice.js';
52
53
  }
53
54
  case 'yarn':
54
55
  {
56
+ const yarnMajor = getYarnMajorVersion();
57
+ const upgradeCmd = yarnMajor !== undefined && yarnMajor >= 2 ? 'up' : 'upgrade';
55
58
  const yarnArgs = [
56
- 'upgrade ',
59
+ upgradeCmd,
57
60
  ...upgradePackageArgs
58
61
  ];
59
62
  output.log(`Running 'yarn ${yarnArgs.join(' ')}'`);
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/util/packageManager/upgradePackages.ts"],"sourcesContent":["import {type Output} from '@sanity/cli-core'\nimport {execa, type Options, type Result} from 'execa'\n\nimport {getPartialEnvWithNpmPath, type PackageManager} from './packageManagerChoice.js'\n\n/**\n * @internal\n */\ninterface UpgradeOptions {\n packageManager: PackageManager\n packages: [name: string, version: string][]\n}\n\n/**\n * @internal\n */\nexport async function upgradePackages(\n options: UpgradeOptions,\n context: {output: Output; workDir: string},\n): Promise<void> {\n const {packageManager, packages} = options\n const {output, workDir} = context\n const execOptions: Options = {\n cwd: workDir,\n encoding: 'utf8',\n env: getPartialEnvWithNpmPath(workDir),\n stdio: 'inherit',\n }\n const upgradePackageArgs = packages.map((pkg) => pkg.join('@'))\n let result: Result | undefined\n switch (packageManager) {\n case 'bun': {\n const bunArgs = ['update', ...upgradePackageArgs]\n output.log(`Running 'bun ${bunArgs.join(' ')}'`)\n result = await execa('bun', bunArgs, execOptions)\n\n break\n }\n case 'manual': {\n output.log(\n `Manual installation selected - run 'npm upgrade ${upgradePackageArgs.join(' ')}' or equivalent`,\n )\n\n break\n }\n case 'npm': {\n const npmArgs = ['install', '--legacy-peer-deps', ...upgradePackageArgs]\n output.log(`Running 'npm ${npmArgs.join(' ')}'`)\n result = await execa('npm', npmArgs, execOptions)\n\n break\n }\n case 'pnpm': {\n const pnpmArgs = ['upgrade', ...upgradePackageArgs]\n output.log(`Running 'pnpm ${pnpmArgs.join(' ')}'`)\n result = await execa('pnpm', pnpmArgs, execOptions)\n\n break\n }\n case 'yarn': {\n const yarnArgs = ['upgrade ', ...upgradePackageArgs]\n output.log(`Running 'yarn ${yarnArgs.join(' ')}'`)\n result = await execa('yarn', yarnArgs, execOptions)\n\n break\n }\n // No default\n }\n\n if (result?.exitCode || result?.failed) {\n throw new Error('Package upgrade failed')\n }\n}\n"],"names":["execa","getPartialEnvWithNpmPath","upgradePackages","options","context","packageManager","packages","output","workDir","execOptions","cwd","encoding","env","stdio","upgradePackageArgs","map","pkg","join","result","bunArgs","log","npmArgs","pnpmArgs","yarnArgs","exitCode","failed","Error"],"mappings":"AACA,SAAQA,KAAK,QAAkC,QAAO;AAEtD,SAAQC,wBAAwB,QAA4B,4BAA2B;AAUvF;;CAEC,GACD,OAAO,eAAeC,gBACpBC,OAAuB,EACvBC,OAA0C;IAE1C,MAAM,EAACC,cAAc,EAAEC,QAAQ,EAAC,GAAGH;IACnC,MAAM,EAACI,MAAM,EAAEC,OAAO,EAAC,GAAGJ;IAC1B,MAAMK,cAAuB;QAC3BC,KAAKF;QACLG,UAAU;QACVC,KAAKX,yBAAyBO;QAC9BK,OAAO;IACT;IACA,MAAMC,qBAAqBR,SAASS,GAAG,CAAC,CAACC,MAAQA,IAAIC,IAAI,CAAC;IAC1D,IAAIC;IACJ,OAAQb;QACN,KAAK;YAAO;gBACV,MAAMc,UAAU;oBAAC;uBAAaL;iBAAmB;gBACjDP,OAAOa,GAAG,CAAC,CAAC,aAAa,EAAED,QAAQF,IAAI,CAAC,KAAK,CAAC,CAAC;gBAC/CC,SAAS,MAAMlB,MAAM,OAAOmB,SAASV;gBAErC;YACF;QACA,KAAK;YAAU;gBACbF,OAAOa,GAAG,CACR,CAAC,gDAAgD,EAAEN,mBAAmBG,IAAI,CAAC,KAAK,eAAe,CAAC;gBAGlG;YACF;QACA,KAAK;YAAO;gBACV,MAAMI,UAAU;oBAAC;oBAAW;uBAAyBP;iBAAmB;gBACxEP,OAAOa,GAAG,CAAC,CAAC,aAAa,EAAEC,QAAQJ,IAAI,CAAC,KAAK,CAAC,CAAC;gBAC/CC,SAAS,MAAMlB,MAAM,OAAOqB,SAASZ;gBAErC;YACF;QACA,KAAK;YAAQ;gBACX,MAAMa,WAAW;oBAAC;uBAAcR;iBAAmB;gBACnDP,OAAOa,GAAG,CAAC,CAAC,cAAc,EAAEE,SAASL,IAAI,CAAC,KAAK,CAAC,CAAC;gBACjDC,SAAS,MAAMlB,MAAM,QAAQsB,UAAUb;gBAEvC;YACF;QACA,KAAK;YAAQ;gBACX,MAAMc,WAAW;oBAAC;uBAAeT;iBAAmB;gBACpDP,OAAOa,GAAG,CAAC,CAAC,cAAc,EAAEG,SAASN,IAAI,CAAC,KAAK,CAAC,CAAC;gBACjDC,SAAS,MAAMlB,MAAM,QAAQuB,UAAUd;gBAEvC;YACF;IAEF;IAEA,IAAIS,QAAQM,YAAYN,QAAQO,QAAQ;QACtC,MAAM,IAAIC,MAAM;IAClB;AACF"}
1
+ {"version":3,"sources":["../../../src/util/packageManager/upgradePackages.ts"],"sourcesContent":["import {type Output} from '@sanity/cli-core'\nimport {getYarnMajorVersion} from '@sanity/cli-core/package-manager'\nimport {execa, type Options, type Result} from 'execa'\n\nimport {getPartialEnvWithNpmPath, type PackageManager} from './packageManagerChoice.js'\n\n/**\n * @internal\n */\ninterface UpgradeOptions {\n packageManager: PackageManager\n packages: [name: string, version: string][]\n}\n\n/**\n * @internal\n */\nexport async function upgradePackages(\n options: UpgradeOptions,\n context: {output: Output; workDir: string},\n): Promise<void> {\n const {packageManager, packages} = options\n const {output, workDir} = context\n const execOptions: Options = {\n cwd: workDir,\n encoding: 'utf8',\n env: getPartialEnvWithNpmPath(workDir),\n stdio: 'inherit',\n }\n const upgradePackageArgs = packages.map((pkg) => pkg.join('@'))\n let result: Result | undefined\n switch (packageManager) {\n case 'bun': {\n const bunArgs = ['update', ...upgradePackageArgs]\n output.log(`Running 'bun ${bunArgs.join(' ')}'`)\n result = await execa('bun', bunArgs, execOptions)\n\n break\n }\n case 'manual': {\n output.log(\n `Manual installation selected - run 'npm upgrade ${upgradePackageArgs.join(' ')}' or equivalent`,\n )\n\n break\n }\n case 'npm': {\n const npmArgs = ['install', '--legacy-peer-deps', ...upgradePackageArgs]\n output.log(`Running 'npm ${npmArgs.join(' ')}'`)\n result = await execa('npm', npmArgs, execOptions)\n\n break\n }\n case 'pnpm': {\n const pnpmArgs = ['upgrade', ...upgradePackageArgs]\n output.log(`Running 'pnpm ${pnpmArgs.join(' ')}'`)\n result = await execa('pnpm', pnpmArgs, execOptions)\n\n break\n }\n case 'yarn': {\n const yarnMajor = getYarnMajorVersion()\n const upgradeCmd = yarnMajor !== undefined && yarnMajor >= 2 ? 'up' : 'upgrade'\n const yarnArgs = [upgradeCmd, ...upgradePackageArgs]\n output.log(`Running 'yarn ${yarnArgs.join(' ')}'`)\n result = await execa('yarn', yarnArgs, execOptions)\n\n break\n }\n // No default\n }\n\n if (result?.exitCode || result?.failed) {\n throw new Error('Package upgrade failed')\n }\n}\n"],"names":["getYarnMajorVersion","execa","getPartialEnvWithNpmPath","upgradePackages","options","context","packageManager","packages","output","workDir","execOptions","cwd","encoding","env","stdio","upgradePackageArgs","map","pkg","join","result","bunArgs","log","npmArgs","pnpmArgs","yarnMajor","upgradeCmd","undefined","yarnArgs","exitCode","failed","Error"],"mappings":"AACA,SAAQA,mBAAmB,QAAO,mCAAkC;AACpE,SAAQC,KAAK,QAAkC,QAAO;AAEtD,SAAQC,wBAAwB,QAA4B,4BAA2B;AAUvF;;CAEC,GACD,OAAO,eAAeC,gBACpBC,OAAuB,EACvBC,OAA0C;IAE1C,MAAM,EAACC,cAAc,EAAEC,QAAQ,EAAC,GAAGH;IACnC,MAAM,EAACI,MAAM,EAAEC,OAAO,EAAC,GAAGJ;IAC1B,MAAMK,cAAuB;QAC3BC,KAAKF;QACLG,UAAU;QACVC,KAAKX,yBAAyBO;QAC9BK,OAAO;IACT;IACA,MAAMC,qBAAqBR,SAASS,GAAG,CAAC,CAACC,MAAQA,IAAIC,IAAI,CAAC;IAC1D,IAAIC;IACJ,OAAQb;QACN,KAAK;YAAO;gBACV,MAAMc,UAAU;oBAAC;uBAAaL;iBAAmB;gBACjDP,OAAOa,GAAG,CAAC,CAAC,aAAa,EAAED,QAAQF,IAAI,CAAC,KAAK,CAAC,CAAC;gBAC/CC,SAAS,MAAMlB,MAAM,OAAOmB,SAASV;gBAErC;YACF;QACA,KAAK;YAAU;gBACbF,OAAOa,GAAG,CACR,CAAC,gDAAgD,EAAEN,mBAAmBG,IAAI,CAAC,KAAK,eAAe,CAAC;gBAGlG;YACF;QACA,KAAK;YAAO;gBACV,MAAMI,UAAU;oBAAC;oBAAW;uBAAyBP;iBAAmB;gBACxEP,OAAOa,GAAG,CAAC,CAAC,aAAa,EAAEC,QAAQJ,IAAI,CAAC,KAAK,CAAC,CAAC;gBAC/CC,SAAS,MAAMlB,MAAM,OAAOqB,SAASZ;gBAErC;YACF;QACA,KAAK;YAAQ;gBACX,MAAMa,WAAW;oBAAC;uBAAcR;iBAAmB;gBACnDP,OAAOa,GAAG,CAAC,CAAC,cAAc,EAAEE,SAASL,IAAI,CAAC,KAAK,CAAC,CAAC;gBACjDC,SAAS,MAAMlB,MAAM,QAAQsB,UAAUb;gBAEvC;YACF;QACA,KAAK;YAAQ;gBACX,MAAMc,YAAYxB;gBAClB,MAAMyB,aAAaD,cAAcE,aAAaF,aAAa,IAAI,OAAO;gBACtE,MAAMG,WAAW;oBAACF;uBAAeV;iBAAmB;gBACpDP,OAAOa,GAAG,CAAC,CAAC,cAAc,EAAEM,SAAST,IAAI,CAAC,KAAK,CAAC,CAAC;gBACjDC,SAAS,MAAMlB,MAAM,QAAQ0B,UAAUjB;gBAEvC;YACF;IAEF;IAEA,IAAIS,QAAQS,YAAYT,QAAQU,QAAQ;QACtC,MAAM,IAAIC,MAAM;IAClB;AACF"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Race a promise against a timeout, with proper cleanup of the timeout timer
3
+ *
4
+ * @param promise - The promise to race
5
+ * @param timeout - Timeout in milliseconds
6
+ * @returns The promise result, or null if timeout wins
7
+ */ export async function promiseRaceWithTimeout(promise, timeout) {
8
+ let timeoutId;
9
+ try {
10
+ const result = await Promise.race([
11
+ promise,
12
+ new Promise((resolve)=>{
13
+ timeoutId = setTimeout(()=>resolve(null), timeout);
14
+ })
15
+ ]);
16
+ // Clear timeout if promise won
17
+ if (timeoutId && result !== null) {
18
+ clearTimeout(timeoutId);
19
+ }
20
+ return result;
21
+ } finally{
22
+ if (timeoutId) {
23
+ clearTimeout(timeoutId);
24
+ }
25
+ }
26
+ }
27
+
28
+ //# sourceMappingURL=promiseRaceWithTimeout.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/util/promiseRaceWithTimeout.ts"],"sourcesContent":["/**\n * Race a promise against a timeout, with proper cleanup of the timeout timer\n *\n * @param promise - The promise to race\n * @param timeout - Timeout in milliseconds\n * @returns The promise result, or null if timeout wins\n */\nexport async function promiseRaceWithTimeout<T>(\n promise: Promise<T>,\n timeout: number,\n): Promise<T | null> {\n let timeoutId: NodeJS.Timeout | undefined\n\n try {\n const result = await Promise.race([\n promise,\n new Promise<null>((resolve) => {\n timeoutId = setTimeout(() => resolve(null), timeout)\n }),\n ])\n\n // Clear timeout if promise won\n if (timeoutId && result !== null) {\n clearTimeout(timeoutId)\n }\n\n return result\n } finally {\n if (timeoutId) {\n clearTimeout(timeoutId)\n }\n }\n}\n"],"names":["promiseRaceWithTimeout","promise","timeout","timeoutId","result","Promise","race","resolve","setTimeout","clearTimeout"],"mappings":"AAAA;;;;;;CAMC,GACD,OAAO,eAAeA,uBACpBC,OAAmB,EACnBC,OAAe;IAEf,IAAIC;IAEJ,IAAI;QACF,MAAMC,SAAS,MAAMC,QAAQC,IAAI,CAAC;YAChCL;YACA,IAAII,QAAc,CAACE;gBACjBJ,YAAYK,WAAW,IAAMD,QAAQ,OAAOL;YAC9C;SACD;QAED,+BAA+B;QAC/B,IAAIC,aAAaC,WAAW,MAAM;YAChCK,aAAaN;QACf;QAEA,OAAOC;IACT,SAAU;QACR,IAAID,WAAW;YACbM,aAAaN;QACf;IACF;AACF"}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/util/readdirRecursive.ts"],"sourcesContent":["import fs from 'node:fs/promises'\nimport path from 'node:path'\n\nexport interface ReaddirItem {\n isDir: boolean\n path: string\n}\n\nexport async function readdirRecursive(dir: string): Promise<ReaddirItem[]> {\n let content: ReaddirItem[] = []\n\n const currentPath = path.resolve(dir)\n const dirContent = (await fs.readdir(currentPath)).map((item) => path.join(currentPath, item))\n\n for (const subPath of dirContent) {\n const stat = await fs.stat(subPath)\n const isDir = stat.isDirectory()\n content.push({isDir, path: subPath})\n\n if (isDir) {\n content = [...content, ...(await readdirRecursive(subPath))]\n }\n }\n\n return content\n}\n"],"names":["fs","path","readdirRecursive","dir","content","currentPath","resolve","dirContent","readdir","map","item","join","subPath","stat","isDir","isDirectory","push"],"mappings":"AAAA,OAAOA,QAAQ,mBAAkB;AACjC,OAAOC,UAAU,YAAW;AAO5B,OAAO,eAAeC,iBAAiBC,GAAW;IAChD,IAAIC,UAAyB,EAAE;IAE/B,MAAMC,cAAcJ,KAAKK,OAAO,CAACH;IACjC,MAAMI,aAAa,AAAC,CAAA,MAAMP,GAAGQ,OAAO,CAACH,YAAW,EAAGI,GAAG,CAAC,CAACC,OAAST,KAAKU,IAAI,CAACN,aAAaK;IAExF,KAAK,MAAME,WAAWL,WAAY;QAChC,MAAMM,OAAO,MAAMb,GAAGa,IAAI,CAACD;QAC3B,MAAME,QAAQD,KAAKE,WAAW;QAC9BX,QAAQY,IAAI,CAAC;YAACF;YAAOb,MAAMW;QAAO;QAElC,IAAIE,OAAO;YACTV,UAAU;mBAAIA;mBAAa,MAAMF,iBAAiBU;aAAU;QAC9D;IACF;IAEA,OAAOR;AACT"}
1
+ {"version":3,"sources":["../../src/util/readdirRecursive.ts"],"sourcesContent":["import fs from 'node:fs/promises'\nimport path from 'node:path'\n\ninterface ReaddirItem {\n isDir: boolean\n path: string\n}\n\nexport async function readdirRecursive(dir: string): Promise<ReaddirItem[]> {\n let content: ReaddirItem[] = []\n\n const currentPath = path.resolve(dir)\n const dirContent = (await fs.readdir(currentPath)).map((item) => path.join(currentPath, item))\n\n for (const subPath of dirContent) {\n const stat = await fs.stat(subPath)\n const isDir = stat.isDirectory()\n content.push({isDir, path: subPath})\n\n if (isDir) {\n content = [...content, ...(await readdirRecursive(subPath))]\n }\n }\n\n return content\n}\n"],"names":["fs","path","readdirRecursive","dir","content","currentPath","resolve","dirContent","readdir","map","item","join","subPath","stat","isDir","isDirectory","push"],"mappings":"AAAA,OAAOA,QAAQ,mBAAkB;AACjC,OAAOC,UAAU,YAAW;AAO5B,OAAO,eAAeC,iBAAiBC,GAAW;IAChD,IAAIC,UAAyB,EAAE;IAE/B,MAAMC,cAAcJ,KAAKK,OAAO,CAACH;IACjC,MAAMI,aAAa,AAAC,CAAA,MAAMP,GAAGQ,OAAO,CAACH,YAAW,EAAGI,GAAG,CAAC,CAACC,OAAST,KAAKU,IAAI,CAACN,aAAaK;IAExF,KAAK,MAAME,WAAWL,WAAY;QAChC,MAAMM,OAAO,MAAMb,GAAGa,IAAI,CAACD;QAC3B,MAAME,QAAQD,KAAKE,WAAW;QAC9BX,QAAQY,IAAI,CAAC;YAACF;YAAOb,MAAMW;QAAO;QAElC,IAAIE,OAAO;YACTV,UAAU;mBAAIA;mBAAa,MAAMF,iBAAiBU;aAAU;QAC9D;IACF;IAEA,OAAOR;AACT"}
@@ -1,4 +1,4 @@
1
- import latestVersion from 'get-latest-version';
1
+ import { getLatestVersion } from 'get-latest-version';
2
2
  import promiseProps from 'promise-props-recursive';
3
3
  /**
4
4
  * Resolve the latest versions of given packages within their defined ranges
@@ -8,7 +8,7 @@ import promiseProps from 'promise-props-recursive';
8
8
  */ export function resolveLatestVersions(pkgs) {
9
9
  const lookups = {};
10
10
  for (const [packageName, range] of Object.entries(pkgs)){
11
- lookups[packageName] = range === 'latest' ? latestVersion(packageName, {
11
+ lookups[packageName] = range === 'latest' ? getLatestVersion(packageName, {
12
12
  range
13
13
  }).then(caretify) : range;
14
14
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/util/resolveLatestVersions.ts"],"sourcesContent":["import latestVersion from 'get-latest-version'\nimport promiseProps from 'promise-props-recursive'\n\n/**\n * Resolve the latest versions of given packages within their defined ranges\n *\n * @param pkgs - `{packageName: rangeOrTag}`\n * @returns Object of resolved version numbers\n */\nexport function resolveLatestVersions(\n pkgs: Record<string, string>,\n): Promise<Record<string, string>> {\n const lookups: Record<string, Promise<string> | string> = {}\n for (const [packageName, range] of Object.entries(pkgs)) {\n lookups[packageName] =\n range === 'latest' ? latestVersion(packageName, {range}).then(caretify) : range\n }\n\n return promiseProps(lookups)\n}\n\nfunction caretify(version: string | undefined) {\n return version ? `^${version}` : 'latest'\n}\n"],"names":["latestVersion","promiseProps","resolveLatestVersions","pkgs","lookups","packageName","range","Object","entries","then","caretify","version"],"mappings":"AAAA,OAAOA,mBAAmB,qBAAoB;AAC9C,OAAOC,kBAAkB,0BAAyB;AAElD;;;;;CAKC,GACD,OAAO,SAASC,sBACdC,IAA4B;IAE5B,MAAMC,UAAoD,CAAC;IAC3D,KAAK,MAAM,CAACC,aAAaC,MAAM,IAAIC,OAAOC,OAAO,CAACL,MAAO;QACvDC,OAAO,CAACC,YAAY,GAClBC,UAAU,WAAWN,cAAcK,aAAa;YAACC;QAAK,GAAGG,IAAI,CAACC,YAAYJ;IAC9E;IAEA,OAAOL,aAAaG;AACtB;AAEA,SAASM,SAASC,OAA2B;IAC3C,OAAOA,UAAU,CAAC,CAAC,EAAEA,SAAS,GAAG;AACnC"}
1
+ {"version":3,"sources":["../../src/util/resolveLatestVersions.ts"],"sourcesContent":["import {getLatestVersion} from 'get-latest-version'\nimport promiseProps from 'promise-props-recursive'\n\n/**\n * Resolve the latest versions of given packages within their defined ranges\n *\n * @param pkgs - `{packageName: rangeOrTag}`\n * @returns Object of resolved version numbers\n */\nexport function resolveLatestVersions(\n pkgs: Record<string, string>,\n): Promise<Record<string, string>> {\n const lookups: Record<string, Promise<string> | string> = {}\n for (const [packageName, range] of Object.entries(pkgs)) {\n lookups[packageName] =\n range === 'latest' ? getLatestVersion(packageName, {range}).then(caretify) : range\n }\n\n return promiseProps(lookups)\n}\n\nfunction caretify(version: string | undefined) {\n return version ? `^${version}` : 'latest'\n}\n"],"names":["getLatestVersion","promiseProps","resolveLatestVersions","pkgs","lookups","packageName","range","Object","entries","then","caretify","version"],"mappings":"AAAA,SAAQA,gBAAgB,QAAO,qBAAoB;AACnD,OAAOC,kBAAkB,0BAAyB;AAElD;;;;;CAKC,GACD,OAAO,SAASC,sBACdC,IAA4B;IAE5B,MAAMC,UAAoD,CAAC;IAC3D,KAAK,MAAM,CAACC,aAAaC,MAAM,IAAIC,OAAOC,OAAO,CAACL,MAAO;QACvDC,OAAO,CAACC,YAAY,GAClBC,UAAU,WAAWN,iBAAiBK,aAAa;YAACC;QAAK,GAAGG,IAAI,CAACC,YAAYJ;IACjF;IAEA,OAAOL,aAAaG;AACtB;AAEA,SAASM,SAASC,OAA2B;IAC3C,OAAOA,UAAU,CAAC,CAAC,EAAEA,SAAS,GAAG;AACnC"}
@@ -0,0 +1,54 @@
1
+ import { Flags } from '@oclif/core';
2
+ const OVERRIDE_SUFFIX = ' (overrides CLI configuration)';
3
+ /**
4
+ * Returns a `--project-id` / `-p` flag definition.
5
+ *
6
+ * Locked: flag name (`project-id`), char (`p`), `helpValue` (`<id>`), and parse (trims + validates non-empty).
7
+ */ export function getProjectIdFlag(options) {
8
+ const { description: baseDescription, helpGroup, semantics, ...rest } = options;
9
+ const isOverride = semantics === 'override';
10
+ const description = (baseDescription ?? 'Project ID to use') + (isOverride ? OVERRIDE_SUFFIX : '');
11
+ return {
12
+ 'project-id': Flags.string({
13
+ description,
14
+ helpGroup: helpGroup ?? (isOverride ? 'OVERRIDE' : undefined),
15
+ helpValue: '<id>',
16
+ ...rest,
17
+ char: 'p',
18
+ parse: async (input)=>{
19
+ const trimmed = input.trim();
20
+ if (trimmed === '') {
21
+ throw new Error('`--project-id` cannot be empty if provided');
22
+ }
23
+ return trimmed;
24
+ }
25
+ })
26
+ };
27
+ }
28
+ /**
29
+ * Returns a `--dataset` / `-d` flag definition.
30
+ *
31
+ * Locked: flag name (`dataset`), char (`d`), `helpValue` (`<name>`), and parse (trims + validates non-empty).
32
+ */ export function getDatasetFlag(options) {
33
+ const { description: baseDescription, helpGroup, semantics, ...rest } = options;
34
+ const isOverride = semantics === 'override';
35
+ const description = (baseDescription ?? 'Dataset to use') + (isOverride ? OVERRIDE_SUFFIX : '');
36
+ return {
37
+ dataset: Flags.string({
38
+ description,
39
+ helpGroup: helpGroup ?? (isOverride ? 'OVERRIDE' : undefined),
40
+ helpValue: '<name>',
41
+ ...rest,
42
+ char: 'd',
43
+ parse: async (input)=>{
44
+ const trimmed = input.trim();
45
+ if (trimmed === '') {
46
+ throw new Error('`--dataset` cannot be empty if provided');
47
+ }
48
+ return trimmed;
49
+ }
50
+ })
51
+ };
52
+ }
53
+
54
+ //# sourceMappingURL=sharedFlags.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/util/sharedFlags.ts"],"sourcesContent":["import {Flags} from '@oclif/core'\n\n/**\n * Controls how the flag relates to CLI configuration:\n *\n * - `'override'` — The command falls back to CLI config (sanity.cli.ts) when the flag is not\n * provided. The flag description automatically gets an \" (overrides CLI configuration)\" suffix,\n * and `helpGroup` defaults to `'OVERRIDE'`.\n *\n * - `'specify'` — The command does NOT fall back to CLI config; the flag is simply how the user\n * provides the value. No suffix is appended, and no default `helpGroup` is set.\n */\ntype FlagSemantics = 'override' | 'specify'\n\n/**\n * Options accepted by the shared flag getters.\n * Locked properties (char, parse, name, helpValue) are excluded to ensure\n * consistent behavior across all commands.\n */\ninterface SharedFlagOptions {\n /**\n * Controls description suffix and default helpGroup.\n * @see {@link FlagSemantics}\n */\n semantics: FlagSemantics\n\n dependsOn?: string[]\n description?: string\n env?: string\n exclusive?: string[]\n helpGroup?: string\n hidden?: boolean\n required?: boolean\n}\n\nconst OVERRIDE_SUFFIX = ' (overrides CLI configuration)'\n\n/**\n * Returns a `--project-id` / `-p` flag definition.\n *\n * Locked: flag name (`project-id`), char (`p`), `helpValue` (`<id>`), and parse (trims + validates non-empty).\n */\nexport function getProjectIdFlag(options: SharedFlagOptions) {\n const {description: baseDescription, helpGroup, semantics, ...rest} = options\n const isOverride = semantics === 'override'\n const description = (baseDescription ?? 'Project ID to use') + (isOverride ? OVERRIDE_SUFFIX : '')\n\n return {\n 'project-id': Flags.string({\n description,\n helpGroup: helpGroup ?? (isOverride ? 'OVERRIDE' : undefined),\n helpValue: '<id>',\n ...rest,\n char: 'p',\n parse: async (input: string) => {\n const trimmed = input.trim()\n if (trimmed === '') {\n throw new Error('`--project-id` cannot be empty if provided')\n }\n return trimmed\n },\n }),\n }\n}\n\n/**\n * Returns a `--dataset` / `-d` flag definition.\n *\n * Locked: flag name (`dataset`), char (`d`), `helpValue` (`<name>`), and parse (trims + validates non-empty).\n */\nexport function getDatasetFlag(options: SharedFlagOptions) {\n const {description: baseDescription, helpGroup, semantics, ...rest} = options\n const isOverride = semantics === 'override'\n const description = (baseDescription ?? 'Dataset to use') + (isOverride ? OVERRIDE_SUFFIX : '')\n\n return {\n dataset: Flags.string({\n description,\n helpGroup: helpGroup ?? (isOverride ? 'OVERRIDE' : undefined),\n helpValue: '<name>',\n ...rest,\n char: 'd',\n parse: async (input: string) => {\n const trimmed = input.trim()\n if (trimmed === '') {\n throw new Error('`--dataset` cannot be empty if provided')\n }\n return trimmed\n },\n }),\n }\n}\n"],"names":["Flags","OVERRIDE_SUFFIX","getProjectIdFlag","options","description","baseDescription","helpGroup","semantics","rest","isOverride","string","undefined","helpValue","char","parse","input","trimmed","trim","Error","getDatasetFlag","dataset"],"mappings":"AAAA,SAAQA,KAAK,QAAO,cAAa;AAmCjC,MAAMC,kBAAkB;AAExB;;;;CAIC,GACD,OAAO,SAASC,iBAAiBC,OAA0B;IACzD,MAAM,EAACC,aAAaC,eAAe,EAAEC,SAAS,EAAEC,SAAS,EAAE,GAAGC,MAAK,GAAGL;IACtE,MAAMM,aAAaF,cAAc;IACjC,MAAMH,cAAc,AAACC,CAAAA,mBAAmB,mBAAkB,IAAMI,CAAAA,aAAaR,kBAAkB,EAAC;IAEhG,OAAO;QACL,cAAcD,MAAMU,MAAM,CAAC;YACzBN;YACAE,WAAWA,aAAcG,CAAAA,aAAa,aAAaE,SAAQ;YAC3DC,WAAW;YACX,GAAGJ,IAAI;YACPK,MAAM;YACNC,OAAO,OAAOC;gBACZ,MAAMC,UAAUD,MAAME,IAAI;gBAC1B,IAAID,YAAY,IAAI;oBAClB,MAAM,IAAIE,MAAM;gBAClB;gBACA,OAAOF;YACT;QACF;IACF;AACF;AAEA;;;;CAIC,GACD,OAAO,SAASG,eAAehB,OAA0B;IACvD,MAAM,EAACC,aAAaC,eAAe,EAAEC,SAAS,EAAEC,SAAS,EAAE,GAAGC,MAAK,GAAGL;IACtE,MAAMM,aAAaF,cAAc;IACjC,MAAMH,cAAc,AAACC,CAAAA,mBAAmB,gBAAe,IAAMI,CAAAA,aAAaR,kBAAkB,EAAC;IAE7F,OAAO;QACLmB,SAASpB,MAAMU,MAAM,CAAC;YACpBN;YACAE,WAAWA,aAAcG,CAAAA,aAAa,aAAaE,SAAQ;YAC3DC,WAAW;YACX,GAAGJ,IAAI;YACPK,MAAM;YACNC,OAAO,OAAOC;gBACZ,MAAMC,UAAUD,MAAME,IAAI;gBAC1B,IAAID,YAAY,IAAI;oBAClB,MAAM,IAAIE,MAAM;gBAClB;gBACA,OAAOF;YACT;QACF;IACF;AACF"}
@@ -0,0 +1,30 @@
1
+ import { rm, stat } from 'node:fs/promises';
2
+ import { findTelemetryFiles } from './findTelemetryFiles.js';
3
+ import { telemetryStoreDebug } from './telemetryStoreDebug.js';
4
+ /**
5
+ * Cleans up telemetry files older than the specified number of days
6
+ * @internal
7
+ */ export async function cleanupOldTelemetryFiles(maxAgeDays = 7) {
8
+ try {
9
+ const files = await findTelemetryFiles();
10
+ const cutoffTime = Date.now() - maxAgeDays * 24 * 60 * 60 * 1000;
11
+ for (const filePath of files){
12
+ try {
13
+ const stats = await stat(filePath);
14
+ if (stats.mtime.getTime() < cutoffTime) {
15
+ telemetryStoreDebug('Cleaning up old telemetry file: %s', filePath);
16
+ await rm(filePath, {
17
+ force: true
18
+ });
19
+ }
20
+ } catch (error) {
21
+ telemetryStoreDebug('Error checking/removing old file %s: %o', filePath, error);
22
+ }
23
+ }
24
+ } catch (error) {
25
+ telemetryStoreDebug('Error during cleanup: %o', error);
26
+ // Don't throw - cleanup is best effort
27
+ }
28
+ }
29
+
30
+ //# sourceMappingURL=cleanupOldTelemetryFiles.js.map