@sanity/cli 6.0.0-alpha.9 → 6.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (600) hide show
  1. package/README.md +602 -258
  2. package/bin/run.js +2 -0
  3. package/dist/SanityHelp.js +51 -23
  4. package/dist/SanityHelp.js.map +1 -1
  5. package/dist/actions/auth/authServer.js +28 -22
  6. package/dist/actions/auth/authServer.js.map +1 -1
  7. package/dist/actions/auth/login/getProvider.js +49 -38
  8. package/dist/actions/auth/login/getProvider.js.map +1 -1
  9. package/dist/actions/auth/login/getSSOProvider.js +25 -19
  10. package/dist/actions/auth/login/getSSOProvider.js.map +1 -1
  11. package/dist/actions/auth/login/login.js +12 -33
  12. package/dist/actions/auth/login/login.js.map +1 -1
  13. package/dist/actions/auth/types.js.map +1 -1
  14. package/dist/actions/backup/downloadAsset.js +9 -9
  15. package/dist/actions/backup/downloadAsset.js.map +1 -1
  16. package/dist/actions/backup/downloadDocument.js +8 -8
  17. package/dist/actions/backup/downloadDocument.js.map +1 -1
  18. package/dist/actions/build/buildApp.js +55 -18
  19. package/dist/actions/build/buildApp.js.map +1 -1
  20. package/dist/actions/build/buildStaticFiles.js +3 -2
  21. package/dist/actions/build/buildStaticFiles.js.map +1 -1
  22. package/dist/actions/build/buildStudio.js +72 -44
  23. package/dist/actions/build/buildStudio.js.map +1 -1
  24. package/dist/actions/build/buildVendorDependencies.js +18 -52
  25. package/dist/actions/build/buildVendorDependencies.js.map +1 -1
  26. package/dist/actions/build/checkRequiredDependencies.js +13 -8
  27. package/dist/actions/build/checkRequiredDependencies.js.map +1 -1
  28. package/dist/actions/build/checkStudioDependencyVersions.js +19 -17
  29. package/dist/actions/build/checkStudioDependencyVersions.js.map +1 -1
  30. package/dist/actions/build/createExternalFromImportMap.js +1 -1
  31. package/dist/actions/build/createExternalFromImportMap.js.map +1 -1
  32. package/dist/actions/build/determineBasePath.js +5 -2
  33. package/dist/actions/build/determineBasePath.js.map +1 -1
  34. package/dist/actions/build/getViteConfig.js +47 -4
  35. package/dist/actions/build/getViteConfig.js.map +1 -1
  36. package/dist/actions/build/handlePrereleaseVersions.js +44 -0
  37. package/dist/actions/build/handlePrereleaseVersions.js.map +1 -0
  38. package/dist/actions/build/renderDocument.js +6 -10
  39. package/dist/actions/build/renderDocument.js.map +1 -1
  40. package/dist/actions/build/renderDocumentWorker/components/BasicDocument.js +4 -4
  41. package/dist/actions/build/renderDocumentWorker/components/BasicDocument.js.map +1 -1
  42. package/dist/actions/build/renderDocumentWorker/components/DefaultDocument.js +3 -3
  43. package/dist/actions/build/renderDocumentWorker/components/DefaultDocument.js.map +1 -1
  44. package/dist/actions/build/renderDocumentWorker/components/GlobalErrorHandler.js +1 -0
  45. package/dist/actions/build/renderDocumentWorker/components/GlobalErrorHandler.js.map +1 -1
  46. package/dist/actions/build/renderDocumentWorker/getDocumentComponent.js +2 -2
  47. package/dist/actions/build/renderDocumentWorker/getDocumentComponent.js.map +1 -1
  48. package/dist/actions/build/renderDocumentWorker/renderDocumentWorker.js +1 -1
  49. package/dist/actions/build/renderDocumentWorker/renderDocumentWorker.js.map +1 -1
  50. package/dist/actions/build/shouldAutoUpdate.js +2 -0
  51. package/dist/actions/build/shouldAutoUpdate.js.map +1 -1
  52. package/dist/actions/build/types.js.map +1 -1
  53. package/dist/actions/build/writeFavicons.js +3 -5
  54. package/dist/actions/build/writeFavicons.js.map +1 -1
  55. package/dist/actions/build/writeSanityRuntime.js +4 -3
  56. package/dist/actions/build/writeSanityRuntime.js.map +1 -1
  57. package/dist/actions/codemods/reactIconsV3.js +2 -2
  58. package/dist/actions/codemods/reactIconsV3.js.map +1 -1
  59. package/dist/actions/dataset/create.js +7 -1
  60. package/dist/actions/dataset/create.js.map +1 -1
  61. package/dist/actions/dataset/determineDatasetAclMode.js.map +1 -1
  62. package/dist/actions/dataset/resolveDataset.js +26 -0
  63. package/dist/actions/dataset/resolveDataset.js.map +1 -0
  64. package/dist/actions/debug/formatters.js +22 -0
  65. package/dist/actions/debug/formatters.js.map +1 -0
  66. package/dist/actions/deploy/createStudioUserApplication.js +17 -4
  67. package/dist/actions/deploy/createStudioUserApplication.js.map +1 -1
  68. package/dist/actions/deploy/deployApp.js +41 -15
  69. package/dist/actions/deploy/deployApp.js.map +1 -1
  70. package/dist/actions/deploy/deployStudio.js +92 -44
  71. package/dist/actions/deploy/deployStudio.js.map +1 -1
  72. package/dist/actions/deploy/deployStudioSchemasAndManifests.js +55 -0
  73. package/dist/actions/deploy/deployStudioSchemasAndManifests.js.map +1 -0
  74. package/dist/actions/deploy/deployStudioSchemasAndManifests.worker.js +120 -0
  75. package/dist/actions/deploy/deployStudioSchemasAndManifests.worker.js.map +1 -0
  76. package/dist/actions/deploy/findUserApplicationForStudio.js +35 -12
  77. package/dist/actions/deploy/findUserApplicationForStudio.js.map +1 -1
  78. package/dist/actions/deploy/types.js +10 -1
  79. package/dist/actions/deploy/types.js.map +1 -1
  80. package/dist/actions/deploy/urlUtils.js +21 -0
  81. package/dist/actions/deploy/urlUtils.js.map +1 -0
  82. package/dist/actions/dev/getDashboardAppUrl.js +48 -0
  83. package/dist/actions/dev/getDashboardAppUrl.js.map +1 -0
  84. package/dist/actions/dev/getDevServerConfig.js +7 -3
  85. package/dist/actions/dev/getDevServerConfig.js.map +1 -1
  86. package/dist/actions/dev/startAppDevServer.js +3 -3
  87. package/dist/actions/dev/startAppDevServer.js.map +1 -1
  88. package/dist/actions/dev/startStudioDevServer.js +14 -14
  89. package/dist/actions/dev/startStudioDevServer.js.map +1 -1
  90. package/dist/actions/doctor/checks/cliInstallation.js +56 -0
  91. package/dist/actions/doctor/checks/cliInstallation.js.map +1 -0
  92. package/dist/actions/doctor/checks/index.js +16 -0
  93. package/dist/actions/doctor/checks/index.js.map +1 -0
  94. package/dist/actions/doctor/runDoctorChecks.js +56 -0
  95. package/dist/actions/doctor/runDoctorChecks.js.map +1 -0
  96. package/dist/actions/doctor/types.js +3 -0
  97. package/dist/actions/doctor/types.js.map +1 -0
  98. package/dist/actions/documents/types.js.map +1 -1
  99. package/dist/actions/documents/validate.js +11 -2
  100. package/dist/actions/documents/validate.js.map +1 -1
  101. package/dist/actions/documents/validateDocuments.worker.js +4 -4
  102. package/dist/actions/documents/validateDocuments.worker.js.map +1 -1
  103. package/dist/actions/documents/validation/reporters/jsonReporter.js +1 -1
  104. package/dist/actions/documents/validation/reporters/jsonReporter.js.map +1 -1
  105. package/dist/actions/documents/validation/reporters/ndjsonReporter.js +1 -1
  106. package/dist/actions/documents/validation/reporters/ndjsonReporter.js.map +1 -1
  107. package/dist/actions/documents/validation/reporters/prettyReporter/formatDocumentValidation.js +1 -1
  108. package/dist/actions/documents/validation/reporters/prettyReporter/formatDocumentValidation.js.map +1 -1
  109. package/dist/actions/documents/validation/reporters/prettyReporter/tree.js +108 -0
  110. package/dist/actions/documents/validation/reporters/prettyReporter/tree.js.map +1 -0
  111. package/dist/actions/graphql/SchemaError.js +4 -26
  112. package/dist/actions/graphql/SchemaError.js.map +1 -1
  113. package/dist/actions/graphql/__tests__/fixtures/many-self-refs.js +540 -0
  114. package/dist/actions/graphql/__tests__/fixtures/many-self-refs.js.map +1 -0
  115. package/dist/actions/graphql/__tests__/fixtures/test-studio.js +1143 -0
  116. package/dist/actions/graphql/__tests__/fixtures/test-studio.js.map +1 -0
  117. package/dist/actions/graphql/__tests__/fixtures/union-refs.js +591 -0
  118. package/dist/actions/graphql/__tests__/fixtures/union-refs.js.map +1 -0
  119. package/dist/actions/graphql/__tests__/helpers.js +23 -0
  120. package/dist/actions/graphql/__tests__/helpers.js.map +1 -0
  121. package/dist/actions/graphql/extractFromSanitySchema.js +5 -5
  122. package/dist/actions/graphql/extractFromSanitySchema.js.map +1 -1
  123. package/dist/actions/graphql/extractGraphQLAPIs.js +150 -0
  124. package/dist/actions/graphql/extractGraphQLAPIs.js.map +1 -0
  125. package/dist/actions/graphql/extractGraphQLAPIs.worker.js +12 -0
  126. package/dist/actions/graphql/extractGraphQLAPIs.worker.js.map +1 -0
  127. package/dist/actions/graphql/gen1/generateTypeFilters.js +1 -1
  128. package/dist/actions/graphql/gen1/generateTypeFilters.js.map +1 -1
  129. package/dist/actions/graphql/gen1/generateTypeQueries.js +2 -1
  130. package/dist/actions/graphql/gen1/generateTypeQueries.js.map +1 -1
  131. package/dist/actions/graphql/gen1/index.js +5 -5
  132. package/dist/actions/graphql/gen1/index.js.map +1 -1
  133. package/dist/actions/graphql/gen2/generateTypeQueries.js +1 -1
  134. package/dist/actions/graphql/gen2/generateTypeQueries.js.map +1 -1
  135. package/dist/actions/graphql/gen2/index.js +6 -6
  136. package/dist/actions/graphql/gen2/index.js.map +1 -1
  137. package/dist/actions/graphql/gen3/generateTypeQueries.js +3 -4
  138. package/dist/actions/graphql/gen3/generateTypeQueries.js.map +1 -1
  139. package/dist/actions/graphql/gen3/index.js +6 -7
  140. package/dist/actions/graphql/gen3/index.js.map +1 -1
  141. package/dist/actions/graphql/getGraphQLAPIs.js +15 -57
  142. package/dist/actions/graphql/getGraphQLAPIs.js.map +1 -1
  143. package/dist/actions/graphql/getGraphQLAPIs.worker.js +75 -106
  144. package/dist/actions/graphql/getGraphQLAPIs.worker.js.map +1 -1
  145. package/dist/actions/graphql/helpers.js +13 -0
  146. package/dist/actions/graphql/helpers.js.map +1 -1
  147. package/dist/actions/graphql/resolveGraphQLApisFromWorkspaces.js +187 -0
  148. package/dist/actions/graphql/resolveGraphQLApisFromWorkspaces.js.map +1 -0
  149. package/dist/actions/graphql/types.js +1 -1
  150. package/dist/actions/graphql/types.js.map +1 -1
  151. package/dist/actions/init/bootstrapLocalTemplate.js +10 -8
  152. package/dist/actions/init/bootstrapLocalTemplate.js.map +1 -1
  153. package/dist/actions/init/bootstrapRemoteTemplate.js +6 -5
  154. package/dist/actions/init/bootstrapRemoteTemplate.js.map +1 -1
  155. package/dist/actions/init/bootstrapTemplate.js.map +1 -1
  156. package/dist/actions/init/checkNextJsReactCompatibility.js +1 -1
  157. package/dist/actions/init/checkNextJsReactCompatibility.js.map +1 -1
  158. package/dist/actions/init/createAppCliConfig.js.map +1 -1
  159. package/dist/actions/init/createCliConfig.js.map +1 -1
  160. package/dist/actions/init/createPackageManifest.js +21 -9
  161. package/dist/actions/init/createPackageManifest.js.map +1 -1
  162. package/dist/actions/init/remoteTemplate.js +1 -2
  163. package/dist/actions/init/remoteTemplate.js.map +1 -1
  164. package/dist/actions/init/sdkAppDependencies.js +19 -0
  165. package/dist/actions/init/sdkAppDependencies.js.map +1 -0
  166. package/dist/actions/init/studioDependencies.js.map +1 -0
  167. package/dist/actions/init/templates/appQuickstart.js +1 -22
  168. package/dist/actions/init/templates/appQuickstart.js.map +1 -1
  169. package/dist/actions/init/templates/appSanityUi.js +3 -22
  170. package/dist/actions/init/templates/appSanityUi.js.map +1 -1
  171. package/dist/actions/init/types.js.map +1 -1
  172. package/dist/actions/manifest/SchemaIcon.js +6 -4
  173. package/dist/actions/manifest/SchemaIcon.js.map +1 -1
  174. package/dist/actions/manifest/blockTypeTransformer.js +67 -0
  175. package/dist/actions/manifest/blockTypeTransformer.js.map +1 -0
  176. package/dist/actions/manifest/debug.js +4 -0
  177. package/dist/actions/manifest/debug.js.map +1 -0
  178. package/dist/actions/manifest/extractAppManifest.js +39 -22
  179. package/dist/actions/manifest/extractAppManifest.js.map +1 -1
  180. package/dist/actions/manifest/extractManifest.js +27 -78
  181. package/dist/actions/manifest/extractManifest.js.map +1 -1
  182. package/dist/actions/manifest/extractManifest.worker.js +30 -0
  183. package/dist/actions/manifest/extractManifest.worker.js.map +1 -0
  184. package/dist/actions/manifest/extractWorkspaceManifest.js +31 -372
  185. package/dist/actions/manifest/extractWorkspaceManifest.js.map +1 -1
  186. package/dist/actions/manifest/iconResolver.js +30 -0
  187. package/dist/actions/manifest/iconResolver.js.map +1 -0
  188. package/dist/actions/manifest/referenceTransformer.js +51 -0
  189. package/dist/actions/manifest/referenceTransformer.js.map +1 -0
  190. package/dist/actions/manifest/schemaTypeHelpers.js +2 -2
  191. package/dist/actions/manifest/schemaTypeHelpers.js.map +1 -1
  192. package/dist/actions/manifest/schemaTypeTransformer.js +168 -0
  193. package/dist/actions/manifest/schemaTypeTransformer.js.map +1 -0
  194. package/dist/actions/manifest/transformerUtils.js +40 -0
  195. package/dist/actions/manifest/transformerUtils.js.map +1 -0
  196. package/dist/actions/manifest/types.js +5 -0
  197. package/dist/actions/manifest/types.js.map +1 -1
  198. package/dist/actions/manifest/validationTransformer.js +84 -0
  199. package/dist/actions/manifest/validationTransformer.js.map +1 -0
  200. package/dist/actions/manifest/writeManifestFile.js +30 -0
  201. package/dist/actions/manifest/writeManifestFile.js.map +1 -0
  202. package/dist/actions/manifest/writeWorkspaceFiles.js +30 -0
  203. package/dist/actions/manifest/writeWorkspaceFiles.js.map +1 -0
  204. package/dist/actions/mcp/detectAvailableEditors.js +16 -4
  205. package/dist/actions/mcp/detectAvailableEditors.js.map +1 -1
  206. package/dist/actions/mcp/editorConfigs.js +64 -6
  207. package/dist/actions/mcp/editorConfigs.js.map +1 -1
  208. package/dist/actions/mcp/setupMCP.js.map +1 -1
  209. package/dist/actions/mcp/writeMCPConfig.js +27 -15
  210. package/dist/actions/mcp/writeMCPConfig.js.map +1 -1
  211. package/dist/actions/media/buildNdjsonIndex.js +32 -0
  212. package/dist/actions/media/buildNdjsonIndex.js.map +1 -0
  213. package/dist/actions/media/importAspects.js +2 -11
  214. package/dist/actions/media/importAspects.js.map +1 -1
  215. package/dist/actions/media/importMedia.js +22 -18
  216. package/dist/actions/media/importMedia.js.map +1 -1
  217. package/dist/actions/organizations/findOrganizationByUserName.js +5 -0
  218. package/dist/actions/organizations/findOrganizationByUserName.js.map +1 -0
  219. package/dist/actions/organizations/getOrganization.js +3 -2
  220. package/dist/actions/organizations/getOrganization.js.map +1 -1
  221. package/dist/actions/organizations/getOrganizationChoices.js +27 -19
  222. package/dist/actions/organizations/getOrganizationChoices.js.map +1 -1
  223. package/dist/actions/organizations/types.js +3 -0
  224. package/dist/actions/organizations/types.js.map +1 -0
  225. package/dist/actions/projects/getManageUrl.js +1 -2
  226. package/dist/actions/projects/getManageUrl.js.map +1 -1
  227. package/dist/actions/schema/deleteSchemaAction.js +14 -30
  228. package/dist/actions/schema/deleteSchemaAction.js.map +1 -1
  229. package/dist/actions/schema/deploySchemas.js +22 -91
  230. package/dist/actions/schema/deploySchemas.js.map +1 -1
  231. package/dist/actions/schema/extractSanitySchema.worker.js +0 -5
  232. package/dist/actions/schema/extractSanitySchema.worker.js.map +1 -1
  233. package/dist/actions/schema/extractSanityWorkspace.worker.js +24 -0
  234. package/dist/actions/schema/extractSanityWorkspace.worker.js.map +1 -0
  235. package/dist/actions/schema/extractSchema.js +8 -40
  236. package/dist/actions/schema/extractSchema.js.map +1 -1
  237. package/dist/actions/schema/extractSchemaWatcher.js +128 -0
  238. package/dist/actions/schema/extractSchemaWatcher.js.map +1 -0
  239. package/dist/actions/schema/formatSchemaValidation.js +5 -1
  240. package/dist/actions/schema/formatSchemaValidation.js.map +1 -1
  241. package/dist/actions/schema/getExtractOptions.js +16 -0
  242. package/dist/actions/schema/getExtractOptions.js.map +1 -0
  243. package/dist/actions/schema/listSchemas.js +53 -56
  244. package/dist/actions/schema/listSchemas.js.map +1 -1
  245. package/dist/actions/schema/matchSchemaPattern.js +22 -0
  246. package/dist/actions/schema/matchSchemaPattern.js.map +1 -0
  247. package/dist/actions/schema/runSchemaExtraction.js +39 -0
  248. package/dist/actions/schema/runSchemaExtraction.js.map +1 -0
  249. package/dist/actions/schema/types.js +8 -0
  250. package/dist/actions/schema/types.js.map +1 -1
  251. package/dist/actions/schema/uniqueWorkspaces.worker.js +24 -0
  252. package/dist/actions/schema/uniqueWorkspaces.worker.js.map +1 -0
  253. package/dist/actions/schema/updateWorkspaceSchema.js +63 -0
  254. package/dist/actions/schema/updateWorkspaceSchema.js.map +1 -0
  255. package/dist/actions/schema/uploadSchemaToLexicon.js +87 -0
  256. package/dist/actions/schema/uploadSchemaToLexicon.js.map +1 -0
  257. package/dist/actions/schema/utils/SchemaExtractionError.js +10 -0
  258. package/dist/actions/schema/utils/SchemaExtractionError.js.map +1 -0
  259. package/dist/actions/schema/utils/schemaStoreValidation.js +1 -15
  260. package/dist/actions/schema/utils/schemaStoreValidation.js.map +1 -1
  261. package/dist/actions/schema/utils/uniqByProjectIdDataset.js +1 -1
  262. package/dist/actions/schema/utils/uniqByProjectIdDataset.js.map +1 -1
  263. package/dist/actions/schema/validateSchema.worker.js +1 -8
  264. package/dist/actions/schema/validateSchema.worker.js.map +1 -1
  265. package/dist/actions/schema/watchExtractSchema.js +72 -0
  266. package/dist/actions/schema/watchExtractSchema.js.map +1 -0
  267. package/dist/actions/telemetry/isTrueish.js +10 -0
  268. package/dist/actions/telemetry/isTrueish.js.map +1 -0
  269. package/dist/actions/telemetry/resolveConsent.js +2 -1
  270. package/dist/actions/telemetry/resolveConsent.js.map +1 -1
  271. package/dist/actions/telemetry/setConsent.js +2 -1
  272. package/dist/actions/telemetry/setConsent.js.map +1 -1
  273. package/dist/actions/users/getMembersForProject.js.map +1 -1
  274. package/dist/actions/users/getPendingInvitations.js +1 -1
  275. package/dist/actions/users/getPendingInvitations.js.map +1 -1
  276. package/dist/actions/users/types.js.map +1 -1
  277. package/dist/actions/versions/filterSanityModules.js.map +1 -1
  278. package/dist/actions/versions/findSanityModulesVersions.js +2 -3
  279. package/dist/actions/versions/findSanityModulesVersions.js.map +1 -1
  280. package/dist/actions/versions/getFormatters.js +1 -1
  281. package/dist/actions/versions/getFormatters.js.map +1 -1
  282. package/dist/actions/versions/tryFindLatestVersion.js +1 -1
  283. package/dist/actions/versions/tryFindLatestVersion.js.map +1 -1
  284. package/dist/commands/backup/disable.js +22 -7
  285. package/dist/commands/backup/disable.js.map +1 -1
  286. package/dist/commands/backup/download.js +19 -10
  287. package/dist/commands/backup/download.js.map +1 -1
  288. package/dist/commands/backup/enable.js +22 -7
  289. package/dist/commands/backup/enable.js.map +1 -1
  290. package/dist/commands/backup/list.js +20 -8
  291. package/dist/commands/backup/list.js.map +1 -1
  292. package/dist/commands/build.js +2 -5
  293. package/dist/commands/build.js.map +1 -1
  294. package/dist/commands/cors/add.js +20 -7
  295. package/dist/commands/cors/add.js.map +1 -1
  296. package/dist/commands/cors/delete.js +22 -7
  297. package/dist/commands/cors/delete.js.map +1 -1
  298. package/dist/commands/cors/list.js +22 -7
  299. package/dist/commands/cors/list.js.map +1 -1
  300. package/dist/commands/dataset/alias/create.js +26 -7
  301. package/dist/commands/dataset/alias/create.js.map +1 -1
  302. package/dist/commands/dataset/alias/delete.js +20 -7
  303. package/dist/commands/dataset/alias/delete.js.map +1 -1
  304. package/dist/commands/dataset/alias/link.js +20 -7
  305. package/dist/commands/dataset/alias/link.js.map +1 -1
  306. package/dist/commands/dataset/alias/unlink.js +20 -7
  307. package/dist/commands/dataset/alias/unlink.js.map +1 -1
  308. package/dist/commands/dataset/copy.js +45 -30
  309. package/dist/commands/dataset/copy.js.map +1 -1
  310. package/dist/commands/dataset/create.js +32 -7
  311. package/dist/commands/dataset/create.js.map +1 -1
  312. package/dist/commands/dataset/delete.js +16 -7
  313. package/dist/commands/dataset/delete.js.map +1 -1
  314. package/dist/commands/dataset/embeddings/disable.js +77 -0
  315. package/dist/commands/dataset/embeddings/disable.js.map +1 -0
  316. package/dist/commands/dataset/embeddings/enable.js +141 -0
  317. package/dist/commands/dataset/embeddings/enable.js.map +1 -0
  318. package/dist/commands/dataset/embeddings/status.js +72 -0
  319. package/dist/commands/dataset/embeddings/status.js.map +1 -0
  320. package/dist/commands/dataset/export.js +25 -16
  321. package/dist/commands/dataset/export.js.map +1 -1
  322. package/dist/commands/dataset/import.js +306 -1
  323. package/dist/commands/dataset/import.js.map +1 -1
  324. package/dist/commands/dataset/list.js +22 -7
  325. package/dist/commands/dataset/list.js.map +1 -1
  326. package/dist/commands/dataset/visibility/get.js +18 -7
  327. package/dist/commands/dataset/visibility/get.js.map +1 -1
  328. package/dist/commands/dataset/visibility/set.js +22 -7
  329. package/dist/commands/dataset/visibility/set.js.map +1 -1
  330. package/dist/commands/debug.js +4 -2
  331. package/dist/commands/debug.js.map +1 -1
  332. package/dist/commands/deploy.js +22 -11
  333. package/dist/commands/deploy.js.map +1 -1
  334. package/dist/commands/dev.js +2 -4
  335. package/dist/commands/dev.js.map +1 -1
  336. package/dist/commands/doctor.js +125 -0
  337. package/dist/commands/doctor.js.map +1 -0
  338. package/dist/commands/documents/create.js +19 -12
  339. package/dist/commands/documents/create.js.map +1 -1
  340. package/dist/commands/documents/delete.js +19 -12
  341. package/dist/commands/documents/delete.js.map +1 -1
  342. package/dist/commands/documents/get.js +17 -12
  343. package/dist/commands/documents/get.js.map +1 -1
  344. package/dist/commands/documents/query.js +26 -18
  345. package/dist/commands/documents/query.js.map +1 -1
  346. package/dist/commands/documents/validate.js +32 -10
  347. package/dist/commands/documents/validate.js.map +1 -1
  348. package/dist/commands/graphql/deploy.js +58 -30
  349. package/dist/commands/graphql/deploy.js.map +1 -1
  350. package/dist/commands/graphql/list.js +15 -7
  351. package/dist/commands/graphql/list.js.map +1 -1
  352. package/dist/commands/graphql/undeploy.js +37 -19
  353. package/dist/commands/graphql/undeploy.js.map +1 -1
  354. package/dist/commands/hook/attempt.js +22 -7
  355. package/dist/commands/hook/attempt.js.map +1 -1
  356. package/dist/commands/hook/create.js +23 -8
  357. package/dist/commands/hook/create.js.map +1 -1
  358. package/dist/commands/hook/delete.js +22 -7
  359. package/dist/commands/hook/delete.js.map +1 -1
  360. package/dist/commands/hook/list.js +22 -7
  361. package/dist/commands/hook/list.js.map +1 -1
  362. package/dist/commands/hook/logs.js +21 -8
  363. package/dist/commands/hook/logs.js.map +1 -1
  364. package/dist/commands/init.js +46 -28
  365. package/dist/commands/init.js.map +1 -1
  366. package/dist/commands/login.js +19 -6
  367. package/dist/commands/login.js.map +1 -1
  368. package/dist/commands/logout.js +8 -6
  369. package/dist/commands/logout.js.map +1 -1
  370. package/dist/commands/manage.js +0 -1
  371. package/dist/commands/manage.js.map +1 -1
  372. package/dist/commands/manifest/extract.js +14 -10
  373. package/dist/commands/manifest/extract.js.map +1 -1
  374. package/dist/commands/mcp/configure.js +1 -1
  375. package/dist/commands/mcp/configure.js.map +1 -1
  376. package/dist/commands/media/create-aspect.js +4 -4
  377. package/dist/commands/media/create-aspect.js.map +1 -1
  378. package/dist/commands/media/delete-aspect.js +9 -7
  379. package/dist/commands/media/delete-aspect.js.map +1 -1
  380. package/dist/commands/media/deploy-aspect.js +22 -9
  381. package/dist/commands/media/deploy-aspect.js.map +1 -1
  382. package/dist/commands/media/export.js +9 -7
  383. package/dist/commands/media/export.js.map +1 -1
  384. package/dist/commands/media/import.js +10 -8
  385. package/dist/commands/media/import.js.map +1 -1
  386. package/dist/commands/preview.js +2 -4
  387. package/dist/commands/preview.js.map +1 -1
  388. package/dist/commands/projects/list.js +2 -1
  389. package/dist/commands/projects/list.js.map +1 -1
  390. package/dist/commands/schema/delete.js +33 -34
  391. package/dist/commands/schema/delete.js.map +1 -1
  392. package/dist/commands/schema/deploy.js +19 -30
  393. package/dist/commands/schema/deploy.js.map +1 -1
  394. package/dist/commands/schema/extract.js +32 -4
  395. package/dist/commands/schema/extract.js.map +1 -1
  396. package/dist/commands/schema/list.js +10 -31
  397. package/dist/commands/schema/list.js.map +1 -1
  398. package/dist/commands/tokens/add.js +24 -7
  399. package/dist/commands/tokens/add.js.map +1 -1
  400. package/dist/commands/tokens/delete.js +20 -7
  401. package/dist/commands/tokens/delete.js.map +1 -1
  402. package/dist/commands/tokens/list.js +20 -7
  403. package/dist/commands/tokens/list.js.map +1 -1
  404. package/dist/commands/users/invite.js +24 -7
  405. package/dist/commands/users/invite.js.map +1 -1
  406. package/dist/commands/users/list.js +76 -33
  407. package/dist/commands/users/list.js.map +1 -1
  408. package/dist/commands/versions.js +1 -1
  409. package/dist/commands/versions.js.map +1 -1
  410. package/dist/config/createCliConfig.js +1 -2
  411. package/dist/config/createCliConfig.js.map +1 -1
  412. package/dist/exports/_internal.d.ts +132 -0
  413. package/dist/exports/_internal.js +4 -0
  414. package/dist/exports/_internal.js.map +1 -0
  415. package/dist/exports/index.d.ts +113 -0
  416. package/dist/exports/index.js +6 -0
  417. package/dist/exports/index.js.map +1 -0
  418. package/dist/hooks/init/checkForUpdates.js +14 -0
  419. package/dist/hooks/init/checkForUpdates.js.map +1 -0
  420. package/dist/hooks/prerun/flushTelemetry.worker.js +1 -1
  421. package/dist/hooks/prerun/flushTelemetry.worker.js.map +1 -1
  422. package/dist/hooks/prerun/injectEnvVariables.js +9 -1
  423. package/dist/hooks/prerun/injectEnvVariables.js.map +1 -1
  424. package/dist/hooks/prerun/setupTelemetry.js +9 -3
  425. package/dist/hooks/prerun/setupTelemetry.js.map +1 -1
  426. package/dist/prompts/promptForProject.js +64 -0
  427. package/dist/prompts/promptForProject.js.map +1 -0
  428. package/dist/{actions/auth/login/promptProviders.js → prompts/promptForProviders.js} +3 -3
  429. package/dist/prompts/promptForProviders.js.map +1 -0
  430. package/dist/prompts/selectMediaLibrary.js +1 -1
  431. package/dist/prompts/selectMediaLibrary.js.map +1 -1
  432. package/dist/server/devServer.js +4 -2
  433. package/dist/server/devServer.js.map +1 -1
  434. package/dist/server/previewServer.js +2 -2
  435. package/dist/server/previewServer.js.map +1 -1
  436. package/dist/server/vite/plugin-schema-extraction.js +201 -0
  437. package/dist/server/vite/plugin-schema-extraction.js.map +1 -0
  438. package/dist/server/vite/plugin-typegen.js +217 -0
  439. package/dist/server/vite/plugin-typegen.js.map +1 -0
  440. package/dist/services/auth.js +42 -3
  441. package/dist/services/auth.js.map +1 -1
  442. package/dist/services/datasets.js +7 -5
  443. package/dist/services/datasets.js.map +1 -1
  444. package/dist/services/docs.js +2 -2
  445. package/dist/services/docs.js.map +1 -1
  446. package/dist/services/embeddings.js +25 -0
  447. package/dist/services/embeddings.js.map +1 -0
  448. package/dist/services/getUrlHeaders.js +7 -18
  449. package/dist/services/getUrlHeaders.js.map +1 -1
  450. package/dist/services/grants.js +13 -0
  451. package/dist/services/grants.js.map +1 -0
  452. package/dist/services/graphql.js +1 -1
  453. package/dist/services/graphql.js.map +1 -1
  454. package/dist/services/projects.js +4 -2
  455. package/dist/services/projects.js.map +1 -1
  456. package/dist/services/schemas.js +1 -1
  457. package/dist/services/schemas.js.map +1 -1
  458. package/dist/services/telemetry.js +2 -1
  459. package/dist/services/telemetry.js.map +1 -1
  460. package/dist/services/userApplications.js +21 -6
  461. package/dist/services/userApplications.js.map +1 -1
  462. package/dist/telemetry/extractSchema.telemetry.js +10 -0
  463. package/dist/telemetry/extractSchema.telemetry.js.map +1 -1
  464. package/dist/types/grants.js +3 -0
  465. package/dist/types/grants.js.map +1 -0
  466. package/dist/types.js +3 -0
  467. package/dist/types.js.map +1 -1
  468. package/dist/util/checkProjectPermissions.js +21 -0
  469. package/dist/util/checkProjectPermissions.js.map +1 -0
  470. package/dist/util/cliClient.js +5 -3
  471. package/dist/util/cliClient.js.map +1 -1
  472. package/dist/util/compareDependencyVersions.js +74 -38
  473. package/dist/util/compareDependencyVersions.js.map +1 -1
  474. package/dist/util/createExpiringConfig.js +64 -0
  475. package/dist/util/createExpiringConfig.js.map +1 -0
  476. package/dist/util/detectFramework.js +135 -0
  477. package/dist/util/detectFramework.js.map +1 -0
  478. package/dist/util/errorMessages.js +0 -1
  479. package/dist/util/errorMessages.js.map +1 -1
  480. package/dist/util/extractDocumentsFromNdjsonOrTarball.js +1 -2
  481. package/dist/util/extractDocumentsFromNdjsonOrTarball.js.map +1 -1
  482. package/dist/util/getCliVersion.js +1 -1
  483. package/dist/util/getCliVersion.js.map +1 -1
  484. package/dist/util/getLocalPackageVersion.js +31 -23
  485. package/dist/util/getLocalPackageVersion.js.map +1 -1
  486. package/dist/util/getProjectDefaults.js.map +1 -1
  487. package/dist/util/getSharedServerConfig.js +1 -0
  488. package/dist/util/getSharedServerConfig.js.map +1 -1
  489. package/dist/util/getWorkspace.js +1 -1
  490. package/dist/util/getWorkspace.js.map +1 -1
  491. package/dist/util/isSchemaError.js +11 -0
  492. package/dist/util/isSchemaError.js.map +1 -0
  493. package/dist/util/isTar.js +8 -0
  494. package/dist/util/isTar.js.map +1 -0
  495. package/dist/util/packageManager/getPeerDependencies.js +44 -0
  496. package/dist/util/packageManager/getPeerDependencies.js.map +1 -0
  497. package/dist/util/packageManager/installationInfo/analyzeIssues.js +225 -0
  498. package/dist/util/packageManager/installationInfo/analyzeIssues.js.map +1 -0
  499. package/dist/util/packageManager/installationInfo/commands.js +73 -0
  500. package/dist/util/packageManager/installationInfo/commands.js.map +1 -0
  501. package/dist/util/packageManager/installationInfo/detectCliInstallation.js +66 -0
  502. package/dist/util/packageManager/installationInfo/detectCliInstallation.js.map +1 -0
  503. package/dist/util/packageManager/installationInfo/detectGlobals.js +295 -0
  504. package/dist/util/packageManager/installationInfo/detectGlobals.js.map +1 -0
  505. package/dist/util/packageManager/installationInfo/detectPackages.js +190 -0
  506. package/dist/util/packageManager/installationInfo/detectPackages.js.map +1 -0
  507. package/dist/util/packageManager/installationInfo/detectWorkspace.js +192 -0
  508. package/dist/util/packageManager/installationInfo/detectWorkspace.js.map +1 -0
  509. package/dist/util/packageManager/installationInfo/index.js +4 -0
  510. package/dist/util/packageManager/installationInfo/index.js.map +1 -0
  511. package/dist/util/packageManager/installationInfo/readJsonFile.js +14 -0
  512. package/dist/util/packageManager/installationInfo/readJsonFile.js.map +1 -0
  513. package/dist/util/packageManager/installationInfo/resolveVersionRange.js +42 -0
  514. package/dist/util/packageManager/installationInfo/resolveVersionRange.js.map +1 -0
  515. package/dist/util/packageManager/installationInfo/types.js +3 -0
  516. package/dist/util/packageManager/installationInfo/types.js.map +1 -0
  517. package/dist/util/packageManager/packageManagerChoice.js +1 -20
  518. package/dist/util/packageManager/packageManagerChoice.js.map +1 -1
  519. package/dist/util/packageManager/upgradePackages.js +4 -1
  520. package/dist/util/packageManager/upgradePackages.js.map +1 -1
  521. package/dist/util/promiseRaceWithTimeout.js +28 -0
  522. package/dist/util/promiseRaceWithTimeout.js.map +1 -0
  523. package/dist/util/readdirRecursive.js.map +1 -1
  524. package/dist/util/resolveLatestVersions.js +2 -2
  525. package/dist/util/resolveLatestVersions.js.map +1 -1
  526. package/dist/util/sharedFlags.js +54 -0
  527. package/dist/util/sharedFlags.js.map +1 -0
  528. package/dist/util/telemetry/cleanupOldTelemetryFiles.js +30 -0
  529. package/dist/util/telemetry/cleanupOldTelemetryFiles.js.map +1 -0
  530. package/dist/util/telemetry/createTelemetryStore.js +95 -0
  531. package/dist/util/telemetry/createTelemetryStore.js.map +1 -0
  532. package/dist/util/telemetry/createTraceId.js +10 -0
  533. package/dist/util/telemetry/createTraceId.js.map +1 -0
  534. package/dist/util/telemetry/findTelemetryFiles.js +35 -0
  535. package/dist/util/telemetry/findTelemetryFiles.js.map +1 -0
  536. package/dist/util/telemetry/flushTelemetryFiles.js +118 -0
  537. package/dist/util/telemetry/flushTelemetryFiles.js.map +1 -0
  538. package/dist/util/telemetry/generateTelemetryFilePath.js +30 -0
  539. package/dist/util/telemetry/generateTelemetryFilePath.js.map +1 -0
  540. package/dist/util/telemetry/logger.js +59 -0
  541. package/dist/util/telemetry/logger.js.map +1 -0
  542. package/dist/util/telemetry/readNDJSON.js +28 -0
  543. package/dist/util/telemetry/readNDJSON.js.map +1 -0
  544. package/dist/util/telemetry/telemetryStoreDebug.js +7 -0
  545. package/dist/util/telemetry/telemetryStoreDebug.js.map +1 -0
  546. package/dist/util/telemetry/trace.js +150 -0
  547. package/dist/util/telemetry/trace.js.map +1 -0
  548. package/dist/util/toForwardSlashes.js +8 -0
  549. package/dist/util/toForwardSlashes.js.map +1 -0
  550. package/dist/util/update/fetchLatestVersion.js +21 -0
  551. package/dist/util/update/fetchLatestVersion.js.map +1 -0
  552. package/dist/util/update/getUpdateCommand.js +20 -0
  553. package/dist/util/update/getUpdateCommand.js.map +1 -0
  554. package/dist/util/update/isInstalledUsingYarn.js +17 -0
  555. package/dist/util/update/isInstalledUsingYarn.js.map +1 -0
  556. package/dist/util/update/showNotificationUpdate.js +31 -0
  557. package/dist/util/update/showNotificationUpdate.js.map +1 -0
  558. package/dist/util/update/updateChecker.js +60 -0
  559. package/dist/util/update/updateChecker.js.map +1 -0
  560. package/dist/util/update/updateCheckerDebug.js +4 -0
  561. package/dist/util/update/updateCheckerDebug.js.map +1 -0
  562. package/oclif.config.js +1 -0
  563. package/oclif.manifest.json +900 -107
  564. package/package.json +72 -71
  565. package/static/favicons/apple-touch-icon.png +0 -0
  566. package/static/favicons/favicon-192.png +0 -0
  567. package/static/favicons/favicon-512.png +0 -0
  568. package/static/favicons/favicon-96.png +0 -0
  569. package/static/favicons/favicon.ico +0 -0
  570. package/static/favicons/favicon.svg +12 -0
  571. package/dist/actions/auth/login/promptProviders.js.map +0 -1
  572. package/dist/actions/dev/getCoreAppUrl.js +0 -10
  573. package/dist/actions/dev/getCoreAppUrl.js.map +0 -1
  574. package/dist/actions/schema/schemaStoreTypes.js +0 -19
  575. package/dist/actions/schema/schemaStoreTypes.js.map +0 -1
  576. package/dist/actions/schema/utils/manifestExtractor.js +0 -33
  577. package/dist/actions/schema/utils/manifestExtractor.js.map +0 -1
  578. package/dist/actions/schema/utils/manifestReader.js +0 -71
  579. package/dist/actions/schema/utils/manifestReader.js.map +0 -1
  580. package/dist/index.d.ts +0 -2326
  581. package/dist/index.js +0 -6
  582. package/dist/index.js.map +0 -1
  583. package/dist/studioDependencies.js.map +0 -1
  584. package/dist/typings/deepSortObject.d.js +0 -2
  585. package/dist/typings/deepSortObject.d.js.map +0 -1
  586. package/dist/util/findNdjsonEntry.js +0 -21
  587. package/dist/util/findNdjsonEntry.js.map +0 -1
  588. package/dist/util/importStudioConfig.js +0 -40
  589. package/dist/util/importStudioConfig.js.map +0 -1
  590. package/dist/util/readModuleVersion.js +0 -15
  591. package/dist/util/readModuleVersion.js.map +0 -1
  592. package/dist/util/readPackageJson.js +0 -44
  593. package/dist/util/readPackageJson.js.map +0 -1
  594. package/dist/util/readPackageManifest.js +0 -46
  595. package/dist/util/readPackageManifest.js.map +0 -1
  596. package/dist/util/uniqBy.js +0 -14
  597. package/dist/util/uniqBy.js.map +0 -1
  598. package/dist/util/workerChannels.js +0 -172
  599. package/dist/util/workerChannels.js.map +0 -1
  600. /package/dist/{studioDependencies.js → actions/init/studioDependencies.js} +0 -0
@@ -8,13 +8,12 @@ import { pipeline } from 'node:stream/promises';
8
8
  import { styleText } from 'node:util';
9
9
  import gunzipMaybe from 'gunzip-maybe';
10
10
  // @ts-expect-error `peek-stream` module currently untyped
11
- import isTar from 'is-tar';
12
- // @ts-expect-error `peek-stream` module currently untyped
13
11
  import peek from 'peek-stream';
14
12
  import { catchError, EMPTY, filter, from, map, mergeMap, mergeWith, of, switchMap, tap, zip } from 'rxjs';
15
13
  import tar from 'tar-fs';
16
14
  import { glob } from 'tinyglobby';
17
- import { findNdjsonEntry } from '../../util/findNdjsonEntry.js';
15
+ import { isTar } from '../../util/isTar.js';
16
+ import { buildNdjsonIndex } from './buildNdjsonIndex.js';
18
17
  import { importMediaDebug } from './importMediaDebug.js';
19
18
  const DEFAULT_CONCURRENCY = 6;
20
19
  export function importer(options) {
@@ -23,15 +22,20 @@ export function importer(options) {
23
22
  if (fileCount === 0) {
24
23
  throw new Error('No assets to import');
25
24
  }
26
- const context = {
27
- ...options,
28
- ndjson: ()=>createReadStream(aspectsNdjsonPath),
29
- workingPath
30
- };
31
- return from(files).pipe(switchMap((file)=>zip(of('file'), of(file))), mergeWith(from(images).pipe(switchMap((file)=>zip(of('image'), of(file))))), fetchExistingAssets(context), uploadAsset(context), resolveAspectData(context), setAspects(context), map((asset)=>({
32
- asset,
33
- fileCount
34
- })));
25
+ // Stream the ndjson file once and build an index to avoid creating
26
+ // multiple read streams (which causes file descriptor leaks)
27
+ const aspectsIndexPromise = buildNdjsonIndex(createReadStream(aspectsNdjsonPath), 'filename', 'aspects');
28
+ return from(aspectsIndexPromise).pipe(mergeMap((aspectsIndex)=>{
29
+ const context = {
30
+ ...options,
31
+ aspectsIndex,
32
+ workingPath
33
+ };
34
+ return from(files).pipe(switchMap((file)=>zip(of('file'), of(file))), mergeWith(from(images).pipe(switchMap((file)=>zip(of('image'), of(file))))), fetchExistingAssets(context), uploadAsset(context), resolveAspectData(context), setAspects(context), map((asset)=>({
35
+ asset,
36
+ fileCount
37
+ })));
38
+ }));
35
39
  }));
36
40
  }
37
41
  /**
@@ -141,14 +145,14 @@ function fetchExistingAssets({ client, workingPath }) {
141
145
  });
142
146
  }
143
147
  /**
144
- * Find the first matching entry in the provided NDJSON stream and attach it to the asset object.
148
+ * Find the first matching entry in the cached aspect data and attach it to the asset object.
145
149
  *
146
150
  * @internal
147
- */ function resolveAspectData({ ndjson }) {
148
- return mergeMap((resolvedAsset)=>from(findNdjsonEntry(ndjson(), (line)=>typeof line === 'object' && line !== null && 'filename' in line && line.filename === resolvedAsset.originalFilename)).pipe(map((aspectsFromImport)=>({
149
- ...resolvedAsset,
150
- aspects: aspectsFromImport?.aspects
151
- }))));
151
+ */ function resolveAspectData({ aspectsIndex }) {
152
+ return map((resolvedAsset)=>({
153
+ ...resolvedAsset,
154
+ aspects: aspectsIndex.get(resolvedAsset.originalFilename)
155
+ }));
152
156
  }
153
157
  // TODO: Batch mutations to reduce HTTP request count.
154
158
  export function setAspects({ client, replaceAspects }) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/actions/media/importMedia.ts"],"sourcesContent":["import {createHash} from 'node:crypto'\nimport {createReadStream, type ReadStream} from 'node:fs'\nimport fs, {mkdtemp} from 'node:fs/promises'\nimport {tmpdir} from 'node:os'\nimport path from 'node:path'\nimport {text} from 'node:stream/consumers'\nimport {pipeline} from 'node:stream/promises'\nimport {styleText} from 'node:util'\n\nimport {spinner} from '@sanity/cli-core/ux'\nimport {type SanityClient} from '@sanity/client'\nimport {type FileAsset, type ImageAsset, type SanityDocument} from '@sanity/types'\nimport gunzipMaybe from 'gunzip-maybe'\n// @ts-expect-error `peek-stream` module currently untyped\nimport isTar from 'is-tar'\n// @ts-expect-error `peek-stream` module currently untyped\nimport peek from 'peek-stream'\nimport {\n catchError,\n EMPTY,\n filter,\n from,\n map,\n mergeMap,\n mergeWith,\n type Observable,\n of,\n type OperatorFunction,\n switchMap,\n tap,\n zip,\n} from 'rxjs'\nimport tar from 'tar-fs'\nimport {glob} from 'tinyglobby'\n\nimport {findNdjsonEntry} from '../../util/findNdjsonEntry.js'\nimport {importMediaDebug} from './importMediaDebug.js'\n\nconst DEFAULT_CONCURRENCY = 6\n\ninterface MediaLibraryUploadResult {\n asset: SanityDocument & {\n _type: 'sanity.asset'\n aspects: unknown\n assetType: FileAsset['_type'] | ImageAsset['_type']\n }\n assetInstance: FileAsset | ImageAsset\n}\n\ninterface MediaLibraryUploadResponse {\n body: MediaLibraryUploadResult\n type: 'response'\n}\n\nexport interface State {\n /**\n * The last asset processed.\n */\n asset: AssetWithAspects\n /**\n * The count of input files.\n */\n fileCount: number\n}\n\ninterface ResolvedAsset {\n /**\n * The ids of the `sanity.asset` documents that currently refer to the asset.\n *\n * These documents contain aspects, and reference an asset instance document.\n */\n assetIds: string[]\n isExistingAsset: boolean\n /**\n * The original filename of the asset as it appears in the import source.\n *\n * Note: Currently includes `images/` or `files/` prefix.\n */\n originalFilename: string\n sha1Hash: string\n}\n\nexport type AssetWithAspects<Asset extends ResolvedAsset = ResolvedAsset> = Asset & {\n aspects: unknown | undefined\n}\n\ninterface Options {\n client: SanityClient\n replaceAspects: boolean\n sourcePath: string\n spinner: ReturnType<typeof spinner>\n}\n\ninterface Context extends Options {\n ndjson: () => ReadStream\n workingPath: string\n}\n\nexport function importer(options: Options): Observable<State> {\n return resolveSource(options).pipe(\n mergeMap(({aspectsNdjsonPath, files, images, workingPath}) => {\n const fileCount = files.length + images.length\n\n if (fileCount === 0) {\n throw new Error('No assets to import')\n }\n\n const context: Context = {\n ...options,\n ndjson: () => createReadStream(aspectsNdjsonPath),\n workingPath,\n }\n\n return from(files).pipe(\n switchMap((file) => zip(of<'file'>('file'), of(file))),\n mergeWith(from(images).pipe(switchMap((file) => zip(of<'image'>('image'), of(file))))),\n fetchExistingAssets(context),\n uploadAsset(context),\n resolveAspectData(context),\n setAspects(context),\n map((asset) => ({\n asset,\n fileCount,\n })),\n )\n }),\n )\n}\n\n/**\n * @internal\n */\nexport function resolveSource({sourcePath}: Pick<Context, 'sourcePath'>): Observable<{\n aspectsNdjsonPath: string\n files: string[]\n images: string[]\n workingPath: string\n}> {\n return from(fs.stat(sourcePath)).pipe(\n switchMap((stats) => {\n return stats.isDirectory()\n ? of(sourcePath)\n : from(mkdtemp(path.join(tmpdir(), 'sanity-media-library-import'))).pipe(\n switchMap((tempPath) => {\n return from(\n pipeline(createReadStream(sourcePath), gunzipMaybe(), untarMaybe(tempPath)),\n ).pipe(map(() => tempPath))\n }),\n )\n }),\n switchMap((importSourcePath) => {\n return from(\n glob(['**/data.ndjson'], {\n absolute: true,\n cwd: importSourcePath,\n deep: 2,\n }),\n ).pipe(\n map(([aspectsNdjsonPath]) => ({\n aspectsNdjsonPath,\n importSourcePath,\n workingPath:\n aspectsNdjsonPath === undefined ? importSourcePath : path.dirname(aspectsNdjsonPath),\n })),\n )\n }),\n tap(({aspectsNdjsonPath, importSourcePath}) => {\n if (aspectsNdjsonPath === undefined) {\n throw new Error(\n `No ${styleText('bold', 'data.ndjson')} file found in import source ${styleText('bold', importSourcePath)}`,\n )\n }\n importMediaDebug(`[Found NDJSON file] ${aspectsNdjsonPath}`)\n }),\n switchMap(({aspectsNdjsonPath, workingPath}) => {\n return from(\n Promise.all([\n glob(['files/*'], {\n cwd: workingPath,\n }),\n glob(['images/*'], {\n cwd: workingPath,\n }),\n ]),\n ).pipe(\n map(([files, images]) => ({\n aspectsNdjsonPath,\n files,\n images,\n workingPath,\n })),\n )\n }),\n )\n}\n\n/**\n * Untar the stream if its contents appear to be tarred.\n *\n * @internal\n */\nfunction untarMaybe(outputPath: string) {\n // @ts-expect-error `peek-stream` module currently untyped\n return peek({maxBuffer: 300, newline: false}, (data, swap) => {\n if (isTar(data)) {\n return swap(null, tar.extract(outputPath))\n }\n\n return swap(null)\n })\n}\n\n/**\n * Fetch the ids of all asset documents that reference the input asset.\n * The input asset is identified by its SHA-1 hash.\n *\n * @internal\n */\nfunction fetchAssetsByHash({\n client,\n type,\n}: {\n client: SanityClient\n type: 'file' | 'image'\n}): OperatorFunction<string, [hash: string, assetIds: string[]]> {\n return switchMap((hash) =>\n client.observable\n .fetch<string[]>(\n `*[\n _type == \"sanity.asset\" &&\n currentVersion._ref == *[\n _type == $type &&\n sha1hash == $hash\n ][0]._id\n ]._id`,\n {\n hash,\n type: ['sanity', `${type}Asset`].join('.'),\n },\n {\n tag: 'asset.getId',\n },\n )\n .pipe(switchMap((assetIds) => zip(of(hash), of(assetIds)))),\n )\n}\n\nfunction fetchExistingAssets({\n client,\n workingPath,\n}: Context): OperatorFunction<\n [type: 'file' | 'image', asset: string],\n [type: 'file' | 'image', asset: string, hash: string] | ResolvedAsset\n> {\n return mergeMap(([type, asset]) => {\n const createSha1Hash = createHash('sha1')\n\n const sha1hash = text(\n createReadStream(path.join(workingPath, asset)).pipe(createSha1Hash).setEncoding('hex'),\n )\n\n return from(sha1hash).pipe(\n tap((hash) =>\n importMediaDebug(`[Asset ${asset}] Checking for ${type} asset with hash ${hash}`),\n ),\n fetchAssetsByHash({client, type}),\n map<\n [string, string[]],\n [type: 'file' | 'image', asset: string, hash: string] | ResolvedAsset\n >(([hash, assetIds]) => {\n if (assetIds.length === 0) {\n return [type, asset, hash]\n }\n\n return {\n assetIds,\n isExistingAsset: true,\n originalFilename: asset,\n sha1Hash: hash,\n }\n }),\n )\n })\n}\n\n/**\n * Find the first matching entry in the provided NDJSON stream and attach it to the asset object.\n *\n * @internal\n */\nfunction resolveAspectData({ndjson}: Context): OperatorFunction<ResolvedAsset, AssetWithAspects> {\n return mergeMap((resolvedAsset) =>\n from(\n findNdjsonEntry<{aspects: unknown}>(\n ndjson(),\n (line) =>\n typeof line === 'object' &&\n line !== null &&\n 'filename' in line &&\n line.filename === resolvedAsset.originalFilename,\n ),\n ).pipe(\n map((aspectsFromImport) => ({\n ...resolvedAsset,\n aspects: aspectsFromImport?.aspects,\n })),\n ),\n )\n}\n\n// TODO: Batch mutations to reduce HTTP request count.\nexport function setAspects({\n client,\n replaceAspects,\n}: Pick<Context, 'client' | 'replaceAspects'>): OperatorFunction<\n AssetWithAspects,\n AssetWithAspects\n> {\n return mergeMap((asset) => {\n const {aspects, assetIds, isExistingAsset} = asset\n\n if (isExistingAsset && !replaceAspects) {\n importMediaDebug(`[Asset ${asset.originalFilename}] Skipping replacement of existing aspects`)\n return of(asset)\n }\n\n if (aspects === undefined) {\n importMediaDebug(`[Asset ${asset.originalFilename}] No aspects to import`)\n return of(asset)\n }\n\n const transaction = client.observable.transaction()\n for (const assetId of assetIds) {\n transaction.patch(assetId, {set: {aspects}})\n }\n\n importMediaDebug(\n `[Asset ${asset.originalFilename}] Setting aspects on asset documents ${JSON.stringify(assetIds)}`,\n )\n\n return transaction\n .commit({\n tag: 'asset.setAspects',\n visibility: 'async',\n })\n .pipe(map(() => asset))\n }, DEFAULT_CONCURRENCY)\n}\n\nfunction uploadAsset({\n client,\n workingPath,\n}: Context): OperatorFunction<\n [type: 'file' | 'image', asset: string, hash: string] | ResolvedAsset,\n ResolvedAsset\n> {\n return mergeMap((maybeResolvedAsset) => {\n if ('assetIds' in maybeResolvedAsset) {\n importMediaDebug(\n `[Asset ${maybeResolvedAsset.originalFilename}] Skipping upload of existing asset with hash ${maybeResolvedAsset.sha1Hash}`,\n )\n return of(maybeResolvedAsset)\n }\n\n const [type, asset, hash] = maybeResolvedAsset\n importMediaDebug(`[Asset ${asset}] Uploading new asset`)\n\n return client.observable.assets\n .upload(type, createReadStream(path.join(workingPath, asset)), {\n tag: 'asset.upload',\n })\n .pipe(\n catchError((error) => {\n // An asset matching the hash was not found during previous steps, but appears to exist upon upload.\n //\n // This may occur if:\n // - The asset was uploaded by another client since the check was performed.\n // - The asset instance document exists, but is not referenced by any asset document.\n if (error.statusCode === 409) {\n importMediaDebug(\n `[Asset ${asset}] Cannot overwrite existing ${type} asset with hash ${hash}`,\n )\n return EMPTY\n }\n return EMPTY\n }),\n filter((response) => response.type === 'response'),\n tap(() => importMediaDebug(`[Asset ${asset}] Finished uploading new asset`)),\n // TODO: The `client.assets.upload` method should return `MediaLibraryUploadResponse` when operating on Media Library resources. When that occurs, this type assertion can be removed.\n map((response) => (response as unknown as MediaLibraryUploadResponse).body),\n map<MediaLibraryUploadResult, ResolvedAsset>((result) => ({\n assetIds: [result.asset._id],\n isExistingAsset: false,\n originalFilename: asset,\n sha1Hash: hash,\n })),\n )\n }, DEFAULT_CONCURRENCY)\n}\n"],"names":["createHash","createReadStream","fs","mkdtemp","tmpdir","path","text","pipeline","styleText","gunzipMaybe","isTar","peek","catchError","EMPTY","filter","from","map","mergeMap","mergeWith","of","switchMap","tap","zip","tar","glob","findNdjsonEntry","importMediaDebug","DEFAULT_CONCURRENCY","importer","options","resolveSource","pipe","aspectsNdjsonPath","files","images","workingPath","fileCount","length","Error","context","ndjson","file","fetchExistingAssets","uploadAsset","resolveAspectData","setAspects","asset","sourcePath","stat","stats","isDirectory","join","tempPath","untarMaybe","importSourcePath","absolute","cwd","deep","undefined","dirname","Promise","all","outputPath","maxBuffer","newline","data","swap","extract","fetchAssetsByHash","client","type","hash","observable","fetch","tag","assetIds","createSha1Hash","sha1hash","setEncoding","isExistingAsset","originalFilename","sha1Hash","resolvedAsset","line","filename","aspectsFromImport","aspects","replaceAspects","transaction","assetId","patch","set","JSON","stringify","commit","visibility","maybeResolvedAsset","assets","upload","error","statusCode","response","body","result","_id"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../src/actions/media/importMedia.ts"],"sourcesContent":["import {createHash} from 'node:crypto'\nimport {createReadStream} from 'node:fs'\nimport fs, {mkdtemp} from 'node:fs/promises'\nimport {tmpdir} from 'node:os'\nimport path from 'node:path'\nimport {text} from 'node:stream/consumers'\nimport {pipeline} from 'node:stream/promises'\nimport {styleText} from 'node:util'\n\nimport {spinner} from '@sanity/cli-core/ux'\nimport {type SanityClient} from '@sanity/client'\nimport {type FileAsset, type ImageAsset, type SanityDocument} from '@sanity/types'\nimport gunzipMaybe from 'gunzip-maybe'\n// @ts-expect-error `peek-stream` module currently untyped\nimport peek from 'peek-stream'\nimport {\n catchError,\n EMPTY,\n filter,\n from,\n map,\n mergeMap,\n mergeWith,\n type Observable,\n of,\n type OperatorFunction,\n switchMap,\n tap,\n zip,\n} from 'rxjs'\nimport tar from 'tar-fs'\nimport {glob} from 'tinyglobby'\n\nimport {isTar} from '../../util/isTar.js'\nimport {buildNdjsonIndex} from './buildNdjsonIndex.js'\nimport {importMediaDebug} from './importMediaDebug.js'\n\nconst DEFAULT_CONCURRENCY = 6\n\ninterface MediaLibraryUploadResult {\n asset: SanityDocument & {\n _type: 'sanity.asset'\n aspects: unknown\n assetType: FileAsset['_type'] | ImageAsset['_type']\n }\n assetInstance: FileAsset | ImageAsset\n}\n\ninterface MediaLibraryUploadResponse {\n body: MediaLibraryUploadResult\n type: 'response'\n}\n\nexport interface State {\n /**\n * The last asset processed.\n */\n asset: AssetWithAspects\n /**\n * The count of input files.\n */\n fileCount: number\n}\n\ninterface ResolvedAsset {\n /**\n * The ids of the `sanity.asset` documents that currently refer to the asset.\n *\n * These documents contain aspects, and reference an asset instance document.\n */\n assetIds: string[]\n isExistingAsset: boolean\n /**\n * The original filename of the asset as it appears in the import source.\n *\n * Note: Currently includes `images/` or `files/` prefix.\n */\n originalFilename: string\n sha1Hash: string\n}\n\nexport type AssetWithAspects<Asset extends ResolvedAsset = ResolvedAsset> = Asset & {\n aspects: unknown | undefined\n}\n\ninterface Options {\n client: SanityClient\n replaceAspects: boolean\n sourcePath: string\n spinner: ReturnType<typeof spinner>\n}\n\ninterface Context extends Options {\n aspectsIndex: Map<string, unknown>\n workingPath: string\n}\n\nexport function importer(options: Options): Observable<State> {\n return resolveSource(options).pipe(\n mergeMap(({aspectsNdjsonPath, files, images, workingPath}) => {\n const fileCount = files.length + images.length\n\n if (fileCount === 0) {\n throw new Error('No assets to import')\n }\n\n // Stream the ndjson file once and build an index to avoid creating\n // multiple read streams (which causes file descriptor leaks)\n const aspectsIndexPromise = buildNdjsonIndex(\n createReadStream(aspectsNdjsonPath),\n 'filename',\n 'aspects',\n )\n\n return from(aspectsIndexPromise).pipe(\n mergeMap((aspectsIndex) => {\n const context: Context = {\n ...options,\n aspectsIndex,\n workingPath,\n }\n\n return from(files).pipe(\n switchMap((file) => zip(of<'file'>('file'), of(file))),\n mergeWith(from(images).pipe(switchMap((file) => zip(of<'image'>('image'), of(file))))),\n fetchExistingAssets(context),\n uploadAsset(context),\n resolveAspectData(context),\n setAspects(context),\n map((asset) => ({\n asset,\n fileCount,\n })),\n )\n }),\n )\n }),\n )\n}\n\n/**\n * @internal\n */\nexport function resolveSource({sourcePath}: Pick<Context, 'sourcePath'>): Observable<{\n aspectsNdjsonPath: string\n files: string[]\n images: string[]\n workingPath: string\n}> {\n return from(fs.stat(sourcePath)).pipe(\n switchMap((stats) => {\n return stats.isDirectory()\n ? of(sourcePath)\n : from(mkdtemp(path.join(tmpdir(), 'sanity-media-library-import'))).pipe(\n switchMap((tempPath) => {\n return from(\n pipeline(createReadStream(sourcePath), gunzipMaybe(), untarMaybe(tempPath)),\n ).pipe(map(() => tempPath))\n }),\n )\n }),\n switchMap((importSourcePath) => {\n return from(\n glob(['**/data.ndjson'], {\n absolute: true,\n cwd: importSourcePath,\n deep: 2,\n }),\n ).pipe(\n map(([aspectsNdjsonPath]) => ({\n aspectsNdjsonPath,\n importSourcePath,\n workingPath:\n aspectsNdjsonPath === undefined ? importSourcePath : path.dirname(aspectsNdjsonPath),\n })),\n )\n }),\n tap(({aspectsNdjsonPath, importSourcePath}) => {\n if (aspectsNdjsonPath === undefined) {\n throw new Error(\n `No ${styleText('bold', 'data.ndjson')} file found in import source ${styleText('bold', importSourcePath)}`,\n )\n }\n importMediaDebug(`[Found NDJSON file] ${aspectsNdjsonPath}`)\n }),\n switchMap(({aspectsNdjsonPath, workingPath}) => {\n return from(\n Promise.all([\n glob(['files/*'], {\n cwd: workingPath,\n }),\n glob(['images/*'], {\n cwd: workingPath,\n }),\n ]),\n ).pipe(\n map(([files, images]) => ({\n aspectsNdjsonPath,\n files,\n images,\n workingPath,\n })),\n )\n }),\n )\n}\n\n/**\n * Untar the stream if its contents appear to be tarred.\n *\n * @internal\n */\nfunction untarMaybe(outputPath: string) {\n // @ts-expect-error `peek-stream` module currently untyped\n return peek({maxBuffer: 300, newline: false}, (data, swap) => {\n if (isTar(data)) {\n return swap(null, tar.extract(outputPath))\n }\n\n return swap(null)\n })\n}\n\n/**\n * Fetch the ids of all asset documents that reference the input asset.\n * The input asset is identified by its SHA-1 hash.\n *\n * @internal\n */\nfunction fetchAssetsByHash({\n client,\n type,\n}: {\n client: SanityClient\n type: 'file' | 'image'\n}): OperatorFunction<string, [hash: string, assetIds: string[]]> {\n return switchMap((hash) =>\n client.observable\n .fetch<string[]>(\n `*[\n _type == \"sanity.asset\" &&\n currentVersion._ref == *[\n _type == $type &&\n sha1hash == $hash\n ][0]._id\n ]._id`,\n {\n hash,\n type: ['sanity', `${type}Asset`].join('.'),\n },\n {\n tag: 'asset.getId',\n },\n )\n .pipe(switchMap((assetIds) => zip(of(hash), of(assetIds)))),\n )\n}\n\nfunction fetchExistingAssets({\n client,\n workingPath,\n}: Context): OperatorFunction<\n [type: 'file' | 'image', asset: string],\n [type: 'file' | 'image', asset: string, hash: string] | ResolvedAsset\n> {\n return mergeMap(([type, asset]) => {\n const createSha1Hash = createHash('sha1')\n\n const sha1hash = text(\n createReadStream(path.join(workingPath, asset)).pipe(createSha1Hash).setEncoding('hex'),\n )\n\n return from(sha1hash).pipe(\n tap((hash) =>\n importMediaDebug(`[Asset ${asset}] Checking for ${type} asset with hash ${hash}`),\n ),\n fetchAssetsByHash({client, type}),\n map<\n [string, string[]],\n [type: 'file' | 'image', asset: string, hash: string] | ResolvedAsset\n >(([hash, assetIds]) => {\n if (assetIds.length === 0) {\n return [type, asset, hash]\n }\n\n return {\n assetIds,\n isExistingAsset: true,\n originalFilename: asset,\n sha1Hash: hash,\n }\n }),\n )\n })\n}\n\n/**\n * Find the first matching entry in the cached aspect data and attach it to the asset object.\n *\n * @internal\n */\nfunction resolveAspectData({\n aspectsIndex,\n}: Context): OperatorFunction<ResolvedAsset, AssetWithAspects> {\n return map((resolvedAsset) => ({\n ...resolvedAsset,\n aspects: aspectsIndex.get(resolvedAsset.originalFilename),\n }))\n}\n\n// TODO: Batch mutations to reduce HTTP request count.\nexport function setAspects({\n client,\n replaceAspects,\n}: Pick<Context, 'client' | 'replaceAspects'>): OperatorFunction<\n AssetWithAspects,\n AssetWithAspects\n> {\n return mergeMap((asset) => {\n const {aspects, assetIds, isExistingAsset} = asset\n\n if (isExistingAsset && !replaceAspects) {\n importMediaDebug(`[Asset ${asset.originalFilename}] Skipping replacement of existing aspects`)\n return of(asset)\n }\n\n if (aspects === undefined) {\n importMediaDebug(`[Asset ${asset.originalFilename}] No aspects to import`)\n return of(asset)\n }\n\n const transaction = client.observable.transaction()\n for (const assetId of assetIds) {\n transaction.patch(assetId, {set: {aspects}})\n }\n\n importMediaDebug(\n `[Asset ${asset.originalFilename}] Setting aspects on asset documents ${JSON.stringify(assetIds)}`,\n )\n\n return transaction\n .commit({\n tag: 'asset.setAspects',\n visibility: 'async',\n })\n .pipe(map(() => asset))\n }, DEFAULT_CONCURRENCY)\n}\n\nfunction uploadAsset({\n client,\n workingPath,\n}: Context): OperatorFunction<\n [type: 'file' | 'image', asset: string, hash: string] | ResolvedAsset,\n ResolvedAsset\n> {\n return mergeMap((maybeResolvedAsset) => {\n if ('assetIds' in maybeResolvedAsset) {\n importMediaDebug(\n `[Asset ${maybeResolvedAsset.originalFilename}] Skipping upload of existing asset with hash ${maybeResolvedAsset.sha1Hash}`,\n )\n return of(maybeResolvedAsset)\n }\n\n const [type, asset, hash] = maybeResolvedAsset\n importMediaDebug(`[Asset ${asset}] Uploading new asset`)\n\n return client.observable.assets\n .upload(type, createReadStream(path.join(workingPath, asset)), {\n tag: 'asset.upload',\n })\n .pipe(\n catchError((error) => {\n // An asset matching the hash was not found during previous steps, but appears to exist upon upload.\n //\n // This may occur if:\n // - The asset was uploaded by another client since the check was performed.\n // - The asset instance document exists, but is not referenced by any asset document.\n if (error.statusCode === 409) {\n importMediaDebug(\n `[Asset ${asset}] Cannot overwrite existing ${type} asset with hash ${hash}`,\n )\n return EMPTY\n }\n return EMPTY\n }),\n filter((response) => response.type === 'response'),\n tap(() => importMediaDebug(`[Asset ${asset}] Finished uploading new asset`)),\n // TODO: The `client.assets.upload` method should return `MediaLibraryUploadResponse` when operating on Media Library resources. When that occurs, this type assertion can be removed.\n map((response) => (response as unknown as MediaLibraryUploadResponse).body),\n map<MediaLibraryUploadResult, ResolvedAsset>((result) => ({\n assetIds: [result.asset._id],\n isExistingAsset: false,\n originalFilename: asset,\n sha1Hash: hash,\n })),\n )\n }, DEFAULT_CONCURRENCY)\n}\n"],"names":["createHash","createReadStream","fs","mkdtemp","tmpdir","path","text","pipeline","styleText","gunzipMaybe","peek","catchError","EMPTY","filter","from","map","mergeMap","mergeWith","of","switchMap","tap","zip","tar","glob","isTar","buildNdjsonIndex","importMediaDebug","DEFAULT_CONCURRENCY","importer","options","resolveSource","pipe","aspectsNdjsonPath","files","images","workingPath","fileCount","length","Error","aspectsIndexPromise","aspectsIndex","context","file","fetchExistingAssets","uploadAsset","resolveAspectData","setAspects","asset","sourcePath","stat","stats","isDirectory","join","tempPath","untarMaybe","importSourcePath","absolute","cwd","deep","undefined","dirname","Promise","all","outputPath","maxBuffer","newline","data","swap","extract","fetchAssetsByHash","client","type","hash","observable","fetch","tag","assetIds","createSha1Hash","sha1hash","setEncoding","isExistingAsset","originalFilename","sha1Hash","resolvedAsset","aspects","get","replaceAspects","transaction","assetId","patch","set","JSON","stringify","commit","visibility","maybeResolvedAsset","assets","upload","error","statusCode","response","body","result","_id"],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ export function findOrganizationByUserName(organizations, user) {
2
+ return organizations.find((org)=>org.name === user?.name)?.id;
3
+ }
4
+
5
+ //# sourceMappingURL=findOrganizationByUserName.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/actions/organizations/findOrganizationByUserName.ts"],"sourcesContent":["import {type SanityOrgUser} from '@sanity/cli-core'\n\nimport {type ProjectOrganization} from '../../services/organizations.js'\n\nexport function findOrganizationByUserName(\n organizations: ProjectOrganization[],\n user: SanityOrgUser,\n): string | undefined {\n return organizations.find((org) => org.name === user?.name)?.id\n}\n"],"names":["findOrganizationByUserName","organizations","user","find","org","name","id"],"mappings":"AAIA,OAAO,SAASA,2BACdC,aAAoC,EACpCC,IAAmB;IAEnB,OAAOD,cAAcE,IAAI,CAAC,CAACC,MAAQA,IAAIC,IAAI,KAAKH,MAAMG,OAAOC;AAC/D"}
@@ -2,6 +2,7 @@ import { subdebug } from '@sanity/cli-core';
2
2
  import { select, spinner } from '@sanity/cli-core/ux';
3
3
  import { promptForOrganizationName } from '../../prompts/promptForOrganizationName.js';
4
4
  import { createOrganization, listOrganizations } from '../../services/organizations.js';
5
+ import { findOrganizationByUserName } from './findOrganizationByUserName.js';
5
6
  import { getOrganizationChoices } from './getOrganizationChoices.js';
6
7
  import { getOrganizationsWithAttachGrantInfo } from './getOrganizationsWithAttachGrantInfo.js';
7
8
  const debug = subdebug('getOrganizationId');
@@ -43,7 +44,7 @@ export async function getOrganization({ isUnattended, output, requestedId, user
43
44
  const withGrantInfo = await getOrganizationsWithAttachGrantInfo(organizations);
44
45
  const withAttach = withGrantInfo.filter(({ hasAttachGrant })=>hasAttachGrant);
45
46
  debug('User has attach access to %d organizations.', withAttach.length);
46
- const organizationChoices = getOrganizationChoices(withAttach);
47
+ const organizationChoices = getOrganizationChoices(withGrantInfo);
47
48
  // In unattended mode use defaults without prompting
48
49
  if (isUnattended) {
49
50
  // Use the first organization with attach permissions
@@ -52,7 +53,7 @@ export async function getOrganization({ isUnattended, output, requestedId, user
52
53
  // If the user only has a single organization (and they have attach access to it),
53
54
  // we'll default to that one. Otherwise, we'll default to the organization with the
54
55
  // same name as the user if it exists.
55
- const defaultOrganizationId = withAttach.length === 1 ? withAttach[0].organization.id : organizations.find((org)=>org.name === user?.name)?.id;
56
+ const defaultOrganizationId = withAttach.length === 1 ? withAttach[0].organization.id : findOrganizationByUserName(organizations, user);
56
57
  const chosenOrg = await select({
57
58
  choices: organizationChoices,
58
59
  default: defaultOrganizationId || undefined,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/actions/organizations/getOrganization.ts"],"sourcesContent":["import {Output, type SanityOrgUser, subdebug} from '@sanity/cli-core'\nimport {select, spinner} from '@sanity/cli-core/ux'\n\nimport {promptForOrganizationName} from '../../prompts/promptForOrganizationName.js'\nimport {\n createOrganization,\n listOrganizations,\n type ProjectOrganization,\n} from '../../services/organizations.js'\nimport {getOrganizationChoices} from './getOrganizationChoices.js'\nimport {getOrganizationsWithAttachGrantInfo} from './getOrganizationsWithAttachGrantInfo.js'\n\nconst debug = subdebug('getOrganizationId')\n\ninterface GetOrganizationOptions {\n isUnattended: boolean\n output: Output\n requestedId: string | undefined\n user: SanityOrgUser\n}\n\nconst promptAndCreateNewOrganization = async (user: SanityOrgUser) => {\n const organizationName = await promptForOrganizationName(user)\n const spin = spinner('Creating organization').start()\n const newOrganization = await createOrganization(organizationName)\n spin.succeed()\n return newOrganization\n}\n\nexport async function getOrganization({\n isUnattended,\n output,\n requestedId,\n user,\n}: GetOrganizationOptions) {\n // Get available organizations\n const spin = spinner('Loading organizations').start()\n let organizations: ProjectOrganization[]\n try {\n organizations = await listOrganizations()\n spin.succeed()\n } catch (error) {\n spin.fail()\n debug('Error retrieving organization list', error)\n throw error\n }\n\n // If organization is specified, validate it\n if (requestedId) {\n const org = organizations.find((o) => o.id === requestedId || o.slug === requestedId)\n if (org) return org\n\n throw new Error(`Organization \"${requestedId}\" not found or you don't have access to it`)\n }\n\n // If the user has no organizations, prompt them to create one with the same name as\n // their user, but allow them to customize it if they want\n if (organizations.length === 0) {\n output.log('You need to create an organization to create projects.')\n return promptAndCreateNewOrganization(user)\n }\n\n // If the user has organizations, let them choose from them, but also allow them to\n // create a new one in case they do not have access to any of them, or they want to\n // create a personal/other organization.\n debug(`User has ${organizations.length} organization(s), checking attach access`)\n const withGrantInfo = await getOrganizationsWithAttachGrantInfo(organizations)\n const withAttach = withGrantInfo.filter(({hasAttachGrant}) => hasAttachGrant)\n\n debug('User has attach access to %d organizations.', withAttach.length)\n const organizationChoices = getOrganizationChoices(withAttach)\n\n // In unattended mode use defaults without prompting\n if (isUnattended) {\n // Use the first organization with attach permissions\n return withAttach.length > 0 ? withAttach[0].organization : undefined\n }\n\n // If the user only has a single organization (and they have attach access to it),\n // we'll default to that one. Otherwise, we'll default to the organization with the\n // same name as the user if it exists.\n const defaultOrganizationId =\n withAttach.length === 1\n ? withAttach[0].organization.id\n : organizations.find((org) => org.name === user?.name)?.id\n\n const chosenOrg = await select({\n choices: organizationChoices,\n default: defaultOrganizationId || undefined,\n message: 'Select organization:',\n })\n\n if (chosenOrg === '-new-') {\n return promptAndCreateNewOrganization(user)\n }\n\n return organizations.find((org) => org.id === chosenOrg)\n}\n"],"names":["subdebug","select","spinner","promptForOrganizationName","createOrganization","listOrganizations","getOrganizationChoices","getOrganizationsWithAttachGrantInfo","debug","promptAndCreateNewOrganization","user","organizationName","spin","start","newOrganization","succeed","getOrganization","isUnattended","output","requestedId","organizations","error","fail","org","find","o","id","slug","Error","length","log","withGrantInfo","withAttach","filter","hasAttachGrant","organizationChoices","organization","undefined","defaultOrganizationId","name","chosenOrg","choices","default","message"],"mappings":"AAAA,SAAoCA,QAAQ,QAAO,mBAAkB;AACrE,SAAQC,MAAM,EAAEC,OAAO,QAAO,sBAAqB;AAEnD,SAAQC,yBAAyB,QAAO,6CAA4C;AACpF,SACEC,kBAAkB,EAClBC,iBAAiB,QAEZ,kCAAiC;AACxC,SAAQC,sBAAsB,QAAO,8BAA6B;AAClE,SAAQC,mCAAmC,QAAO,2CAA0C;AAE5F,MAAMC,QAAQR,SAAS;AASvB,MAAMS,iCAAiC,OAAOC;IAC5C,MAAMC,mBAAmB,MAAMR,0BAA0BO;IACzD,MAAME,OAAOV,QAAQ,yBAAyBW,KAAK;IACnD,MAAMC,kBAAkB,MAAMV,mBAAmBO;IACjDC,KAAKG,OAAO;IACZ,OAAOD;AACT;AAEA,OAAO,eAAeE,gBAAgB,EACpCC,YAAY,EACZC,MAAM,EACNC,WAAW,EACXT,IAAI,EACmB;IACvB,8BAA8B;IAC9B,MAAME,OAAOV,QAAQ,yBAAyBW,KAAK;IACnD,IAAIO;IACJ,IAAI;QACFA,gBAAgB,MAAMf;QACtBO,KAAKG,OAAO;IACd,EAAE,OAAOM,OAAO;QACdT,KAAKU,IAAI;QACTd,MAAM,sCAAsCa;QAC5C,MAAMA;IACR;IAEA,4CAA4C;IAC5C,IAAIF,aAAa;QACf,MAAMI,MAAMH,cAAcI,IAAI,CAAC,CAACC,IAAMA,EAAEC,EAAE,KAAKP,eAAeM,EAAEE,IAAI,KAAKR;QACzE,IAAII,KAAK,OAAOA;QAEhB,MAAM,IAAIK,MAAM,CAAC,cAAc,EAAET,YAAY,0CAA0C,CAAC;IAC1F;IAEA,oFAAoF;IACpF,0DAA0D;IAC1D,IAAIC,cAAcS,MAAM,KAAK,GAAG;QAC9BX,OAAOY,GAAG,CAAC;QACX,OAAOrB,+BAA+BC;IACxC;IAEA,mFAAmF;IACnF,mFAAmF;IACnF,wCAAwC;IACxCF,MAAM,CAAC,SAAS,EAAEY,cAAcS,MAAM,CAAC,wCAAwC,CAAC;IAChF,MAAME,gBAAgB,MAAMxB,oCAAoCa;IAChE,MAAMY,aAAaD,cAAcE,MAAM,CAAC,CAAC,EAACC,cAAc,EAAC,GAAKA;IAE9D1B,MAAM,+CAA+CwB,WAAWH,MAAM;IACtE,MAAMM,sBAAsB7B,uBAAuB0B;IAEnD,qDAAqD;IACrD,IAAIf,cAAc;QAChB,qDAAqD;QACrD,OAAOe,WAAWH,MAAM,GAAG,IAAIG,UAAU,CAAC,EAAE,CAACI,YAAY,GAAGC;IAC9D;IAEA,kFAAkF;IAClF,mFAAmF;IACnF,sCAAsC;IACtC,MAAMC,wBACJN,WAAWH,MAAM,KAAK,IAClBG,UAAU,CAAC,EAAE,CAACI,YAAY,CAACV,EAAE,GAC7BN,cAAcI,IAAI,CAAC,CAACD,MAAQA,IAAIgB,IAAI,KAAK7B,MAAM6B,OAAOb;IAE5D,MAAMc,YAAY,MAAMvC,OAAO;QAC7BwC,SAASN;QACTO,SAASJ,yBAAyBD;QAClCM,SAAS;IACX;IAEA,IAAIH,cAAc,SAAS;QACzB,OAAO/B,+BAA+BC;IACxC;IAEA,OAAOU,cAAcI,IAAI,CAAC,CAACD,MAAQA,IAAIG,EAAE,KAAKc;AAChD"}
1
+ {"version":3,"sources":["../../../src/actions/organizations/getOrganization.ts"],"sourcesContent":["import {Output, type SanityOrgUser, subdebug} from '@sanity/cli-core'\nimport {select, spinner} from '@sanity/cli-core/ux'\n\nimport {promptForOrganizationName} from '../../prompts/promptForOrganizationName.js'\nimport {\n createOrganization,\n listOrganizations,\n type ProjectOrganization,\n} from '../../services/organizations.js'\nimport {findOrganizationByUserName} from './findOrganizationByUserName.js'\nimport {getOrganizationChoices} from './getOrganizationChoices.js'\nimport {getOrganizationsWithAttachGrantInfo} from './getOrganizationsWithAttachGrantInfo.js'\n\nconst debug = subdebug('getOrganizationId')\n\ninterface GetOrganizationOptions {\n isUnattended: boolean\n output: Output\n requestedId: string | undefined\n user: SanityOrgUser\n}\n\nconst promptAndCreateNewOrganization = async (user: SanityOrgUser) => {\n const organizationName = await promptForOrganizationName(user)\n const spin = spinner('Creating organization').start()\n const newOrganization = await createOrganization(organizationName)\n spin.succeed()\n return newOrganization\n}\n\nexport async function getOrganization({\n isUnattended,\n output,\n requestedId,\n user,\n}: GetOrganizationOptions) {\n // Get available organizations\n const spin = spinner('Loading organizations').start()\n let organizations: ProjectOrganization[]\n try {\n organizations = await listOrganizations()\n spin.succeed()\n } catch (error) {\n spin.fail()\n debug('Error retrieving organization list', error)\n throw error\n }\n\n // If organization is specified, validate it\n if (requestedId) {\n const org = organizations.find((o) => o.id === requestedId || o.slug === requestedId)\n if (org) return org\n\n throw new Error(`Organization \"${requestedId}\" not found or you don't have access to it`)\n }\n\n // If the user has no organizations, prompt them to create one with the same name as\n // their user, but allow them to customize it if they want\n if (organizations.length === 0) {\n output.log('You need to create an organization to create projects.')\n return promptAndCreateNewOrganization(user)\n }\n\n // If the user has organizations, let them choose from them, but also allow them to\n // create a new one in case they do not have access to any of them, or they want to\n // create a personal/other organization.\n debug(`User has ${organizations.length} organization(s), checking attach access`)\n const withGrantInfo = await getOrganizationsWithAttachGrantInfo(organizations)\n const withAttach = withGrantInfo.filter(({hasAttachGrant}) => hasAttachGrant)\n\n debug('User has attach access to %d organizations.', withAttach.length)\n const organizationChoices = getOrganizationChoices(withGrantInfo)\n\n // In unattended mode use defaults without prompting\n if (isUnattended) {\n // Use the first organization with attach permissions\n return withAttach.length > 0 ? withAttach[0].organization : undefined\n }\n\n // If the user only has a single organization (and they have attach access to it),\n // we'll default to that one. Otherwise, we'll default to the organization with the\n // same name as the user if it exists.\n const defaultOrganizationId =\n withAttach.length === 1\n ? withAttach[0].organization.id\n : findOrganizationByUserName(organizations, user)\n\n const chosenOrg = await select({\n choices: organizationChoices,\n default: defaultOrganizationId || undefined,\n message: 'Select organization:',\n })\n\n if (chosenOrg === '-new-') {\n return promptAndCreateNewOrganization(user)\n }\n\n return organizations.find((org) => org.id === chosenOrg)\n}\n"],"names":["subdebug","select","spinner","promptForOrganizationName","createOrganization","listOrganizations","findOrganizationByUserName","getOrganizationChoices","getOrganizationsWithAttachGrantInfo","debug","promptAndCreateNewOrganization","user","organizationName","spin","start","newOrganization","succeed","getOrganization","isUnattended","output","requestedId","organizations","error","fail","org","find","o","id","slug","Error","length","log","withGrantInfo","withAttach","filter","hasAttachGrant","organizationChoices","organization","undefined","defaultOrganizationId","chosenOrg","choices","default","message"],"mappings":"AAAA,SAAoCA,QAAQ,QAAO,mBAAkB;AACrE,SAAQC,MAAM,EAAEC,OAAO,QAAO,sBAAqB;AAEnD,SAAQC,yBAAyB,QAAO,6CAA4C;AACpF,SACEC,kBAAkB,EAClBC,iBAAiB,QAEZ,kCAAiC;AACxC,SAAQC,0BAA0B,QAAO,kCAAiC;AAC1E,SAAQC,sBAAsB,QAAO,8BAA6B;AAClE,SAAQC,mCAAmC,QAAO,2CAA0C;AAE5F,MAAMC,QAAQT,SAAS;AASvB,MAAMU,iCAAiC,OAAOC;IAC5C,MAAMC,mBAAmB,MAAMT,0BAA0BQ;IACzD,MAAME,OAAOX,QAAQ,yBAAyBY,KAAK;IACnD,MAAMC,kBAAkB,MAAMX,mBAAmBQ;IACjDC,KAAKG,OAAO;IACZ,OAAOD;AACT;AAEA,OAAO,eAAeE,gBAAgB,EACpCC,YAAY,EACZC,MAAM,EACNC,WAAW,EACXT,IAAI,EACmB;IACvB,8BAA8B;IAC9B,MAAME,OAAOX,QAAQ,yBAAyBY,KAAK;IACnD,IAAIO;IACJ,IAAI;QACFA,gBAAgB,MAAMhB;QACtBQ,KAAKG,OAAO;IACd,EAAE,OAAOM,OAAO;QACdT,KAAKU,IAAI;QACTd,MAAM,sCAAsCa;QAC5C,MAAMA;IACR;IAEA,4CAA4C;IAC5C,IAAIF,aAAa;QACf,MAAMI,MAAMH,cAAcI,IAAI,CAAC,CAACC,IAAMA,EAAEC,EAAE,KAAKP,eAAeM,EAAEE,IAAI,KAAKR;QACzE,IAAII,KAAK,OAAOA;QAEhB,MAAM,IAAIK,MAAM,CAAC,cAAc,EAAET,YAAY,0CAA0C,CAAC;IAC1F;IAEA,oFAAoF;IACpF,0DAA0D;IAC1D,IAAIC,cAAcS,MAAM,KAAK,GAAG;QAC9BX,OAAOY,GAAG,CAAC;QACX,OAAOrB,+BAA+BC;IACxC;IAEA,mFAAmF;IACnF,mFAAmF;IACnF,wCAAwC;IACxCF,MAAM,CAAC,SAAS,EAAEY,cAAcS,MAAM,CAAC,wCAAwC,CAAC;IAChF,MAAME,gBAAgB,MAAMxB,oCAAoCa;IAChE,MAAMY,aAAaD,cAAcE,MAAM,CAAC,CAAC,EAACC,cAAc,EAAC,GAAKA;IAE9D1B,MAAM,+CAA+CwB,WAAWH,MAAM;IACtE,MAAMM,sBAAsB7B,uBAAuByB;IAEnD,qDAAqD;IACrD,IAAId,cAAc;QAChB,qDAAqD;QACrD,OAAOe,WAAWH,MAAM,GAAG,IAAIG,UAAU,CAAC,EAAE,CAACI,YAAY,GAAGC;IAC9D;IAEA,kFAAkF;IAClF,mFAAmF;IACnF,sCAAsC;IACtC,MAAMC,wBACJN,WAAWH,MAAM,KAAK,IAClBG,UAAU,CAAC,EAAE,CAACI,YAAY,CAACV,EAAE,GAC7BrB,2BAA2Be,eAAeV;IAEhD,MAAM6B,YAAY,MAAMvC,OAAO;QAC7BwC,SAASL;QACTM,SAASH,yBAAyBD;QAClCK,SAAS;IACX;IAEA,IAAIH,cAAc,SAAS;QACzB,OAAO9B,+BAA+BC;IACxC;IAEA,OAAOU,cAAcI,IAAI,CAAC,CAACD,MAAQA,IAAIG,EAAE,KAAKa;AAChD"}
@@ -1,23 +1,31 @@
1
- export function getOrganizationChoices(withGrantInfo) {
2
- const choices = withGrantInfo.map(({ hasAttachGrant, organization })=>({
3
- disabled: hasAttachGrant ? false : 'Insufficient permissions',
4
- name: `${organization.name} [${organization.id}]`,
5
- value: organization.id
6
- }));
7
- choices.push({
8
- disabled: true,
9
- name: '─────────',
10
- value: '---separator---'
11
- }, {
12
- disabled: false,
13
- name: 'Create new organization',
14
- value: '-new-'
15
- }, {
16
- disabled: true,
17
- name: '─────────',
18
- value: '---separator2---'
1
+ import { Separator } from '@sanity/cli-core/ux';
2
+ function isOrganizationWithGrant(org) {
3
+ return 'hasAttachGrant' in org;
4
+ }
5
+ export function getOrganizationChoices(organizations) {
6
+ const choices = organizations.map((org)=>{
7
+ if (isOrganizationWithGrant(org)) {
8
+ return {
9
+ disabled: org.hasAttachGrant ? false : 'Insufficient permissions',
10
+ name: `${org.organization.name} [${org.organization.id}]`,
11
+ value: org.organization.id
12
+ };
13
+ }
14
+ return {
15
+ name: `${org.name} [${org.id}]`,
16
+ value: org.id
17
+ };
19
18
  });
20
- return choices;
19
+ return [
20
+ {
21
+ name: 'Create new organization',
22
+ value: '-new-'
23
+ },
24
+ ...choices.length > 0 ? [
25
+ new Separator(),
26
+ ...choices
27
+ ] : []
28
+ ];
21
29
  }
22
30
 
23
31
  //# sourceMappingURL=getOrganizationChoices.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/actions/organizations/getOrganizationChoices.ts"],"sourcesContent":["import {type OrganizationWithGrant} from '../../services/organizations.js'\n\nexport function getOrganizationChoices(withGrantInfo: OrganizationWithGrant[]): Array<{\n disabled: boolean | string\n name: string\n value: string\n}> {\n const choices = withGrantInfo.map(({hasAttachGrant, organization}) => ({\n disabled: hasAttachGrant ? false : 'Insufficient permissions',\n name: `${organization.name} [${organization.id}]`,\n value: organization.id,\n }))\n\n choices.push(\n {disabled: true, name: '─────────', value: '---separator---'},\n {disabled: false, name: 'Create new organization', value: '-new-'},\n {disabled: true, name: '─────────', value: '---separator2---'},\n )\n\n return choices\n}\n"],"names":["getOrganizationChoices","withGrantInfo","choices","map","hasAttachGrant","organization","disabled","name","id","value","push"],"mappings":"AAEA,OAAO,SAASA,uBAAuBC,aAAsC;IAK3E,MAAMC,UAAUD,cAAcE,GAAG,CAAC,CAAC,EAACC,cAAc,EAAEC,YAAY,EAAC,GAAM,CAAA;YACrEC,UAAUF,iBAAiB,QAAQ;YACnCG,MAAM,GAAGF,aAAaE,IAAI,CAAC,EAAE,EAAEF,aAAaG,EAAE,CAAC,CAAC,CAAC;YACjDC,OAAOJ,aAAaG,EAAE;QACxB,CAAA;IAEAN,QAAQQ,IAAI,CACV;QAACJ,UAAU;QAAMC,MAAM;QAAaE,OAAO;IAAiB,GAC5D;QAACH,UAAU;QAAOC,MAAM;QAA2BE,OAAO;IAAO,GACjE;QAACH,UAAU;QAAMC,MAAM;QAAaE,OAAO;IAAkB;IAG/D,OAAOP;AACT"}
1
+ {"version":3,"sources":["../../../src/actions/organizations/getOrganizationChoices.ts"],"sourcesContent":["import {Separator} from '@sanity/cli-core/ux'\n\nimport {type OrganizationWithGrant, type ProjectOrganization} from '../../services/organizations.js'\nimport {type OrganizationChoices} from './types.js'\n\nfunction isOrganizationWithGrant(\n org: OrganizationWithGrant | ProjectOrganization,\n): org is OrganizationWithGrant {\n return 'hasAttachGrant' in org\n}\n\nexport function getOrganizationChoices(organizations: ProjectOrganization[]): OrganizationChoices\nexport function getOrganizationChoices(organizations: OrganizationWithGrant[]): OrganizationChoices\nexport function getOrganizationChoices(\n organizations: OrganizationWithGrant[] | ProjectOrganization[],\n): OrganizationChoices {\n const choices = organizations.map((org) => {\n if (isOrganizationWithGrant(org)) {\n return {\n disabled: org.hasAttachGrant ? false : 'Insufficient permissions',\n name: `${org.organization.name} [${org.organization.id}]`,\n value: org.organization.id,\n }\n }\n return {name: `${org.name} [${org.id}]`, value: org.id}\n })\n\n return [\n {name: 'Create new organization', value: '-new-'},\n ...(choices.length > 0 ? [new Separator(), ...choices] : []),\n ]\n}\n"],"names":["Separator","isOrganizationWithGrant","org","getOrganizationChoices","organizations","choices","map","disabled","hasAttachGrant","name","organization","id","value","length"],"mappings":"AAAA,SAAQA,SAAS,QAAO,sBAAqB;AAK7C,SAASC,wBACPC,GAAgD;IAEhD,OAAO,oBAAoBA;AAC7B;AAIA,OAAO,SAASC,uBACdC,aAA8D;IAE9D,MAAMC,UAAUD,cAAcE,GAAG,CAAC,CAACJ;QACjC,IAAID,wBAAwBC,MAAM;YAChC,OAAO;gBACLK,UAAUL,IAAIM,cAAc,GAAG,QAAQ;gBACvCC,MAAM,GAAGP,IAAIQ,YAAY,CAACD,IAAI,CAAC,EAAE,EAAEP,IAAIQ,YAAY,CAACC,EAAE,CAAC,CAAC,CAAC;gBACzDC,OAAOV,IAAIQ,YAAY,CAACC,EAAE;YAC5B;QACF;QACA,OAAO;YAACF,MAAM,GAAGP,IAAIO,IAAI,CAAC,EAAE,EAAEP,IAAIS,EAAE,CAAC,CAAC,CAAC;YAAEC,OAAOV,IAAIS,EAAE;QAAA;IACxD;IAEA,OAAO;QACL;YAACF,MAAM;YAA2BG,OAAO;QAAO;WAC5CP,QAAQQ,MAAM,GAAG,IAAI;YAAC,IAAIb;eAAgBK;SAAQ,GAAG,EAAE;KAC5D;AACH"}
@@ -0,0 +1,3 @@
1
+ export { };
2
+
3
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/actions/organizations/types.ts"],"sourcesContent":["import {Separator} from '@sanity/cli-core/ux'\n\nexport type OrganizationChoices = Array<\n Separator | {disabled?: boolean | string; name: string; value: string}\n>\n"],"names":[],"mappings":"AAEA,WAEC"}
@@ -1,7 +1,6 @@
1
1
  import { getSanityUrl } from '@sanity/cli-core';
2
2
  export function getManageUrl(projectId) {
3
- const sanityUrl = getSanityUrl();
4
- return projectId ? `${sanityUrl}/manage/project/${projectId}` : `${sanityUrl}/manage/`;
3
+ return projectId ? getSanityUrl(`/manage/project/${projectId}`) : getSanityUrl('/manage/');
5
4
  }
6
5
 
7
6
  //# sourceMappingURL=getManageUrl.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/actions/projects/getManageUrl.ts"],"sourcesContent":["import {getSanityUrl} from '@sanity/cli-core'\n\nexport function getManageUrl(projectId: string | undefined): string {\n const sanityUrl = getSanityUrl()\n return projectId ? `${sanityUrl}/manage/project/${projectId}` : `${sanityUrl}/manage/`\n}\n"],"names":["getSanityUrl","getManageUrl","projectId","sanityUrl"],"mappings":"AAAA,SAAQA,YAAY,QAAO,mBAAkB;AAE7C,OAAO,SAASC,aAAaC,SAA6B;IACxD,MAAMC,YAAYH;IAClB,OAAOE,YAAY,GAAGC,UAAU,gBAAgB,EAAED,WAAW,GAAG,GAAGC,UAAU,QAAQ,CAAC;AACxF"}
1
+ {"version":3,"sources":["../../../src/actions/projects/getManageUrl.ts"],"sourcesContent":["import {getSanityUrl} from '@sanity/cli-core'\n\nexport function getManageUrl(projectId: string | undefined): string {\n return projectId ? getSanityUrl(`/manage/project/${projectId}`) : getSanityUrl('/manage/')\n}\n"],"names":["getSanityUrl","getManageUrl","projectId"],"mappings":"AAAA,SAAQA,YAAY,QAAO,mBAAkB;AAE7C,OAAO,SAASC,aAAaC,SAA6B;IACxD,OAAOA,YAAYF,aAAa,CAAC,gBAAgB,EAAEE,WAAW,IAAIF,aAAa;AACjF"}
@@ -1,10 +1,9 @@
1
1
  import { styleText } from 'node:util';
2
+ import { CLIError } from '@oclif/core/errors';
3
+ import { studioWorkerTask } from '@sanity/cli-core';
2
4
  import { deleteSchema } from '../../services/schemas.js';
3
5
  import { isDefined } from '../manifest/schemaTypeHelpers.js';
4
- import { ensureManifestExtractSatisfied } from './utils/manifestExtractor.js';
5
- import { createManifestReader } from './utils/manifestReader.js';
6
6
  import { getDatasetsOutString, getStringList } from './utils/schemaStoreOutStrings.js';
7
- import { filterLogReadProjectIdMismatch } from './utils/schemaStoreValidation.js';
8
7
  // Native implementation instead of lodash/uniq
9
8
  function uniq(array) {
10
9
  return [
@@ -21,31 +20,17 @@ class DeleteIdError extends Error {
21
20
  this.dataset = dataset;
22
21
  }
23
22
  }
24
- /**
25
- * Deletes all stored schemas matching --ids in workspace datasets.
26
- *
27
- * Workspaces are determined by on-disk manifest file – not directly from sanity.config.
28
- * All schema store actions require a manifest to exist, so we regenerate it by default.
29
- * Manifest generation can be optionally disabled with --no-manifest-extract.
30
- * In this case the command uses and existing file or throws when missing.
31
- */ export async function deleteSchemaAction(options) {
32
- const { dataset, extractManifest, ids, manifestDir, output, projectId, verbose, workDir } = options;
33
- if (!await ensureManifestExtractSatisfied({
34
- extractManifest,
35
- manifestDir,
36
- output,
37
- schemaRequired: true,
38
- workDir
39
- })) {
40
- return 'failure';
41
- }
42
- const manifest = await createManifestReader({
43
- manifestDir,
44
- output,
45
- workDir
46
- }).getManifest();
47
- const workspaces = manifest.workspaces.filter((workspace)=>!dataset || workspace.dataset === dataset).filter((workspace)=>filterLogReadProjectIdMismatch(workspace, projectId, output));
48
- const datasets = uniq(workspaces.map((w)=>w.dataset));
23
+ export async function deleteSchemaAction(options) {
24
+ const { configPath, dataset, ids, output, projectId, verbose, workDir } = options;
25
+ const projectDatasets = await studioWorkerTask(new URL('uniqueWorkspaces.worker.js', import.meta.url), {
26
+ name: 'uniqueWorkspaces',
27
+ studioRootPath: workDir,
28
+ workerData: {
29
+ configPath,
30
+ dataset
31
+ }
32
+ });
33
+ const datasets = projectDatasets.map((w)=>w.dataset);
49
34
  const results = await Promise.allSettled(datasets.flatMap((targetDataset)=>{
50
35
  return ids.map(async ({ schemaId })=>{
51
36
  try {
@@ -83,7 +68,7 @@ class DeleteIdError extends Error {
83
68
  if (success) {
84
69
  output.log(`Successfully deleted ${uniqueDeletedSchemaIds.length}/${ids.length} schemas`);
85
70
  } else {
86
- output.error([
71
+ throw new CLIError([
87
72
  `Deleted ${uniqueDeletedSchemaIds.length}/${ids.length} schemas.`,
88
73
  deletedIds.length > 0 ? `Successfully deleted ids:\n${deletedIds.map(({ dataset: targetDataset, schemaId })=>`- "${schemaId}" (in ${getDatasetsOutString([
89
74
  targetDataset
@@ -95,7 +80,6 @@ class DeleteIdError extends Error {
95
80
  ] : []
96
81
  ].filter((item)=>isDefined(item)).join('\n'));
97
82
  }
98
- return success ? 'success' : 'failure';
99
83
  }
100
84
 
101
85
  //# sourceMappingURL=deleteSchemaAction.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/actions/schema/deleteSchemaAction.ts"],"sourcesContent":["import {styleText} from 'node:util'\n\nimport {type Output} from '@sanity/cli-core'\n\nimport {deleteSchema} from '../../services/schemas.js'\nimport {isDefined} from '../manifest/schemaTypeHelpers.js'\nimport {type SchemaStoreActionResult} from './schemaStoreTypes.js'\nimport {ensureManifestExtractSatisfied} from './utils/manifestExtractor.js'\nimport {createManifestReader} from './utils/manifestReader.js'\nimport {getDatasetsOutString, getStringList} from './utils/schemaStoreOutStrings.js'\nimport {\n filterLogReadProjectIdMismatch,\n type WorkspaceSchemaId,\n} from './utils/schemaStoreValidation.js'\n\n// Native implementation instead of lodash/uniq\nfunction uniq<T>(array: T[]): T[] {\n return [...new Set(array)]\n}\n\ninterface DeleteSchemasOptions {\n extractManifest: boolean\n ids: WorkspaceSchemaId[]\n manifestDir: string\n output: Output\n projectId: string\n verbose: boolean\n workDir: string\n\n dataset?: string\n}\n\ninterface DeleteResult {\n dataset: string\n deleted: boolean\n schemaId: string\n}\n\nclass DeleteIdError extends Error {\n public dataset: string\n public id: string\n constructor(id: string, dataset: string, options?: ErrorOptions) {\n super((options?.cause as {message?: string})?.message, options)\n this.name = 'DeleteIdError'\n this.id = id\n this.dataset = dataset\n }\n}\n\n/**\n * Deletes all stored schemas matching --ids in workspace datasets.\n *\n * Workspaces are determined by on-disk manifest file – not directly from sanity.config.\n * All schema store actions require a manifest to exist, so we regenerate it by default.\n * Manifest generation can be optionally disabled with --no-manifest-extract.\n * In this case the command uses and existing file or throws when missing.\n */\nexport async function deleteSchemaAction(\n options: DeleteSchemasOptions,\n): Promise<SchemaStoreActionResult> {\n const {dataset, extractManifest, ids, manifestDir, output, projectId, verbose, workDir} = options\n\n if (\n !(await ensureManifestExtractSatisfied({\n extractManifest,\n manifestDir,\n output,\n schemaRequired: true,\n workDir,\n }))\n ) {\n return 'failure'\n }\n\n const manifest = await createManifestReader({\n manifestDir,\n output,\n workDir,\n }).getManifest()\n\n const workspaces = manifest.workspaces\n .filter((workspace) => !dataset || workspace.dataset === dataset)\n .filter((workspace) => filterLogReadProjectIdMismatch(workspace, projectId, output))\n\n const datasets = uniq(workspaces.map((w) => w.dataset))\n\n const results = await Promise.allSettled(\n datasets.flatMap((targetDataset: string) => {\n return ids.map(async ({schemaId}): Promise<DeleteResult> => {\n try {\n const deletedSchema = await deleteSchema(targetDataset, projectId, schemaId)\n return {dataset: targetDataset, deleted: deletedSchema.deleted, schemaId}\n } catch (err) {\n throw new DeleteIdError(schemaId, targetDataset, {cause: err})\n }\n })\n }),\n )\n\n const deletedIds = results\n .filter((r): r is PromiseFulfilledResult<DeleteResult> => r.status === 'fulfilled')\n .filter((r) => r.value.deleted)\n .map((r) => r.value)\n\n const notFound = uniq(\n results\n .filter((r): r is PromiseFulfilledResult<DeleteResult> => r.status === 'fulfilled')\n .filter((r) => !r.value.deleted)\n .filter((r) => !deletedIds.map(({schemaId}) => schemaId).includes(r.value.schemaId))\n .map((r) => r.value.schemaId),\n )\n\n const deleteFailureIds = uniq(\n results\n .filter((r) => r.status === 'rejected')\n .map((result) => {\n const error = result.reason\n if (error instanceof DeleteIdError) {\n output.warn(\n styleText(\n 'red',\n [\n `Failed to delete schema \"${error.id}\" in dataset \"${error.dataset}\":`,\n error.message,\n ].join('\\n'),\n ),\n )\n if (verbose) output.warn(error)\n return error.id\n }\n //hubris inc: given the try-catch wrapping the full promise \"this should never happen\"\n throw error\n }),\n )\n\n // Compare unique schema IDs deleted vs requested (not total deletions across datasets)\n const uniqueDeletedSchemaIds = uniq(deletedIds.map(({schemaId}) => schemaId))\n const success = uniqueDeletedSchemaIds.length === ids.length\n if (success) {\n output.log(`Successfully deleted ${uniqueDeletedSchemaIds.length}/${ids.length} schemas`)\n } else {\n output.error(\n [\n `Deleted ${uniqueDeletedSchemaIds.length}/${ids.length} schemas.`,\n deletedIds.length > 0\n ? `Successfully deleted ids:\\n${deletedIds\n .map(\n ({dataset: targetDataset, schemaId}) =>\n `- \"${schemaId}\" (in ${getDatasetsOutString([targetDataset])})`,\n )\n .join('\\n')}`\n : undefined,\n notFound.length > 0\n ? `Ids not found in ${getDatasetsOutString(datasets)}:\\n${getStringList(notFound)}`\n : undefined,\n ...(deleteFailureIds.length > 0\n ? [`Failed to delete ids:\\n${getStringList(deleteFailureIds)}`, 'Check logs for errors.']\n : []),\n ]\n .filter((item) => isDefined(item))\n .join('\\n'),\n )\n }\n\n return success ? 'success' : 'failure'\n}\n"],"names":["styleText","deleteSchema","isDefined","ensureManifestExtractSatisfied","createManifestReader","getDatasetsOutString","getStringList","filterLogReadProjectIdMismatch","uniq","array","Set","DeleteIdError","Error","dataset","id","options","cause","message","name","deleteSchemaAction","extractManifest","ids","manifestDir","output","projectId","verbose","workDir","schemaRequired","manifest","getManifest","workspaces","filter","workspace","datasets","map","w","results","Promise","allSettled","flatMap","targetDataset","schemaId","deletedSchema","deleted","err","deletedIds","r","status","value","notFound","includes","deleteFailureIds","result","error","reason","warn","join","uniqueDeletedSchemaIds","success","length","log","undefined","item"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../src/actions/schema/deleteSchemaAction.ts"],"sourcesContent":["import {styleText} from 'node:util'\n\nimport {CLIError} from '@oclif/core/errors'\nimport {type Output, studioWorkerTask} from '@sanity/cli-core'\nimport {type Workspace} from 'sanity'\n\nimport {deleteSchema} from '../../services/schemas.js'\nimport {isDefined} from '../manifest/schemaTypeHelpers.js'\nimport {type UniqWorkspaceWorkerData} from './types.js'\nimport {getDatasetsOutString, getStringList} from './utils/schemaStoreOutStrings.js'\nimport {type WorkspaceSchemaId} from './utils/schemaStoreValidation.js'\n\n// Native implementation instead of lodash/uniq\nfunction uniq<T>(array: T[]): T[] {\n return [...new Set(array)]\n}\n\ninterface DeleteSchemasOptions {\n configPath: string\n ids: WorkspaceSchemaId[]\n output: Output\n projectId: string\n verbose: boolean\n workDir: string\n\n dataset?: string\n}\n\ninterface DeleteResult {\n dataset: string\n deleted: boolean\n schemaId: string\n}\n\nclass DeleteIdError extends Error {\n public dataset: string\n public id: string\n constructor(id: string, dataset: string, options?: ErrorOptions) {\n super((options?.cause as {message?: string})?.message, options)\n this.name = 'DeleteIdError'\n this.id = id\n this.dataset = dataset\n }\n}\n\nexport async function deleteSchemaAction(options: DeleteSchemasOptions): Promise<void> {\n const {configPath, dataset, ids, output, projectId, verbose, workDir} = options\n\n const projectDatasets = await studioWorkerTask<(Workspace & {key: string})[]>(\n new URL('uniqueWorkspaces.worker.js', import.meta.url),\n {\n name: 'uniqueWorkspaces',\n studioRootPath: workDir,\n workerData: {configPath, dataset} satisfies UniqWorkspaceWorkerData,\n },\n )\n\n const datasets = projectDatasets.map((w) => w.dataset)\n\n const results = await Promise.allSettled(\n datasets.flatMap((targetDataset: string) => {\n return ids.map(async ({schemaId}): Promise<DeleteResult> => {\n try {\n const deletedSchema = await deleteSchema(targetDataset, projectId, schemaId)\n return {dataset: targetDataset, deleted: deletedSchema.deleted, schemaId}\n } catch (err) {\n throw new DeleteIdError(schemaId, targetDataset, {cause: err})\n }\n })\n }),\n )\n\n const deletedIds = results\n .filter((r): r is PromiseFulfilledResult<DeleteResult> => r.status === 'fulfilled')\n .filter((r) => r.value.deleted)\n .map((r) => r.value)\n\n const notFound = uniq(\n results\n .filter((r): r is PromiseFulfilledResult<DeleteResult> => r.status === 'fulfilled')\n .filter((r) => !r.value.deleted)\n .filter((r) => !deletedIds.map(({schemaId}) => schemaId).includes(r.value.schemaId))\n .map((r) => r.value.schemaId),\n )\n\n const deleteFailureIds = uniq(\n results\n .filter((r) => r.status === 'rejected')\n .map((result) => {\n const error = result.reason\n if (error instanceof DeleteIdError) {\n output.warn(\n styleText(\n 'red',\n [\n `Failed to delete schema \"${error.id}\" in dataset \"${error.dataset}\":`,\n error.message,\n ].join('\\n'),\n ),\n )\n if (verbose) output.warn(error)\n return error.id\n }\n //hubris inc: given the try-catch wrapping the full promise \"this should never happen\"\n throw error\n }),\n )\n\n // Compare unique schema IDs deleted vs requested (not total deletions across datasets)\n const uniqueDeletedSchemaIds = uniq(deletedIds.map(({schemaId}) => schemaId))\n const success = uniqueDeletedSchemaIds.length === ids.length\n if (success) {\n output.log(`Successfully deleted ${uniqueDeletedSchemaIds.length}/${ids.length} schemas`)\n } else {\n throw new CLIError(\n [\n `Deleted ${uniqueDeletedSchemaIds.length}/${ids.length} schemas.`,\n deletedIds.length > 0\n ? `Successfully deleted ids:\\n${deletedIds\n .map(\n ({dataset: targetDataset, schemaId}) =>\n `- \"${schemaId}\" (in ${getDatasetsOutString([targetDataset])})`,\n )\n .join('\\n')}`\n : undefined,\n notFound.length > 0\n ? `Ids not found in ${getDatasetsOutString(datasets)}:\\n${getStringList(notFound)}`\n : undefined,\n ...(deleteFailureIds.length > 0\n ? [`Failed to delete ids:\\n${getStringList(deleteFailureIds)}`, 'Check logs for errors.']\n : []),\n ]\n .filter((item) => isDefined(item))\n .join('\\n'),\n )\n }\n}\n"],"names":["styleText","CLIError","studioWorkerTask","deleteSchema","isDefined","getDatasetsOutString","getStringList","uniq","array","Set","DeleteIdError","Error","dataset","id","options","cause","message","name","deleteSchemaAction","configPath","ids","output","projectId","verbose","workDir","projectDatasets","URL","url","studioRootPath","workerData","datasets","map","w","results","Promise","allSettled","flatMap","targetDataset","schemaId","deletedSchema","deleted","err","deletedIds","filter","r","status","value","notFound","includes","deleteFailureIds","result","error","reason","warn","join","uniqueDeletedSchemaIds","success","length","log","undefined","item"],"mappings":"AAAA,SAAQA,SAAS,QAAO,YAAW;AAEnC,SAAQC,QAAQ,QAAO,qBAAoB;AAC3C,SAAqBC,gBAAgB,QAAO,mBAAkB;AAG9D,SAAQC,YAAY,QAAO,4BAA2B;AACtD,SAAQC,SAAS,QAAO,mCAAkC;AAE1D,SAAQC,oBAAoB,EAAEC,aAAa,QAAO,mCAAkC;AAGpF,+CAA+C;AAC/C,SAASC,KAAQC,KAAU;IACzB,OAAO;WAAI,IAAIC,IAAID;KAAO;AAC5B;AAmBA,MAAME,sBAAsBC;IACnBC,QAAe;IACfC,GAAU;IACjB,YAAYA,EAAU,EAAED,OAAe,EAAEE,OAAsB,CAAE;QAC/D,KAAK,CAAEA,SAASC,OAA8BC,SAASF;QACvD,IAAI,CAACG,IAAI,GAAG;QACZ,IAAI,CAACJ,EAAE,GAAGA;QACV,IAAI,CAACD,OAAO,GAAGA;IACjB;AACF;AAEA,OAAO,eAAeM,mBAAmBJ,OAA6B;IACpE,MAAM,EAACK,UAAU,EAAEP,OAAO,EAAEQ,GAAG,EAAEC,MAAM,EAAEC,SAAS,EAAEC,OAAO,EAAEC,OAAO,EAAC,GAAGV;IAExE,MAAMW,kBAAkB,MAAMvB,iBAC5B,IAAIwB,IAAI,8BAA8B,YAAYC,GAAG,GACrD;QACEV,MAAM;QACNW,gBAAgBJ;QAChBK,YAAY;YAACV;YAAYP;QAAO;IAClC;IAGF,MAAMkB,WAAWL,gBAAgBM,GAAG,CAAC,CAACC,IAAMA,EAAEpB,OAAO;IAErD,MAAMqB,UAAU,MAAMC,QAAQC,UAAU,CACtCL,SAASM,OAAO,CAAC,CAACC;QAChB,OAAOjB,IAAIW,GAAG,CAAC,OAAO,EAACO,QAAQ,EAAC;YAC9B,IAAI;gBACF,MAAMC,gBAAgB,MAAMpC,aAAakC,eAAef,WAAWgB;gBACnE,OAAO;oBAAC1B,SAASyB;oBAAeG,SAASD,cAAcC,OAAO;oBAAEF;gBAAQ;YAC1E,EAAE,OAAOG,KAAK;gBACZ,MAAM,IAAI/B,cAAc4B,UAAUD,eAAe;oBAACtB,OAAO0B;gBAAG;YAC9D;QACF;IACF;IAGF,MAAMC,aAAaT,QAChBU,MAAM,CAAC,CAACC,IAAiDA,EAAEC,MAAM,KAAK,aACtEF,MAAM,CAAC,CAACC,IAAMA,EAAEE,KAAK,CAACN,OAAO,EAC7BT,GAAG,CAAC,CAACa,IAAMA,EAAEE,KAAK;IAErB,MAAMC,WAAWxC,KACf0B,QACGU,MAAM,CAAC,CAACC,IAAiDA,EAAEC,MAAM,KAAK,aACtEF,MAAM,CAAC,CAACC,IAAM,CAACA,EAAEE,KAAK,CAACN,OAAO,EAC9BG,MAAM,CAAC,CAACC,IAAM,CAACF,WAAWX,GAAG,CAAC,CAAC,EAACO,QAAQ,EAAC,GAAKA,UAAUU,QAAQ,CAACJ,EAAEE,KAAK,CAACR,QAAQ,GACjFP,GAAG,CAAC,CAACa,IAAMA,EAAEE,KAAK,CAACR,QAAQ;IAGhC,MAAMW,mBAAmB1C,KACvB0B,QACGU,MAAM,CAAC,CAACC,IAAMA,EAAEC,MAAM,KAAK,YAC3Bd,GAAG,CAAC,CAACmB;QACJ,MAAMC,QAAQD,OAAOE,MAAM;QAC3B,IAAID,iBAAiBzC,eAAe;YAClCW,OAAOgC,IAAI,CACTrD,UACE,OACA;gBACE,CAAC,yBAAyB,EAAEmD,MAAMtC,EAAE,CAAC,cAAc,EAAEsC,MAAMvC,OAAO,CAAC,EAAE,CAAC;gBACtEuC,MAAMnC,OAAO;aACd,CAACsC,IAAI,CAAC;YAGX,IAAI/B,SAASF,OAAOgC,IAAI,CAACF;YACzB,OAAOA,MAAMtC,EAAE;QACjB;QACA,sFAAsF;QACtF,MAAMsC;IACR;IAGJ,uFAAuF;IACvF,MAAMI,yBAAyBhD,KAAKmC,WAAWX,GAAG,CAAC,CAAC,EAACO,QAAQ,EAAC,GAAKA;IACnE,MAAMkB,UAAUD,uBAAuBE,MAAM,KAAKrC,IAAIqC,MAAM;IAC5D,IAAID,SAAS;QACXnC,OAAOqC,GAAG,CAAC,CAAC,qBAAqB,EAAEH,uBAAuBE,MAAM,CAAC,CAAC,EAAErC,IAAIqC,MAAM,CAAC,QAAQ,CAAC;IAC1F,OAAO;QACL,MAAM,IAAIxD,SACR;YACE,CAAC,QAAQ,EAAEsD,uBAAuBE,MAAM,CAAC,CAAC,EAAErC,IAAIqC,MAAM,CAAC,SAAS,CAAC;YACjEf,WAAWe,MAAM,GAAG,IAChB,CAAC,2BAA2B,EAAEf,WAC3BX,GAAG,CACF,CAAC,EAACnB,SAASyB,aAAa,EAAEC,QAAQ,EAAC,GACjC,CAAC,GAAG,EAAEA,SAAS,MAAM,EAAEjC,qBAAqB;oBAACgC;iBAAc,EAAE,CAAC,CAAC,EAElEiB,IAAI,CAAC,OAAO,GACfK;YACJZ,SAASU,MAAM,GAAG,IACd,CAAC,iBAAiB,EAAEpD,qBAAqByB,UAAU,GAAG,EAAExB,cAAcyC,WAAW,GACjFY;eACAV,iBAAiBQ,MAAM,GAAG,IAC1B;gBAAC,CAAC,uBAAuB,EAAEnD,cAAc2C,mBAAmB;gBAAE;aAAyB,GACvF,EAAE;SACP,CACEN,MAAM,CAAC,CAACiB,OAASxD,UAAUwD,OAC3BN,IAAI,CAAC;IAEZ;AACF"}
@@ -1,98 +1,29 @@
1
- import { styleText } from 'node:util';
2
- import { updateSchemas } from '../../services/schemas.js';
3
- import { CURRENT_WORKSPACE_SCHEMA_VERSION } from '../manifest/types.js';
4
- import { schemasDeployDebug } from './utils/debug.js';
5
- import { ensureManifestExtractSatisfied } from './utils/manifestExtractor.js';
6
- import { createManifestReader } from './utils/manifestReader.js';
7
- import { FlagValidationError, SCHEMA_PERMISSION_HELP_TEXT } from './utils/schemaStoreValidation.js';
8
- import { getWorkspaceSchemaId } from './utils/workspaceSchemaId.js';
1
+ import { studioWorkerTask } from '@sanity/cli-core';
2
+ import { updateWorkspacesSchemas } from './updateWorkspaceSchema.js';
3
+ import { SchemaExtractionError } from './utils/SchemaExtractionError.js';
9
4
  export async function deploySchemas(options) {
10
- const { extractManifest, manifestDir, manifestSafe, output, schemaRequired, tag, verbose, workDir, workspaceName } = options;
11
- if (!await ensureManifestExtractSatisfied({
12
- extractManifest,
13
- manifestDir,
14
- manifestSafe,
15
- output,
16
- schemaRequired,
17
- workDir
18
- })) {
19
- return 'failure';
20
- }
21
- try {
22
- const manifestReader = await createManifestReader({
23
- manifestDir,
24
- output,
5
+ const { tag, verbose, workDir, workspaceName } = options;
6
+ const result = await studioWorkerTask(new URL('extractSanityWorkspace.worker.js', import.meta.url), {
7
+ name: 'extractSanityWorkspace',
8
+ studioRootPath: workDir,
9
+ workerData: {
10
+ configPath: workDir,
25
11
  workDir
26
- });
27
- const manifest = await manifestReader.getManifest();
28
- const workspaces = manifest.workspaces.filter((workspace)=>!workspaceName || workspace.name === workspaceName);
29
- if (workspaces.length === 0) {
30
- const error = workspaceName ? new FlagValidationError(`Found no workspaces named "${workspaceName}"`) : new Error('Workspace array in manifest is empty.');
31
- throw error;
32
- }
33
- const updateSchema = getUpdateSchema({
34
- manifestReader,
35
- output,
36
- tag,
37
- verbose
38
- });
39
- /* Known caveat: we _don't_ rollback failed operations or partial success */ const results = await Promise.allSettled(workspaces.map(async (workspace)=>{
40
- await updateSchema(workspace);
41
- }));
42
- const fulfilledUpdates = results.filter((result)=>result.status === 'fulfilled');
43
- const rejectedUpdates = results.filter((result)=>result.status === 'rejected');
44
- if (rejectedUpdates.length > 0) {
45
- throw new Error(`Failed to deploy ${rejectedUpdates.length}/${workspaces.length} schemas. Successfully deployed ${fulfilledUpdates.length}/${workspaces.length} schemas.`);
46
- }
47
- output.log(`Deployed ${fulfilledUpdates.length}/${workspaces.length} schemas`);
48
- return 'success';
49
- } catch (err) {
50
- if (schemaRequired || err instanceof FlagValidationError) {
51
- output.error(err.message);
52
- } else {
53
- output.error(`↳ Error when storing schemas:\n ${err.message}`);
54
12
  }
55
- schemasDeployDebug('Error updating schemas', err.message);
56
- return 'failure';
57
- } finally{
58
- output.log(`${styleText('gray', '↳ List deployed schemas with:')} ${styleText('cyan', 'sanity schema list')}`);
13
+ });
14
+ if (result.type === 'error') {
15
+ throw new SchemaExtractionError(result.error, result.validation);
59
16
  }
60
- }
61
- function getUpdateSchema(args) {
62
- const { manifestReader, output, tag, verbose } = args;
63
- return async (workspace)=>{
64
- const { dataset, projectId } = workspace;
65
- const { idWarning, safeBaseId: id } = getWorkspaceSchemaId({
66
- tag,
67
- workspaceName: workspace.name
68
- });
69
- if (idWarning) output.warn(idWarning);
70
- try {
71
- const schema = await manifestReader.getWorkspaceSchema(workspace.name);
72
- await updateSchemas(dataset, projectId, [
73
- {
74
- // the API will stringify the schema – we send as JSON
75
- schema,
76
- tag,
77
- version: CURRENT_WORKSPACE_SCHEMA_VERSION,
78
- workspace: {
79
- name: workspace.name,
80
- title: workspace.title
81
- }
82
- }
83
- ]);
84
- if (verbose) {
85
- output.log(styleText('gray', `↳ schemaId: ${id}, projectId: ${projectId}, dataset: ${dataset}`));
86
- }
87
- } catch (err) {
88
- if ('statusCode' in err && err?.statusCode === 401) {
89
- output.warn(`↳ No permissions to write schema for workspace "${workspace.name}" in dataset "${workspace.dataset}". ${SCHEMA_PERMISSION_HELP_TEXT}:\n ${styleText('red', `${err.message}`)}`);
90
- } else {
91
- output.error(`↳ Error deploying schema for workspace "${workspace.name}":\n ${styleText('red', `${err.message}`)}`);
92
- }
93
- throw err;
94
- }
95
- };
17
+ const workspaces = result.workspaces.filter((workspace)=>!workspaceName || workspace.name === workspaceName);
18
+ if (workspaces.length === 0) {
19
+ const error = workspaceName ? new Error(`Found no workspaces named "${workspaceName}"`) : new Error('No workspaces found');
20
+ throw error;
21
+ }
22
+ await updateWorkspacesSchemas({
23
+ tag,
24
+ verbose,
25
+ workspaces
26
+ });
96
27
  }
97
28
 
98
29
  //# sourceMappingURL=deploySchemas.js.map