@sanity/cli 6.0.0-alpha.9 → 6.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (613) hide show
  1. package/README.md +602 -291
  2. package/bin/run.js +2 -0
  3. package/dist/SanityHelp.js +51 -23
  4. package/dist/SanityHelp.js.map +1 -1
  5. package/dist/actions/auth/authServer.js +28 -22
  6. package/dist/actions/auth/authServer.js.map +1 -1
  7. package/dist/actions/auth/login/getProvider.js +49 -38
  8. package/dist/actions/auth/login/getProvider.js.map +1 -1
  9. package/dist/actions/auth/login/getSSOProvider.js +25 -19
  10. package/dist/actions/auth/login/getSSOProvider.js.map +1 -1
  11. package/dist/actions/auth/login/login.js +12 -33
  12. package/dist/actions/auth/login/login.js.map +1 -1
  13. package/dist/actions/auth/types.js.map +1 -1
  14. package/dist/actions/backup/downloadAsset.js +9 -9
  15. package/dist/actions/backup/downloadAsset.js.map +1 -1
  16. package/dist/actions/backup/downloadDocument.js +8 -8
  17. package/dist/actions/backup/downloadDocument.js.map +1 -1
  18. package/dist/actions/build/buildApp.js +55 -18
  19. package/dist/actions/build/buildApp.js.map +1 -1
  20. package/dist/actions/build/buildStaticFiles.js +3 -2
  21. package/dist/actions/build/buildStaticFiles.js.map +1 -1
  22. package/dist/actions/build/buildStudio.js +72 -44
  23. package/dist/actions/build/buildStudio.js.map +1 -1
  24. package/dist/actions/build/buildVendorDependencies.js +18 -52
  25. package/dist/actions/build/buildVendorDependencies.js.map +1 -1
  26. package/dist/actions/build/checkRequiredDependencies.js +13 -8
  27. package/dist/actions/build/checkRequiredDependencies.js.map +1 -1
  28. package/dist/actions/build/checkStudioDependencyVersions.js +19 -17
  29. package/dist/actions/build/checkStudioDependencyVersions.js.map +1 -1
  30. package/dist/actions/build/createExternalFromImportMap.js +1 -1
  31. package/dist/actions/build/createExternalFromImportMap.js.map +1 -1
  32. package/dist/actions/build/determineBasePath.js +5 -2
  33. package/dist/actions/build/determineBasePath.js.map +1 -1
  34. package/dist/actions/build/getViteConfig.js +47 -4
  35. package/dist/actions/build/getViteConfig.js.map +1 -1
  36. package/dist/actions/build/handlePrereleaseVersions.js +44 -0
  37. package/dist/actions/build/handlePrereleaseVersions.js.map +1 -0
  38. package/dist/actions/build/renderDocument.js +6 -10
  39. package/dist/actions/build/renderDocument.js.map +1 -1
  40. package/dist/actions/build/renderDocumentWorker/components/BasicDocument.js +4 -4
  41. package/dist/actions/build/renderDocumentWorker/components/BasicDocument.js.map +1 -1
  42. package/dist/actions/build/renderDocumentWorker/components/DefaultDocument.js +3 -3
  43. package/dist/actions/build/renderDocumentWorker/components/DefaultDocument.js.map +1 -1
  44. package/dist/actions/build/renderDocumentWorker/components/GlobalErrorHandler.js +1 -0
  45. package/dist/actions/build/renderDocumentWorker/components/GlobalErrorHandler.js.map +1 -1
  46. package/dist/actions/build/renderDocumentWorker/getDocumentComponent.js +2 -2
  47. package/dist/actions/build/renderDocumentWorker/getDocumentComponent.js.map +1 -1
  48. package/dist/actions/build/renderDocumentWorker/renderDocumentWorker.js +1 -1
  49. package/dist/actions/build/renderDocumentWorker/renderDocumentWorker.js.map +1 -1
  50. package/dist/actions/build/shouldAutoUpdate.js +2 -0
  51. package/dist/actions/build/shouldAutoUpdate.js.map +1 -1
  52. package/dist/actions/build/types.js.map +1 -1
  53. package/dist/actions/build/writeFavicons.js +3 -5
  54. package/dist/actions/build/writeFavicons.js.map +1 -1
  55. package/dist/actions/build/writeSanityRuntime.js +4 -3
  56. package/dist/actions/build/writeSanityRuntime.js.map +1 -1
  57. package/dist/actions/codemods/reactIconsV3.js +2 -2
  58. package/dist/actions/codemods/reactIconsV3.js.map +1 -1
  59. package/dist/actions/dataset/create.js +7 -1
  60. package/dist/actions/dataset/create.js.map +1 -1
  61. package/dist/actions/dataset/determineDatasetAclMode.js.map +1 -1
  62. package/dist/actions/dataset/resolveDataset.js +26 -0
  63. package/dist/actions/dataset/resolveDataset.js.map +1 -0
  64. package/dist/actions/debug/formatters.js +22 -0
  65. package/dist/actions/debug/formatters.js.map +1 -0
  66. package/dist/actions/deploy/createStudioUserApplication.js +17 -4
  67. package/dist/actions/deploy/createStudioUserApplication.js.map +1 -1
  68. package/dist/actions/deploy/deployApp.js +41 -15
  69. package/dist/actions/deploy/deployApp.js.map +1 -1
  70. package/dist/actions/deploy/deployStudio.js +92 -44
  71. package/dist/actions/deploy/deployStudio.js.map +1 -1
  72. package/dist/actions/deploy/deployStudioSchemasAndManifests.js +55 -0
  73. package/dist/actions/deploy/deployStudioSchemasAndManifests.js.map +1 -0
  74. package/dist/actions/deploy/deployStudioSchemasAndManifests.worker.js +120 -0
  75. package/dist/actions/deploy/deployStudioSchemasAndManifests.worker.js.map +1 -0
  76. package/dist/actions/deploy/findUserApplicationForStudio.js +35 -12
  77. package/dist/actions/deploy/findUserApplicationForStudio.js.map +1 -1
  78. package/dist/actions/deploy/types.js +10 -1
  79. package/dist/actions/deploy/types.js.map +1 -1
  80. package/dist/actions/deploy/urlUtils.js +21 -0
  81. package/dist/actions/deploy/urlUtils.js.map +1 -0
  82. package/dist/actions/dev/getDashboardAppUrl.js +48 -0
  83. package/dist/actions/dev/getDashboardAppUrl.js.map +1 -0
  84. package/dist/actions/dev/getDevServerConfig.js +7 -3
  85. package/dist/actions/dev/getDevServerConfig.js.map +1 -1
  86. package/dist/actions/dev/startAppDevServer.js +3 -3
  87. package/dist/actions/dev/startAppDevServer.js.map +1 -1
  88. package/dist/actions/dev/startStudioDevServer.js +14 -14
  89. package/dist/actions/dev/startStudioDevServer.js.map +1 -1
  90. package/dist/actions/doctor/checks/cliInstallation.js +56 -0
  91. package/dist/actions/doctor/checks/cliInstallation.js.map +1 -0
  92. package/dist/actions/doctor/checks/index.js +16 -0
  93. package/dist/actions/doctor/checks/index.js.map +1 -0
  94. package/dist/actions/doctor/runDoctorChecks.js +56 -0
  95. package/dist/actions/doctor/runDoctorChecks.js.map +1 -0
  96. package/dist/actions/doctor/types.js +3 -0
  97. package/dist/actions/doctor/types.js.map +1 -0
  98. package/dist/actions/documents/types.js.map +1 -1
  99. package/dist/actions/documents/validate.js +11 -2
  100. package/dist/actions/documents/validate.js.map +1 -1
  101. package/dist/actions/documents/validateDocuments.worker.js +4 -4
  102. package/dist/actions/documents/validateDocuments.worker.js.map +1 -1
  103. package/dist/actions/documents/validation/reporters/jsonReporter.js +1 -1
  104. package/dist/actions/documents/validation/reporters/jsonReporter.js.map +1 -1
  105. package/dist/actions/documents/validation/reporters/ndjsonReporter.js +1 -1
  106. package/dist/actions/documents/validation/reporters/ndjsonReporter.js.map +1 -1
  107. package/dist/actions/documents/validation/reporters/prettyReporter/formatDocumentValidation.js +1 -1
  108. package/dist/actions/documents/validation/reporters/prettyReporter/formatDocumentValidation.js.map +1 -1
  109. package/dist/actions/documents/validation/reporters/prettyReporter/tree.js +108 -0
  110. package/dist/actions/documents/validation/reporters/prettyReporter/tree.js.map +1 -0
  111. package/dist/actions/graphql/SchemaError.js +4 -26
  112. package/dist/actions/graphql/SchemaError.js.map +1 -1
  113. package/dist/actions/graphql/__tests__/fixtures/many-self-refs.js +540 -0
  114. package/dist/actions/graphql/__tests__/fixtures/many-self-refs.js.map +1 -0
  115. package/dist/actions/graphql/__tests__/fixtures/test-studio.js +1143 -0
  116. package/dist/actions/graphql/__tests__/fixtures/test-studio.js.map +1 -0
  117. package/dist/actions/graphql/__tests__/fixtures/union-refs.js +591 -0
  118. package/dist/actions/graphql/__tests__/fixtures/union-refs.js.map +1 -0
  119. package/dist/actions/graphql/__tests__/helpers.js +23 -0
  120. package/dist/actions/graphql/__tests__/helpers.js.map +1 -0
  121. package/dist/actions/graphql/extractFromSanitySchema.js +5 -5
  122. package/dist/actions/graphql/extractFromSanitySchema.js.map +1 -1
  123. package/dist/actions/graphql/extractGraphQLAPIs.js +150 -0
  124. package/dist/actions/graphql/extractGraphQLAPIs.js.map +1 -0
  125. package/dist/actions/graphql/extractGraphQLAPIs.worker.js +12 -0
  126. package/dist/actions/graphql/extractGraphQLAPIs.worker.js.map +1 -0
  127. package/dist/actions/graphql/gen1/generateTypeFilters.js +1 -1
  128. package/dist/actions/graphql/gen1/generateTypeFilters.js.map +1 -1
  129. package/dist/actions/graphql/gen1/generateTypeQueries.js +2 -1
  130. package/dist/actions/graphql/gen1/generateTypeQueries.js.map +1 -1
  131. package/dist/actions/graphql/gen1/index.js +5 -5
  132. package/dist/actions/graphql/gen1/index.js.map +1 -1
  133. package/dist/actions/graphql/gen2/generateTypeQueries.js +1 -1
  134. package/dist/actions/graphql/gen2/generateTypeQueries.js.map +1 -1
  135. package/dist/actions/graphql/gen2/index.js +6 -6
  136. package/dist/actions/graphql/gen2/index.js.map +1 -1
  137. package/dist/actions/graphql/gen3/generateTypeQueries.js +3 -4
  138. package/dist/actions/graphql/gen3/generateTypeQueries.js.map +1 -1
  139. package/dist/actions/graphql/gen3/index.js +6 -7
  140. package/dist/actions/graphql/gen3/index.js.map +1 -1
  141. package/dist/actions/graphql/getGraphQLAPIs.js +15 -57
  142. package/dist/actions/graphql/getGraphQLAPIs.js.map +1 -1
  143. package/dist/actions/graphql/getGraphQLAPIs.worker.js +75 -106
  144. package/dist/actions/graphql/getGraphQLAPIs.worker.js.map +1 -1
  145. package/dist/actions/graphql/helpers.js +13 -0
  146. package/dist/actions/graphql/helpers.js.map +1 -1
  147. package/dist/actions/graphql/resolveGraphQLApisFromWorkspaces.js +187 -0
  148. package/dist/actions/graphql/resolveGraphQLApisFromWorkspaces.js.map +1 -0
  149. package/dist/actions/graphql/types.js +1 -1
  150. package/dist/actions/graphql/types.js.map +1 -1
  151. package/dist/actions/init/bootstrapLocalTemplate.js +10 -8
  152. package/dist/actions/init/bootstrapLocalTemplate.js.map +1 -1
  153. package/dist/actions/init/bootstrapRemoteTemplate.js +6 -5
  154. package/dist/actions/init/bootstrapRemoteTemplate.js.map +1 -1
  155. package/dist/actions/init/bootstrapTemplate.js.map +1 -1
  156. package/dist/actions/init/checkNextJsReactCompatibility.js +1 -1
  157. package/dist/actions/init/checkNextJsReactCompatibility.js.map +1 -1
  158. package/dist/actions/init/createAppCliConfig.js.map +1 -1
  159. package/dist/actions/init/createCliConfig.js.map +1 -1
  160. package/dist/actions/init/createPackageManifest.js +21 -9
  161. package/dist/actions/init/createPackageManifest.js.map +1 -1
  162. package/dist/actions/init/remoteTemplate.js +1 -2
  163. package/dist/actions/init/remoteTemplate.js.map +1 -1
  164. package/dist/actions/init/sdkAppDependencies.js +19 -0
  165. package/dist/actions/init/sdkAppDependencies.js.map +1 -0
  166. package/dist/actions/init/studioDependencies.js.map +1 -0
  167. package/dist/actions/init/templates/appQuickstart.js +1 -22
  168. package/dist/actions/init/templates/appQuickstart.js.map +1 -1
  169. package/dist/actions/init/templates/appSanityUi.js +3 -22
  170. package/dist/actions/init/templates/appSanityUi.js.map +1 -1
  171. package/dist/actions/init/types.js.map +1 -1
  172. package/dist/actions/manifest/SchemaIcon.js +6 -4
  173. package/dist/actions/manifest/SchemaIcon.js.map +1 -1
  174. package/dist/actions/manifest/blockTypeTransformer.js +67 -0
  175. package/dist/actions/manifest/blockTypeTransformer.js.map +1 -0
  176. package/dist/actions/manifest/debug.js +4 -0
  177. package/dist/actions/manifest/debug.js.map +1 -0
  178. package/dist/actions/manifest/extractAppManifest.js +39 -22
  179. package/dist/actions/manifest/extractAppManifest.js.map +1 -1
  180. package/dist/actions/manifest/extractManifest.js +27 -78
  181. package/dist/actions/manifest/extractManifest.js.map +1 -1
  182. package/dist/actions/manifest/extractManifest.worker.js +30 -0
  183. package/dist/actions/manifest/extractManifest.worker.js.map +1 -0
  184. package/dist/actions/manifest/extractWorkspaceManifest.js +31 -372
  185. package/dist/actions/manifest/extractWorkspaceManifest.js.map +1 -1
  186. package/dist/actions/manifest/iconResolver.js +30 -0
  187. package/dist/actions/manifest/iconResolver.js.map +1 -0
  188. package/dist/actions/manifest/referenceTransformer.js +51 -0
  189. package/dist/actions/manifest/referenceTransformer.js.map +1 -0
  190. package/dist/actions/manifest/schemaTypeHelpers.js +2 -2
  191. package/dist/actions/manifest/schemaTypeHelpers.js.map +1 -1
  192. package/dist/actions/manifest/schemaTypeTransformer.js +168 -0
  193. package/dist/actions/manifest/schemaTypeTransformer.js.map +1 -0
  194. package/dist/actions/manifest/transformerUtils.js +40 -0
  195. package/dist/actions/manifest/transformerUtils.js.map +1 -0
  196. package/dist/actions/manifest/types.js +5 -0
  197. package/dist/actions/manifest/types.js.map +1 -1
  198. package/dist/actions/manifest/validationTransformer.js +84 -0
  199. package/dist/actions/manifest/validationTransformer.js.map +1 -0
  200. package/dist/actions/manifest/writeManifestFile.js +30 -0
  201. package/dist/actions/manifest/writeManifestFile.js.map +1 -0
  202. package/dist/actions/manifest/writeWorkspaceFiles.js +30 -0
  203. package/dist/actions/manifest/writeWorkspaceFiles.js.map +1 -0
  204. package/dist/actions/mcp/detectAvailableEditors.js +34 -13
  205. package/dist/actions/mcp/detectAvailableEditors.js.map +1 -1
  206. package/dist/actions/mcp/editorConfigs.js +231 -109
  207. package/dist/actions/mcp/editorConfigs.js.map +1 -1
  208. package/dist/actions/mcp/promptForMCPSetup.js +16 -7
  209. package/dist/actions/mcp/promptForMCPSetup.js.map +1 -1
  210. package/dist/actions/mcp/setupMCP.js +62 -23
  211. package/dist/actions/mcp/setupMCP.js.map +1 -1
  212. package/dist/actions/mcp/types.js.map +1 -1
  213. package/dist/actions/mcp/validateEditorTokens.js +56 -0
  214. package/dist/actions/mcp/validateEditorTokens.js.map +1 -0
  215. package/dist/actions/mcp/writeMCPConfig.js +27 -15
  216. package/dist/actions/mcp/writeMCPConfig.js.map +1 -1
  217. package/dist/actions/media/buildNdjsonIndex.js +32 -0
  218. package/dist/actions/media/buildNdjsonIndex.js.map +1 -0
  219. package/dist/actions/media/importAspects.js +2 -11
  220. package/dist/actions/media/importAspects.js.map +1 -1
  221. package/dist/actions/media/importMedia.js +22 -18
  222. package/dist/actions/media/importMedia.js.map +1 -1
  223. package/dist/actions/organizations/findOrganizationByUserName.js +5 -0
  224. package/dist/actions/organizations/findOrganizationByUserName.js.map +1 -0
  225. package/dist/actions/organizations/getOrganization.js +3 -2
  226. package/dist/actions/organizations/getOrganization.js.map +1 -1
  227. package/dist/actions/organizations/getOrganizationChoices.js +27 -19
  228. package/dist/actions/organizations/getOrganizationChoices.js.map +1 -1
  229. package/dist/actions/organizations/types.js +3 -0
  230. package/dist/actions/organizations/types.js.map +1 -0
  231. package/dist/actions/projects/getManageUrl.js +1 -2
  232. package/dist/actions/projects/getManageUrl.js.map +1 -1
  233. package/dist/actions/schema/deleteSchemaAction.js +14 -30
  234. package/dist/actions/schema/deleteSchemaAction.js.map +1 -1
  235. package/dist/actions/schema/deploySchemas.js +22 -91
  236. package/dist/actions/schema/deploySchemas.js.map +1 -1
  237. package/dist/actions/schema/extractSanitySchema.worker.js +0 -5
  238. package/dist/actions/schema/extractSanitySchema.worker.js.map +1 -1
  239. package/dist/actions/schema/extractSanityWorkspace.worker.js +24 -0
  240. package/dist/actions/schema/extractSanityWorkspace.worker.js.map +1 -0
  241. package/dist/actions/schema/extractSchema.js +8 -40
  242. package/dist/actions/schema/extractSchema.js.map +1 -1
  243. package/dist/actions/schema/extractSchemaWatcher.js +128 -0
  244. package/dist/actions/schema/extractSchemaWatcher.js.map +1 -0
  245. package/dist/actions/schema/formatSchemaValidation.js +5 -1
  246. package/dist/actions/schema/formatSchemaValidation.js.map +1 -1
  247. package/dist/actions/schema/getExtractOptions.js +16 -0
  248. package/dist/actions/schema/getExtractOptions.js.map +1 -0
  249. package/dist/actions/schema/listSchemas.js +53 -56
  250. package/dist/actions/schema/listSchemas.js.map +1 -1
  251. package/dist/actions/schema/matchSchemaPattern.js +22 -0
  252. package/dist/actions/schema/matchSchemaPattern.js.map +1 -0
  253. package/dist/actions/schema/runSchemaExtraction.js +39 -0
  254. package/dist/actions/schema/runSchemaExtraction.js.map +1 -0
  255. package/dist/actions/schema/types.js +8 -0
  256. package/dist/actions/schema/types.js.map +1 -1
  257. package/dist/actions/schema/uniqueWorkspaces.worker.js +24 -0
  258. package/dist/actions/schema/uniqueWorkspaces.worker.js.map +1 -0
  259. package/dist/actions/schema/updateWorkspaceSchema.js +63 -0
  260. package/dist/actions/schema/updateWorkspaceSchema.js.map +1 -0
  261. package/dist/actions/schema/uploadSchemaToLexicon.js +87 -0
  262. package/dist/actions/schema/uploadSchemaToLexicon.js.map +1 -0
  263. package/dist/actions/schema/utils/SchemaExtractionError.js +10 -0
  264. package/dist/actions/schema/utils/SchemaExtractionError.js.map +1 -0
  265. package/dist/actions/schema/utils/schemaStoreValidation.js +1 -15
  266. package/dist/actions/schema/utils/schemaStoreValidation.js.map +1 -1
  267. package/dist/actions/schema/utils/uniqByProjectIdDataset.js +1 -1
  268. package/dist/actions/schema/utils/uniqByProjectIdDataset.js.map +1 -1
  269. package/dist/actions/schema/validateSchema.worker.js +1 -8
  270. package/dist/actions/schema/validateSchema.worker.js.map +1 -1
  271. package/dist/actions/schema/watchExtractSchema.js +72 -0
  272. package/dist/actions/schema/watchExtractSchema.js.map +1 -0
  273. package/dist/actions/telemetry/isTrueish.js +10 -0
  274. package/dist/actions/telemetry/isTrueish.js.map +1 -0
  275. package/dist/actions/telemetry/resolveConsent.js +2 -1
  276. package/dist/actions/telemetry/resolveConsent.js.map +1 -1
  277. package/dist/actions/telemetry/setConsent.js +2 -1
  278. package/dist/actions/telemetry/setConsent.js.map +1 -1
  279. package/dist/actions/telemetry/telemetryDebug.js +2 -2
  280. package/dist/actions/telemetry/telemetryDebug.js.map +1 -1
  281. package/dist/actions/users/getMembersForProject.js.map +1 -1
  282. package/dist/actions/users/getPendingInvitations.js +1 -1
  283. package/dist/actions/users/getPendingInvitations.js.map +1 -1
  284. package/dist/actions/users/types.js.map +1 -1
  285. package/dist/actions/versions/filterSanityModules.js.map +1 -1
  286. package/dist/actions/versions/findSanityModulesVersions.js +2 -3
  287. package/dist/actions/versions/findSanityModulesVersions.js.map +1 -1
  288. package/dist/actions/versions/getFormatters.js +1 -1
  289. package/dist/actions/versions/getFormatters.js.map +1 -1
  290. package/dist/actions/versions/tryFindLatestVersion.js +1 -1
  291. package/dist/actions/versions/tryFindLatestVersion.js.map +1 -1
  292. package/dist/commands/backup/disable.js +22 -7
  293. package/dist/commands/backup/disable.js.map +1 -1
  294. package/dist/commands/backup/download.js +19 -10
  295. package/dist/commands/backup/download.js.map +1 -1
  296. package/dist/commands/backup/enable.js +22 -7
  297. package/dist/commands/backup/enable.js.map +1 -1
  298. package/dist/commands/backup/list.js +20 -8
  299. package/dist/commands/backup/list.js.map +1 -1
  300. package/dist/commands/build.js +2 -5
  301. package/dist/commands/build.js.map +1 -1
  302. package/dist/commands/cors/add.js +20 -7
  303. package/dist/commands/cors/add.js.map +1 -1
  304. package/dist/commands/cors/delete.js +22 -7
  305. package/dist/commands/cors/delete.js.map +1 -1
  306. package/dist/commands/cors/list.js +22 -7
  307. package/dist/commands/cors/list.js.map +1 -1
  308. package/dist/commands/dataset/alias/create.js +26 -7
  309. package/dist/commands/dataset/alias/create.js.map +1 -1
  310. package/dist/commands/dataset/alias/delete.js +20 -7
  311. package/dist/commands/dataset/alias/delete.js.map +1 -1
  312. package/dist/commands/dataset/alias/link.js +20 -7
  313. package/dist/commands/dataset/alias/link.js.map +1 -1
  314. package/dist/commands/dataset/alias/unlink.js +20 -7
  315. package/dist/commands/dataset/alias/unlink.js.map +1 -1
  316. package/dist/commands/dataset/copy.js +45 -30
  317. package/dist/commands/dataset/copy.js.map +1 -1
  318. package/dist/commands/dataset/create.js +32 -7
  319. package/dist/commands/dataset/create.js.map +1 -1
  320. package/dist/commands/dataset/delete.js +16 -7
  321. package/dist/commands/dataset/delete.js.map +1 -1
  322. package/dist/commands/dataset/embeddings/disable.js +77 -0
  323. package/dist/commands/dataset/embeddings/disable.js.map +1 -0
  324. package/dist/commands/dataset/embeddings/enable.js +141 -0
  325. package/dist/commands/dataset/embeddings/enable.js.map +1 -0
  326. package/dist/commands/dataset/embeddings/status.js +72 -0
  327. package/dist/commands/dataset/embeddings/status.js.map +1 -0
  328. package/dist/commands/dataset/export.js +25 -16
  329. package/dist/commands/dataset/export.js.map +1 -1
  330. package/dist/commands/dataset/import.js +306 -1
  331. package/dist/commands/dataset/import.js.map +1 -1
  332. package/dist/commands/dataset/list.js +22 -7
  333. package/dist/commands/dataset/list.js.map +1 -1
  334. package/dist/commands/dataset/visibility/get.js +18 -7
  335. package/dist/commands/dataset/visibility/get.js.map +1 -1
  336. package/dist/commands/dataset/visibility/set.js +22 -7
  337. package/dist/commands/dataset/visibility/set.js.map +1 -1
  338. package/dist/commands/debug.js +4 -2
  339. package/dist/commands/debug.js.map +1 -1
  340. package/dist/commands/deploy.js +22 -11
  341. package/dist/commands/deploy.js.map +1 -1
  342. package/dist/commands/dev.js +2 -4
  343. package/dist/commands/dev.js.map +1 -1
  344. package/dist/commands/doctor.js +125 -0
  345. package/dist/commands/doctor.js.map +1 -0
  346. package/dist/commands/documents/create.js +19 -12
  347. package/dist/commands/documents/create.js.map +1 -1
  348. package/dist/commands/documents/delete.js +19 -12
  349. package/dist/commands/documents/delete.js.map +1 -1
  350. package/dist/commands/documents/get.js +17 -12
  351. package/dist/commands/documents/get.js.map +1 -1
  352. package/dist/commands/documents/query.js +26 -18
  353. package/dist/commands/documents/query.js.map +1 -1
  354. package/dist/commands/documents/validate.js +32 -10
  355. package/dist/commands/documents/validate.js.map +1 -1
  356. package/dist/commands/graphql/deploy.js +58 -30
  357. package/dist/commands/graphql/deploy.js.map +1 -1
  358. package/dist/commands/graphql/list.js +15 -7
  359. package/dist/commands/graphql/list.js.map +1 -1
  360. package/dist/commands/graphql/undeploy.js +37 -19
  361. package/dist/commands/graphql/undeploy.js.map +1 -1
  362. package/dist/commands/hook/attempt.js +22 -7
  363. package/dist/commands/hook/attempt.js.map +1 -1
  364. package/dist/commands/hook/create.js +23 -8
  365. package/dist/commands/hook/create.js.map +1 -1
  366. package/dist/commands/hook/delete.js +22 -7
  367. package/dist/commands/hook/delete.js.map +1 -1
  368. package/dist/commands/hook/list.js +22 -7
  369. package/dist/commands/hook/list.js.map +1 -1
  370. package/dist/commands/hook/logs.js +21 -8
  371. package/dist/commands/hook/logs.js.map +1 -1
  372. package/dist/commands/init.js +55 -32
  373. package/dist/commands/init.js.map +1 -1
  374. package/dist/commands/login.js +19 -6
  375. package/dist/commands/login.js.map +1 -1
  376. package/dist/commands/logout.js +8 -6
  377. package/dist/commands/logout.js.map +1 -1
  378. package/dist/commands/manage.js +0 -1
  379. package/dist/commands/manage.js.map +1 -1
  380. package/dist/commands/manifest/extract.js +14 -10
  381. package/dist/commands/manifest/extract.js.map +1 -1
  382. package/dist/commands/mcp/configure.js +4 -2
  383. package/dist/commands/mcp/configure.js.map +1 -1
  384. package/dist/commands/media/create-aspect.js +4 -4
  385. package/dist/commands/media/create-aspect.js.map +1 -1
  386. package/dist/commands/media/delete-aspect.js +9 -7
  387. package/dist/commands/media/delete-aspect.js.map +1 -1
  388. package/dist/commands/media/deploy-aspect.js +22 -9
  389. package/dist/commands/media/deploy-aspect.js.map +1 -1
  390. package/dist/commands/media/export.js +9 -7
  391. package/dist/commands/media/export.js.map +1 -1
  392. package/dist/commands/media/import.js +10 -8
  393. package/dist/commands/media/import.js.map +1 -1
  394. package/dist/commands/preview.js +5 -8
  395. package/dist/commands/preview.js.map +1 -1
  396. package/dist/commands/projects/list.js +2 -1
  397. package/dist/commands/projects/list.js.map +1 -1
  398. package/dist/commands/schema/delete.js +33 -34
  399. package/dist/commands/schema/delete.js.map +1 -1
  400. package/dist/commands/schema/deploy.js +19 -30
  401. package/dist/commands/schema/deploy.js.map +1 -1
  402. package/dist/commands/schema/extract.js +32 -4
  403. package/dist/commands/schema/extract.js.map +1 -1
  404. package/dist/commands/schema/list.js +10 -31
  405. package/dist/commands/schema/list.js.map +1 -1
  406. package/dist/commands/tokens/add.js +24 -7
  407. package/dist/commands/tokens/add.js.map +1 -1
  408. package/dist/commands/tokens/delete.js +20 -7
  409. package/dist/commands/tokens/delete.js.map +1 -1
  410. package/dist/commands/tokens/list.js +20 -7
  411. package/dist/commands/tokens/list.js.map +1 -1
  412. package/dist/commands/users/invite.js +24 -7
  413. package/dist/commands/users/invite.js.map +1 -1
  414. package/dist/commands/users/list.js +76 -33
  415. package/dist/commands/users/list.js.map +1 -1
  416. package/dist/commands/versions.js +1 -1
  417. package/dist/commands/versions.js.map +1 -1
  418. package/dist/config/createCliConfig.js +1 -2
  419. package/dist/config/createCliConfig.js.map +1 -1
  420. package/dist/exports/_internal.d.ts +132 -0
  421. package/dist/exports/_internal.js +4 -0
  422. package/dist/exports/_internal.js.map +1 -0
  423. package/dist/exports/index.d.ts +113 -0
  424. package/dist/exports/index.js +6 -0
  425. package/dist/exports/index.js.map +1 -0
  426. package/dist/hooks/init/checkForUpdates.js +14 -0
  427. package/dist/hooks/init/checkForUpdates.js.map +1 -0
  428. package/dist/hooks/prerun/flushTelemetry.worker.js +1 -1
  429. package/dist/hooks/prerun/flushTelemetry.worker.js.map +1 -1
  430. package/dist/hooks/prerun/injectEnvVariables.js +9 -1
  431. package/dist/hooks/prerun/injectEnvVariables.js.map +1 -1
  432. package/dist/hooks/prerun/setupTelemetry.js +16 -10
  433. package/dist/hooks/prerun/setupTelemetry.js.map +1 -1
  434. package/dist/prompts/promptForProject.js +64 -0
  435. package/dist/prompts/promptForProject.js.map +1 -0
  436. package/dist/{actions/auth/login/promptProviders.js → prompts/promptForProviders.js} +3 -3
  437. package/dist/prompts/promptForProviders.js.map +1 -0
  438. package/dist/prompts/selectMediaLibrary.js +1 -1
  439. package/dist/prompts/selectMediaLibrary.js.map +1 -1
  440. package/dist/server/devServer.js +4 -2
  441. package/dist/server/devServer.js.map +1 -1
  442. package/dist/server/previewServer.js +2 -2
  443. package/dist/server/previewServer.js.map +1 -1
  444. package/dist/server/vite/plugin-schema-extraction.js +201 -0
  445. package/dist/server/vite/plugin-schema-extraction.js.map +1 -0
  446. package/dist/server/vite/plugin-typegen.js +217 -0
  447. package/dist/server/vite/plugin-typegen.js.map +1 -0
  448. package/dist/services/auth.js +42 -3
  449. package/dist/services/auth.js.map +1 -1
  450. package/dist/services/datasets.js +7 -5
  451. package/dist/services/datasets.js.map +1 -1
  452. package/dist/services/docs.js +2 -2
  453. package/dist/services/docs.js.map +1 -1
  454. package/dist/services/embeddings.js +25 -0
  455. package/dist/services/embeddings.js.map +1 -0
  456. package/dist/services/getUrlHeaders.js +7 -18
  457. package/dist/services/getUrlHeaders.js.map +1 -1
  458. package/dist/services/grants.js +13 -0
  459. package/dist/services/grants.js.map +1 -0
  460. package/dist/services/graphql.js +1 -1
  461. package/dist/services/graphql.js.map +1 -1
  462. package/dist/services/mcp.js +55 -1
  463. package/dist/services/mcp.js.map +1 -1
  464. package/dist/services/projects.js +4 -2
  465. package/dist/services/projects.js.map +1 -1
  466. package/dist/services/schemas.js +1 -1
  467. package/dist/services/schemas.js.map +1 -1
  468. package/dist/services/telemetry.js +2 -1
  469. package/dist/services/telemetry.js.map +1 -1
  470. package/dist/services/userApplications.js +21 -6
  471. package/dist/services/userApplications.js.map +1 -1
  472. package/dist/telemetry/extractSchema.telemetry.js +10 -0
  473. package/dist/telemetry/extractSchema.telemetry.js.map +1 -1
  474. package/dist/types/grants.js +3 -0
  475. package/dist/types/grants.js.map +1 -0
  476. package/dist/types.js +3 -0
  477. package/dist/types.js.map +1 -1
  478. package/dist/util/checkProjectPermissions.js +21 -0
  479. package/dist/util/checkProjectPermissions.js.map +1 -0
  480. package/dist/util/cliClient.js +5 -3
  481. package/dist/util/cliClient.js.map +1 -1
  482. package/dist/util/compareDependencyVersions.js +74 -38
  483. package/dist/util/compareDependencyVersions.js.map +1 -1
  484. package/dist/util/createExpiringConfig.js +64 -0
  485. package/dist/util/createExpiringConfig.js.map +1 -0
  486. package/dist/util/detectFramework.js +135 -0
  487. package/dist/util/detectFramework.js.map +1 -0
  488. package/dist/util/errorMessages.js +0 -1
  489. package/dist/util/errorMessages.js.map +1 -1
  490. package/dist/util/extractDocumentsFromNdjsonOrTarball.js +1 -2
  491. package/dist/util/extractDocumentsFromNdjsonOrTarball.js.map +1 -1
  492. package/dist/util/getCliVersion.js +1 -1
  493. package/dist/util/getCliVersion.js.map +1 -1
  494. package/dist/util/getLocalPackageVersion.js +33 -23
  495. package/dist/util/getLocalPackageVersion.js.map +1 -1
  496. package/dist/util/getProjectDefaults.js +22 -28
  497. package/dist/util/getProjectDefaults.js.map +1 -1
  498. package/dist/util/getSharedServerConfig.js +1 -0
  499. package/dist/util/getSharedServerConfig.js.map +1 -1
  500. package/dist/util/getWorkspace.js +1 -1
  501. package/dist/util/getWorkspace.js.map +1 -1
  502. package/dist/util/gitConfig.js +45 -0
  503. package/dist/util/gitConfig.js.map +1 -0
  504. package/dist/util/isSchemaError.js +11 -0
  505. package/dist/util/isSchemaError.js.map +1 -0
  506. package/dist/util/isTar.js +8 -0
  507. package/dist/util/isTar.js.map +1 -0
  508. package/dist/util/packageManager/getPeerDependencies.js +44 -0
  509. package/dist/util/packageManager/getPeerDependencies.js.map +1 -0
  510. package/dist/util/packageManager/installationInfo/analyzeIssues.js +225 -0
  511. package/dist/util/packageManager/installationInfo/analyzeIssues.js.map +1 -0
  512. package/dist/util/packageManager/installationInfo/commands.js +73 -0
  513. package/dist/util/packageManager/installationInfo/commands.js.map +1 -0
  514. package/dist/util/packageManager/installationInfo/detectCliInstallation.js +66 -0
  515. package/dist/util/packageManager/installationInfo/detectCliInstallation.js.map +1 -0
  516. package/dist/util/packageManager/installationInfo/detectGlobals.js +295 -0
  517. package/dist/util/packageManager/installationInfo/detectGlobals.js.map +1 -0
  518. package/dist/util/packageManager/installationInfo/detectPackages.js +190 -0
  519. package/dist/util/packageManager/installationInfo/detectPackages.js.map +1 -0
  520. package/dist/util/packageManager/installationInfo/detectWorkspace.js +192 -0
  521. package/dist/util/packageManager/installationInfo/detectWorkspace.js.map +1 -0
  522. package/dist/util/packageManager/installationInfo/index.js +4 -0
  523. package/dist/util/packageManager/installationInfo/index.js.map +1 -0
  524. package/dist/util/packageManager/installationInfo/readJsonFile.js +14 -0
  525. package/dist/util/packageManager/installationInfo/readJsonFile.js.map +1 -0
  526. package/dist/util/packageManager/installationInfo/resolveVersionRange.js +42 -0
  527. package/dist/util/packageManager/installationInfo/resolveVersionRange.js.map +1 -0
  528. package/dist/util/packageManager/installationInfo/types.js +3 -0
  529. package/dist/util/packageManager/installationInfo/types.js.map +1 -0
  530. package/dist/util/packageManager/packageManagerChoice.js +1 -20
  531. package/dist/util/packageManager/packageManagerChoice.js.map +1 -1
  532. package/dist/util/packageManager/upgradePackages.js +4 -1
  533. package/dist/util/packageManager/upgradePackages.js.map +1 -1
  534. package/dist/util/promiseRaceWithTimeout.js +28 -0
  535. package/dist/util/promiseRaceWithTimeout.js.map +1 -0
  536. package/dist/util/readdirRecursive.js.map +1 -1
  537. package/dist/util/resolveLatestVersions.js +2 -2
  538. package/dist/util/resolveLatestVersions.js.map +1 -1
  539. package/dist/util/sharedFlags.js +54 -0
  540. package/dist/util/sharedFlags.js.map +1 -0
  541. package/dist/util/telemetry/cleanupOldTelemetryFiles.js +30 -0
  542. package/dist/util/telemetry/cleanupOldTelemetryFiles.js.map +1 -0
  543. package/dist/util/telemetry/createTelemetryStore.js +95 -0
  544. package/dist/util/telemetry/createTelemetryStore.js.map +1 -0
  545. package/dist/util/telemetry/createTraceId.js +10 -0
  546. package/dist/util/telemetry/createTraceId.js.map +1 -0
  547. package/dist/util/telemetry/findTelemetryFiles.js +35 -0
  548. package/dist/util/telemetry/findTelemetryFiles.js.map +1 -0
  549. package/dist/util/telemetry/flushTelemetryFiles.js +118 -0
  550. package/dist/util/telemetry/flushTelemetryFiles.js.map +1 -0
  551. package/dist/util/telemetry/generateTelemetryFilePath.js +30 -0
  552. package/dist/util/telemetry/generateTelemetryFilePath.js.map +1 -0
  553. package/dist/util/telemetry/logger.js +59 -0
  554. package/dist/util/telemetry/logger.js.map +1 -0
  555. package/dist/util/telemetry/readNDJSON.js +28 -0
  556. package/dist/util/telemetry/readNDJSON.js.map +1 -0
  557. package/dist/util/telemetry/telemetryStoreDebug.js +7 -0
  558. package/dist/util/telemetry/telemetryStoreDebug.js.map +1 -0
  559. package/dist/util/telemetry/trace.js +150 -0
  560. package/dist/util/telemetry/trace.js.map +1 -0
  561. package/dist/util/toForwardSlashes.js +8 -0
  562. package/dist/util/toForwardSlashes.js.map +1 -0
  563. package/dist/util/update/fetchLatestVersion.js +21 -0
  564. package/dist/util/update/fetchLatestVersion.js.map +1 -0
  565. package/dist/util/update/getUpdateCommand.js +20 -0
  566. package/dist/util/update/getUpdateCommand.js.map +1 -0
  567. package/dist/util/update/isInstalledUsingYarn.js +17 -0
  568. package/dist/util/update/isInstalledUsingYarn.js.map +1 -0
  569. package/dist/util/update/showNotificationUpdate.js +31 -0
  570. package/dist/util/update/showNotificationUpdate.js.map +1 -0
  571. package/dist/util/update/updateChecker.js +60 -0
  572. package/dist/util/update/updateChecker.js.map +1 -0
  573. package/dist/util/update/updateCheckerDebug.js +4 -0
  574. package/dist/util/update/updateCheckerDebug.js.map +1 -0
  575. package/oclif.config.js +1 -0
  576. package/oclif.manifest.json +1285 -492
  577. package/package.json +72 -73
  578. package/static/favicons/apple-touch-icon.png +0 -0
  579. package/static/favicons/favicon-192.png +0 -0
  580. package/static/favicons/favicon-512.png +0 -0
  581. package/static/favicons/favicon-96.png +0 -0
  582. package/static/favicons/favicon.ico +0 -0
  583. package/static/favicons/favicon.svg +12 -0
  584. package/dist/actions/auth/login/promptProviders.js.map +0 -1
  585. package/dist/actions/dev/getCoreAppUrl.js +0 -10
  586. package/dist/actions/dev/getCoreAppUrl.js.map +0 -1
  587. package/dist/actions/schema/schemaStoreTypes.js +0 -19
  588. package/dist/actions/schema/schemaStoreTypes.js.map +0 -1
  589. package/dist/actions/schema/utils/manifestExtractor.js +0 -33
  590. package/dist/actions/schema/utils/manifestExtractor.js.map +0 -1
  591. package/dist/actions/schema/utils/manifestReader.js +0 -71
  592. package/dist/actions/schema/utils/manifestReader.js.map +0 -1
  593. package/dist/index.d.ts +0 -2326
  594. package/dist/index.js +0 -6
  595. package/dist/index.js.map +0 -1
  596. package/dist/studioDependencies.js.map +0 -1
  597. package/dist/typings/deepSortObject.d.js +0 -2
  598. package/dist/typings/deepSortObject.d.js.map +0 -1
  599. package/dist/util/findNdjsonEntry.js +0 -21
  600. package/dist/util/findNdjsonEntry.js.map +0 -1
  601. package/dist/util/importStudioConfig.js +0 -40
  602. package/dist/util/importStudioConfig.js.map +0 -1
  603. package/dist/util/readModuleVersion.js +0 -15
  604. package/dist/util/readModuleVersion.js.map +0 -1
  605. package/dist/util/readPackageJson.js +0 -44
  606. package/dist/util/readPackageJson.js.map +0 -1
  607. package/dist/util/readPackageManifest.js +0 -46
  608. package/dist/util/readPackageManifest.js.map +0 -1
  609. package/dist/util/uniqBy.js +0 -14
  610. package/dist/util/uniqBy.js.map +0 -1
  611. package/dist/util/workerChannels.js +0 -172
  612. package/dist/util/workerChannels.js.map +0 -1
  613. /package/dist/{studioDependencies.js → actions/init/studioDependencies.js} +0 -0
@@ -0,0 +1,3 @@
1
+ export { };
2
+
3
+ //# sourceMappingURL=grants.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/types/grants.ts"],"sourcesContent":["export interface RequiredPermission {\n /** The grant type, e.g. 'read', 'create', 'update', 'delete' */\n grant: string\n /** The permission scope, e.g. 'sanity.project.datasets' */\n permission: string\n}\n\ninterface GrantResource {\n grants: Array<{name: string; params: Record<string, unknown>}>\n}\n\nexport interface UserGrantsResponse {\n organizations: Record<string, Record<string, GrantResource[]>>\n projects: Record<string, Record<string, GrantResource[]>>\n}\n"],"names":[],"mappings":"AAWA,WAGC"}
package/dist/types.js CHANGED
@@ -1,4 +1,7 @@
1
1
  /**
2
+ * PackageJson type is now consolidated in readPackageJson.ts
3
+ * Re-exported here for backward compatibility.
4
+ *
2
5
  * @public
3
6
  */ export { };
4
7
 
package/dist/types.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/types.ts"],"sourcesContent":["/**\n * @public\n */\nexport interface PackageJson {\n name: string\n version: string\n\n author?: string\n dependencies?: Record<string, string>\n description?: string\n devDependencies?: Record<string, string>\n engines?: Record<string, string>\n license?: string\n peerDependencies?: Record<string, string>\n private?: boolean\n repository?: {type: string; url: string}\n scripts?: Record<string, string>\n}\n\nexport interface CliApiConfig {\n dataset?: string\n projectId?: string\n}\n\nexport interface SanityJson {\n __experimental_spaces?: {\n api: {\n dataset?: string\n projectId?: string\n }\n default?: true\n name: string\n title: string\n }[]\n api?: CliApiConfig\n env?: {\n development?: SanityJson\n production?: SanityJson\n staging?: SanityJson\n }\n parts?: {\n description?: string\n implements?: string\n name?: string\n path?: string\n }[]\n plugins?: string[]\n project?: {\n basePath?: string\n name?: string\n }\n root?: boolean\n}\n"],"names":[],"mappings":"AAAA;;CAEC,GAsBD,WA4BC"}
1
+ {"version":3,"sources":["../src/types.ts"],"sourcesContent":["/**\n * PackageJson type is now consolidated in readPackageJson.ts\n * Re-exported here for backward compatibility.\n *\n * @public\n */\nexport type {PackageJson, ReadPackageJsonOptions} from '@sanity/cli-core'\n\n/**\n * @public\n */\nexport interface CliApiConfig {\n dataset?: string\n projectId?: string\n}\n\nexport interface SanityJson {\n __experimental_spaces?: {\n api: {\n dataset?: string\n projectId?: string\n }\n default?: true\n name: string\n title: string\n }[]\n api?: CliApiConfig\n env?: {\n development?: SanityJson\n production?: SanityJson\n staging?: SanityJson\n }\n parts?: {\n description?: string\n implements?: string\n name?: string\n path?: string\n }[]\n plugins?: string[]\n project?: {\n basePath?: string\n name?: string\n }\n root?: boolean\n}\n"],"names":[],"mappings":"AAAA;;;;;CAKC,GAWD,WA4BC"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Returns the set of project IDs that have ALL of the required permissions.
3
+ *
4
+ * Iterates through `grants.projects` and checks that each project has every
5
+ * required `{permission, grant}` combination present in its grant resources.
6
+ */ export function getProjectsWithPermissions(grants, requiredPermissions) {
7
+ const permitted = new Set();
8
+ for (const [projectId, permissionMap] of Object.entries(grants.projects)){
9
+ const hasAll = requiredPermissions.every(({ grant, permission })=>{
10
+ const resources = permissionMap[permission];
11
+ if (!resources) return false;
12
+ return resources.some((resource)=>resource.grants.some((g)=>g.name === grant));
13
+ });
14
+ if (hasAll) {
15
+ permitted.add(projectId);
16
+ }
17
+ }
18
+ return permitted;
19
+ }
20
+
21
+ //# sourceMappingURL=checkProjectPermissions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/util/checkProjectPermissions.ts"],"sourcesContent":["import {type RequiredPermission, type UserGrantsResponse} from '../types/grants.js'\n\n/**\n * Returns the set of project IDs that have ALL of the required permissions.\n *\n * Iterates through `grants.projects` and checks that each project has every\n * required `{permission, grant}` combination present in its grant resources.\n */\nexport function getProjectsWithPermissions(\n grants: UserGrantsResponse,\n requiredPermissions: RequiredPermission[],\n): Set<string> {\n const permitted = new Set<string>()\n\n for (const [projectId, permissionMap] of Object.entries(grants.projects)) {\n const hasAll = requiredPermissions.every(({grant, permission}) => {\n const resources = permissionMap[permission]\n if (!resources) return false\n return resources.some((resource) => resource.grants.some((g) => g.name === grant))\n })\n\n if (hasAll) {\n permitted.add(projectId)\n }\n }\n\n return permitted\n}\n"],"names":["getProjectsWithPermissions","grants","requiredPermissions","permitted","Set","projectId","permissionMap","Object","entries","projects","hasAll","every","grant","permission","resources","some","resource","g","name","add"],"mappings":"AAEA;;;;;CAKC,GACD,OAAO,SAASA,2BACdC,MAA0B,EAC1BC,mBAAyC;IAEzC,MAAMC,YAAY,IAAIC;IAEtB,KAAK,MAAM,CAACC,WAAWC,cAAc,IAAIC,OAAOC,OAAO,CAACP,OAAOQ,QAAQ,EAAG;QACxE,MAAMC,SAASR,oBAAoBS,KAAK,CAAC,CAAC,EAACC,KAAK,EAAEC,UAAU,EAAC;YAC3D,MAAMC,YAAYR,aAAa,CAACO,WAAW;YAC3C,IAAI,CAACC,WAAW,OAAO;YACvB,OAAOA,UAAUC,IAAI,CAAC,CAACC,WAAaA,SAASf,MAAM,CAACc,IAAI,CAAC,CAACE,IAAMA,EAAEC,IAAI,KAAKN;QAC7E;QAEA,IAAIF,QAAQ;YACVP,UAAUgB,GAAG,CAACd;QAChB;IACF;IAEA,OAAOF;AACT"}
@@ -9,14 +9,15 @@ import { createClient } from '@sanity/client';
9
9
  if (typeof process !== 'object') {
10
10
  throw new TypeError('getCliClient() should only be called from node.js scripts');
11
11
  }
12
- const { apiVersion = '2022-06-06', cwd = process.env.SANITY_BASE_PATH || process.cwd(), dataset, projectId, token = getCliClient.__internal__getToken(), useCdn = false } = options;
12
+ const { apiVersion = '2022-06-06', cwd = process.env.SANITY_BASE_PATH || process.cwd(), dataset, projectId, token = getCliClient.__internal__getToken(), useCdn = false, ...restOfOptions } = options;
13
13
  if (projectId && dataset) {
14
14
  return createClient({
15
15
  apiVersion,
16
16
  dataset,
17
17
  projectId,
18
18
  token,
19
- useCdn
19
+ useCdn,
20
+ ...restOfOptions
20
21
  });
21
22
  }
22
23
  const projectRoot = findProjectRootSync(cwd);
@@ -33,7 +34,8 @@ import { createClient } from '@sanity/client';
33
34
  dataset: apiConfig.dataset,
34
35
  projectId: apiConfig.projectId,
35
36
  token,
36
- useCdn
37
+ useCdn,
38
+ ...restOfOptions
37
39
  });
38
40
  };
39
41
  getCliClient.__internal__getToken = ()=>undefined;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/util/cliClient.ts"],"sourcesContent":["import {findProjectRootSync, getCliConfigSync} from '@sanity/cli-core'\nimport {createClient, type SanityClient} from '@sanity/client'\n\n/**\n * @public\n */\nexport interface CliClientOptions {\n apiVersion?: string\n\n cwd?: string\n dataset?: string\n projectId?: string\n token?: string\n useCdn?: boolean\n}\n\n/**\n * @public\n *\n * @param options - The options to use for the client.\n * @returns A configured Sanity API client.\n */\nexport const getCliClient: CliClientGetter = (options: CliClientOptions = {}): SanityClient => {\n if (typeof process !== 'object') {\n throw new TypeError('getCliClient() should only be called from node.js scripts')\n }\n\n const {\n apiVersion = '2022-06-06',\n cwd = process.env.SANITY_BASE_PATH || process.cwd(),\n dataset,\n projectId,\n token = getCliClient.__internal__getToken(),\n useCdn = false,\n } = options\n\n if (projectId && dataset) {\n return createClient({apiVersion, dataset, projectId, token, useCdn})\n }\n\n const projectRoot = findProjectRootSync(cwd)\n const cliConfig = getCliConfigSync(projectRoot.directory)\n\n if (!cliConfig) {\n throw new Error('Unable to resolve CLI configuration')\n }\n\n const apiConfig = cliConfig.api || {}\n if (!apiConfig.projectId || !apiConfig.dataset) {\n throw new Error('Unable to resolve project ID/dataset from CLI configuration')\n }\n\n return createClient({\n apiVersion,\n dataset: apiConfig.dataset,\n projectId: apiConfig.projectId,\n token,\n useCdn,\n })\n}\n\ntype CliClientGetter = ((options?: CliClientOptions) => SanityClient) & {\n /**\n * @deprecated This is only for INTERNAL use, and should not be relied upon outside of official Sanity modules\n * @returns A token to use when constructing a client without a `token` explicitly defined, or undefined\n * @internal\n */\n __internal__getToken: () => string | undefined\n}\n\ngetCliClient.__internal__getToken = (): string | undefined => undefined\n"],"names":["findProjectRootSync","getCliConfigSync","createClient","getCliClient","options","process","TypeError","apiVersion","cwd","env","SANITY_BASE_PATH","dataset","projectId","token","__internal__getToken","useCdn","projectRoot","cliConfig","directory","Error","apiConfig","api","undefined"],"mappings":"AAAA,SAAQA,mBAAmB,EAAEC,gBAAgB,QAAO,mBAAkB;AACtE,SAAQC,YAAY,QAA0B,iBAAgB;AAe9D;;;;;CAKC,GACD,OAAO,MAAMC,eAAgC,CAACC,UAA4B,CAAC,CAAC;IAC1E,IAAI,OAAOC,YAAY,UAAU;QAC/B,MAAM,IAAIC,UAAU;IACtB;IAEA,MAAM,EACJC,aAAa,YAAY,EACzBC,MAAMH,QAAQI,GAAG,CAACC,gBAAgB,IAAIL,QAAQG,GAAG,EAAE,EACnDG,OAAO,EACPC,SAAS,EACTC,QAAQV,aAAaW,oBAAoB,EAAE,EAC3CC,SAAS,KAAK,EACf,GAAGX;IAEJ,IAAIQ,aAAaD,SAAS;QACxB,OAAOT,aAAa;YAACK;YAAYI;YAASC;YAAWC;YAAOE;QAAM;IACpE;IAEA,MAAMC,cAAchB,oBAAoBQ;IACxC,MAAMS,YAAYhB,iBAAiBe,YAAYE,SAAS;IAExD,IAAI,CAACD,WAAW;QACd,MAAM,IAAIE,MAAM;IAClB;IAEA,MAAMC,YAAYH,UAAUI,GAAG,IAAI,CAAC;IACpC,IAAI,CAACD,UAAUR,SAAS,IAAI,CAACQ,UAAUT,OAAO,EAAE;QAC9C,MAAM,IAAIQ,MAAM;IAClB;IAEA,OAAOjB,aAAa;QAClBK;QACAI,SAASS,UAAUT,OAAO;QAC1BC,WAAWQ,UAAUR,SAAS;QAC9BC;QACAE;IACF;AACF,EAAC;AAWDZ,aAAaW,oBAAoB,GAAG,IAA0BQ"}
1
+ {"version":3,"sources":["../../src/util/cliClient.ts"],"sourcesContent":["import {findProjectRootSync, getCliConfigSync} from '@sanity/cli-core'\nimport {type ClientConfig, createClient, type SanityClient} from '@sanity/client'\n\n/**\n * @public\n */\nexport interface CliClientOptions extends ClientConfig {\n /**\n * If no `projectId` or `dataset` is provided, `getCliClient` will try to\n * resolve these from the `sanity.cli.ts` configuration file. Use this option\n * to specify the directory to look for this file.\n */\n cwd?: string\n}\n\n/**\n * @public\n *\n * @param options - The options to use for the client.\n * @returns A configured Sanity API client.\n */\nexport const getCliClient: CliClientGetter = (options: CliClientOptions = {}): SanityClient => {\n if (typeof process !== 'object') {\n throw new TypeError('getCliClient() should only be called from node.js scripts')\n }\n\n const {\n apiVersion = '2022-06-06',\n cwd = process.env.SANITY_BASE_PATH || process.cwd(),\n dataset,\n projectId,\n token = getCliClient.__internal__getToken(),\n useCdn = false,\n ...restOfOptions\n } = options\n\n if (projectId && dataset) {\n return createClient({apiVersion, dataset, projectId, token, useCdn, ...restOfOptions})\n }\n\n const projectRoot = findProjectRootSync(cwd)\n const cliConfig = getCliConfigSync(projectRoot.directory)\n\n if (!cliConfig) {\n throw new Error('Unable to resolve CLI configuration')\n }\n\n const apiConfig = cliConfig.api || {}\n if (!apiConfig.projectId || !apiConfig.dataset) {\n throw new Error('Unable to resolve project ID/dataset from CLI configuration')\n }\n\n return createClient({\n apiVersion,\n dataset: apiConfig.dataset,\n projectId: apiConfig.projectId,\n token,\n useCdn,\n ...restOfOptions,\n })\n}\n\ntype CliClientGetter = ((options?: CliClientOptions) => SanityClient) & {\n /**\n * @deprecated This is only for INTERNAL use, and should not be relied upon outside of official Sanity modules\n * @returns A token to use when constructing a client without a `token` explicitly defined, or undefined\n * @internal\n */\n __internal__getToken: () => string | undefined\n}\n\ngetCliClient.__internal__getToken = (): string | undefined => undefined\n"],"names":["findProjectRootSync","getCliConfigSync","createClient","getCliClient","options","process","TypeError","apiVersion","cwd","env","SANITY_BASE_PATH","dataset","projectId","token","__internal__getToken","useCdn","restOfOptions","projectRoot","cliConfig","directory","Error","apiConfig","api","undefined"],"mappings":"AAAA,SAAQA,mBAAmB,EAAEC,gBAAgB,QAAO,mBAAkB;AACtE,SAA2BC,YAAY,QAA0B,iBAAgB;AAcjF;;;;;CAKC,GACD,OAAO,MAAMC,eAAgC,CAACC,UAA4B,CAAC,CAAC;IAC1E,IAAI,OAAOC,YAAY,UAAU;QAC/B,MAAM,IAAIC,UAAU;IACtB;IAEA,MAAM,EACJC,aAAa,YAAY,EACzBC,MAAMH,QAAQI,GAAG,CAACC,gBAAgB,IAAIL,QAAQG,GAAG,EAAE,EACnDG,OAAO,EACPC,SAAS,EACTC,QAAQV,aAAaW,oBAAoB,EAAE,EAC3CC,SAAS,KAAK,EACd,GAAGC,eACJ,GAAGZ;IAEJ,IAAIQ,aAAaD,SAAS;QACxB,OAAOT,aAAa;YAACK;YAAYI;YAASC;YAAWC;YAAOE;YAAQ,GAAGC,aAAa;QAAA;IACtF;IAEA,MAAMC,cAAcjB,oBAAoBQ;IACxC,MAAMU,YAAYjB,iBAAiBgB,YAAYE,SAAS;IAExD,IAAI,CAACD,WAAW;QACd,MAAM,IAAIE,MAAM;IAClB;IAEA,MAAMC,YAAYH,UAAUI,GAAG,IAAI,CAAC;IACpC,IAAI,CAACD,UAAUT,SAAS,IAAI,CAACS,UAAUV,OAAO,EAAE;QAC9C,MAAM,IAAIS,MAAM;IAClB;IAEA,OAAOlB,aAAa;QAClBK;QACAI,SAASU,UAAUV,OAAO;QAC1BC,WAAWS,UAAUT,SAAS;QAC9BC;QACAE;QACA,GAAGC,aAAa;IAClB;AACF,EAAC;AAWDb,aAAaW,oBAAoB,GAAG,IAA0BS"}
@@ -1,28 +1,17 @@
1
1
  import path from 'node:path';
2
- import resolveFrom from 'resolve-from';
2
+ import { readPackageJson } from '@sanity/cli-core';
3
+ import { createRequester } from '@sanity/cli-core/request';
3
4
  import semver from 'semver';
4
5
  import { getModuleUrl } from '../actions/build/getAutoUpdatesImportMap.js';
5
- import { readPackageManifest } from './readPackageManifest.js';
6
- function getRemoteResolvedVersion(fetchFn, url) {
7
- return fetchFn(url, {
8
- method: 'HEAD',
9
- redirect: 'manual'
10
- }).then((res)=>{
11
- // 302 is expected, but lets also handle 2xx
12
- if (res.ok || res.status < 400) {
13
- const resolved = res.headers.get('x-resolved-version');
14
- if (!resolved) {
15
- throw new Error(`Missing 'x-resolved-version' header on response from HEAD ${url}`);
16
- }
17
- return resolved;
6
+ import { getLocalPackageVersion } from './getLocalPackageVersion.js';
7
+ const defaultRequester = createRequester({
8
+ middleware: {
9
+ httpErrors: false,
10
+ promise: {
11
+ onlyBody: false
18
12
  }
19
- throw new Error(`Unexpected HTTP response: ${res.status} ${res.statusText}`);
20
- }, (err)=>{
21
- throw new Error(`Failed to fetch remote version for ${url}: ${err.message}`, {
22
- cause: err
23
- });
24
- });
25
- }
13
+ }
14
+ });
26
15
  /**
27
16
  * @internal
28
17
  *
@@ -35,39 +24,86 @@ function getRemoteResolvedVersion(fetchFn, url) {
35
24
  * The failed dependencies are anything that does not strictly match the remote version.
36
25
  * This means that if a version is lower or greater by even a patch it will be marked as failed.
37
26
  *
38
- * @param autoUpdatesImports - An object mapping package names to their remote import URLs.
27
+ * @param packages - An array of packages with their name and version to compare against remote.
39
28
  * @param workDir - The path to the working directory containing the package.json file.
40
- * @param fetchFn - Optional {@link https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API | Fetch}-compatible function to use for requesting the current remote version of a module
29
+ * @param options - Optional configuration for version comparison.
41
30
  *
42
- * @returns A promise that resolves to an array of objects, each containing
43
- * the name of a package whose local and remote versions do not match, along with the local and remote versions.
31
+ * @returns A promise that resolves to an object containing `mismatched` (packages whose local and remote versions differ)
32
+ * and `unresolvedPrerelease` (packages with prerelease versions that could not be resolved remotely).
44
33
  *
45
- * @throws Throws an error if the remote version of a package cannot be fetched, or if the local version of a package
46
- * cannot be parsed.
47
- */ export async function compareDependencyVersions(packages, workDir, { fetchFn = globalThis.fetch } = {}) {
48
- const manifest = await readPackageManifest(path.join(workDir, 'package.json'));
34
+ * @throws Throws an error if the remote version of a non-prerelease package cannot be fetched, or if the local version
35
+ * of a package cannot be parsed.
36
+ */ export async function compareDependencyVersions(packages, workDir, { appId, requester = defaultRequester } = {}) {
37
+ const manifest = await readPackageJson(path.join(workDir, 'package.json'), {
38
+ skipSchemaValidation: true
39
+ });
49
40
  const dependencies = {
50
- ...manifest.dependencies,
51
- ...manifest.devDependencies
41
+ ...manifest?.dependencies,
42
+ ...manifest?.devDependencies
52
43
  };
53
- const failedDependencies = [];
44
+ const mismatched = [];
45
+ const unresolvedPrerelease = [];
54
46
  for (const pkg of packages){
55
- const resolvedVersion = await getRemoteResolvedVersion(fetchFn, getModuleUrl(pkg));
56
- const manifestPath = resolveFrom.silent(workDir, path.join(pkg.name, 'package.json'));
47
+ // Skip packages that are not declared in the local package.json
48
+ if (!dependencies[pkg.name]) {
49
+ continue;
50
+ }
51
+ const resolvedVersion = await getRemoteResolvedVersion(getModuleUrl(pkg, {
52
+ appId
53
+ }), requester);
54
+ if (resolvedVersion === null) {
55
+ if (semver.prerelease(pkg.version)) {
56
+ unresolvedPrerelease.push({
57
+ pkg: pkg.name,
58
+ version: pkg.version
59
+ });
60
+ continue;
61
+ }
62
+ throw new Error(`Failed to resolve remote version for ${pkg.name}@${pkg.version}: package not found`);
63
+ }
64
+ const packageVersion = await getLocalPackageVersion(pkg.name, workDir);
57
65
  const manifestVersion = dependencies[pkg.name];
58
- const installed = semver.coerce(manifestPath ? semver.parse((await readPackageManifest(manifestPath)).version) : semver.coerce(manifestVersion));
66
+ const installed = semver.coerce(packageVersion ? semver.parse(packageVersion) : semver.coerce(manifestVersion));
59
67
  if (!installed) {
60
- throw new Error(`Failed to parse installed version for ${pkg}`);
68
+ throw new Error(`Failed to parse installed version for ${pkg.name}`);
61
69
  }
62
70
  if (!semver.eq(resolvedVersion, installed.version)) {
63
- failedDependencies.push({
71
+ mismatched.push({
64
72
  installed: installed.version,
65
73
  pkg: pkg.name,
66
74
  remote: resolvedVersion
67
75
  });
68
76
  }
69
77
  }
70
- return failedDependencies;
78
+ return {
79
+ mismatched,
80
+ unresolvedPrerelease
81
+ };
82
+ }
83
+ async function getRemoteResolvedVersion(url, request) {
84
+ let response;
85
+ try {
86
+ response = await request({
87
+ maxRedirects: 0,
88
+ method: 'HEAD',
89
+ url
90
+ });
91
+ } catch (err) {
92
+ const message = err instanceof Error ? err.message : String(err);
93
+ throw new Error(`Failed to fetch remote version for ${url}: ${message}`);
94
+ }
95
+ // 302 is expected, but lets also handle 2xx
96
+ if (response.statusCode < 400) {
97
+ const resolved = response.headers['x-resolved-version'];
98
+ if (!resolved) {
99
+ throw new Error(`Missing 'x-resolved-version' header on response from HEAD ${url}`);
100
+ }
101
+ return resolved;
102
+ }
103
+ if (response.statusCode === 404) {
104
+ return null;
105
+ }
106
+ throw new Error(`Unexpected HTTP response: ${response.statusCode} ${response.statusMessage}`);
71
107
  }
72
108
 
73
109
  //# sourceMappingURL=compareDependencyVersions.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/util/compareDependencyVersions.ts"],"sourcesContent":["import path from 'node:path'\n\nimport resolveFrom from 'resolve-from'\nimport semver from 'semver'\n\nimport {getModuleUrl} from '../actions/build/getAutoUpdatesImportMap.js'\nimport {readPackageManifest} from './readPackageManifest.js'\n\nfunction getRemoteResolvedVersion(fetchFn: typeof fetch, url: string) {\n return fetchFn(url, {\n method: 'HEAD',\n redirect: 'manual',\n }).then(\n (res) => {\n // 302 is expected, but lets also handle 2xx\n if (res.ok || res.status < 400) {\n const resolved = res.headers.get('x-resolved-version')\n if (!resolved) {\n throw new Error(`Missing 'x-resolved-version' header on response from HEAD ${url}`)\n }\n return resolved\n }\n throw new Error(`Unexpected HTTP response: ${res.status} ${res.statusText}`)\n },\n (err) => {\n throw new Error(`Failed to fetch remote version for ${url}: ${err.message}`, {cause: err})\n },\n )\n}\n\ninterface CompareDependencyVersions {\n installed: string\n pkg: string\n remote: string\n}\n\n/**\n * @internal\n *\n * Compares the versions of dependencies in the studio or app with their remote versions.\n *\n * This function reads the package.json file in the provided working directory, and compares the versions of the dependencies\n * specified in the `autoUpdatesImports` parameter with their remote versions. If the versions do not match, the dependency is\n * added to a list of failed dependencies, which is returned by the function.\n *\n * The failed dependencies are anything that does not strictly match the remote version.\n * This means that if a version is lower or greater by even a patch it will be marked as failed.\n *\n * @param autoUpdatesImports - An object mapping package names to their remote import URLs.\n * @param workDir - The path to the working directory containing the package.json file.\n * @param fetchFn - Optional {@link https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API | Fetch}-compatible function to use for requesting the current remote version of a module\n *\n * @returns A promise that resolves to an array of objects, each containing\n * the name of a package whose local and remote versions do not match, along with the local and remote versions.\n *\n * @throws Throws an error if the remote version of a package cannot be fetched, or if the local version of a package\n * cannot be parsed.\n */\nexport async function compareDependencyVersions(\n packages: {name: string; version: string}[],\n workDir: string,\n {fetchFn = globalThis.fetch}: {appId?: string; fetchFn?: typeof fetch} = {},\n): Promise<Array<CompareDependencyVersions>> {\n const manifest = await readPackageManifest(path.join(workDir, 'package.json'))\n const dependencies = {...manifest.dependencies, ...manifest.devDependencies}\n\n const failedDependencies: Array<CompareDependencyVersions> = []\n\n for (const pkg of packages) {\n const resolvedVersion = await getRemoteResolvedVersion(fetchFn, getModuleUrl(pkg))\n\n const manifestPath = resolveFrom.silent(workDir, path.join(pkg.name, 'package.json'))\n\n const manifestVersion = dependencies[pkg.name]\n\n const installed = semver.coerce(\n manifestPath\n ? semver.parse((await readPackageManifest(manifestPath)).version)\n : semver.coerce(manifestVersion),\n )\n\n if (!installed) {\n throw new Error(`Failed to parse installed version for ${pkg}`)\n }\n\n if (!semver.eq(resolvedVersion, installed.version)) {\n failedDependencies.push({\n installed: installed.version,\n pkg: pkg.name,\n remote: resolvedVersion,\n })\n }\n }\n\n return failedDependencies\n}\n"],"names":["path","resolveFrom","semver","getModuleUrl","readPackageManifest","getRemoteResolvedVersion","fetchFn","url","method","redirect","then","res","ok","status","resolved","headers","get","Error","statusText","err","message","cause","compareDependencyVersions","packages","workDir","globalThis","fetch","manifest","join","dependencies","devDependencies","failedDependencies","pkg","resolvedVersion","manifestPath","silent","name","manifestVersion","installed","coerce","parse","version","eq","push","remote"],"mappings":"AAAA,OAAOA,UAAU,YAAW;AAE5B,OAAOC,iBAAiB,eAAc;AACtC,OAAOC,YAAY,SAAQ;AAE3B,SAAQC,YAAY,QAAO,8CAA6C;AACxE,SAAQC,mBAAmB,QAAO,2BAA0B;AAE5D,SAASC,yBAAyBC,OAAqB,EAAEC,GAAW;IAClE,OAAOD,QAAQC,KAAK;QAClBC,QAAQ;QACRC,UAAU;IACZ,GAAGC,IAAI,CACL,CAACC;QACC,4CAA4C;QAC5C,IAAIA,IAAIC,EAAE,IAAID,IAAIE,MAAM,GAAG,KAAK;YAC9B,MAAMC,WAAWH,IAAII,OAAO,CAACC,GAAG,CAAC;YACjC,IAAI,CAACF,UAAU;gBACb,MAAM,IAAIG,MAAM,CAAC,0DAA0D,EAAEV,KAAK;YACpF;YACA,OAAOO;QACT;QACA,MAAM,IAAIG,MAAM,CAAC,0BAA0B,EAAEN,IAAIE,MAAM,CAAC,CAAC,EAAEF,IAAIO,UAAU,EAAE;IAC7E,GACA,CAACC;QACC,MAAM,IAAIF,MAAM,CAAC,mCAAmC,EAAEV,IAAI,EAAE,EAAEY,IAAIC,OAAO,EAAE,EAAE;YAACC,OAAOF;QAAG;IAC1F;AAEJ;AAQA;;;;;;;;;;;;;;;;;;;;;CAqBC,GACD,OAAO,eAAeG,0BACpBC,QAA2C,EAC3CC,OAAe,EACf,EAAClB,UAAUmB,WAAWC,KAAK,EAA2C,GAAG,CAAC,CAAC;IAE3E,MAAMC,WAAW,MAAMvB,oBAAoBJ,KAAK4B,IAAI,CAACJ,SAAS;IAC9D,MAAMK,eAAe;QAAC,GAAGF,SAASE,YAAY;QAAE,GAAGF,SAASG,eAAe;IAAA;IAE3E,MAAMC,qBAAuD,EAAE;IAE/D,KAAK,MAAMC,OAAOT,SAAU;QAC1B,MAAMU,kBAAkB,MAAM5B,yBAAyBC,SAASH,aAAa6B;QAE7E,MAAME,eAAejC,YAAYkC,MAAM,CAACX,SAASxB,KAAK4B,IAAI,CAACI,IAAII,IAAI,EAAE;QAErE,MAAMC,kBAAkBR,YAAY,CAACG,IAAII,IAAI,CAAC;QAE9C,MAAME,YAAYpC,OAAOqC,MAAM,CAC7BL,eACIhC,OAAOsC,KAAK,CAAC,AAAC,CAAA,MAAMpC,oBAAoB8B,aAAY,EAAGO,OAAO,IAC9DvC,OAAOqC,MAAM,CAACF;QAGpB,IAAI,CAACC,WAAW;YACd,MAAM,IAAIrB,MAAM,CAAC,sCAAsC,EAAEe,KAAK;QAChE;QAEA,IAAI,CAAC9B,OAAOwC,EAAE,CAACT,iBAAiBK,UAAUG,OAAO,GAAG;YAClDV,mBAAmBY,IAAI,CAAC;gBACtBL,WAAWA,UAAUG,OAAO;gBAC5BT,KAAKA,IAAII,IAAI;gBACbQ,QAAQX;YACV;QACF;IACF;IAEA,OAAOF;AACT"}
1
+ {"version":3,"sources":["../../src/util/compareDependencyVersions.ts"],"sourcesContent":["import path from 'node:path'\n\nimport {readPackageJson} from '@sanity/cli-core'\nimport {createRequester} from '@sanity/cli-core/request'\nimport semver from 'semver'\n\nimport {getModuleUrl} from '../actions/build/getAutoUpdatesImportMap.js'\nimport {getLocalPackageVersion} from './getLocalPackageVersion.js'\n\nconst defaultRequester = createRequester({\n middleware: {httpErrors: false, promise: {onlyBody: false}},\n})\n\ninterface CompareDependencyVersions {\n installed: string\n pkg: string\n remote: string\n}\n\nexport interface UnresolvedPrerelease {\n pkg: string\n version: string\n}\n\ninterface CompareDependencyVersionsResult {\n mismatched: Array<CompareDependencyVersions>\n unresolvedPrerelease: Array<UnresolvedPrerelease>\n}\n\ninterface CompareDependencyVersionsOptions {\n /** When provided, uses the app-specific module endpoint instead of the default endpoint. */\n appId?: string\n /** Optional requester for dependency injection (primarily for testing). */\n requester?: typeof defaultRequester\n}\n\n/**\n * @internal\n *\n * Compares the versions of dependencies in the studio or app with their remote versions.\n *\n * This function reads the package.json file in the provided working directory, and compares the versions of the dependencies\n * specified in the `autoUpdatesImports` parameter with their remote versions. If the versions do not match, the dependency is\n * added to a list of failed dependencies, which is returned by the function.\n *\n * The failed dependencies are anything that does not strictly match the remote version.\n * This means that if a version is lower or greater by even a patch it will be marked as failed.\n *\n * @param packages - An array of packages with their name and version to compare against remote.\n * @param workDir - The path to the working directory containing the package.json file.\n * @param options - Optional configuration for version comparison.\n *\n * @returns A promise that resolves to an object containing `mismatched` (packages whose local and remote versions differ)\n * and `unresolvedPrerelease` (packages with prerelease versions that could not be resolved remotely).\n *\n * @throws Throws an error if the remote version of a non-prerelease package cannot be fetched, or if the local version\n * of a package cannot be parsed.\n */\nexport async function compareDependencyVersions(\n packages: {name: string; version: string}[],\n workDir: string,\n {appId, requester = defaultRequester}: CompareDependencyVersionsOptions = {},\n): Promise<CompareDependencyVersionsResult> {\n const manifest = await readPackageJson(path.join(workDir, 'package.json'), {\n skipSchemaValidation: true,\n })\n const dependencies = {...manifest?.dependencies, ...manifest?.devDependencies}\n\n const mismatched: Array<CompareDependencyVersions> = []\n const unresolvedPrerelease: Array<UnresolvedPrerelease> = []\n\n for (const pkg of packages) {\n // Skip packages that are not declared in the local package.json\n if (!dependencies[pkg.name]) {\n continue\n }\n\n const resolvedVersion = await getRemoteResolvedVersion(getModuleUrl(pkg, {appId}), requester)\n\n if (resolvedVersion === null) {\n if (semver.prerelease(pkg.version)) {\n unresolvedPrerelease.push({pkg: pkg.name, version: pkg.version})\n continue\n }\n throw new Error(\n `Failed to resolve remote version for ${pkg.name}@${pkg.version}: package not found`,\n )\n }\n\n const packageVersion = await getLocalPackageVersion(pkg.name, workDir)\n\n const manifestVersion = dependencies[pkg.name]\n\n const installed = semver.coerce(\n packageVersion ? semver.parse(packageVersion) : semver.coerce(manifestVersion),\n )\n\n if (!installed) {\n throw new Error(`Failed to parse installed version for ${pkg.name}`)\n }\n\n if (!semver.eq(resolvedVersion, installed.version)) {\n mismatched.push({\n installed: installed.version,\n pkg: pkg.name,\n remote: resolvedVersion,\n })\n }\n }\n\n return {mismatched, unresolvedPrerelease}\n}\n\nasync function getRemoteResolvedVersion(\n url: string,\n request: typeof defaultRequester,\n): Promise<string | null> {\n let response\n try {\n response = await request({\n maxRedirects: 0,\n method: 'HEAD',\n url,\n })\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err)\n throw new Error(`Failed to fetch remote version for ${url}: ${message}`)\n }\n\n // 302 is expected, but lets also handle 2xx\n if (response.statusCode < 400) {\n const resolved = response.headers['x-resolved-version']\n if (!resolved) {\n throw new Error(`Missing 'x-resolved-version' header on response from HEAD ${url}`)\n }\n return resolved\n }\n\n if (response.statusCode === 404) {\n return null\n }\n\n throw new Error(`Unexpected HTTP response: ${response.statusCode} ${response.statusMessage}`)\n}\n"],"names":["path","readPackageJson","createRequester","semver","getModuleUrl","getLocalPackageVersion","defaultRequester","middleware","httpErrors","promise","onlyBody","compareDependencyVersions","packages","workDir","appId","requester","manifest","join","skipSchemaValidation","dependencies","devDependencies","mismatched","unresolvedPrerelease","pkg","name","resolvedVersion","getRemoteResolvedVersion","prerelease","version","push","Error","packageVersion","manifestVersion","installed","coerce","parse","eq","remote","url","request","response","maxRedirects","method","err","message","String","statusCode","resolved","headers","statusMessage"],"mappings":"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"}
@@ -0,0 +1,64 @@
1
+ /**
2
+ * Minimal interface for a config store that supports get/set/delete operations.
3
+ * Compatible with the `configstore` package.
4
+ */ /**
5
+ * Create a config in the provided config store that expires after the provided TTL.
6
+ */ export function createExpiringConfig({ fetchValue, key, onCacheHit = ()=>null, onFetch = ()=>null, onRevalidate = ()=>null, store, ttl, validateValue = (value)=>true }) {
7
+ let currentFetch = null;
8
+ return {
9
+ delete () {
10
+ store.delete(key);
11
+ },
12
+ async get () {
13
+ const stored = store.get(key);
14
+ if (isExpiringValue(stored)) {
15
+ const { updatedAt, value } = stored;
16
+ if (!validateValue(value)) {
17
+ throw new Error('Stored value is invalid');
18
+ }
19
+ const hasExpired = Date.now() - updatedAt > ttl;
20
+ if (!hasExpired) {
21
+ onCacheHit();
22
+ return value;
23
+ }
24
+ onRevalidate();
25
+ }
26
+ // Return existing fetch if one is already in progress
27
+ if (currentFetch) {
28
+ return currentFetch;
29
+ }
30
+ onFetch();
31
+ currentFetch = Promise.resolve(fetchValue());
32
+ const nextValue = await currentFetch;
33
+ if (!validateValue(nextValue)) {
34
+ throw new Error('Fetched value is invalid');
35
+ }
36
+ currentFetch = null;
37
+ store.set(key, {
38
+ updatedAt: Date.now(),
39
+ value: nextValue
40
+ });
41
+ return nextValue;
42
+ }
43
+ };
44
+ }
45
+ /**
46
+ * Checks if the given stored value is valid (does not check if expired, only verified shape)
47
+ *
48
+ * @param stored - The stored value to check
49
+ * @returns True if the stored value is valid
50
+ * @internal
51
+ */ function isExpiringValue(stored) {
52
+ if (typeof stored !== 'object' || stored === null || Array.isArray(stored)) {
53
+ return false;
54
+ }
55
+ if (!('updatedAt' in stored) || typeof stored.updatedAt !== 'number') {
56
+ return false;
57
+ }
58
+ if (!('value' in stored)) {
59
+ return false;
60
+ }
61
+ return true;
62
+ }
63
+
64
+ //# sourceMappingURL=createExpiringConfig.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/util/createExpiringConfig.ts"],"sourcesContent":["/**\n * Minimal interface for a config store that supports get/set/delete operations.\n * Compatible with the `configstore` package.\n */\ninterface ConfigStoreApi {\n delete: (key: string) => void\n get: (key: string) => unknown\n set: (key: string, value: unknown) => void\n}\n\ninterface ExpiringConfigValue {\n updatedAt: number\n value: unknown\n}\n\ninterface ExpiringConfigOptions<Type> {\n /** Fetch value */\n fetchValue: () => Promise<Type> | Type\n /** Config key */\n key: string\n /** Config store */\n store: ConfigStoreApi\n /** TTL (milliseconds) */\n ttl: number\n\n /** Subscribe to cache hit event */\n onCacheHit?: () => void\n /** Subscribe to fetch event */\n onFetch?: () => void\n /** Subscribe to revalidate event */\n onRevalidate?: () => void\n\n /**\n * Assert the fetched value is valid, or throw if invalid.\n * If none is provided, it will always accept the fetched value.\n */\n validateValue?: (value: unknown) => value is Type\n}\n\ninterface ExpiringConfigApi<Type> {\n /**\n * Delete the cached value.\n */\n delete: () => void\n /**\n * Attempt to get the cached value. If there is no cached value, or the cached value has expired,\n * fetch, cache, and return the value.\n */\n get: () => Promise<Type>\n}\n\n/**\n * Create a config in the provided config store that expires after the provided TTL.\n */\nexport function createExpiringConfig<Type>({\n fetchValue,\n key,\n onCacheHit = () => null,\n onFetch = () => null,\n onRevalidate = () => null,\n store,\n ttl,\n validateValue = (value: unknown): value is Type => true,\n}: ExpiringConfigOptions<Type>): ExpiringConfigApi<Type> {\n let currentFetch: Promise<Type> | null = null\n return {\n delete() {\n store.delete(key)\n },\n async get(): Promise<Type> {\n const stored = store.get(key)\n\n if (isExpiringValue(stored)) {\n const {updatedAt, value} = stored\n if (!validateValue(value)) {\n throw new Error('Stored value is invalid')\n }\n\n const hasExpired = Date.now() - updatedAt > ttl\n\n if (!hasExpired) {\n onCacheHit()\n return value\n }\n\n onRevalidate()\n }\n\n // Return existing fetch if one is already in progress\n if (currentFetch) {\n return currentFetch\n }\n\n onFetch()\n\n currentFetch = Promise.resolve(fetchValue())\n const nextValue = await currentFetch\n if (!validateValue(nextValue)) {\n throw new Error('Fetched value is invalid')\n }\n\n currentFetch = null\n\n store.set(key, {\n updatedAt: Date.now(),\n value: nextValue,\n })\n\n return nextValue\n },\n }\n}\n\n/**\n * Checks if the given stored value is valid (does not check if expired, only verified shape)\n *\n * @param stored - The stored value to check\n * @returns True if the stored value is valid\n * @internal\n */\nfunction isExpiringValue(stored: unknown): stored is ExpiringConfigValue {\n if (typeof stored !== 'object' || stored === null || Array.isArray(stored)) {\n return false\n }\n\n if (!('updatedAt' in stored) || typeof stored.updatedAt !== 'number') {\n return false\n }\n\n if (!('value' in stored)) {\n return false\n }\n\n return true\n}\n"],"names":["createExpiringConfig","fetchValue","key","onCacheHit","onFetch","onRevalidate","store","ttl","validateValue","value","currentFetch","delete","get","stored","isExpiringValue","updatedAt","Error","hasExpired","Date","now","Promise","resolve","nextValue","set","Array","isArray"],"mappings":"AAAA;;;CAGC,GAgDD;;CAEC,GACD,OAAO,SAASA,qBAA2B,EACzCC,UAAU,EACVC,GAAG,EACHC,aAAa,IAAM,IAAI,EACvBC,UAAU,IAAM,IAAI,EACpBC,eAAe,IAAM,IAAI,EACzBC,KAAK,EACLC,GAAG,EACHC,gBAAgB,CAACC,QAAkC,IAAI,EAC3B;IAC5B,IAAIC,eAAqC;IACzC,OAAO;QACLC;YACEL,MAAMK,MAAM,CAACT;QACf;QACA,MAAMU;YACJ,MAAMC,SAASP,MAAMM,GAAG,CAACV;YAEzB,IAAIY,gBAAgBD,SAAS;gBAC3B,MAAM,EAACE,SAAS,EAAEN,KAAK,EAAC,GAAGI;gBAC3B,IAAI,CAACL,cAAcC,QAAQ;oBACzB,MAAM,IAAIO,MAAM;gBAClB;gBAEA,MAAMC,aAAaC,KAAKC,GAAG,KAAKJ,YAAYR;gBAE5C,IAAI,CAACU,YAAY;oBACfd;oBACA,OAAOM;gBACT;gBAEAJ;YACF;YAEA,sDAAsD;YACtD,IAAIK,cAAc;gBAChB,OAAOA;YACT;YAEAN;YAEAM,eAAeU,QAAQC,OAAO,CAACpB;YAC/B,MAAMqB,YAAY,MAAMZ;YACxB,IAAI,CAACF,cAAcc,YAAY;gBAC7B,MAAM,IAAIN,MAAM;YAClB;YAEAN,eAAe;YAEfJ,MAAMiB,GAAG,CAACrB,KAAK;gBACba,WAAWG,KAAKC,GAAG;gBACnBV,OAAOa;YACT;YAEA,OAAOA;QACT;IACF;AACF;AAEA;;;;;;CAMC,GACD,SAASR,gBAAgBD,MAAe;IACtC,IAAI,OAAOA,WAAW,YAAYA,WAAW,QAAQW,MAAMC,OAAO,CAACZ,SAAS;QAC1E,OAAO;IACT;IAEA,IAAI,CAAE,CAAA,eAAeA,MAAK,KAAM,OAAOA,OAAOE,SAAS,KAAK,UAAU;QACpE,OAAO;IACT;IAEA,IAAI,CAAE,CAAA,WAAWF,MAAK,GAAI;QACxB,OAAO;IACT;IAEA,OAAO;AACT"}
@@ -0,0 +1,135 @@
1
+ import { readFile, stat } from 'node:fs/promises';
2
+ import { join } from 'node:path';
3
+ async function fileExists(filePath) {
4
+ try {
5
+ await stat(filePath);
6
+ return true;
7
+ } catch {
8
+ return false;
9
+ }
10
+ }
11
+ async function isFile(filePath) {
12
+ try {
13
+ const s = await stat(filePath);
14
+ return s.isFile();
15
+ } catch {
16
+ return false;
17
+ }
18
+ }
19
+ async function checkDetector(rootPath, framework, detector) {
20
+ let { matchContent, path: filePath } = detector;
21
+ const { matchPackage } = detector;
22
+ if (matchPackage && matchContent) {
23
+ throw new Error(`Cannot specify "matchPackage" and "matchContent" in the same detector for "${framework.slug}"`);
24
+ }
25
+ if (matchPackage && filePath) {
26
+ throw new Error(`Cannot specify "matchPackage" and "path" in the same detector for "${framework.slug}"`);
27
+ }
28
+ if (!filePath && !matchPackage) {
29
+ throw new Error(`Must specify either "path" or "matchPackage" in detector for "${framework.slug}".`);
30
+ }
31
+ if (!filePath) {
32
+ filePath = 'package.json';
33
+ }
34
+ if (matchPackage) {
35
+ const escapedPkg = matchPackage.replaceAll(/[.*+?^${}()|[\]\\]/g, String.raw`\$&`);
36
+ matchContent = String.raw`"(dev)?(d|D)ependencies":\s*{[^}]*"${escapedPkg}":\s*"(.+?)"[^}]*}`;
37
+ }
38
+ const fullPath = join(rootPath, filePath);
39
+ if (!await fileExists(fullPath)) {
40
+ return undefined;
41
+ }
42
+ if (matchContent) {
43
+ if (!await isFile(fullPath)) {
44
+ return undefined;
45
+ }
46
+ const content = await readFile(fullPath, 'utf8');
47
+ const match = content.match(new RegExp(matchContent, 'm'));
48
+ if (!match) {
49
+ return undefined;
50
+ }
51
+ if (matchPackage && match[3]) {
52
+ return {
53
+ detectedVersion: match[3],
54
+ framework
55
+ };
56
+ }
57
+ }
58
+ return {
59
+ framework
60
+ };
61
+ }
62
+ async function matchFramework(rootPath, framework) {
63
+ const { detectors } = framework;
64
+ if (!detectors) return undefined;
65
+ const { every, some } = detectors;
66
+ if (every !== undefined && !Array.isArray(every)) return undefined;
67
+ if (some !== undefined && !Array.isArray(some)) return undefined;
68
+ const results = [];
69
+ if (every) {
70
+ const everyResults = await Promise.all(every.map((item)=>checkDetector(rootPath, framework, item)));
71
+ results.push(...everyResults);
72
+ }
73
+ if (some) {
74
+ let someResult;
75
+ for (const item of some){
76
+ const result = await checkDetector(rootPath, framework, item);
77
+ if (result) {
78
+ someResult = result;
79
+ break;
80
+ }
81
+ }
82
+ results.push(someResult);
83
+ }
84
+ if (results.length === 0) return undefined;
85
+ if (!results.every((r)=>r !== undefined)) {
86
+ return undefined;
87
+ }
88
+ const detectedVersion = results.find((r)=>r !== undefined && r.detectedVersion !== undefined)?.detectedVersion;
89
+ return {
90
+ detectedVersion,
91
+ framework
92
+ };
93
+ }
94
+ function removeSupersededFrameworks(matches) {
95
+ // Snapshot to avoid mutation-during-iteration when splice shifts elements
96
+ const snapshot = [
97
+ ...matches
98
+ ];
99
+ for (const match of snapshot){
100
+ if (match?.supersedes) {
101
+ for (const slug of match.supersedes){
102
+ removeSupersededFramework(matches, slug);
103
+ }
104
+ }
105
+ }
106
+ }
107
+ function removeSupersededFramework(matches, slug) {
108
+ const index = matches.findIndex((f)=>f?.slug === slug);
109
+ const framework = matches[index];
110
+ if (framework) {
111
+ matches.splice(index, 1);
112
+ if (framework.supersedes) {
113
+ for (const s of framework.supersedes){
114
+ removeSupersededFramework(matches, s);
115
+ }
116
+ }
117
+ }
118
+ }
119
+ export async function detectFrameworkRecord(options) {
120
+ const { frameworkList, rootPath } = options;
121
+ const results = await Promise.all(frameworkList.map(async (fw)=>{
122
+ const match = await matchFramework(rootPath, fw);
123
+ if (match) {
124
+ return {
125
+ ...fw,
126
+ detectedVersion: match.detectedVersion
127
+ };
128
+ }
129
+ return null;
130
+ }));
131
+ removeSupersededFrameworks(results);
132
+ return results.find((r)=>r !== null) ?? null;
133
+ }
134
+
135
+ //# sourceMappingURL=detectFramework.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/util/detectFramework.ts"],"sourcesContent":["import {readFile, stat} from 'node:fs/promises'\nimport {join} from 'node:path'\n\nimport {type Framework} from '@vercel/frameworks'\n\ntype VersionedFramework = Framework & {detectedVersion?: string}\n\ninterface DetectorMatch {\n framework: Framework\n\n detectedVersion?: string\n}\n\nasync function fileExists(filePath: string): Promise<boolean> {\n try {\n await stat(filePath)\n return true\n } catch {\n return false\n }\n}\n\nasync function isFile(filePath: string): Promise<boolean> {\n try {\n const s = await stat(filePath)\n return s.isFile()\n } catch {\n return false\n }\n}\n\nasync function checkDetector(\n rootPath: string,\n framework: Framework,\n detector: {matchContent?: string; matchPackage?: string; path?: string},\n): Promise<DetectorMatch | undefined> {\n let {matchContent, path: filePath} = detector\n const {matchPackage} = detector\n\n if (matchPackage && matchContent) {\n throw new Error(\n `Cannot specify \"matchPackage\" and \"matchContent\" in the same detector for \"${framework.slug}\"`,\n )\n }\n if (matchPackage && filePath) {\n throw new Error(\n `Cannot specify \"matchPackage\" and \"path\" in the same detector for \"${framework.slug}\"`,\n )\n }\n if (!filePath && !matchPackage) {\n throw new Error(\n `Must specify either \"path\" or \"matchPackage\" in detector for \"${framework.slug}\".`,\n )\n }\n\n if (!filePath) {\n filePath = 'package.json'\n }\n\n if (matchPackage) {\n const escapedPkg = matchPackage.replaceAll(/[.*+?^${}()|[\\]\\\\]/g, String.raw`\\$&`)\n matchContent = String.raw`\"(dev)?(d|D)ependencies\":\\s*{[^}]*\"${escapedPkg}\":\\s*\"(.+?)\"[^}]*}`\n }\n\n const fullPath = join(rootPath, filePath)\n\n if (!(await fileExists(fullPath))) {\n return undefined\n }\n\n if (matchContent) {\n if (!(await isFile(fullPath))) {\n return undefined\n }\n const content = await readFile(fullPath, 'utf8')\n const match = content.match(new RegExp(matchContent, 'm'))\n if (!match) {\n return undefined\n }\n if (matchPackage && match[3]) {\n return {detectedVersion: match[3], framework}\n }\n }\n\n return {framework}\n}\n\nasync function matchFramework(\n rootPath: string,\n framework: Framework,\n): Promise<DetectorMatch | undefined> {\n const {detectors} = framework\n if (!detectors) return undefined\n\n const {every, some} = detectors\n if (every !== undefined && !Array.isArray(every)) return undefined\n if (some !== undefined && !Array.isArray(some)) return undefined\n\n const results: (DetectorMatch | undefined)[] = []\n\n if (every) {\n const everyResults = await Promise.all(\n every.map((item) => checkDetector(rootPath, framework, item)),\n )\n results.push(...everyResults)\n }\n\n if (some) {\n let someResult: DetectorMatch | undefined\n for (const item of some) {\n const result = await checkDetector(rootPath, framework, item)\n if (result) {\n someResult = result\n break\n }\n }\n results.push(someResult)\n }\n\n if (results.length === 0) return undefined\n\n if (!results.every((r) => r !== undefined)) {\n return undefined\n }\n\n const detectedVersion = results.find(\n (r): r is DetectorMatch => r !== undefined && r.detectedVersion !== undefined,\n )?.detectedVersion\n\n return {detectedVersion, framework}\n}\n\nfunction removeSupersededFrameworks(matches: (Framework | null)[]): void {\n // Snapshot to avoid mutation-during-iteration when splice shifts elements\n const snapshot = [...matches]\n for (const match of snapshot) {\n if (match?.supersedes) {\n for (const slug of match.supersedes) {\n removeSupersededFramework(matches, slug)\n }\n }\n }\n}\n\nfunction removeSupersededFramework(matches: (Framework | null)[], slug: string): void {\n const index = matches.findIndex((f) => f?.slug === slug)\n const framework = matches[index]\n if (framework) {\n matches.splice(index, 1)\n if (framework.supersedes) {\n for (const s of framework.supersedes) {\n removeSupersededFramework(matches, s)\n }\n }\n }\n}\n\nexport async function detectFrameworkRecord(options: {\n frameworkList: readonly Framework[]\n rootPath: string\n}): Promise<VersionedFramework | null> {\n const {frameworkList, rootPath} = options\n\n const results = await Promise.all(\n frameworkList.map(async (fw): Promise<VersionedFramework | null> => {\n const match = await matchFramework(rootPath, fw)\n if (match) {\n return {...fw, detectedVersion: match.detectedVersion}\n }\n return null\n }),\n )\n\n removeSupersededFrameworks(results)\n return results.find((r) => r !== null) ?? null\n}\n"],"names":["readFile","stat","join","fileExists","filePath","isFile","s","checkDetector","rootPath","framework","detector","matchContent","path","matchPackage","Error","slug","escapedPkg","replaceAll","String","raw","fullPath","undefined","content","match","RegExp","detectedVersion","matchFramework","detectors","every","some","Array","isArray","results","everyResults","Promise","all","map","item","push","someResult","result","length","r","find","removeSupersededFrameworks","matches","snapshot","supersedes","removeSupersededFramework","index","findIndex","f","splice","detectFrameworkRecord","options","frameworkList","fw"],"mappings":"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"}
@@ -1,5 +1,4 @@
1
1
  export const NO_PROJECT_ID = `sanity.cli.ts does not contain a project identifier ("api.projectId"), which is required for the Sanity CLI to communicate with the Sanity API`;
2
- export const NO_DATASET_ID = `sanity.cli.ts does not contain a dataset identifier ("api.dataset"), which is required for the Sanity CLI to communicate with the Sanity API`;
3
2
  export const NO_ORGANIZATION_ID = `sanity.cli.ts does not contain an organization identifier ("app.organizationId"), which is required for the Sanity CLI to communicate with the Sanity API`;
4
3
  export const NO_MEDIA_LIBRARY_ASPECTS_PATH = `sanity.cli.ts does not contain a media library aspects path ("mediaLibrary.aspectsPath"), which is required for the Sanity CLI to manage aspects.`;
5
4
 
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/util/errorMessages.ts"],"sourcesContent":["export const NO_PROJECT_ID = `sanity.cli.ts does not contain a project identifier (\"api.projectId\"), which is required for the Sanity CLI to communicate with the Sanity API`\nexport const NO_DATASET_ID = `sanity.cli.ts does not contain a dataset identifier (\"api.dataset\"), which is required for the Sanity CLI to communicate with the Sanity API`\nexport const NO_ORGANIZATION_ID = `sanity.cli.ts does not contain an organization identifier (\"app.organizationId\"), which is required for the Sanity CLI to communicate with the Sanity API`\nexport const NO_MEDIA_LIBRARY_ASPECTS_PATH = `sanity.cli.ts does not contain a media library aspects path (\"mediaLibrary.aspectsPath\"), which is required for the Sanity CLI to manage aspects.`\n"],"names":["NO_PROJECT_ID","NO_DATASET_ID","NO_ORGANIZATION_ID","NO_MEDIA_LIBRARY_ASPECTS_PATH"],"mappings":"AAAA,OAAO,MAAMA,gBAAgB,CAAC,8IAA8I,CAAC,CAAA;AAC7K,OAAO,MAAMC,gBAAgB,CAAC,4IAA4I,CAAC,CAAA;AAC3K,OAAO,MAAMC,qBAAqB,CAAC,yJAAyJ,CAAC,CAAA;AAC7L,OAAO,MAAMC,gCAAgC,CAAC,iJAAiJ,CAAC,CAAA"}
1
+ {"version":3,"sources":["../../src/util/errorMessages.ts"],"sourcesContent":["export const NO_PROJECT_ID = `sanity.cli.ts does not contain a project identifier (\"api.projectId\"), which is required for the Sanity CLI to communicate with the Sanity API`\nexport const NO_ORGANIZATION_ID = `sanity.cli.ts does not contain an organization identifier (\"app.organizationId\"), which is required for the Sanity CLI to communicate with the Sanity API`\nexport const NO_MEDIA_LIBRARY_ASPECTS_PATH = `sanity.cli.ts does not contain a media library aspects path (\"mediaLibrary.aspectsPath\"), which is required for the Sanity CLI to manage aspects.`\n"],"names":["NO_PROJECT_ID","NO_ORGANIZATION_ID","NO_MEDIA_LIBRARY_ASPECTS_PATH"],"mappings":"AAAA,OAAO,MAAMA,gBAAgB,CAAC,8IAA8I,CAAC,CAAA;AAC7K,OAAO,MAAMC,qBAAqB,CAAC,yJAAyJ,CAAC,CAAA;AAC7L,OAAO,MAAMC,gCAAgC,CAAC,iJAAiJ,CAAC,CAAA"}
@@ -3,13 +3,12 @@ import readline from 'node:readline';
3
3
  import { Readable } from 'node:stream';
4
4
  import zlib from 'node:zlib';
5
5
  import tar from 'tar-stream';
6
+ import { isTar } from './isTar.js';
6
7
  const HEADER_SIZE = 300;
7
8
  // https://github.com/kevva/is-gzip/blob/13dab7c877787bd5cff9de5482b1736f00df99c6/index.js
8
9
  const isGzip = (buf)=>buf.length >= 3 && buf[0] === 0x1f && buf[1] === 0x8b && buf[2] === 0x08;
9
10
  // https://github.com/watson/is-deflate/blob/f9e8f0c7814eed715e13e29e97c69acee319686a/index.js
10
11
  const isDeflate = (buf)=>buf.length >= 2 && buf[0] === 0x78 && (buf[1] === 1 || buf[1] === 0x9c || buf[1] === 0xda);
11
- // https://github.com/kevva/is-tar/blob/d295ffa2002a5d415946fc3d49f024ace8c28bd3/index.js
12
- const isTar = (buf)=>buf.length >= 262 && buf[257] === 0x75 && buf[258] === 0x73 && buf[259] === 0x74 && buf[260] === 0x61 && buf[261] === 0x72;
13
12
  async function* extract(stream, extractor) {
14
13
  // set up a task to drain the input iterable into the extractor asynchronously
15
14
  // before this function delegates to the extractor's iterable (containing the
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/util/extractDocumentsFromNdjsonOrTarball.ts"],"sourcesContent":["import path from 'node:path'\nimport readline from 'node:readline'\nimport {Readable, type Writable} from 'node:stream'\nimport zlib from 'node:zlib'\n\nimport {type SanityDocument} from '@sanity/types'\nimport tar from 'tar-stream'\n\nconst HEADER_SIZE = 300\n\n// https://github.com/kevva/is-gzip/blob/13dab7c877787bd5cff9de5482b1736f00df99c6/index.js\nconst isGzip = (buf: Buffer) =>\n buf.length >= 3 && buf[0] === 0x1f && buf[1] === 0x8b && buf[2] === 0x08\n\n// https://github.com/watson/is-deflate/blob/f9e8f0c7814eed715e13e29e97c69acee319686a/index.js\nconst isDeflate = (buf: Buffer) =>\n buf.length >= 2 && buf[0] === 0x78 && (buf[1] === 1 || buf[1] === 0x9c || buf[1] === 0xda)\n\n// https://github.com/kevva/is-tar/blob/d295ffa2002a5d415946fc3d49f024ace8c28bd3/index.js\nconst isTar = (buf: Buffer) =>\n buf.length >= 262 &&\n buf[257] === 0x75 &&\n buf[258] === 0x73 &&\n buf[259] === 0x74 &&\n buf[260] === 0x61 &&\n buf[261] === 0x72\n\nasync function* extract<TReturn>(\n stream: AsyncIterable<Buffer>,\n extractor: AsyncIterable<TReturn> & Writable,\n) {\n // set up a task to drain the input iterable into the extractor asynchronously\n // before this function delegates to the extractor's iterable (containing the\n // result of the extraction)\n const drained = new Promise<void>((resolve, reject) => {\n // setTimeout is used here to ensure draining occurs after delegation\n setTimeout(async () => {\n try {\n for await (const chunk of stream) extractor.write(chunk)\n extractor.end()\n resolve()\n } catch (err) {\n reject(err)\n }\n })\n })\n\n // have this function delegate the results of the extractor\n yield* extractor\n await drained\n extractor.destroy()\n}\n\n/**\n * Given a async iterable of buffers, looks at the header of the file in the\n * first few bytes to see the file type then extracts the contents tries again.\n * If the given iterable of buffers is a tarball then it looks for an ndjson\n * files and returns another iterable of buffers with the contents of the\n * ndjson file\n */\nasync function* maybeExtractNdjson(stream: AsyncIterable<Buffer>): AsyncIterable<Buffer> {\n let buffer = Buffer.alloc(0)\n\n for await (const chunk of stream) {\n buffer = Buffer.concat([buffer, chunk])\n if (buffer.length < HEADER_SIZE) continue\n\n const fileHeader = buffer\n const restOfStream = async function* restOfStream() {\n yield fileHeader\n yield* stream\n }\n\n if (isGzip(fileHeader)) {\n yield* maybeExtractNdjson(extract(restOfStream(), zlib.createGunzip()))\n return\n }\n\n if (isDeflate(fileHeader)) {\n yield* maybeExtractNdjson(extract(restOfStream(), zlib.createDeflate()))\n return\n }\n\n if (isTar(fileHeader)) {\n for await (const entry of extract(restOfStream(), tar.extract())) {\n const filename = path.basename(entry.header.name)\n const extname = path.extname(filename).toLowerCase()\n // ignore hidden and non-ndjson files\n if (extname !== '.ndjson' || filename.startsWith('.')) continue\n\n for await (const ndjsonChunk of entry) yield ndjsonChunk\n return\n }\n }\n\n yield* restOfStream()\n }\n}\n\n/**\n * Takes in an async iterable of buffers from an ndjson file or tarball and\n * returns an async iterable of sanity documents.\n */\nexport async function* extractDocumentsFromNdjsonOrTarball(\n file: AsyncIterable<Buffer>,\n): AsyncIterable<SanityDocument> {\n const lines = readline.createInterface({\n input: Readable.from(maybeExtractNdjson(file)),\n })\n\n for await (const line of lines) {\n const trimmed = line.trim()\n if (trimmed) yield JSON.parse(trimmed) as SanityDocument\n }\n lines.close()\n}\n"],"names":["path","readline","Readable","zlib","tar","HEADER_SIZE","isGzip","buf","length","isDeflate","isTar","extract","stream","extractor","drained","Promise","resolve","reject","setTimeout","chunk","write","end","err","destroy","maybeExtractNdjson","buffer","Buffer","alloc","concat","fileHeader","restOfStream","createGunzip","createDeflate","entry","filename","basename","header","name","extname","toLowerCase","startsWith","ndjsonChunk","extractDocumentsFromNdjsonOrTarball","file","lines","createInterface","input","from","line","trimmed","trim","JSON","parse","close"],"mappings":"AAAA,OAAOA,UAAU,YAAW;AAC5B,OAAOC,cAAc,gBAAe;AACpC,SAAQC,QAAQ,QAAsB,cAAa;AACnD,OAAOC,UAAU,YAAW;AAG5B,OAAOC,SAAS,aAAY;AAE5B,MAAMC,cAAc;AAEpB,0FAA0F;AAC1F,MAAMC,SAAS,CAACC,MACdA,IAAIC,MAAM,IAAI,KAAKD,GAAG,CAAC,EAAE,KAAK,QAAQA,GAAG,CAAC,EAAE,KAAK,QAAQA,GAAG,CAAC,EAAE,KAAK;AAEtE,8FAA8F;AAC9F,MAAME,YAAY,CAACF,MACjBA,IAAIC,MAAM,IAAI,KAAKD,GAAG,CAAC,EAAE,KAAK,QAASA,CAAAA,GAAG,CAAC,EAAE,KAAK,KAAKA,GAAG,CAAC,EAAE,KAAK,QAAQA,GAAG,CAAC,EAAE,KAAK,IAAG;AAE1F,yFAAyF;AACzF,MAAMG,QAAQ,CAACH,MACbA,IAAIC,MAAM,IAAI,OACdD,GAAG,CAAC,IAAI,KAAK,QACbA,GAAG,CAAC,IAAI,KAAK,QACbA,GAAG,CAAC,IAAI,KAAK,QACbA,GAAG,CAAC,IAAI,KAAK,QACbA,GAAG,CAAC,IAAI,KAAK;AAEf,gBAAgBI,QACdC,MAA6B,EAC7BC,SAA4C;IAE5C,8EAA8E;IAC9E,6EAA6E;IAC7E,4BAA4B;IAC5B,MAAMC,UAAU,IAAIC,QAAc,CAACC,SAASC;QAC1C,qEAAqE;QACrEC,WAAW;YACT,IAAI;gBACF,WAAW,MAAMC,SAASP,OAAQC,UAAUO,KAAK,CAACD;gBAClDN,UAAUQ,GAAG;gBACbL;YACF,EAAE,OAAOM,KAAK;gBACZL,OAAOK;YACT;QACF;IACF;IAEA,2DAA2D;IAC3D,OAAOT;IACP,MAAMC;IACND,UAAUU,OAAO;AACnB;AAEA;;;;;;CAMC,GACD,gBAAgBC,mBAAmBZ,MAA6B;IAC9D,IAAIa,SAASC,OAAOC,KAAK,CAAC;IAE1B,WAAW,MAAMR,SAASP,OAAQ;QAChCa,SAASC,OAAOE,MAAM,CAAC;YAACH;YAAQN;SAAM;QACtC,IAAIM,OAAOjB,MAAM,GAAGH,aAAa;QAEjC,MAAMwB,aAAaJ;QACnB,MAAMK,eAAe,gBAAgBA;YACnC,MAAMD;YACN,OAAOjB;QACT;QAEA,IAAIN,OAAOuB,aAAa;YACtB,OAAOL,mBAAmBb,QAAQmB,gBAAgB3B,KAAK4B,YAAY;YACnE;QACF;QAEA,IAAItB,UAAUoB,aAAa;YACzB,OAAOL,mBAAmBb,QAAQmB,gBAAgB3B,KAAK6B,aAAa;YACpE;QACF;QAEA,IAAItB,MAAMmB,aAAa;YACrB,WAAW,MAAMI,SAAStB,QAAQmB,gBAAgB1B,IAAIO,OAAO,IAAK;gBAChE,MAAMuB,WAAWlC,KAAKmC,QAAQ,CAACF,MAAMG,MAAM,CAACC,IAAI;gBAChD,MAAMC,UAAUtC,KAAKsC,OAAO,CAACJ,UAAUK,WAAW;gBAClD,qCAAqC;gBACrC,IAAID,YAAY,aAAaJ,SAASM,UAAU,CAAC,MAAM;gBAEvD,WAAW,MAAMC,eAAeR,MAAO,MAAMQ;gBAC7C;YACF;QACF;QAEA,OAAOX;IACT;AACF;AAEA;;;CAGC,GACD,OAAO,gBAAgBY,oCACrBC,IAA2B;IAE3B,MAAMC,QAAQ3C,SAAS4C,eAAe,CAAC;QACrCC,OAAO5C,SAAS6C,IAAI,CAACvB,mBAAmBmB;IAC1C;IAEA,WAAW,MAAMK,QAAQJ,MAAO;QAC9B,MAAMK,UAAUD,KAAKE,IAAI;QACzB,IAAID,SAAS,MAAME,KAAKC,KAAK,CAACH;IAChC;IACAL,MAAMS,KAAK;AACb"}
1
+ {"version":3,"sources":["../../src/util/extractDocumentsFromNdjsonOrTarball.ts"],"sourcesContent":["import path from 'node:path'\nimport readline from 'node:readline'\nimport {Readable, type Writable} from 'node:stream'\nimport zlib from 'node:zlib'\n\nimport {type SanityDocument} from '@sanity/types'\nimport tar from 'tar-stream'\n\nimport {isTar} from './isTar.js'\n\nconst HEADER_SIZE = 300\n\n// https://github.com/kevva/is-gzip/blob/13dab7c877787bd5cff9de5482b1736f00df99c6/index.js\nconst isGzip = (buf: Buffer) =>\n buf.length >= 3 && buf[0] === 0x1f && buf[1] === 0x8b && buf[2] === 0x08\n\n// https://github.com/watson/is-deflate/blob/f9e8f0c7814eed715e13e29e97c69acee319686a/index.js\nconst isDeflate = (buf: Buffer) =>\n buf.length >= 2 && buf[0] === 0x78 && (buf[1] === 1 || buf[1] === 0x9c || buf[1] === 0xda)\n\nasync function* extract<TReturn>(\n stream: AsyncIterable<Buffer>,\n extractor: AsyncIterable<TReturn> & Writable,\n) {\n // set up a task to drain the input iterable into the extractor asynchronously\n // before this function delegates to the extractor's iterable (containing the\n // result of the extraction)\n const drained = new Promise<void>((resolve, reject) => {\n // setTimeout is used here to ensure draining occurs after delegation\n setTimeout(async () => {\n try {\n for await (const chunk of stream) extractor.write(chunk)\n extractor.end()\n resolve()\n } catch (err) {\n reject(err)\n }\n })\n })\n\n // have this function delegate the results of the extractor\n yield* extractor\n await drained\n extractor.destroy()\n}\n\n/**\n * Given a async iterable of buffers, looks at the header of the file in the\n * first few bytes to see the file type then extracts the contents tries again.\n * If the given iterable of buffers is a tarball then it looks for an ndjson\n * files and returns another iterable of buffers with the contents of the\n * ndjson file\n */\nasync function* maybeExtractNdjson(stream: AsyncIterable<Buffer>): AsyncIterable<Buffer> {\n let buffer = Buffer.alloc(0)\n\n for await (const chunk of stream) {\n buffer = Buffer.concat([buffer, chunk])\n if (buffer.length < HEADER_SIZE) continue\n\n const fileHeader = buffer\n const restOfStream = async function* restOfStream() {\n yield fileHeader\n yield* stream\n }\n\n if (isGzip(fileHeader)) {\n yield* maybeExtractNdjson(extract(restOfStream(), zlib.createGunzip()))\n return\n }\n\n if (isDeflate(fileHeader)) {\n yield* maybeExtractNdjson(extract(restOfStream(), zlib.createDeflate()))\n return\n }\n\n if (isTar(fileHeader)) {\n for await (const entry of extract(restOfStream(), tar.extract())) {\n const filename = path.basename(entry.header.name)\n const extname = path.extname(filename).toLowerCase()\n // ignore hidden and non-ndjson files\n if (extname !== '.ndjson' || filename.startsWith('.')) continue\n\n for await (const ndjsonChunk of entry) yield ndjsonChunk\n return\n }\n }\n\n yield* restOfStream()\n }\n}\n\n/**\n * Takes in an async iterable of buffers from an ndjson file or tarball and\n * returns an async iterable of sanity documents.\n */\nexport async function* extractDocumentsFromNdjsonOrTarball(\n file: AsyncIterable<Buffer>,\n): AsyncIterable<SanityDocument> {\n const lines = readline.createInterface({\n input: Readable.from(maybeExtractNdjson(file)),\n })\n\n for await (const line of lines) {\n const trimmed = line.trim()\n if (trimmed) yield JSON.parse(trimmed) as SanityDocument\n }\n lines.close()\n}\n"],"names":["path","readline","Readable","zlib","tar","isTar","HEADER_SIZE","isGzip","buf","length","isDeflate","extract","stream","extractor","drained","Promise","resolve","reject","setTimeout","chunk","write","end","err","destroy","maybeExtractNdjson","buffer","Buffer","alloc","concat","fileHeader","restOfStream","createGunzip","createDeflate","entry","filename","basename","header","name","extname","toLowerCase","startsWith","ndjsonChunk","extractDocumentsFromNdjsonOrTarball","file","lines","createInterface","input","from","line","trimmed","trim","JSON","parse","close"],"mappings":"AAAA,OAAOA,UAAU,YAAW;AAC5B,OAAOC,cAAc,gBAAe;AACpC,SAAQC,QAAQ,QAAsB,cAAa;AACnD,OAAOC,UAAU,YAAW;AAG5B,OAAOC,SAAS,aAAY;AAE5B,SAAQC,KAAK,QAAO,aAAY;AAEhC,MAAMC,cAAc;AAEpB,0FAA0F;AAC1F,MAAMC,SAAS,CAACC,MACdA,IAAIC,MAAM,IAAI,KAAKD,GAAG,CAAC,EAAE,KAAK,QAAQA,GAAG,CAAC,EAAE,KAAK,QAAQA,GAAG,CAAC,EAAE,KAAK;AAEtE,8FAA8F;AAC9F,MAAME,YAAY,CAACF,MACjBA,IAAIC,MAAM,IAAI,KAAKD,GAAG,CAAC,EAAE,KAAK,QAASA,CAAAA,GAAG,CAAC,EAAE,KAAK,KAAKA,GAAG,CAAC,EAAE,KAAK,QAAQA,GAAG,CAAC,EAAE,KAAK,IAAG;AAE1F,gBAAgBG,QACdC,MAA6B,EAC7BC,SAA4C;IAE5C,8EAA8E;IAC9E,6EAA6E;IAC7E,4BAA4B;IAC5B,MAAMC,UAAU,IAAIC,QAAc,CAACC,SAASC;QAC1C,qEAAqE;QACrEC,WAAW;YACT,IAAI;gBACF,WAAW,MAAMC,SAASP,OAAQC,UAAUO,KAAK,CAACD;gBAClDN,UAAUQ,GAAG;gBACbL;YACF,EAAE,OAAOM,KAAK;gBACZL,OAAOK;YACT;QACF;IACF;IAEA,2DAA2D;IAC3D,OAAOT;IACP,MAAMC;IACND,UAAUU,OAAO;AACnB;AAEA;;;;;;CAMC,GACD,gBAAgBC,mBAAmBZ,MAA6B;IAC9D,IAAIa,SAASC,OAAOC,KAAK,CAAC;IAE1B,WAAW,MAAMR,SAASP,OAAQ;QAChCa,SAASC,OAAOE,MAAM,CAAC;YAACH;YAAQN;SAAM;QACtC,IAAIM,OAAOhB,MAAM,GAAGH,aAAa;QAEjC,MAAMuB,aAAaJ;QACnB,MAAMK,eAAe,gBAAgBA;YACnC,MAAMD;YACN,OAAOjB;QACT;QAEA,IAAIL,OAAOsB,aAAa;YACtB,OAAOL,mBAAmBb,QAAQmB,gBAAgB3B,KAAK4B,YAAY;YACnE;QACF;QAEA,IAAIrB,UAAUmB,aAAa;YACzB,OAAOL,mBAAmBb,QAAQmB,gBAAgB3B,KAAK6B,aAAa;YACpE;QACF;QAEA,IAAI3B,MAAMwB,aAAa;YACrB,WAAW,MAAMI,SAAStB,QAAQmB,gBAAgB1B,IAAIO,OAAO,IAAK;gBAChE,MAAMuB,WAAWlC,KAAKmC,QAAQ,CAACF,MAAMG,MAAM,CAACC,IAAI;gBAChD,MAAMC,UAAUtC,KAAKsC,OAAO,CAACJ,UAAUK,WAAW;gBAClD,qCAAqC;gBACrC,IAAID,YAAY,aAAaJ,SAASM,UAAU,CAAC,MAAM;gBAEvD,WAAW,MAAMC,eAAeR,MAAO,MAAMQ;gBAC7C;YACF;QACF;QAEA,OAAOX;IACT;AACF;AAEA;;;CAGC,GACD,OAAO,gBAAgBY,oCACrBC,IAA2B;IAE3B,MAAMC,QAAQ3C,SAAS4C,eAAe,CAAC;QACrCC,OAAO5C,SAAS6C,IAAI,CAACvB,mBAAmBmB;IAC1C;IAEA,WAAW,MAAMK,QAAQJ,MAAO;QAC9B,MAAMK,UAAUD,KAAKE,IAAI;QACzB,IAAID,SAAS,MAAME,KAAKC,KAAK,CAACH;IAChC;IACAL,MAAMS,KAAK;AACb"}
@@ -1,7 +1,7 @@
1
1
  import path from 'node:path';
2
2
  import { fileURLToPath } from 'node:url';
3
+ import { readPackageJson } from '@sanity/cli-core';
3
4
  import { packageDirectory } from 'package-directory';
4
- import { readPackageJson } from './readPackageJson.js';
5
5
  /**
6
6
  * Get the version of the `@sanity/cli` package.
7
7
  *