@sanity/cli 6.0.0-alpha.4 → 6.0.0-alpha.6

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 (608) hide show
  1. package/dist/actions/dataset/create.d.ts +49 -0
  2. package/dist/actions/dataset/create.js +48 -0
  3. package/dist/actions/dataset/create.js.map +1 -0
  4. package/dist/actions/dataset/determineDatasetAclMode.d.ts +37 -0
  5. package/dist/actions/dataset/determineDatasetAclMode.js +36 -0
  6. package/dist/actions/dataset/determineDatasetAclMode.js.map +1 -0
  7. package/dist/actions/debug/gatherDebugInfo.js +15 -21
  8. package/dist/actions/debug/gatherDebugInfo.js.map +1 -1
  9. package/dist/actions/debug/types.d.ts +0 -2
  10. package/dist/actions/debug/types.js.map +1 -1
  11. package/dist/actions/deploy/deployApp.js +13 -0
  12. package/dist/actions/deploy/deployApp.js.map +1 -1
  13. package/dist/actions/dev/startStudioDevServer.js +3 -8
  14. package/dist/actions/dev/startStudioDevServer.js.map +1 -1
  15. package/dist/actions/dev/types.d.ts +1 -3
  16. package/dist/actions/dev/types.js.map +1 -1
  17. package/dist/actions/documents/validate.d.ts +0 -2
  18. package/dist/actions/documents/validate.js +21 -1
  19. package/dist/actions/documents/validate.js.map +1 -1
  20. package/dist/actions/exec/execScript.js +1 -1
  21. package/dist/actions/exec/execScript.js.map +1 -1
  22. package/dist/actions/graphql/getGraphQLAPIs.js +1 -1
  23. package/dist/actions/graphql/getGraphQLAPIs.js.map +1 -1
  24. package/dist/actions/init/remoteTemplate.js +1 -1
  25. package/dist/actions/init/remoteTemplate.js.map +1 -1
  26. package/dist/actions/manifest/extractAppManifest.d.ts +20 -0
  27. package/dist/actions/manifest/extractAppManifest.js +51 -0
  28. package/dist/actions/manifest/extractAppManifest.js.map +1 -0
  29. package/dist/actions/manifest/extractManifest.js +2 -5
  30. package/dist/actions/manifest/extractManifest.js.map +1 -1
  31. package/dist/actions/manifest/types.d.ts +6 -1
  32. package/dist/actions/manifest/types.js.map +1 -1
  33. package/dist/actions/media/importAspects.js +2 -1
  34. package/dist/actions/media/importAspects.js.map +1 -1
  35. package/dist/actions/schema/deleteSchemaAction.d.ts +13 -5
  36. package/dist/actions/schema/deleteSchemaAction.js +12 -17
  37. package/dist/actions/schema/deleteSchemaAction.js.map +1 -1
  38. package/dist/actions/schema/deploySchemas.d.ts +15 -0
  39. package/dist/actions/schema/deploySchemas.js +98 -0
  40. package/dist/actions/schema/deploySchemas.js.map +1 -0
  41. package/dist/actions/schema/listSchemas.d.ts +12 -0
  42. package/dist/actions/schema/listSchemas.js +119 -0
  43. package/dist/actions/schema/listSchemas.js.map +1 -0
  44. package/dist/actions/schema/schemaStoreTypes.d.ts +0 -11
  45. package/dist/actions/schema/schemaStoreTypes.js.map +1 -1
  46. package/dist/actions/schema/utils/debug.d.ts +2 -0
  47. package/dist/actions/schema/utils/debug.js +5 -0
  48. package/dist/actions/schema/utils/debug.js.map +1 -0
  49. package/dist/actions/schema/utils/manifestExtractor.d.ts +3 -8
  50. package/dist/actions/schema/utils/manifestExtractor.js +12 -17
  51. package/dist/actions/schema/utils/manifestExtractor.js.map +1 -1
  52. package/dist/actions/schema/utils/manifestReader.d.ts +2 -9
  53. package/dist/actions/schema/utils/manifestReader.js +6 -12
  54. package/dist/actions/schema/utils/manifestReader.js.map +1 -1
  55. package/dist/actions/schema/utils/schemaStoreOutStrings.d.ts +0 -1
  56. package/dist/actions/schema/utils/schemaStoreOutStrings.js +1 -1
  57. package/dist/actions/schema/utils/schemaStoreOutStrings.js.map +1 -1
  58. package/dist/actions/schema/utils/schemaStoreValidation.d.ts +10 -62
  59. package/dist/actions/schema/utils/schemaStoreValidation.js +38 -125
  60. package/dist/actions/schema/utils/schemaStoreValidation.js.map +1 -1
  61. package/dist/actions/schema/utils/uniqByProjectIdDataset.d.ts +14 -0
  62. package/dist/actions/schema/utils/uniqByProjectIdDataset.js +9 -0
  63. package/dist/actions/schema/utils/uniqByProjectIdDataset.js.map +1 -0
  64. package/dist/actions/users/getMembersForProject.d.ts +1 -3
  65. package/dist/actions/users/getMembersForProject.js +6 -17
  66. package/dist/actions/users/getMembersForProject.js.map +1 -1
  67. package/dist/actions/users/types.d.ts +0 -11
  68. package/dist/actions/users/types.js.map +1 -1
  69. package/dist/commands/backup/disable.js +5 -11
  70. package/dist/commands/backup/disable.js.map +1 -1
  71. package/dist/commands/backup/enable.js +5 -11
  72. package/dist/commands/backup/enable.js.map +1 -1
  73. package/dist/commands/backup/list.js +7 -8
  74. package/dist/commands/backup/list.js.map +1 -1
  75. package/dist/commands/cors/add.js +5 -13
  76. package/dist/commands/cors/add.js.map +1 -1
  77. package/dist/commands/cors/delete.js +7 -15
  78. package/dist/commands/cors/delete.js.map +1 -1
  79. package/dist/commands/cors/list.js +2 -10
  80. package/dist/commands/cors/list.js.map +1 -1
  81. package/dist/commands/dataset/create.d.ts +0 -2
  82. package/dist/commands/dataset/create.js +8 -54
  83. package/dist/commands/dataset/create.js.map +1 -1
  84. package/dist/commands/dataset/export.js +4 -4
  85. package/dist/commands/dataset/export.js.map +1 -1
  86. package/dist/commands/debug.js +5 -9
  87. package/dist/commands/debug.js.map +1 -1
  88. package/dist/commands/dev.js +0 -1
  89. package/dist/commands/dev.js.map +1 -1
  90. package/dist/commands/documents/create.d.ts +1 -0
  91. package/dist/commands/documents/create.js +10 -9
  92. package/dist/commands/documents/create.js.map +1 -1
  93. package/dist/commands/documents/delete.js +2 -3
  94. package/dist/commands/documents/delete.js.map +1 -1
  95. package/dist/commands/documents/get.js +2 -3
  96. package/dist/commands/documents/get.js.map +1 -1
  97. package/dist/commands/documents/query.js +2 -3
  98. package/dist/commands/documents/query.js.map +1 -1
  99. package/dist/commands/documents/validate.js +0 -20
  100. package/dist/commands/documents/validate.js.map +1 -1
  101. package/dist/commands/graphql/list.js +2 -2
  102. package/dist/commands/graphql/list.js.map +1 -1
  103. package/dist/commands/graphql/undeploy.js +4 -9
  104. package/dist/commands/graphql/undeploy.js.map +1 -1
  105. package/dist/commands/hook/create.js +2 -6
  106. package/dist/commands/hook/create.js.map +1 -1
  107. package/dist/commands/hook/delete.js +5 -17
  108. package/dist/commands/hook/delete.js.map +1 -1
  109. package/dist/commands/hook/list.js +2 -8
  110. package/dist/commands/hook/list.js.map +1 -1
  111. package/dist/commands/init.d.ts +6 -1
  112. package/dist/commands/init.js +358 -20
  113. package/dist/commands/init.js.map +1 -1
  114. package/dist/commands/manifest/extract.js +7 -8
  115. package/dist/commands/manifest/extract.js.map +1 -1
  116. package/dist/commands/media/export.js +2 -2
  117. package/dist/commands/media/export.js.map +1 -1
  118. package/dist/commands/media/import.js +2 -2
  119. package/dist/commands/media/import.js.map +1 -1
  120. package/dist/commands/projects/list.js +2 -6
  121. package/dist/commands/projects/list.js.map +1 -1
  122. package/dist/commands/schema/delete.d.ts +1 -1
  123. package/dist/commands/schema/delete.js +20 -23
  124. package/dist/commands/schema/delete.js.map +1 -1
  125. package/dist/commands/schema/deploy.d.ts +16 -0
  126. package/dist/commands/schema/deploy.js +98 -0
  127. package/dist/commands/schema/deploy.js.map +1 -0
  128. package/dist/commands/schema/list.d.ts +15 -0
  129. package/dist/commands/schema/list.js +104 -0
  130. package/dist/commands/schema/list.js.map +1 -0
  131. package/dist/commands/tokens/add.js +3 -5
  132. package/dist/commands/tokens/add.js.map +1 -1
  133. package/dist/commands/users/invite.js +6 -17
  134. package/dist/commands/users/invite.js.map +1 -1
  135. package/dist/commands/users/list.js +4 -7
  136. package/dist/commands/users/list.js.map +1 -1
  137. package/dist/config/createCliConfig.d.ts +13 -4
  138. package/dist/prompts/init/promptForTypescript.d.ts +2 -0
  139. package/dist/prompts/init/promptForTypescript.js +15 -0
  140. package/dist/prompts/init/promptForTypescript.js.map +1 -0
  141. package/dist/prompts/promptForDatasetAclMode.d.ts +9 -0
  142. package/dist/prompts/promptForDatasetAclMode.js +27 -0
  143. package/dist/prompts/promptForDatasetAclMode.js.map +1 -0
  144. package/dist/prompts/promptForDatasetName.d.ts +1 -1
  145. package/dist/prompts/promptForDatasetName.js +4 -1
  146. package/dist/prompts/promptForDatasetName.js.map +1 -1
  147. package/dist/services/backup.d.ts +8 -0
  148. package/dist/services/backup.js +19 -0
  149. package/dist/services/backup.js.map +1 -1
  150. package/dist/services/cors.d.ts +23 -0
  151. package/dist/services/cors.js +38 -0
  152. package/dist/services/cors.js.map +1 -0
  153. package/dist/services/graphql.d.ts +7 -0
  154. package/dist/services/graphql.js +11 -0
  155. package/dist/services/graphql.js.map +1 -1
  156. package/dist/services/hooks.d.ts +2 -0
  157. package/dist/services/hooks.js +19 -0
  158. package/dist/services/hooks.js.map +1 -1
  159. package/dist/services/organizations.d.ts +4 -2
  160. package/dist/services/organizations.js +3 -2
  161. package/dist/services/organizations.js.map +1 -1
  162. package/dist/services/projects.d.ts +11 -0
  163. package/dist/services/projects.js +41 -0
  164. package/dist/services/projects.js.map +1 -1
  165. package/dist/services/schemas.d.ts +4 -0
  166. package/dist/services/schemas.js +40 -0
  167. package/dist/services/schemas.js.map +1 -0
  168. package/dist/services/user.d.ts +13 -0
  169. package/dist/services/user.js +27 -3
  170. package/dist/services/user.js.map +1 -1
  171. package/dist/services/userApplications.d.ts +3 -1
  172. package/dist/services/userApplications.js +5 -1
  173. package/dist/services/userApplications.js.map +1 -1
  174. package/dist/util/errorMessages.d.ts +1 -0
  175. package/dist/util/errorMessages.js +1 -0
  176. package/dist/util/errorMessages.js.map +1 -1
  177. package/dist/util/getCliVersion.js +1 -1
  178. package/dist/util/getCliVersion.js.map +1 -1
  179. package/dist/util/readPackageJson.d.ts +1 -15
  180. package/dist/util/readPackageJson.js +1 -1
  181. package/dist/util/readPackageJson.js.map +1 -1
  182. package/dist/util/uniqBy.d.ts +1 -0
  183. package/dist/util/uniqBy.js +14 -0
  184. package/dist/util/uniqBy.js.map +1 -0
  185. package/oclif.manifest.json +284 -139
  186. package/package.json +36 -33
  187. package/templates/app-quickstart/src/App.css +20 -0
  188. package/templates/app-quickstart/src/App.tsx +25 -0
  189. package/templates/app-quickstart/src/ExampleComponent.css +90 -0
  190. package/templates/app-quickstart/src/ExampleComponent.tsx +37 -0
  191. package/templates/app-sanity-ui/src/App.tsx +34 -0
  192. package/templates/app-sanity-ui/src/ExampleComponent.tsx +34 -0
  193. package/templates/app-sanity-ui/src/SanityUI.tsx +23 -0
  194. package/templates/blog/README.md +11 -0
  195. package/templates/blog/schemaTypes/author.js +50 -0
  196. package/templates/blog/schemaTypes/blockContent.js +67 -0
  197. package/templates/blog/schemaTypes/category.js +19 -0
  198. package/templates/blog/schemaTypes/index.js +6 -0
  199. package/templates/blog/schemaTypes/post.js +65 -0
  200. package/templates/blog/static/.gitkeep +1 -0
  201. package/templates/clean/README.md +9 -0
  202. package/templates/clean/schemaTypes/index.js +1 -0
  203. package/templates/clean/static/.gitkeep +1 -0
  204. package/templates/ecommerce/README.md +11 -0
  205. package/templates/ecommerce/plugins/.gitkeep +1 -0
  206. package/templates/ecommerce/plugins/barcode-input/BarcodeInput.js +62 -0
  207. package/templates/ecommerce/plugins/barcode-input/index.js +9 -0
  208. package/templates/ecommerce/plugins/barcode-input/schemaType.js +60 -0
  209. package/templates/ecommerce/schemaTypes/blockContent.js +67 -0
  210. package/templates/ecommerce/schemaTypes/category.js +39 -0
  211. package/templates/ecommerce/schemaTypes/index.js +23 -0
  212. package/templates/ecommerce/schemaTypes/locale/localeBlockContent.js +19 -0
  213. package/templates/ecommerce/schemaTypes/locale/localeString.js +19 -0
  214. package/templates/ecommerce/schemaTypes/locale/localeText.js +19 -0
  215. package/templates/ecommerce/schemaTypes/locale/supportedLanguages.js +5 -0
  216. package/templates/ecommerce/schemaTypes/product.js +83 -0
  217. package/templates/ecommerce/schemaTypes/productVariant.js +52 -0
  218. package/templates/ecommerce/schemaTypes/vendor.js +39 -0
  219. package/templates/ecommerce/static/.gitkeep +1 -0
  220. package/templates/get-started/README.md +9 -0
  221. package/templates/get-started/plugins/.gitkeep +1 -0
  222. package/templates/get-started/plugins/sanity-plugin-tutorial/CustomDefaultLayout.tsx +16 -0
  223. package/templates/get-started/plugins/sanity-plugin-tutorial/GetStartedTutorial.tsx +104 -0
  224. package/templates/get-started/plugins/sanity-plugin-tutorial/index.ts +11 -0
  225. package/templates/get-started/schemaTypes/index.ts +1 -0
  226. package/templates/get-started/static/.gitkeep +1 -0
  227. package/templates/moviedb/README.md +10 -0
  228. package/templates/moviedb/schemaTypes/blockContent.js +67 -0
  229. package/templates/moviedb/schemaTypes/castMember.js +37 -0
  230. package/templates/moviedb/schemaTypes/crewMember.js +52 -0
  231. package/templates/moviedb/schemaTypes/index.js +22 -0
  232. package/templates/moviedb/schemaTypes/movie.js +85 -0
  233. package/templates/moviedb/schemaTypes/person.js +37 -0
  234. package/templates/moviedb/schemaTypes/plotSummaries.js +20 -0
  235. package/templates/moviedb/schemaTypes/plotSummary.js +24 -0
  236. package/templates/moviedb/schemaTypes/screening.js +81 -0
  237. package/templates/moviedb/static/.gitkeep +1 -0
  238. package/templates/quickstart/README.md +9 -0
  239. package/templates/quickstart/schemaTypes/index.js +1 -0
  240. package/templates/quickstart/static/.gitkeep +1 -0
  241. package/templates/shared/gitignore.txt +29 -0
  242. package/templates/shared/tsconfig.json +17 -0
  243. package/templates/shopify/README.md +85 -0
  244. package/templates/shopify/components/hotspots/ProductTooltip.tsx +38 -0
  245. package/templates/shopify/components/icons/Shopify.tsx +20 -0
  246. package/templates/shopify/components/inputs/CollectionHidden.tsx +23 -0
  247. package/templates/shopify/components/inputs/PlaceholderString.tsx +20 -0
  248. package/templates/shopify/components/inputs/ProductHidden.tsx +64 -0
  249. package/templates/shopify/components/inputs/ProductVariantHidden.tsx +24 -0
  250. package/templates/shopify/components/inputs/ProxyString.tsx +32 -0
  251. package/templates/shopify/components/media/ColorTheme.tsx +38 -0
  252. package/templates/shopify/components/media/ShopifyDocumentStatus.tsx +82 -0
  253. package/templates/shopify/components/studio/Navbar.tsx +29 -0
  254. package/templates/shopify/constants.ts +61 -0
  255. package/templates/shopify/docs/features.md +158 -0
  256. package/templates/shopify/plugins/customDocumentActions/index.ts +55 -0
  257. package/templates/shopify/plugins/customDocumentActions/shopifyDelete.tsx +144 -0
  258. package/templates/shopify/plugins/customDocumentActions/shopifyLink.ts +39 -0
  259. package/templates/shopify/plugins/customDocumentActions/types.ts +14 -0
  260. package/templates/shopify/schemaTypes/documents/collection.tsx +142 -0
  261. package/templates/shopify/schemaTypes/documents/colorTheme.tsx +44 -0
  262. package/templates/shopify/schemaTypes/documents/page.ts +70 -0
  263. package/templates/shopify/schemaTypes/documents/product.tsx +132 -0
  264. package/templates/shopify/schemaTypes/documents/productVariant.tsx +67 -0
  265. package/templates/shopify/schemaTypes/index.ts +108 -0
  266. package/templates/shopify/schemaTypes/objects/collection/collectionGroupType.ts +27 -0
  267. package/templates/shopify/schemaTypes/objects/collection/collectionLinksType.ts +16 -0
  268. package/templates/shopify/schemaTypes/objects/customProductOption/customProductOptionColorObjectType.tsx +48 -0
  269. package/templates/shopify/schemaTypes/objects/customProductOption/customProductOptionColorType.tsx +50 -0
  270. package/templates/shopify/schemaTypes/objects/customProductOption/customProductOptionSizeObjectType.ts +40 -0
  271. package/templates/shopify/schemaTypes/objects/customProductOption/customProductOptionSizeType.ts +49 -0
  272. package/templates/shopify/schemaTypes/objects/global/footerType.ts +22 -0
  273. package/templates/shopify/schemaTypes/objects/global/menuLinksType.ts +21 -0
  274. package/templates/shopify/schemaTypes/objects/global/menuType.ts +17 -0
  275. package/templates/shopify/schemaTypes/objects/global/notFoundPageType.ts +37 -0
  276. package/templates/shopify/schemaTypes/objects/hotspot/imageWithProductHotspotsType.ts +48 -0
  277. package/templates/shopify/schemaTypes/objects/hotspot/productHotspotsType.tsx +17 -0
  278. package/templates/shopify/schemaTypes/objects/hotspot/spotType.tsx +60 -0
  279. package/templates/shopify/schemaTypes/objects/link/linkEmailType.tsx +34 -0
  280. package/templates/shopify/schemaTypes/objects/link/linkExternalType.tsx +37 -0
  281. package/templates/shopify/schemaTypes/objects/link/linkInternalType.tsx +33 -0
  282. package/templates/shopify/schemaTypes/objects/link/linkProductType.tsx +60 -0
  283. package/templates/shopify/schemaTypes/objects/module/accordionGroupType.ts +33 -0
  284. package/templates/shopify/schemaTypes/objects/module/accordionType.ts +28 -0
  285. package/templates/shopify/schemaTypes/objects/module/callToActionType.tsx +85 -0
  286. package/templates/shopify/schemaTypes/objects/module/calloutType.ts +38 -0
  287. package/templates/shopify/schemaTypes/objects/module/collectionReferenceType.tsx +47 -0
  288. package/templates/shopify/schemaTypes/objects/module/gridItemType.ts +41 -0
  289. package/templates/shopify/schemaTypes/objects/module/gridType.ts +28 -0
  290. package/templates/shopify/schemaTypes/objects/module/heroType.tsx +40 -0
  291. package/templates/shopify/schemaTypes/objects/module/imageCallToActionType.tsx +19 -0
  292. package/templates/shopify/schemaTypes/objects/module/imageFeatureType.ts +80 -0
  293. package/templates/shopify/schemaTypes/objects/module/imageFeaturesType.tsx +51 -0
  294. package/templates/shopify/schemaTypes/objects/module/instagramType.ts +35 -0
  295. package/templates/shopify/schemaTypes/objects/module/productFeaturesType.tsx +50 -0
  296. package/templates/shopify/schemaTypes/objects/module/productReferenceType.tsx +42 -0
  297. package/templates/shopify/schemaTypes/objects/seoType.ts +31 -0
  298. package/templates/shopify/schemaTypes/objects/shopify/collectionRuleType.tsx +37 -0
  299. package/templates/shopify/schemaTypes/objects/shopify/inventoryType.ts +25 -0
  300. package/templates/shopify/schemaTypes/objects/shopify/optionType.tsx +31 -0
  301. package/templates/shopify/schemaTypes/objects/shopify/placeholderStringType.ts +11 -0
  302. package/templates/shopify/schemaTypes/objects/shopify/priceRangeType.ts +20 -0
  303. package/templates/shopify/schemaTypes/objects/shopify/productWithVariantType.tsx +142 -0
  304. package/templates/shopify/schemaTypes/objects/shopify/proxyStringType.ts +12 -0
  305. package/templates/shopify/schemaTypes/objects/shopify/shopType.ts +15 -0
  306. package/templates/shopify/schemaTypes/objects/shopify/shopifyCollectionType.ts +84 -0
  307. package/templates/shopify/schemaTypes/objects/shopify/shopifyProductType.ts +131 -0
  308. package/templates/shopify/schemaTypes/objects/shopify/shopifyProductVariantType.ts +121 -0
  309. package/templates/shopify/schemaTypes/portableText/portableTextSimpleType.tsx +45 -0
  310. package/templates/shopify/schemaTypes/portableText/portableTextType.tsx +52 -0
  311. package/templates/shopify/schemaTypes/singletons/homeType.ts +49 -0
  312. package/templates/shopify/schemaTypes/singletons/settingsType.ts +96 -0
  313. package/templates/shopify/static/.gitkeep +1 -0
  314. package/templates/shopify/structure/collectionStructure.ts +9 -0
  315. package/templates/shopify/structure/colorThemeStructure.ts +9 -0
  316. package/templates/shopify/structure/homeStructure.ts +9 -0
  317. package/templates/shopify/structure/index.ts +57 -0
  318. package/templates/shopify/structure/pageStructure.ts +11 -0
  319. package/templates/shopify/structure/productStructure.ts +51 -0
  320. package/templates/shopify/structure/settingStructure.ts +9 -0
  321. package/templates/shopify/utils/blocksToText.ts +20 -0
  322. package/templates/shopify/utils/defineStructure.ts +11 -0
  323. package/templates/shopify/utils/getPriceRange.ts +24 -0
  324. package/templates/shopify/utils/shopifyUrls.ts +22 -0
  325. package/templates/shopify/utils/validateSlug.ts +18 -0
  326. package/templates/shopify-online-storefront/README.md +54 -0
  327. package/templates/shopify-online-storefront/components/icons/Shopify.tsx +22 -0
  328. package/templates/shopify-online-storefront/components/inputs/CollectionHidden.tsx +23 -0
  329. package/templates/shopify-online-storefront/components/inputs/PlaceholderString.tsx +25 -0
  330. package/templates/shopify-online-storefront/components/inputs/ProductHidden.tsx +66 -0
  331. package/templates/shopify-online-storefront/components/inputs/ProductVariantHidden.tsx +25 -0
  332. package/templates/shopify-online-storefront/components/inputs/ProxyString.tsx +38 -0
  333. package/templates/shopify-online-storefront/components/media/ShopifyDocumentStatus.tsx +83 -0
  334. package/templates/shopify-online-storefront/constants.ts +18 -0
  335. package/templates/shopify-online-storefront/plugins/shopifyDocumentActions/index.ts +45 -0
  336. package/templates/shopify-online-storefront/plugins/shopifyDocumentActions/shopifyDelete.tsx +144 -0
  337. package/templates/shopify-online-storefront/plugins/shopifyDocumentActions/shopifyLink.ts +39 -0
  338. package/templates/shopify-online-storefront/plugins/shopifyDocumentActions/types.ts +14 -0
  339. package/templates/shopify-online-storefront/schemaTypes/blocks/blockContent.ts +32 -0
  340. package/templates/shopify-online-storefront/schemaTypes/documents/collection.tsx +83 -0
  341. package/templates/shopify-online-storefront/schemaTypes/documents/product.tsx +102 -0
  342. package/templates/shopify-online-storefront/schemaTypes/documents/productVariant.tsx +82 -0
  343. package/templates/shopify-online-storefront/schemaTypes/index.ts +43 -0
  344. package/templates/shopify-online-storefront/schemaTypes/objects/accordion.ts +31 -0
  345. package/templates/shopify-online-storefront/schemaTypes/objects/accordionGroup.ts +35 -0
  346. package/templates/shopify-online-storefront/schemaTypes/objects/callout.ts +40 -0
  347. package/templates/shopify-online-storefront/schemaTypes/objects/inventory.ts +30 -0
  348. package/templates/shopify-online-storefront/schemaTypes/objects/option.ts +30 -0
  349. package/templates/shopify-online-storefront/schemaTypes/objects/priceRange.ts +22 -0
  350. package/templates/shopify-online-storefront/schemaTypes/objects/proxyString.ts +11 -0
  351. package/templates/shopify-online-storefront/schemaTypes/objects/shopifyCollection.ts +109 -0
  352. package/templates/shopify-online-storefront/schemaTypes/objects/shopifyCollectionRule.tsx +45 -0
  353. package/templates/shopify-online-storefront/schemaTypes/objects/shopifyProduct.ts +165 -0
  354. package/templates/shopify-online-storefront/schemaTypes/objects/shopifyProductVariant.ts +151 -0
  355. package/templates/shopify-online-storefront/structure/collectionStructure.ts +9 -0
  356. package/templates/shopify-online-storefront/structure/index.ts +37 -0
  357. package/templates/shopify-online-storefront/structure/productStructure.ts +35 -0
  358. package/templates/shopify-online-storefront/utils/defineStructure.ts +11 -0
  359. package/templates/shopify-online-storefront/utils/getPriceRange.ts +24 -0
  360. package/templates/shopify-online-storefront/utils/shopifyUrls.ts +22 -0
  361. package/dist/actions/build/__tests__/buildApp.test.js +0 -367
  362. package/dist/actions/build/__tests__/buildApp.test.js.map +0 -1
  363. package/dist/actions/build/__tests__/buildStudio.test.js +0 -561
  364. package/dist/actions/build/__tests__/buildStudio.test.js.map +0 -1
  365. package/dist/actions/build/__tests__/checkRequiredDependencies.test.js +0 -233
  366. package/dist/actions/build/__tests__/checkRequiredDependencies.test.js.map +0 -1
  367. package/dist/actions/build/__tests__/checkStudioDependencyVersions.test.js +0 -414
  368. package/dist/actions/build/__tests__/checkStudioDependencyVersions.test.js.map +0 -1
  369. package/dist/actions/build/__tests__/determineBasePath.test.js +0 -24
  370. package/dist/actions/build/__tests__/determineBasePath.test.js.map +0 -1
  371. package/dist/actions/build/__tests__/getAutoUpdatesImportMap.test.js +0 -109
  372. package/dist/actions/build/__tests__/getAutoUpdatesImportMap.test.js.map +0 -1
  373. package/dist/actions/build/__tests__/getViteConfig.test.js +0 -493
  374. package/dist/actions/build/__tests__/getViteConfig.test.js.map +0 -1
  375. package/dist/actions/build/__tests__/renderDocument.test.js +0 -278
  376. package/dist/actions/build/__tests__/renderDocument.test.js.map +0 -1
  377. package/dist/actions/build/__tests__/shouldAutoUpdate.test.js +0 -153
  378. package/dist/actions/build/__tests__/shouldAutoUpdate.test.js.map +0 -1
  379. package/dist/actions/build/renderDocumentWorker/__tests__/renderDocumentWorker.test.js +0 -657
  380. package/dist/actions/build/renderDocumentWorker/__tests__/renderDocumentWorker.test.js.map +0 -1
  381. package/dist/actions/cors/constants.d.ts +0 -1
  382. package/dist/actions/cors/constants.js +0 -3
  383. package/dist/actions/cors/constants.js.map +0 -1
  384. package/dist/actions/cors/types.d.ts +0 -9
  385. package/dist/actions/cors/types.js +0 -3
  386. package/dist/actions/cors/types.js.map +0 -1
  387. package/dist/actions/dataset/__tests__/validateDatasetName.test.js +0 -182
  388. package/dist/actions/dataset/__tests__/validateDatasetName.test.js.map +0 -1
  389. package/dist/actions/deploy/__tests__/checkDir.test.js +0 -120
  390. package/dist/actions/deploy/__tests__/checkDir.test.js.map +0 -1
  391. package/dist/actions/docs/__tests__/normalizeDocsPath.test.js +0 -16
  392. package/dist/actions/docs/__tests__/normalizeDocsPath.test.js.map +0 -1
  393. package/dist/actions/documents/validation/reporters/prettyReporter/__tests__/formatDocumentValidation.test.js +0 -124
  394. package/dist/actions/documents/validation/reporters/prettyReporter/__tests__/formatDocumentValidation.test.js.map +0 -1
  395. package/dist/actions/graphql/__tests__/getGraphQLAPIs.test.js +0 -274
  396. package/dist/actions/graphql/__tests__/getGraphQLAPIs.test.js.map +0 -1
  397. package/dist/actions/media/__tests__/importMedia.test.js +0 -182
  398. package/dist/actions/media/__tests__/importMedia.test.js.map +0 -1
  399. package/dist/actions/schema/__tests__/deleteSchemaAction.test.js +0 -294
  400. package/dist/actions/schema/__tests__/deleteSchemaAction.test.js.map +0 -1
  401. package/dist/actions/schema/__tests__/formatSchemaValidation.test.js +0 -174
  402. package/dist/actions/schema/__tests__/formatSchemaValidation.test.js.map +0 -1
  403. package/dist/actions/schema/__tests__/validateAction.test.js +0 -281
  404. package/dist/actions/schema/__tests__/validateAction.test.js.map +0 -1
  405. package/dist/actions/schema/schemaStoreConstants.d.ts +0 -1
  406. package/dist/actions/schema/schemaStoreConstants.js +0 -4
  407. package/dist/actions/schema/schemaStoreConstants.js.map +0 -1
  408. package/dist/actions/schema/utils/schemaActionHelpers.d.ts +0 -1
  409. package/dist/actions/schema/utils/schemaActionHelpers.js +0 -5
  410. package/dist/actions/schema/utils/schemaActionHelpers.js.map +0 -1
  411. package/dist/actions/schema/utils/schemaApiClient.d.ts +0 -6
  412. package/dist/actions/schema/utils/schemaApiClient.js +0 -17
  413. package/dist/actions/schema/utils/schemaApiClient.js.map +0 -1
  414. package/dist/actions/telemetry/__tests__/fetchTelemetryConsent.test.js +0 -27
  415. package/dist/actions/telemetry/__tests__/fetchTelemetryConsent.test.js.map +0 -1
  416. package/dist/actions/users/__tests__/validateEmail.test.js +0 -16
  417. package/dist/actions/users/__tests__/validateEmail.test.js.map +0 -1
  418. package/dist/actions/users/apiVersion.d.ts +0 -6
  419. package/dist/actions/users/apiVersion.js +0 -7
  420. package/dist/actions/users/apiVersion.js.map +0 -1
  421. package/dist/commands/__tests__/blueprints.test.js +0 -54
  422. package/dist/commands/__tests__/blueprints.test.js.map +0 -1
  423. package/dist/commands/__tests__/build.test.js +0 -132
  424. package/dist/commands/__tests__/build.test.js.map +0 -1
  425. package/dist/commands/__tests__/codemod.test.js +0 -271
  426. package/dist/commands/__tests__/codemod.test.js.map +0 -1
  427. package/dist/commands/__tests__/debug.test.js +0 -697
  428. package/dist/commands/__tests__/debug.test.js.map +0 -1
  429. package/dist/commands/__tests__/deploy.test.js +0 -1913
  430. package/dist/commands/__tests__/deploy.test.js.map +0 -1
  431. package/dist/commands/__tests__/dev.test.js +0 -410
  432. package/dist/commands/__tests__/dev.test.js.map +0 -1
  433. package/dist/commands/__tests__/exec.test.js +0 -207
  434. package/dist/commands/__tests__/exec.test.js.map +0 -1
  435. package/dist/commands/__tests__/init/init.authentication.test.js +0 -60
  436. package/dist/commands/__tests__/init/init.authentication.test.js.map +0 -1
  437. package/dist/commands/__tests__/init/init.create-new-project.test.js +0 -196
  438. package/dist/commands/__tests__/init/init.create-new-project.test.js.map +0 -1
  439. package/dist/commands/__tests__/init/init.plan.test.js +0 -220
  440. package/dist/commands/__tests__/init/init.plan.test.js.map +0 -1
  441. package/dist/commands/__tests__/init/init.setup.test.js +0 -279
  442. package/dist/commands/__tests__/init/init.setup.test.js.map +0 -1
  443. package/dist/commands/__tests__/install.test.js +0 -258
  444. package/dist/commands/__tests__/install.test.js.map +0 -1
  445. package/dist/commands/__tests__/learn.test.js +0 -29
  446. package/dist/commands/__tests__/learn.test.js.map +0 -1
  447. package/dist/commands/__tests__/logout.test.js +0 -88
  448. package/dist/commands/__tests__/logout.test.js.map +0 -1
  449. package/dist/commands/__tests__/manage.test.js +0 -105
  450. package/dist/commands/__tests__/manage.test.js.map +0 -1
  451. package/dist/commands/__tests__/migration.test.js +0 -119
  452. package/dist/commands/__tests__/migration.test.js.map +0 -1
  453. package/dist/commands/__tests__/preview.test.js +0 -261
  454. package/dist/commands/__tests__/preview.test.js.map +0 -1
  455. package/dist/commands/__tests__/start.test.js +0 -253
  456. package/dist/commands/__tests__/start.test.js.map +0 -1
  457. package/dist/commands/__tests__/undeploy.test.js +0 -382
  458. package/dist/commands/__tests__/undeploy.test.js.map +0 -1
  459. package/dist/commands/__tests__/versions.test.js +0 -134
  460. package/dist/commands/__tests__/versions.test.js.map +0 -1
  461. package/dist/commands/backup/__tests__/disable.test.js +0 -207
  462. package/dist/commands/backup/__tests__/disable.test.js.map +0 -1
  463. package/dist/commands/backup/__tests__/download.test.js +0 -679
  464. package/dist/commands/backup/__tests__/download.test.js.map +0 -1
  465. package/dist/commands/backup/__tests__/enable.test.js +0 -317
  466. package/dist/commands/backup/__tests__/enable.test.js.map +0 -1
  467. package/dist/commands/backup/__tests__/list.test.js +0 -321
  468. package/dist/commands/backup/__tests__/list.test.js.map +0 -1
  469. package/dist/commands/cors/__tests__/add.test.js +0 -346
  470. package/dist/commands/cors/__tests__/add.test.js.map +0 -1
  471. package/dist/commands/cors/__tests__/delete.test.js +0 -293
  472. package/dist/commands/cors/__tests__/delete.test.js.map +0 -1
  473. package/dist/commands/cors/__tests__/list.test.js +0 -218
  474. package/dist/commands/cors/__tests__/list.test.js.map +0 -1
  475. package/dist/commands/dataset/__tests__/copy.test.js +0 -520
  476. package/dist/commands/dataset/__tests__/copy.test.js.map +0 -1
  477. package/dist/commands/dataset/__tests__/create.test.js +0 -312
  478. package/dist/commands/dataset/__tests__/create.test.js.map +0 -1
  479. package/dist/commands/dataset/__tests__/delete.test.js +0 -224
  480. package/dist/commands/dataset/__tests__/delete.test.js.map +0 -1
  481. package/dist/commands/dataset/__tests__/export.test.js +0 -561
  482. package/dist/commands/dataset/__tests__/export.test.js.map +0 -1
  483. package/dist/commands/dataset/__tests__/import.test.js +0 -53
  484. package/dist/commands/dataset/__tests__/import.test.js.map +0 -1
  485. package/dist/commands/dataset/__tests__/list.test.js +0 -174
  486. package/dist/commands/dataset/__tests__/list.test.js.map +0 -1
  487. package/dist/commands/dataset/alias/__tests__/create.test.js +0 -299
  488. package/dist/commands/dataset/alias/__tests__/create.test.js.map +0 -1
  489. package/dist/commands/dataset/alias/__tests__/delete.test.js +0 -236
  490. package/dist/commands/dataset/alias/__tests__/delete.test.js.map +0 -1
  491. package/dist/commands/dataset/alias/__tests__/link.test.js +0 -336
  492. package/dist/commands/dataset/alias/__tests__/link.test.js.map +0 -1
  493. package/dist/commands/dataset/alias/__tests__/unlink.test.js +0 -298
  494. package/dist/commands/dataset/alias/__tests__/unlink.test.js.map +0 -1
  495. package/dist/commands/dataset/visibility/__tests__/get.test.js +0 -147
  496. package/dist/commands/dataset/visibility/__tests__/get.test.js.map +0 -1
  497. package/dist/commands/dataset/visibility/__tests__/set.test.js +0 -245
  498. package/dist/commands/dataset/visibility/__tests__/set.test.js.map +0 -1
  499. package/dist/commands/docs/__tests__/browse.test.js +0 -29
  500. package/dist/commands/docs/__tests__/browse.test.js.map +0 -1
  501. package/dist/commands/docs/__tests__/read.test.js +0 -78
  502. package/dist/commands/docs/__tests__/read.test.js.map +0 -1
  503. package/dist/commands/docs/__tests__/search.test.js +0 -254
  504. package/dist/commands/docs/__tests__/search.test.js.map +0 -1
  505. package/dist/commands/documents/__tests__/create.test.js +0 -967
  506. package/dist/commands/documents/__tests__/create.test.js.map +0 -1
  507. package/dist/commands/documents/__tests__/delete.test.js +0 -268
  508. package/dist/commands/documents/__tests__/delete.test.js.map +0 -1
  509. package/dist/commands/documents/__tests__/get.test.js +0 -209
  510. package/dist/commands/documents/__tests__/get.test.js.map +0 -1
  511. package/dist/commands/documents/__tests__/query.test.js +0 -405
  512. package/dist/commands/documents/__tests__/query.test.js.map +0 -1
  513. package/dist/commands/documents/__tests__/validate.test.js +0 -226
  514. package/dist/commands/documents/__tests__/validate.test.js.map +0 -1
  515. package/dist/commands/graphql/__tests__/list.test.js +0 -228
  516. package/dist/commands/graphql/__tests__/list.test.js.map +0 -1
  517. package/dist/commands/graphql/__tests__/undeploy.test.js +0 -384
  518. package/dist/commands/graphql/__tests__/undeploy.test.js.map +0 -1
  519. package/dist/commands/hook/__tests__/attempt.test.js +0 -260
  520. package/dist/commands/hook/__tests__/attempt.test.js.map +0 -1
  521. package/dist/commands/hook/__tests__/create.test.js +0 -121
  522. package/dist/commands/hook/__tests__/create.test.js.map +0 -1
  523. package/dist/commands/hook/__tests__/delete.test.js +0 -220
  524. package/dist/commands/hook/__tests__/delete.test.js.map +0 -1
  525. package/dist/commands/hook/__tests__/list.test.js +0 -138
  526. package/dist/commands/hook/__tests__/list.test.js.map +0 -1
  527. package/dist/commands/hook/__tests__/logs.test.js +0 -770
  528. package/dist/commands/hook/__tests__/logs.test.js.map +0 -1
  529. package/dist/commands/manifest/__tests__/extract.test.js +0 -123
  530. package/dist/commands/manifest/__tests__/extract.test.js.map +0 -1
  531. package/dist/commands/mcp/__tests__/configure.test.js +0 -397
  532. package/dist/commands/mcp/__tests__/configure.test.js.map +0 -1
  533. package/dist/commands/media/__tests__/create-aspect.test.js +0 -160
  534. package/dist/commands/media/__tests__/create-aspect.test.js.map +0 -1
  535. package/dist/commands/media/__tests__/delete-aspect.test.js +0 -333
  536. package/dist/commands/media/__tests__/delete-aspect.test.js.map +0 -1
  537. package/dist/commands/media/__tests__/deploy-aspect.test.js +0 -632
  538. package/dist/commands/media/__tests__/deploy-aspect.test.js.map +0 -1
  539. package/dist/commands/media/__tests__/export.test.js +0 -398
  540. package/dist/commands/media/__tests__/export.test.js.map +0 -1
  541. package/dist/commands/media/__tests__/import.test.js +0 -281
  542. package/dist/commands/media/__tests__/import.test.js.map +0 -1
  543. package/dist/commands/openapi/__tests__/get.test.js +0 -149
  544. package/dist/commands/openapi/__tests__/get.test.js.map +0 -1
  545. package/dist/commands/openapi/__tests__/list.test.js +0 -113
  546. package/dist/commands/openapi/__tests__/list.test.js.map +0 -1
  547. package/dist/commands/projects/__tests__/list.test.js +0 -153
  548. package/dist/commands/projects/__tests__/list.test.js.map +0 -1
  549. package/dist/commands/schema/__tests__/delete.test.js +0 -209
  550. package/dist/commands/schema/__tests__/delete.test.js.map +0 -1
  551. package/dist/commands/schema/__tests__/extract.test.js +0 -113
  552. package/dist/commands/schema/__tests__/extract.test.js.map +0 -1
  553. package/dist/commands/schema/__tests__/validate.test.js +0 -104
  554. package/dist/commands/schema/__tests__/validate.test.js.map +0 -1
  555. package/dist/commands/telemetry/__tests__/disable.test.js +0 -145
  556. package/dist/commands/telemetry/__tests__/disable.test.js.map +0 -1
  557. package/dist/commands/telemetry/__tests__/enable.test.js +0 -131
  558. package/dist/commands/telemetry/__tests__/enable.test.js.map +0 -1
  559. package/dist/commands/telemetry/__tests__/status.test.js +0 -153
  560. package/dist/commands/telemetry/__tests__/status.test.js.map +0 -1
  561. package/dist/commands/tokens/__tests__/add.test.js +0 -420
  562. package/dist/commands/tokens/__tests__/add.test.js.map +0 -1
  563. package/dist/commands/tokens/__tests__/delete.test.js +0 -375
  564. package/dist/commands/tokens/__tests__/delete.test.js.map +0 -1
  565. package/dist/commands/tokens/__tests__/list.test.js +0 -368
  566. package/dist/commands/tokens/__tests__/list.test.js.map +0 -1
  567. package/dist/commands/users/__tests__/invite.test.js +0 -341
  568. package/dist/commands/users/__tests__/invite.test.js.map +0 -1
  569. package/dist/commands/users/__tests__/list.test.js +0 -401
  570. package/dist/commands/users/__tests__/list.test.js.map +0 -1
  571. package/dist/hooks/prerun/__tests__/setupTelemetry.test.js +0 -77
  572. package/dist/hooks/prerun/__tests__/setupTelemetry.test.js.map +0 -1
  573. package/dist/services/__tests__/datasetAliases.test.js +0 -131
  574. package/dist/services/__tests__/datasetAliases.test.js.map +0 -1
  575. package/dist/services/__tests__/datasets.test.js +0 -436
  576. package/dist/services/__tests__/datasets.test.js.map +0 -1
  577. package/dist/services/__tests__/graphql.test.js +0 -43
  578. package/dist/services/__tests__/graphql.test.js.map +0 -1
  579. package/dist/services/__tests__/mediaLibraries.test.js +0 -88
  580. package/dist/services/__tests__/mediaLibraries.test.js.map +0 -1
  581. package/dist/services/__tests__/projects.test.js +0 -41
  582. package/dist/services/__tests__/projects.test.js.map +0 -1
  583. package/dist/services/__tests__/userApplications.test.js +0 -113
  584. package/dist/services/__tests__/userApplications.test.js.map +0 -1
  585. package/dist/util/__tests__/appId.test.js +0 -31
  586. package/dist/util/__tests__/appId.test.js.map +0 -1
  587. package/dist/util/__tests__/cliClient.test.js +0 -184
  588. package/dist/util/__tests__/cliClient.test.js.map +0 -1
  589. package/dist/util/__tests__/compareDependencyVersions.test.js +0 -426
  590. package/dist/util/__tests__/compareDependencyVersions.test.js.map +0 -1
  591. package/dist/util/__tests__/extractDocumentsFromNdjsonOrTarball.test.js +0 -74
  592. package/dist/util/__tests__/extractDocumentsFromNdjsonOrTarball.test.js.map +0 -1
  593. package/dist/util/__tests__/findNdjsonEntry.test.js +0 -54
  594. package/dist/util/__tests__/findNdjsonEntry.test.js.map +0 -1
  595. package/dist/util/__tests__/getCliVersion.test.js +0 -28
  596. package/dist/util/__tests__/getCliVersion.test.js.map +0 -1
  597. package/dist/util/__tests__/getLocalPackageVersion.test.js +0 -84
  598. package/dist/util/__tests__/getLocalPackageVersion.test.js.map +0 -1
  599. package/dist/util/__tests__/getWorkspace.test.js +0 -37
  600. package/dist/util/__tests__/getWorkspace.test.js.map +0 -1
  601. package/dist/util/__tests__/readPackageJson.test.js +0 -69
  602. package/dist/util/__tests__/readPackageJson.test.js.map +0 -1
  603. package/dist/util/__tests__/warnAboutMissingAppId.test.js +0 -28
  604. package/dist/util/__tests__/warnAboutMissingAppId.test.js.map +0 -1
  605. package/dist/util/packageManager/__tests__/installPackages.test.js +0 -388
  606. package/dist/util/packageManager/__tests__/installPackages.test.js.map +0 -1
  607. package/dist/util/validation/ __tests__/validateDocuments.test.js +0 -274
  608. package/dist/util/validation/ __tests__/validateDocuments.test.js.map +0 -1
@@ -1,7 +1,7 @@
1
1
  import { spawn } from 'node:child_process';
2
2
  import fs from 'node:fs/promises';
3
3
  import path from 'node:path';
4
- import { packageDirectory } from 'pkg-dir';
4
+ import { packageDirectory } from 'package-directory';
5
5
  export async function execScript(options) {
6
6
  const { extraArguments, flags, scriptPath, workDir } = options;
7
7
  const mockBrowserEnv = flags['mock-browser-env'];
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/actions/exec/execScript.ts"],"sourcesContent":["import {spawn} from 'node:child_process'\nimport fs from 'node:fs/promises'\nimport path from 'node:path'\n\nimport {packageDirectory} from 'pkg-dir'\n\ninterface ExecScriptOptions {\n extraArguments: string[]\n flags: {\n 'mock-browser-env': boolean\n 'with-user-token': boolean\n }\n scriptPath: string\n workDir: string\n}\n\nexport async function execScript(options: ExecScriptOptions): Promise<void> {\n const {extraArguments, flags, scriptPath, workDir} = options\n const mockBrowserEnv = flags['mock-browser-env']\n const withUserToken = flags['with-user-token']\n\n const resolvedScriptPath = path.resolve(scriptPath)\n\n const cliPkgDir = await packageDirectory({cwd: import.meta.dirname})\n if (!cliPkgDir) {\n throw new Error('Unable to resolve @sanity/cli module root')\n }\n\n const threadsDir = path.join(cliPkgDir, 'dist', 'threads')\n const browserEnvPath = path.join(threadsDir, 'registerBrowserEnv.js')\n const configClientPath = path.join(threadsDir, 'configClient.js')\n\n // Verify threads directory exists\n if (!(await fs.stat(threadsDir).catch(() => false))) {\n throw new Error('@sanity/cli module build error: missing threads directory')\n }\n\n // Use tsx loader for TypeScript support in the spawned child process\n // We need to resolve the tsx loader path from the CLI's node_modules since the child\n // process will run from the user's script directory where tsx may not be installed.\n let tsxLoaderPath: string\n try {\n // Resolve the tsx loader using Node's module resolution relative to package.json\n const tsxPackageUrl = import.meta.resolve('tsx/package.json', import.meta.url)\n tsxLoaderPath = new URL('dist/loader.mjs', tsxPackageUrl).pathname\n } catch {\n throw new Error('@sanity/cli not able to resolve tsx loader')\n }\n\n const baseArgs = mockBrowserEnv\n ? ['--import', tsxLoaderPath, '--import', browserEnvPath]\n : ['--import', tsxLoaderPath]\n const tokenArgs = withUserToken ? ['--import', configClientPath] : []\n\n const nodeArgs = [...baseArgs, ...tokenArgs, resolvedScriptPath, ...extraArguments]\n\n const proc = spawn(process.argv[0], nodeArgs, {\n env: {\n ...process.env,\n SANITY_BASE_PATH: workDir,\n },\n stdio: 'inherit',\n })\n return new Promise<void>((resolve, reject) => {\n proc.on('exit', (code, signal) => {\n if (signal) reject(new Error(`Script terminated by signal: ${signal}`))\n else if (code && code !== 0) reject(new Error(`Script exited with code: ${code}`))\n else resolve()\n })\n proc.on('error', reject)\n process.on('exit', () => proc.kill())\n process.on('SIGINT', () => proc.kill('SIGINT'))\n process.on('SIGTERM', () => proc.kill('SIGTERM'))\n })\n}\n"],"names":["spawn","fs","path","packageDirectory","execScript","options","extraArguments","flags","scriptPath","workDir","mockBrowserEnv","withUserToken","resolvedScriptPath","resolve","cliPkgDir","cwd","dirname","Error","threadsDir","join","browserEnvPath","configClientPath","stat","catch","tsxLoaderPath","tsxPackageUrl","url","URL","pathname","baseArgs","tokenArgs","nodeArgs","proc","process","argv","env","SANITY_BASE_PATH","stdio","Promise","reject","on","code","signal","kill"],"mappings":"AAAA,SAAQA,KAAK,QAAO,qBAAoB;AACxC,OAAOC,QAAQ,mBAAkB;AACjC,OAAOC,UAAU,YAAW;AAE5B,SAAQC,gBAAgB,QAAO,UAAS;AAYxC,OAAO,eAAeC,WAAWC,OAA0B;IACzD,MAAM,EAACC,cAAc,EAAEC,KAAK,EAAEC,UAAU,EAAEC,OAAO,EAAC,GAAGJ;IACrD,MAAMK,iBAAiBH,KAAK,CAAC,mBAAmB;IAChD,MAAMI,gBAAgBJ,KAAK,CAAC,kBAAkB;IAE9C,MAAMK,qBAAqBV,KAAKW,OAAO,CAACL;IAExC,MAAMM,YAAY,MAAMX,iBAAiB;QAACY,KAAK,YAAYC,OAAO;IAAA;IAClE,IAAI,CAACF,WAAW;QACd,MAAM,IAAIG,MAAM;IAClB;IAEA,MAAMC,aAAahB,KAAKiB,IAAI,CAACL,WAAW,QAAQ;IAChD,MAAMM,iBAAiBlB,KAAKiB,IAAI,CAACD,YAAY;IAC7C,MAAMG,mBAAmBnB,KAAKiB,IAAI,CAACD,YAAY;IAE/C,kCAAkC;IAClC,IAAI,CAAE,MAAMjB,GAAGqB,IAAI,CAACJ,YAAYK,KAAK,CAAC,IAAM,QAAS;QACnD,MAAM,IAAIN,MAAM;IAClB;IAEA,qEAAqE;IACrE,qFAAqF;IACrF,oFAAoF;IACpF,IAAIO;IACJ,IAAI;QACF,iFAAiF;QACjF,MAAMC,gBAAgB,YAAYZ,OAAO,CAAC,oBAAoB,YAAYa,GAAG;QAC7EF,gBAAgB,IAAIG,IAAI,mBAAmBF,eAAeG,QAAQ;IACpE,EAAE,OAAM;QACN,MAAM,IAAIX,MAAM;IAClB;IAEA,MAAMY,WAAWnB,iBACb;QAAC;QAAYc;QAAe;QAAYJ;KAAe,GACvD;QAAC;QAAYI;KAAc;IAC/B,MAAMM,YAAYnB,gBAAgB;QAAC;QAAYU;KAAiB,GAAG,EAAE;IAErE,MAAMU,WAAW;WAAIF;WAAaC;QAAWlB;WAAuBN;KAAe;IAEnF,MAAM0B,OAAOhC,MAAMiC,QAAQC,IAAI,CAAC,EAAE,EAAEH,UAAU;QAC5CI,KAAK;YACH,GAAGF,QAAQE,GAAG;YACdC,kBAAkB3B;QACpB;QACA4B,OAAO;IACT;IACA,OAAO,IAAIC,QAAc,CAACzB,SAAS0B;QACjCP,KAAKQ,EAAE,CAAC,QAAQ,CAACC,MAAMC;YACrB,IAAIA,QAAQH,OAAO,IAAItB,MAAM,CAAC,6BAA6B,EAAEyB,QAAQ;iBAChE,IAAID,QAAQA,SAAS,GAAGF,OAAO,IAAItB,MAAM,CAAC,yBAAyB,EAAEwB,MAAM;iBAC3E5B;QACP;QACAmB,KAAKQ,EAAE,CAAC,SAASD;QACjBN,QAAQO,EAAE,CAAC,QAAQ,IAAMR,KAAKW,IAAI;QAClCV,QAAQO,EAAE,CAAC,UAAU,IAAMR,KAAKW,IAAI,CAAC;QACrCV,QAAQO,EAAE,CAAC,WAAW,IAAMR,KAAKW,IAAI,CAAC;IACxC;AACF"}
1
+ {"version":3,"sources":["../../../src/actions/exec/execScript.ts"],"sourcesContent":["import {spawn} from 'node:child_process'\nimport fs from 'node:fs/promises'\nimport path from 'node:path'\n\nimport {packageDirectory} from 'package-directory'\n\ninterface ExecScriptOptions {\n extraArguments: string[]\n flags: {\n 'mock-browser-env': boolean\n 'with-user-token': boolean\n }\n scriptPath: string\n workDir: string\n}\n\nexport async function execScript(options: ExecScriptOptions): Promise<void> {\n const {extraArguments, flags, scriptPath, workDir} = options\n const mockBrowserEnv = flags['mock-browser-env']\n const withUserToken = flags['with-user-token']\n\n const resolvedScriptPath = path.resolve(scriptPath)\n\n const cliPkgDir = await packageDirectory({cwd: import.meta.dirname})\n if (!cliPkgDir) {\n throw new Error('Unable to resolve @sanity/cli module root')\n }\n\n const threadsDir = path.join(cliPkgDir, 'dist', 'threads')\n const browserEnvPath = path.join(threadsDir, 'registerBrowserEnv.js')\n const configClientPath = path.join(threadsDir, 'configClient.js')\n\n // Verify threads directory exists\n if (!(await fs.stat(threadsDir).catch(() => false))) {\n throw new Error('@sanity/cli module build error: missing threads directory')\n }\n\n // Use tsx loader for TypeScript support in the spawned child process\n // We need to resolve the tsx loader path from the CLI's node_modules since the child\n // process will run from the user's script directory where tsx may not be installed.\n let tsxLoaderPath: string\n try {\n // Resolve the tsx loader using Node's module resolution relative to package.json\n const tsxPackageUrl = import.meta.resolve('tsx/package.json', import.meta.url)\n tsxLoaderPath = new URL('dist/loader.mjs', tsxPackageUrl).pathname\n } catch {\n throw new Error('@sanity/cli not able to resolve tsx loader')\n }\n\n const baseArgs = mockBrowserEnv\n ? ['--import', tsxLoaderPath, '--import', browserEnvPath]\n : ['--import', tsxLoaderPath]\n const tokenArgs = withUserToken ? ['--import', configClientPath] : []\n\n const nodeArgs = [...baseArgs, ...tokenArgs, resolvedScriptPath, ...extraArguments]\n\n const proc = spawn(process.argv[0], nodeArgs, {\n env: {\n ...process.env,\n SANITY_BASE_PATH: workDir,\n },\n stdio: 'inherit',\n })\n return new Promise<void>((resolve, reject) => {\n proc.on('exit', (code, signal) => {\n if (signal) reject(new Error(`Script terminated by signal: ${signal}`))\n else if (code && code !== 0) reject(new Error(`Script exited with code: ${code}`))\n else resolve()\n })\n proc.on('error', reject)\n process.on('exit', () => proc.kill())\n process.on('SIGINT', () => proc.kill('SIGINT'))\n process.on('SIGTERM', () => proc.kill('SIGTERM'))\n })\n}\n"],"names":["spawn","fs","path","packageDirectory","execScript","options","extraArguments","flags","scriptPath","workDir","mockBrowserEnv","withUserToken","resolvedScriptPath","resolve","cliPkgDir","cwd","dirname","Error","threadsDir","join","browserEnvPath","configClientPath","stat","catch","tsxLoaderPath","tsxPackageUrl","url","URL","pathname","baseArgs","tokenArgs","nodeArgs","proc","process","argv","env","SANITY_BASE_PATH","stdio","Promise","reject","on","code","signal","kill"],"mappings":"AAAA,SAAQA,KAAK,QAAO,qBAAoB;AACxC,OAAOC,QAAQ,mBAAkB;AACjC,OAAOC,UAAU,YAAW;AAE5B,SAAQC,gBAAgB,QAAO,oBAAmB;AAYlD,OAAO,eAAeC,WAAWC,OAA0B;IACzD,MAAM,EAACC,cAAc,EAAEC,KAAK,EAAEC,UAAU,EAAEC,OAAO,EAAC,GAAGJ;IACrD,MAAMK,iBAAiBH,KAAK,CAAC,mBAAmB;IAChD,MAAMI,gBAAgBJ,KAAK,CAAC,kBAAkB;IAE9C,MAAMK,qBAAqBV,KAAKW,OAAO,CAACL;IAExC,MAAMM,YAAY,MAAMX,iBAAiB;QAACY,KAAK,YAAYC,OAAO;IAAA;IAClE,IAAI,CAACF,WAAW;QACd,MAAM,IAAIG,MAAM;IAClB;IAEA,MAAMC,aAAahB,KAAKiB,IAAI,CAACL,WAAW,QAAQ;IAChD,MAAMM,iBAAiBlB,KAAKiB,IAAI,CAACD,YAAY;IAC7C,MAAMG,mBAAmBnB,KAAKiB,IAAI,CAACD,YAAY;IAE/C,kCAAkC;IAClC,IAAI,CAAE,MAAMjB,GAAGqB,IAAI,CAACJ,YAAYK,KAAK,CAAC,IAAM,QAAS;QACnD,MAAM,IAAIN,MAAM;IAClB;IAEA,qEAAqE;IACrE,qFAAqF;IACrF,oFAAoF;IACpF,IAAIO;IACJ,IAAI;QACF,iFAAiF;QACjF,MAAMC,gBAAgB,YAAYZ,OAAO,CAAC,oBAAoB,YAAYa,GAAG;QAC7EF,gBAAgB,IAAIG,IAAI,mBAAmBF,eAAeG,QAAQ;IACpE,EAAE,OAAM;QACN,MAAM,IAAIX,MAAM;IAClB;IAEA,MAAMY,WAAWnB,iBACb;QAAC;QAAYc;QAAe;QAAYJ;KAAe,GACvD;QAAC;QAAYI;KAAc;IAC/B,MAAMM,YAAYnB,gBAAgB;QAAC;QAAYU;KAAiB,GAAG,EAAE;IAErE,MAAMU,WAAW;WAAIF;WAAaC;QAAWlB;WAAuBN;KAAe;IAEnF,MAAM0B,OAAOhC,MAAMiC,QAAQC,IAAI,CAAC,EAAE,EAAEH,UAAU;QAC5CI,KAAK;YACH,GAAGF,QAAQE,GAAG;YACdC,kBAAkB3B;QACpB;QACA4B,OAAO;IACT;IACA,OAAO,IAAIC,QAAc,CAACzB,SAAS0B;QACjCP,KAAKQ,EAAE,CAAC,QAAQ,CAACC,MAAMC;YACrB,IAAIA,QAAQH,OAAO,IAAItB,MAAM,CAAC,6BAA6B,EAAEyB,QAAQ;iBAChE,IAAID,QAAQA,SAAS,GAAGF,OAAO,IAAItB,MAAM,CAAC,yBAAyB,EAAEwB,MAAM;iBAC3E5B;QACP;QACAmB,KAAKQ,EAAE,CAAC,SAASD;QACjBN,QAAQO,EAAE,CAAC,QAAQ,IAAMR,KAAKW,IAAI;QAClCV,QAAQO,EAAE,CAAC,UAAU,IAAMR,KAAKW,IAAI,CAAC;QACrCV,QAAQO,EAAE,CAAC,WAAW,IAAMR,KAAKW,IAAI,CAAC;IACxC;AACF"}
@@ -1,6 +1,6 @@
1
1
  import { isMainThread, Worker } from 'node:worker_threads';
2
2
  import { getCliConfig, getStudioConfig, resolveLocalPackage } from '@sanity/cli-core';
3
- import { packageDirectory } from 'pkg-dir';
3
+ import { packageDirectory } from 'package-directory';
4
4
  export async function getGraphQLAPIs(workDir) {
5
5
  if (!isMainThread) {
6
6
  throw new Error('getGraphQLAPIs() must be called from the main thread');
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/actions/graphql/getGraphQLAPIs.ts"],"sourcesContent":["import {isMainThread, Worker} from 'node:worker_threads'\n\nimport {type CliConfig, getCliConfig, getStudioConfig, resolveLocalPackage} from '@sanity/cli-core'\nimport {packageDirectory} from 'pkg-dir'\n\nimport {\n type ResolvedGraphQLAPI,\n type ResolvedSourceProperties,\n type SchemaDefinitionish,\n type TypeResolvedGraphQLAPI,\n} from './types.js'\n\nexport async function getGraphQLAPIs(workDir: string): Promise<ResolvedGraphQLAPI[]> {\n if (!isMainThread) {\n throw new Error('getGraphQLAPIs() must be called from the main thread')\n }\n\n // Resolve `sanity` local to the project in order to avoid using incompatible versions, and to avoid circular dependencies\n const {createSchema} = await resolveLocalPackage<typeof import('sanity')>('sanity', workDir)\n\n const defaultSchema = createSchema({name: 'default', types: []})\n const defaultTypes = defaultSchema.getTypeNames()\n const isCustomType = (type: SchemaDefinitionish) => !defaultTypes.includes(type.name)\n\n const apis = await getApisWithSchemaTypes(workDir)\n const resolved = apis.map(\n ({schemaTypes, ...api}): ResolvedSourceProperties => ({\n schema: createSchema({\n name: 'default',\n types: schemaTypes.filter((element) => isCustomType(element)),\n }),\n ...api,\n }),\n )\n\n return resolved\n}\n\nasync function getApisWithSchemaTypes(workDir: string): Promise<TypeResolvedGraphQLAPI[]> {\n const cliConfig = await getCliConfig(workDir)\n const workspaces = await getStudioConfig(workDir, {resolvePlugins: true})\n\n const cliPkgDir = await packageDirectory({cwd: import.meta.dirname})\n if (!cliPkgDir) {\n throw new Error('Unable to resolve @sanity/cli module root')\n }\n\n return new Promise<TypeResolvedGraphQLAPI[]>((resolve, reject) => {\n const worker = new Worker(new URL(`getGraphQLAPIs.worker.js`, import.meta.url), {\n env: process.env,\n workerData: {\n cliConfig: extractGraphQLConfig(cliConfig),\n workDir,\n workspaces,\n },\n })\n worker.on('message', resolve)\n worker.on('error', (error) => {\n reject(error)\n worker.terminate()\n })\n worker.on('exit', (code) => {\n if (code !== 0) {\n reject(new Error(`Worker stopped with exit code ${code}`))\n }\n })\n })\n}\n\nfunction extractGraphQLConfig(config: CliConfig) {\n return structuredClone({\n api: config.api,\n graphql: config.graphql,\n })\n}\n"],"names":["isMainThread","Worker","getCliConfig","getStudioConfig","resolveLocalPackage","packageDirectory","getGraphQLAPIs","workDir","Error","createSchema","defaultSchema","name","types","defaultTypes","getTypeNames","isCustomType","type","includes","apis","getApisWithSchemaTypes","resolved","map","schemaTypes","api","schema","filter","element","cliConfig","workspaces","resolvePlugins","cliPkgDir","cwd","dirname","Promise","resolve","reject","worker","URL","url","env","process","workerData","extractGraphQLConfig","on","error","terminate","code","config","structuredClone","graphql"],"mappings":"AAAA,SAAQA,YAAY,EAAEC,MAAM,QAAO,sBAAqB;AAExD,SAAwBC,YAAY,EAAEC,eAAe,EAAEC,mBAAmB,QAAO,mBAAkB;AACnG,SAAQC,gBAAgB,QAAO,UAAS;AASxC,OAAO,eAAeC,eAAeC,OAAe;IAClD,IAAI,CAACP,cAAc;QACjB,MAAM,IAAIQ,MAAM;IAClB;IAEA,0HAA0H;IAC1H,MAAM,EAACC,YAAY,EAAC,GAAG,MAAML,oBAA6C,UAAUG;IAEpF,MAAMG,gBAAgBD,aAAa;QAACE,MAAM;QAAWC,OAAO,EAAE;IAAA;IAC9D,MAAMC,eAAeH,cAAcI,YAAY;IAC/C,MAAMC,eAAe,CAACC,OAA8B,CAACH,aAAaI,QAAQ,CAACD,KAAKL,IAAI;IAEpF,MAAMO,OAAO,MAAMC,uBAAuBZ;IAC1C,MAAMa,WAAWF,KAAKG,GAAG,CACvB,CAAC,EAACC,WAAW,EAAE,GAAGC,KAAI,GAAgC,CAAA;YACpDC,QAAQf,aAAa;gBACnBE,MAAM;gBACNC,OAAOU,YAAYG,MAAM,CAAC,CAACC,UAAYX,aAAaW;YACtD;YACA,GAAGH,GAAG;QACR,CAAA;IAGF,OAAOH;AACT;AAEA,eAAeD,uBAAuBZ,OAAe;IACnD,MAAMoB,YAAY,MAAMzB,aAAaK;IACrC,MAAMqB,aAAa,MAAMzB,gBAAgBI,SAAS;QAACsB,gBAAgB;IAAI;IAEvE,MAAMC,YAAY,MAAMzB,iBAAiB;QAAC0B,KAAK,YAAYC,OAAO;IAAA;IAClE,IAAI,CAACF,WAAW;QACd,MAAM,IAAItB,MAAM;IAClB;IAEA,OAAO,IAAIyB,QAAkC,CAACC,SAASC;QACrD,MAAMC,SAAS,IAAInC,OAAO,IAAIoC,IAAI,CAAC,wBAAwB,CAAC,EAAE,YAAYC,GAAG,GAAG;YAC9EC,KAAKC,QAAQD,GAAG;YAChBE,YAAY;gBACVd,WAAWe,qBAAqBf;gBAChCpB;gBACAqB;YACF;QACF;QACAQ,OAAOO,EAAE,CAAC,WAAWT;QACrBE,OAAOO,EAAE,CAAC,SAAS,CAACC;YAClBT,OAAOS;YACPR,OAAOS,SAAS;QAClB;QACAT,OAAOO,EAAE,CAAC,QAAQ,CAACG;YACjB,IAAIA,SAAS,GAAG;gBACdX,OAAO,IAAI3B,MAAM,CAAC,8BAA8B,EAAEsC,MAAM;YAC1D;QACF;IACF;AACF;AAEA,SAASJ,qBAAqBK,MAAiB;IAC7C,OAAOC,gBAAgB;QACrBzB,KAAKwB,OAAOxB,GAAG;QACf0B,SAASF,OAAOE,OAAO;IACzB;AACF"}
1
+ {"version":3,"sources":["../../../src/actions/graphql/getGraphQLAPIs.ts"],"sourcesContent":["import {isMainThread, Worker} from 'node:worker_threads'\n\nimport {type CliConfig, getCliConfig, getStudioConfig, resolveLocalPackage} from '@sanity/cli-core'\nimport {packageDirectory} from 'package-directory'\n\nimport {\n type ResolvedGraphQLAPI,\n type ResolvedSourceProperties,\n type SchemaDefinitionish,\n type TypeResolvedGraphQLAPI,\n} from './types.js'\n\nexport async function getGraphQLAPIs(workDir: string): Promise<ResolvedGraphQLAPI[]> {\n if (!isMainThread) {\n throw new Error('getGraphQLAPIs() must be called from the main thread')\n }\n\n // Resolve `sanity` local to the project in order to avoid using incompatible versions, and to avoid circular dependencies\n const {createSchema} = await resolveLocalPackage<typeof import('sanity')>('sanity', workDir)\n\n const defaultSchema = createSchema({name: 'default', types: []})\n const defaultTypes = defaultSchema.getTypeNames()\n const isCustomType = (type: SchemaDefinitionish) => !defaultTypes.includes(type.name)\n\n const apis = await getApisWithSchemaTypes(workDir)\n const resolved = apis.map(\n ({schemaTypes, ...api}): ResolvedSourceProperties => ({\n schema: createSchema({\n name: 'default',\n types: schemaTypes.filter((element) => isCustomType(element)),\n }),\n ...api,\n }),\n )\n\n return resolved\n}\n\nasync function getApisWithSchemaTypes(workDir: string): Promise<TypeResolvedGraphQLAPI[]> {\n const cliConfig = await getCliConfig(workDir)\n const workspaces = await getStudioConfig(workDir, {resolvePlugins: true})\n\n const cliPkgDir = await packageDirectory({cwd: import.meta.dirname})\n if (!cliPkgDir) {\n throw new Error('Unable to resolve @sanity/cli module root')\n }\n\n return new Promise<TypeResolvedGraphQLAPI[]>((resolve, reject) => {\n const worker = new Worker(new URL(`getGraphQLAPIs.worker.js`, import.meta.url), {\n env: process.env,\n workerData: {\n cliConfig: extractGraphQLConfig(cliConfig),\n workDir,\n workspaces,\n },\n })\n worker.on('message', resolve)\n worker.on('error', (error) => {\n reject(error)\n worker.terminate()\n })\n worker.on('exit', (code) => {\n if (code !== 0) {\n reject(new Error(`Worker stopped with exit code ${code}`))\n }\n })\n })\n}\n\nfunction extractGraphQLConfig(config: CliConfig) {\n return structuredClone({\n api: config.api,\n graphql: config.graphql,\n })\n}\n"],"names":["isMainThread","Worker","getCliConfig","getStudioConfig","resolveLocalPackage","packageDirectory","getGraphQLAPIs","workDir","Error","createSchema","defaultSchema","name","types","defaultTypes","getTypeNames","isCustomType","type","includes","apis","getApisWithSchemaTypes","resolved","map","schemaTypes","api","schema","filter","element","cliConfig","workspaces","resolvePlugins","cliPkgDir","cwd","dirname","Promise","resolve","reject","worker","URL","url","env","process","workerData","extractGraphQLConfig","on","error","terminate","code","config","structuredClone","graphql"],"mappings":"AAAA,SAAQA,YAAY,EAAEC,MAAM,QAAO,sBAAqB;AAExD,SAAwBC,YAAY,EAAEC,eAAe,EAAEC,mBAAmB,QAAO,mBAAkB;AACnG,SAAQC,gBAAgB,QAAO,oBAAmB;AASlD,OAAO,eAAeC,eAAeC,OAAe;IAClD,IAAI,CAACP,cAAc;QACjB,MAAM,IAAIQ,MAAM;IAClB;IAEA,0HAA0H;IAC1H,MAAM,EAACC,YAAY,EAAC,GAAG,MAAML,oBAA6C,UAAUG;IAEpF,MAAMG,gBAAgBD,aAAa;QAACE,MAAM;QAAWC,OAAO,EAAE;IAAA;IAC9D,MAAMC,eAAeH,cAAcI,YAAY;IAC/C,MAAMC,eAAe,CAACC,OAA8B,CAACH,aAAaI,QAAQ,CAACD,KAAKL,IAAI;IAEpF,MAAMO,OAAO,MAAMC,uBAAuBZ;IAC1C,MAAMa,WAAWF,KAAKG,GAAG,CACvB,CAAC,EAACC,WAAW,EAAE,GAAGC,KAAI,GAAgC,CAAA;YACpDC,QAAQf,aAAa;gBACnBE,MAAM;gBACNC,OAAOU,YAAYG,MAAM,CAAC,CAACC,UAAYX,aAAaW;YACtD;YACA,GAAGH,GAAG;QACR,CAAA;IAGF,OAAOH;AACT;AAEA,eAAeD,uBAAuBZ,OAAe;IACnD,MAAMoB,YAAY,MAAMzB,aAAaK;IACrC,MAAMqB,aAAa,MAAMzB,gBAAgBI,SAAS;QAACsB,gBAAgB;IAAI;IAEvE,MAAMC,YAAY,MAAMzB,iBAAiB;QAAC0B,KAAK,YAAYC,OAAO;IAAA;IAClE,IAAI,CAACF,WAAW;QACd,MAAM,IAAItB,MAAM;IAClB;IAEA,OAAO,IAAIyB,QAAkC,CAACC,SAASC;QACrD,MAAMC,SAAS,IAAInC,OAAO,IAAIoC,IAAI,CAAC,wBAAwB,CAAC,EAAE,YAAYC,GAAG,GAAG;YAC9EC,KAAKC,QAAQD,GAAG;YAChBE,YAAY;gBACVd,WAAWe,qBAAqBf;gBAChCpB;gBACAqB;YACF;QACF;QACAQ,OAAOO,EAAE,CAAC,WAAWT;QACrBE,OAAOO,EAAE,CAAC,SAAS,CAACC;YAClBT,OAAOS;YACPR,OAAOS,SAAS;QAClB;QACAT,OAAOO,EAAE,CAAC,QAAQ,CAACG;YACjB,IAAIA,SAAS,GAAG;gBACdX,OAAO,IAAI3B,MAAM,CAAC,8BAA8B,EAAEsC,MAAM;YAC1D;QACF;IACF;AACF;AAEA,SAASJ,qBAAqBK,MAAiB;IAC7C,OAAOC,gBAAgB;QACrBzB,KAAKwB,OAAOxB,GAAG;QACf0B,SAASF,OAAOE,OAAO;IACzB;AACF"}
@@ -56,7 +56,7 @@ async function downloadTarStream(url, bearerToken) {
56
56
  if (!res.body) {
57
57
  throw new Error(`Failed to download: ${url}`);
58
58
  }
59
- // eslint-disable-next-line n/no-unsupported-features/node-builtins
59
+ // eslint-disable-next-line n/no-unsupported-features/node-builtins, @typescript-eslint/no-explicit-any
60
60
  return Readable.fromWeb(res.body);
61
61
  }
62
62
  export function checkIsRemoteTemplate(templateName) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/actions/init/remoteTemplate.ts"],"sourcesContent":["import {access, readFile, writeFile} from 'node:fs/promises'\nimport {join, posix, sep} from 'node:path'\nimport {Readable} from 'node:stream'\nimport {pipeline} from 'node:stream/promises'\n\nimport {subdebug} from '@sanity/cli-core'\nimport {type SanityClient} from '@sanity/client'\nimport {ENV_TEMPLATE_FILES, REQUIRED_ENV_VAR} from '@sanity/template-validator'\nimport {x} from 'tar'\n\nimport {readPackageJson} from '../../util/readPackageJson.js'\n\nconst debug = subdebug('remoteTemplate')\n\nconst DISALLOWED_PATHS = [\n // Prevent security risks from unknown GitHub Actions\n '/.github/',\n]\n\nconst ENV_VAR = {\n ...REQUIRED_ENV_VAR,\n READ_TOKEN: 'SANITY_API_READ_TOKEN',\n WRITE_TOKEN: 'SANITY_API_WRITE_TOKEN',\n} as const\n\nconst API_READ_TOKEN_ROLE = 'viewer'\nconst API_WRITE_TOKEN_ROLE = 'editor'\n\ntype EnvData = {\n dataset: string\n projectId: string\n readToken?: string\n writeToken?: string\n}\n\ntype GitHubUrlString =\n | `https://github.com/${string}/${string}`\n | `https://www.github.com/${string}/${string}`\n\nexport type RepoInfo = {\n branch: string\n filePath: string\n name: string\n username: string\n}\n\nexport function getGitHubRawContentUrl(repoInfo: RepoInfo): string {\n const {branch, filePath, name, username} = repoInfo\n return `https://raw.githubusercontent.com/${username}/${name}/${branch}/${filePath}`\n}\n\nfunction isGitHubRepoShorthand(value: string): boolean {\n if (URL.canParse(value)) {\n return false\n }\n // This supports :owner/:repo and :owner/:repo/nested/path, e.g.\n // sanity-io/sanity\n // sanity-io/sanity/templates/next-js\n // sanity-io/templates/live-content-api\n // sanity-io/sanity/packages/@sanity/cli/test/test-template\n return /^[\\w-]+\\/[\\w-.]+(\\/[@\\w-.]+)*$/.test(value)\n}\n\nfunction isGitHubRepoUrl(value: string | URL): value is GitHubUrlString | URL {\n if (URL.canParse(value) === false) {\n return false\n }\n const url = new URL(value)\n const pathSegments = url.pathname.slice(1).split('/')\n\n return (\n url.protocol === 'https:' &&\n url.hostname === 'github.com' &&\n // The pathname must have at least 2 segments. If it has more than 2, the\n // third must be \"tree\" and it must have at least 4 segments.\n // https://github.com/:owner/:repo\n // https://github.com/:owner/:repo/tree/:ref\n pathSegments.length >= 2 &&\n (pathSegments.length > 2 ? pathSegments[2] === 'tree' && pathSegments.length >= 4 : true)\n )\n}\n\nasync function downloadTarStream(url: string, bearerToken?: string): Promise<Readable> {\n const headers: Record<string, string> = {}\n if (bearerToken) {\n headers.Authorization = `Bearer ${bearerToken}`\n }\n\n const res = await fetch(url, {headers})\n\n if (!res.body) {\n throw new Error(`Failed to download: ${url}`)\n }\n\n // eslint-disable-next-line n/no-unsupported-features/node-builtins\n return Readable.fromWeb(res.body as any)\n}\n\nexport function checkIsRemoteTemplate(templateName?: string): boolean {\n return templateName?.includes('/') ?? false\n}\n\nexport async function getGitHubRepoInfo(value: string, bearerToken?: string): Promise<RepoInfo> {\n let username = ''\n let name = ''\n let branch = ''\n let filePath = ''\n\n if (isGitHubRepoShorthand(value)) {\n const parts = value.split('/')\n username = parts[0]\n name = parts[1]\n // If there are more segments after owner/repo, they form the file path\n if (parts.length > 2) {\n filePath = parts.slice(2).join('/')\n }\n }\n\n if (isGitHubRepoUrl(value)) {\n const url = new URL(value)\n const pathSegments = url.pathname.slice(1).split('/')\n username = pathSegments[0]\n name = pathSegments[1]\n\n // If we have a \"tree\" segment, everything after branch is the file path\n if (pathSegments[2] === 'tree') {\n branch = pathSegments[3]\n if (pathSegments.length > 4) {\n filePath = pathSegments.slice(4).join('/')\n }\n }\n }\n\n if (!username || !name) {\n throw new Error('Invalid GitHub repository format')\n }\n\n const tokenMessage =\n 'GitHub repository not found. For private repositories, use --template-token to provide an access token.\\n\\n' +\n 'You can generate a new token at https://github.com/settings/personal-access-tokens/new\\n' +\n 'Set the token to \"read-only\" with repository access and a short expiry (e.g. 7 days) for security.'\n\n try {\n const headers: Record<string, string> = {}\n if (bearerToken) {\n headers.Authorization = `Bearer ${bearerToken}`\n }\n\n const infoResponse = await fetch(`https://api.github.com/repos/${username}/${name}`, {\n headers,\n })\n\n if (infoResponse.status !== 200) {\n if (infoResponse.status === 404) {\n throw new Error(tokenMessage)\n }\n throw new Error('GitHub repository not found')\n }\n\n const info = await infoResponse.json()\n\n return {\n branch: branch || info.default_branch,\n filePath,\n name,\n username,\n }\n } catch {\n throw new Error(tokenMessage)\n }\n}\n\nexport async function downloadAndExtractRepo(\n root: string,\n {branch, filePath, name, username}: RepoInfo,\n bearerToken?: string,\n): Promise<void> {\n let rootPath: string | null = null\n await pipeline(\n await downloadTarStream(\n `https://codeload.github.com/${username}/${name}/tar.gz/${branch}`,\n bearerToken,\n ),\n x({\n cwd: root,\n filter: (p: string) => {\n const posixPath = p.split(sep).join(posix.sep)\n if (rootPath === null) {\n const pathSegments = posixPath.split(posix.sep)\n rootPath = pathSegments.length > 0 ? pathSegments[0] : null\n }\n for (const disallowedPath of DISALLOWED_PATHS) {\n if (posixPath.includes(disallowedPath)) return false\n }\n return posixPath.startsWith(`${rootPath}${filePath ? `/${filePath}/` : '/'}`)\n },\n strip: filePath ? filePath.split('/').length + 1 : 1,\n }),\n )\n}\n\nexport async function checkIfNeedsApiToken(root: string, type: 'read' | 'write'): Promise<boolean> {\n try {\n const templatePath = await Promise.any(\n ENV_TEMPLATE_FILES.map(async (file) => {\n await access(join(root, file))\n return file\n }),\n )\n const templateContent = await readFile(join(root, templatePath), 'utf8')\n return templateContent.includes(type === 'read' ? ENV_VAR.READ_TOKEN : ENV_VAR.WRITE_TOKEN)\n } catch {\n return false\n }\n}\n\nexport async function applyEnvVariables(\n root: string,\n envData: EnvData,\n targetName = '.env',\n): Promise<void> {\n const templatePath = await Promise.any(\n ENV_TEMPLATE_FILES.map(async (file) => {\n await access(join(root, file))\n return file\n }),\n ).catch(() => {})\n\n if (!templatePath) {\n return // No template .env file found, skip\n }\n\n try {\n const templateContent = await readFile(join(root, templatePath), 'utf8')\n const {dataset, projectId, readToken = '', writeToken = ''} = envData\n\n const findAndReplaceVariable = (\n content: string,\n varRegex: RegExp | string,\n value: string,\n useQuotes: boolean,\n ) => {\n const varPattern = typeof varRegex === 'string' ? varRegex : varRegex.source\n const pattern = new RegExp(`.*${varPattern}=.*$`, 'gm')\n const matches = content.matchAll(pattern)\n\n let result = content\n for (const match of matches) {\n if (!match[0]) continue\n const varName = match[0].split('=')[0].trim()\n result = result.replaceAll(\n new RegExp(`${varName}=.*$`, 'gm'),\n `${varName}=${useQuotes ? `\"${value}\"` : value}`,\n )\n }\n\n return result\n }\n\n let envContent = templateContent\n const vars = [\n {pattern: ENV_VAR.PROJECT_ID, value: projectId},\n {pattern: ENV_VAR.DATASET, value: dataset},\n {pattern: ENV_VAR.READ_TOKEN, value: readToken},\n {pattern: ENV_VAR.WRITE_TOKEN, value: writeToken},\n ]\n const useQuotes = templateContent.includes('=\"')\n\n for (const {pattern, value} of vars) {\n envContent = findAndReplaceVariable(envContent, pattern, value, useQuotes)\n }\n\n await writeFile(join(root, targetName), envContent)\n } catch (err) {\n debug(`Error setting environment variables: ${err}`)\n throw new Error(\n 'Failed to set environment variables. This could be due to file permissions or the .env file format. See https://www.sanity.io/docs/environment-variables for details on environment variable setup.',\n )\n }\n}\n\nexport async function tryApplyPackageName(root: string, name: string): Promise<void> {\n try {\n const pkg = await readPackageJson(join(root, 'package.json'))\n pkg.name = name\n\n await writeFile(join(root, 'package.json'), JSON.stringify(pkg, null, 2))\n } catch {\n // noop\n }\n}\n\nexport async function generateSanityApiToken(\n client: SanityClient,\n label: string,\n type: 'read' | 'write',\n projectId: string,\n): Promise<string> {\n // const client = await getGlobalCliClient({\n // apiVersion: 'v2021-06-07',\n // requireUser: true,\n // })\n const response = await client.request<{key: string}>({\n body: {\n label: `${label} (${Date.now()})`,\n roleName: type === 'read' ? API_READ_TOKEN_ROLE : API_WRITE_TOKEN_ROLE,\n },\n method: 'POST',\n uri: `/projects/${projectId}/tokens`,\n })\n return response.key\n}\n\nexport async function setCorsOrigin(\n client: SanityClient,\n origin: string,\n projectId: string,\n): Promise<void> {\n try {\n // const client = await getGlobalCliClient({\n // apiVersion: 'v2021-06-07',\n // requireUser: true,\n // })\n\n await client.withConfig({projectId}).request({\n body: {allowCredentials: true, origin: origin}, // allowCredentials is true to allow for embedded studios if needed\n method: 'POST',\n url: '/cors',\n })\n } catch (error) {\n // Silent fail, it most likely means that the origin is already set\n debug('Failed to set CORS origin', error)\n }\n}\n"],"names":["access","readFile","writeFile","join","posix","sep","Readable","pipeline","subdebug","ENV_TEMPLATE_FILES","REQUIRED_ENV_VAR","x","readPackageJson","debug","DISALLOWED_PATHS","ENV_VAR","READ_TOKEN","WRITE_TOKEN","API_READ_TOKEN_ROLE","API_WRITE_TOKEN_ROLE","getGitHubRawContentUrl","repoInfo","branch","filePath","name","username","isGitHubRepoShorthand","value","URL","canParse","test","isGitHubRepoUrl","url","pathSegments","pathname","slice","split","protocol","hostname","length","downloadTarStream","bearerToken","headers","Authorization","res","fetch","body","Error","fromWeb","checkIsRemoteTemplate","templateName","includes","getGitHubRepoInfo","parts","tokenMessage","infoResponse","status","info","json","default_branch","downloadAndExtractRepo","root","rootPath","cwd","filter","p","posixPath","disallowedPath","startsWith","strip","checkIfNeedsApiToken","type","templatePath","Promise","any","map","file","templateContent","applyEnvVariables","envData","targetName","catch","dataset","projectId","readToken","writeToken","findAndReplaceVariable","content","varRegex","useQuotes","varPattern","source","pattern","RegExp","matches","matchAll","result","match","varName","trim","replaceAll","envContent","vars","PROJECT_ID","DATASET","err","tryApplyPackageName","pkg","JSON","stringify","generateSanityApiToken","client","label","response","request","Date","now","roleName","method","uri","key","setCorsOrigin","origin","withConfig","allowCredentials","error"],"mappings":"AAAA,SAAQA,MAAM,EAAEC,QAAQ,EAAEC,SAAS,QAAO,mBAAkB;AAC5D,SAAQC,IAAI,EAAEC,KAAK,EAAEC,GAAG,QAAO,YAAW;AAC1C,SAAQC,QAAQ,QAAO,cAAa;AACpC,SAAQC,QAAQ,QAAO,uBAAsB;AAE7C,SAAQC,QAAQ,QAAO,mBAAkB;AAEzC,SAAQC,kBAAkB,EAAEC,gBAAgB,QAAO,6BAA4B;AAC/E,SAAQC,CAAC,QAAO,MAAK;AAErB,SAAQC,eAAe,QAAO,gCAA+B;AAE7D,MAAMC,QAAQL,SAAS;AAEvB,MAAMM,mBAAmB;IACvB,qDAAqD;IACrD;CACD;AAED,MAAMC,UAAU;IACd,GAAGL,gBAAgB;IACnBM,YAAY;IACZC,aAAa;AACf;AAEA,MAAMC,sBAAsB;AAC5B,MAAMC,uBAAuB;AAoB7B,OAAO,SAASC,uBAAuBC,QAAkB;IACvD,MAAM,EAACC,MAAM,EAAEC,QAAQ,EAAEC,IAAI,EAAEC,QAAQ,EAAC,GAAGJ;IAC3C,OAAO,CAAC,kCAAkC,EAAEI,SAAS,CAAC,EAAED,KAAK,CAAC,EAAEF,OAAO,CAAC,EAAEC,UAAU;AACtF;AAEA,SAASG,sBAAsBC,KAAa;IAC1C,IAAIC,IAAIC,QAAQ,CAACF,QAAQ;QACvB,OAAO;IACT;IACA,gEAAgE;IAChE,mBAAmB;IACnB,qCAAqC;IACrC,uCAAuC;IACvC,2DAA2D;IAC3D,OAAO,iCAAiCG,IAAI,CAACH;AAC/C;AAEA,SAASI,gBAAgBJ,KAAmB;IAC1C,IAAIC,IAAIC,QAAQ,CAACF,WAAW,OAAO;QACjC,OAAO;IACT;IACA,MAAMK,MAAM,IAAIJ,IAAID;IACpB,MAAMM,eAAeD,IAAIE,QAAQ,CAACC,KAAK,CAAC,GAAGC,KAAK,CAAC;IAEjD,OACEJ,IAAIK,QAAQ,KAAK,YACjBL,IAAIM,QAAQ,KAAK,gBACjB,yEAAyE;IACzE,6DAA6D;IAC7D,kCAAkC;IAClC,4CAA4C;IAC5CL,aAAaM,MAAM,IAAI,KACtBN,CAAAA,aAAaM,MAAM,GAAG,IAAIN,YAAY,CAAC,EAAE,KAAK,UAAUA,aAAaM,MAAM,IAAI,IAAI,IAAG;AAE3F;AAEA,eAAeC,kBAAkBR,GAAW,EAAES,WAAoB;IAChE,MAAMC,UAAkC,CAAC;IACzC,IAAID,aAAa;QACfC,QAAQC,aAAa,GAAG,CAAC,OAAO,EAAEF,aAAa;IACjD;IAEA,MAAMG,MAAM,MAAMC,MAAMb,KAAK;QAACU;IAAO;IAErC,IAAI,CAACE,IAAIE,IAAI,EAAE;QACb,MAAM,IAAIC,MAAM,CAAC,oBAAoB,EAAEf,KAAK;IAC9C;IAEA,mEAAmE;IACnE,OAAO1B,SAAS0C,OAAO,CAACJ,IAAIE,IAAI;AAClC;AAEA,OAAO,SAASG,sBAAsBC,YAAqB;IACzD,OAAOA,cAAcC,SAAS,QAAQ;AACxC;AAEA,OAAO,eAAeC,kBAAkBzB,KAAa,EAAEc,WAAoB;IACzE,IAAIhB,WAAW;IACf,IAAID,OAAO;IACX,IAAIF,SAAS;IACb,IAAIC,WAAW;IAEf,IAAIG,sBAAsBC,QAAQ;QAChC,MAAM0B,QAAQ1B,MAAMS,KAAK,CAAC;QAC1BX,WAAW4B,KAAK,CAAC,EAAE;QACnB7B,OAAO6B,KAAK,CAAC,EAAE;QACf,uEAAuE;QACvE,IAAIA,MAAMd,MAAM,GAAG,GAAG;YACpBhB,WAAW8B,MAAMlB,KAAK,CAAC,GAAGhC,IAAI,CAAC;QACjC;IACF;IAEA,IAAI4B,gBAAgBJ,QAAQ;QAC1B,MAAMK,MAAM,IAAIJ,IAAID;QACpB,MAAMM,eAAeD,IAAIE,QAAQ,CAACC,KAAK,CAAC,GAAGC,KAAK,CAAC;QACjDX,WAAWQ,YAAY,CAAC,EAAE;QAC1BT,OAAOS,YAAY,CAAC,EAAE;QAEtB,wEAAwE;QACxE,IAAIA,YAAY,CAAC,EAAE,KAAK,QAAQ;YAC9BX,SAASW,YAAY,CAAC,EAAE;YACxB,IAAIA,aAAaM,MAAM,GAAG,GAAG;gBAC3BhB,WAAWU,aAAaE,KAAK,CAAC,GAAGhC,IAAI,CAAC;YACxC;QACF;IACF;IAEA,IAAI,CAACsB,YAAY,CAACD,MAAM;QACtB,MAAM,IAAIuB,MAAM;IAClB;IAEA,MAAMO,eACJ,gHACA,6FACA;IAEF,IAAI;QACF,MAAMZ,UAAkC,CAAC;QACzC,IAAID,aAAa;YACfC,QAAQC,aAAa,GAAG,CAAC,OAAO,EAAEF,aAAa;QACjD;QAEA,MAAMc,eAAe,MAAMV,MAAM,CAAC,6BAA6B,EAAEpB,SAAS,CAAC,EAAED,MAAM,EAAE;YACnFkB;QACF;QAEA,IAAIa,aAAaC,MAAM,KAAK,KAAK;YAC/B,IAAID,aAAaC,MAAM,KAAK,KAAK;gBAC/B,MAAM,IAAIT,MAAMO;YAClB;YACA,MAAM,IAAIP,MAAM;QAClB;QAEA,MAAMU,OAAO,MAAMF,aAAaG,IAAI;QAEpC,OAAO;YACLpC,QAAQA,UAAUmC,KAAKE,cAAc;YACrCpC;YACAC;YACAC;QACF;IACF,EAAE,OAAM;QACN,MAAM,IAAIsB,MAAMO;IAClB;AACF;AAEA,OAAO,eAAeM,uBACpBC,IAAY,EACZ,EAACvC,MAAM,EAAEC,QAAQ,EAAEC,IAAI,EAAEC,QAAQ,EAAW,EAC5CgB,WAAoB;IAEpB,IAAIqB,WAA0B;IAC9B,MAAMvD,SACJ,MAAMiC,kBACJ,CAAC,4BAA4B,EAAEf,SAAS,CAAC,EAAED,KAAK,QAAQ,EAAEF,QAAQ,EAClEmB,cAEF9B,EAAE;QACAoD,KAAKF;QACLG,QAAQ,CAACC;YACP,MAAMC,YAAYD,EAAE7B,KAAK,CAAC/B,KAAKF,IAAI,CAACC,MAAMC,GAAG;YAC7C,IAAIyD,aAAa,MAAM;gBACrB,MAAM7B,eAAeiC,UAAU9B,KAAK,CAAChC,MAAMC,GAAG;gBAC9CyD,WAAW7B,aAAaM,MAAM,GAAG,IAAIN,YAAY,CAAC,EAAE,GAAG;YACzD;YACA,KAAK,MAAMkC,kBAAkBrD,iBAAkB;gBAC7C,IAAIoD,UAAUf,QAAQ,CAACgB,iBAAiB,OAAO;YACjD;YACA,OAAOD,UAAUE,UAAU,CAAC,GAAGN,WAAWvC,WAAW,CAAC,CAAC,EAAEA,SAAS,CAAC,CAAC,GAAG,KAAK;QAC9E;QACA8C,OAAO9C,WAAWA,SAASa,KAAK,CAAC,KAAKG,MAAM,GAAG,IAAI;IACrD;AAEJ;AAEA,OAAO,eAAe+B,qBAAqBT,IAAY,EAAEU,IAAsB;IAC7E,IAAI;QACF,MAAMC,eAAe,MAAMC,QAAQC,GAAG,CACpCjE,mBAAmBkE,GAAG,CAAC,OAAOC;YAC5B,MAAM5E,OAAOG,KAAK0D,MAAMe;YACxB,OAAOA;QACT;QAEF,MAAMC,kBAAkB,MAAM5E,SAASE,KAAK0D,MAAMW,eAAe;QACjE,OAAOK,gBAAgB1B,QAAQ,CAACoB,SAAS,SAASxD,QAAQC,UAAU,GAAGD,QAAQE,WAAW;IAC5F,EAAE,OAAM;QACN,OAAO;IACT;AACF;AAEA,OAAO,eAAe6D,kBACpBjB,IAAY,EACZkB,OAAgB,EAChBC,aAAa,MAAM;IAEnB,MAAMR,eAAe,MAAMC,QAAQC,GAAG,CACpCjE,mBAAmBkE,GAAG,CAAC,OAAOC;QAC5B,MAAM5E,OAAOG,KAAK0D,MAAMe;QACxB,OAAOA;IACT,IACAK,KAAK,CAAC,KAAO;IAEf,IAAI,CAACT,cAAc;QACjB,QAAO,oCAAoC;IAC7C;IAEA,IAAI;QACF,MAAMK,kBAAkB,MAAM5E,SAASE,KAAK0D,MAAMW,eAAe;QACjE,MAAM,EAACU,OAAO,EAAEC,SAAS,EAAEC,YAAY,EAAE,EAAEC,aAAa,EAAE,EAAC,GAAGN;QAE9D,MAAMO,yBAAyB,CAC7BC,SACAC,UACA7D,OACA8D;YAEA,MAAMC,aAAa,OAAOF,aAAa,WAAWA,WAAWA,SAASG,MAAM;YAC5E,MAAMC,UAAU,IAAIC,OAAO,CAAC,EAAE,EAAEH,WAAW,IAAI,CAAC,EAAE;YAClD,MAAMI,UAAUP,QAAQQ,QAAQ,CAACH;YAEjC,IAAII,SAAST;YACb,KAAK,MAAMU,SAASH,QAAS;gBAC3B,IAAI,CAACG,KAAK,CAAC,EAAE,EAAE;gBACf,MAAMC,UAAUD,KAAK,CAAC,EAAE,CAAC7D,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC+D,IAAI;gBAC3CH,SAASA,OAAOI,UAAU,CACxB,IAAIP,OAAO,GAAGK,QAAQ,IAAI,CAAC,EAAE,OAC7B,GAAGA,QAAQ,CAAC,EAAET,YAAY,CAAC,CAAC,EAAE9D,MAAM,CAAC,CAAC,GAAGA,OAAO;YAEpD;YAEA,OAAOqE;QACT;QAEA,IAAIK,aAAaxB;QACjB,MAAMyB,OAAO;YACX;gBAACV,SAAS7E,QAAQwF,UAAU;gBAAE5E,OAAOwD;YAAS;YAC9C;gBAACS,SAAS7E,QAAQyF,OAAO;gBAAE7E,OAAOuD;YAAO;YACzC;gBAACU,SAAS7E,QAAQC,UAAU;gBAAEW,OAAOyD;YAAS;YAC9C;gBAACQ,SAAS7E,QAAQE,WAAW;gBAAEU,OAAO0D;YAAU;SACjD;QACD,MAAMI,YAAYZ,gBAAgB1B,QAAQ,CAAC;QAE3C,KAAK,MAAM,EAACyC,OAAO,EAAEjE,KAAK,EAAC,IAAI2E,KAAM;YACnCD,aAAaf,uBAAuBe,YAAYT,SAASjE,OAAO8D;QAClE;QAEA,MAAMvF,UAAUC,KAAK0D,MAAMmB,aAAaqB;IAC1C,EAAE,OAAOI,KAAK;QACZ5F,MAAM,CAAC,qCAAqC,EAAE4F,KAAK;QACnD,MAAM,IAAI1D,MACR;IAEJ;AACF;AAEA,OAAO,eAAe2D,oBAAoB7C,IAAY,EAAErC,IAAY;IAClE,IAAI;QACF,MAAMmF,MAAM,MAAM/F,gBAAgBT,KAAK0D,MAAM;QAC7C8C,IAAInF,IAAI,GAAGA;QAEX,MAAMtB,UAAUC,KAAK0D,MAAM,iBAAiB+C,KAAKC,SAAS,CAACF,KAAK,MAAM;IACxE,EAAE,OAAM;IACN,OAAO;IACT;AACF;AAEA,OAAO,eAAeG,uBACpBC,MAAoB,EACpBC,KAAa,EACbzC,IAAsB,EACtBY,SAAiB;IAEjB,4CAA4C;IAC5C,+BAA+B;IAC/B,uBAAuB;IACvB,KAAK;IACL,MAAM8B,WAAW,MAAMF,OAAOG,OAAO,CAAgB;QACnDpE,MAAM;YACJkE,OAAO,GAAGA,MAAM,EAAE,EAAEG,KAAKC,GAAG,GAAG,CAAC,CAAC;YACjCC,UAAU9C,SAAS,SAASrD,sBAAsBC;QACpD;QACAmG,QAAQ;QACRC,KAAK,CAAC,UAAU,EAAEpC,UAAU,OAAO,CAAC;IACtC;IACA,OAAO8B,SAASO,GAAG;AACrB;AAEA,OAAO,eAAeC,cACpBV,MAAoB,EACpBW,MAAc,EACdvC,SAAiB;IAEjB,IAAI;QACF,4CAA4C;QAC5C,+BAA+B;QAC/B,uBAAuB;QACvB,KAAK;QAEL,MAAM4B,OAAOY,UAAU,CAAC;YAACxC;QAAS,GAAG+B,OAAO,CAAC;YAC3CpE,MAAM;gBAAC8E,kBAAkB;gBAAMF,QAAQA;YAAM;YAC7CJ,QAAQ;YACRtF,KAAK;QACP;IACF,EAAE,OAAO6F,OAAO;QACd,mEAAmE;QACnEhH,MAAM,6BAA6BgH;IACrC;AACF"}
1
+ {"version":3,"sources":["../../../src/actions/init/remoteTemplate.ts"],"sourcesContent":["import {access, readFile, writeFile} from 'node:fs/promises'\nimport {join, posix, sep} from 'node:path'\nimport {Readable} from 'node:stream'\nimport {pipeline} from 'node:stream/promises'\n\nimport {subdebug} from '@sanity/cli-core'\nimport {type SanityClient} from '@sanity/client'\nimport {ENV_TEMPLATE_FILES, REQUIRED_ENV_VAR} from '@sanity/template-validator'\nimport {x} from 'tar'\n\nimport {readPackageJson} from '../../util/readPackageJson.js'\n\nconst debug = subdebug('remoteTemplate')\n\nconst DISALLOWED_PATHS = [\n // Prevent security risks from unknown GitHub Actions\n '/.github/',\n]\n\nconst ENV_VAR = {\n ...REQUIRED_ENV_VAR,\n READ_TOKEN: 'SANITY_API_READ_TOKEN',\n WRITE_TOKEN: 'SANITY_API_WRITE_TOKEN',\n} as const\n\nconst API_READ_TOKEN_ROLE = 'viewer'\nconst API_WRITE_TOKEN_ROLE = 'editor'\n\ntype EnvData = {\n dataset: string\n projectId: string\n readToken?: string\n writeToken?: string\n}\n\ntype GitHubUrlString =\n | `https://github.com/${string}/${string}`\n | `https://www.github.com/${string}/${string}`\n\nexport type RepoInfo = {\n branch: string\n filePath: string\n name: string\n username: string\n}\n\nexport function getGitHubRawContentUrl(repoInfo: RepoInfo): string {\n const {branch, filePath, name, username} = repoInfo\n return `https://raw.githubusercontent.com/${username}/${name}/${branch}/${filePath}`\n}\n\nfunction isGitHubRepoShorthand(value: string): boolean {\n if (URL.canParse(value)) {\n return false\n }\n // This supports :owner/:repo and :owner/:repo/nested/path, e.g.\n // sanity-io/sanity\n // sanity-io/sanity/templates/next-js\n // sanity-io/templates/live-content-api\n // sanity-io/sanity/packages/@sanity/cli/test/test-template\n return /^[\\w-]+\\/[\\w-.]+(\\/[@\\w-.]+)*$/.test(value)\n}\n\nfunction isGitHubRepoUrl(value: string | URL): value is GitHubUrlString | URL {\n if (URL.canParse(value) === false) {\n return false\n }\n const url = new URL(value)\n const pathSegments = url.pathname.slice(1).split('/')\n\n return (\n url.protocol === 'https:' &&\n url.hostname === 'github.com' &&\n // The pathname must have at least 2 segments. If it has more than 2, the\n // third must be \"tree\" and it must have at least 4 segments.\n // https://github.com/:owner/:repo\n // https://github.com/:owner/:repo/tree/:ref\n pathSegments.length >= 2 &&\n (pathSegments.length > 2 ? pathSegments[2] === 'tree' && pathSegments.length >= 4 : true)\n )\n}\n\nasync function downloadTarStream(url: string, bearerToken?: string): Promise<Readable> {\n const headers: Record<string, string> = {}\n if (bearerToken) {\n headers.Authorization = `Bearer ${bearerToken}`\n }\n\n const res = await fetch(url, {headers})\n\n if (!res.body) {\n throw new Error(`Failed to download: ${url}`)\n }\n\n // eslint-disable-next-line n/no-unsupported-features/node-builtins, @typescript-eslint/no-explicit-any\n return Readable.fromWeb(res.body as any)\n}\n\nexport function checkIsRemoteTemplate(templateName?: string): boolean {\n return templateName?.includes('/') ?? false\n}\n\nexport async function getGitHubRepoInfo(value: string, bearerToken?: string): Promise<RepoInfo> {\n let username = ''\n let name = ''\n let branch = ''\n let filePath = ''\n\n if (isGitHubRepoShorthand(value)) {\n const parts = value.split('/')\n username = parts[0]\n name = parts[1]\n // If there are more segments after owner/repo, they form the file path\n if (parts.length > 2) {\n filePath = parts.slice(2).join('/')\n }\n }\n\n if (isGitHubRepoUrl(value)) {\n const url = new URL(value)\n const pathSegments = url.pathname.slice(1).split('/')\n username = pathSegments[0]\n name = pathSegments[1]\n\n // If we have a \"tree\" segment, everything after branch is the file path\n if (pathSegments[2] === 'tree') {\n branch = pathSegments[3]\n if (pathSegments.length > 4) {\n filePath = pathSegments.slice(4).join('/')\n }\n }\n }\n\n if (!username || !name) {\n throw new Error('Invalid GitHub repository format')\n }\n\n const tokenMessage =\n 'GitHub repository not found. For private repositories, use --template-token to provide an access token.\\n\\n' +\n 'You can generate a new token at https://github.com/settings/personal-access-tokens/new\\n' +\n 'Set the token to \"read-only\" with repository access and a short expiry (e.g. 7 days) for security.'\n\n try {\n const headers: Record<string, string> = {}\n if (bearerToken) {\n headers.Authorization = `Bearer ${bearerToken}`\n }\n\n const infoResponse = await fetch(`https://api.github.com/repos/${username}/${name}`, {\n headers,\n })\n\n if (infoResponse.status !== 200) {\n if (infoResponse.status === 404) {\n throw new Error(tokenMessage)\n }\n throw new Error('GitHub repository not found')\n }\n\n const info = await infoResponse.json()\n\n return {\n branch: branch || info.default_branch,\n filePath,\n name,\n username,\n }\n } catch {\n throw new Error(tokenMessage)\n }\n}\n\nexport async function downloadAndExtractRepo(\n root: string,\n {branch, filePath, name, username}: RepoInfo,\n bearerToken?: string,\n): Promise<void> {\n let rootPath: string | null = null\n await pipeline(\n await downloadTarStream(\n `https://codeload.github.com/${username}/${name}/tar.gz/${branch}`,\n bearerToken,\n ),\n x({\n cwd: root,\n filter: (p: string) => {\n const posixPath = p.split(sep).join(posix.sep)\n if (rootPath === null) {\n const pathSegments = posixPath.split(posix.sep)\n rootPath = pathSegments.length > 0 ? pathSegments[0] : null\n }\n for (const disallowedPath of DISALLOWED_PATHS) {\n if (posixPath.includes(disallowedPath)) return false\n }\n return posixPath.startsWith(`${rootPath}${filePath ? `/${filePath}/` : '/'}`)\n },\n strip: filePath ? filePath.split('/').length + 1 : 1,\n }),\n )\n}\n\nexport async function checkIfNeedsApiToken(root: string, type: 'read' | 'write'): Promise<boolean> {\n try {\n const templatePath = await Promise.any(\n ENV_TEMPLATE_FILES.map(async (file) => {\n await access(join(root, file))\n return file\n }),\n )\n const templateContent = await readFile(join(root, templatePath), 'utf8')\n return templateContent.includes(type === 'read' ? ENV_VAR.READ_TOKEN : ENV_VAR.WRITE_TOKEN)\n } catch {\n return false\n }\n}\n\nexport async function applyEnvVariables(\n root: string,\n envData: EnvData,\n targetName = '.env',\n): Promise<void> {\n const templatePath = await Promise.any(\n ENV_TEMPLATE_FILES.map(async (file) => {\n await access(join(root, file))\n return file\n }),\n ).catch(() => {})\n\n if (!templatePath) {\n return // No template .env file found, skip\n }\n\n try {\n const templateContent = await readFile(join(root, templatePath), 'utf8')\n const {dataset, projectId, readToken = '', writeToken = ''} = envData\n\n const findAndReplaceVariable = (\n content: string,\n varRegex: RegExp | string,\n value: string,\n useQuotes: boolean,\n ) => {\n const varPattern = typeof varRegex === 'string' ? varRegex : varRegex.source\n const pattern = new RegExp(`.*${varPattern}=.*$`, 'gm')\n const matches = content.matchAll(pattern)\n\n let result = content\n for (const match of matches) {\n if (!match[0]) continue\n const varName = match[0].split('=')[0].trim()\n result = result.replaceAll(\n new RegExp(`${varName}=.*$`, 'gm'),\n `${varName}=${useQuotes ? `\"${value}\"` : value}`,\n )\n }\n\n return result\n }\n\n let envContent = templateContent\n const vars = [\n {pattern: ENV_VAR.PROJECT_ID, value: projectId},\n {pattern: ENV_VAR.DATASET, value: dataset},\n {pattern: ENV_VAR.READ_TOKEN, value: readToken},\n {pattern: ENV_VAR.WRITE_TOKEN, value: writeToken},\n ]\n const useQuotes = templateContent.includes('=\"')\n\n for (const {pattern, value} of vars) {\n envContent = findAndReplaceVariable(envContent, pattern, value, useQuotes)\n }\n\n await writeFile(join(root, targetName), envContent)\n } catch (err) {\n debug(`Error setting environment variables: ${err}`)\n throw new Error(\n 'Failed to set environment variables. This could be due to file permissions or the .env file format. See https://www.sanity.io/docs/environment-variables for details on environment variable setup.',\n )\n }\n}\n\nexport async function tryApplyPackageName(root: string, name: string): Promise<void> {\n try {\n const pkg = await readPackageJson(join(root, 'package.json'))\n pkg.name = name\n\n await writeFile(join(root, 'package.json'), JSON.stringify(pkg, null, 2))\n } catch {\n // noop\n }\n}\n\nexport async function generateSanityApiToken(\n client: SanityClient,\n label: string,\n type: 'read' | 'write',\n projectId: string,\n): Promise<string> {\n // const client = await getGlobalCliClient({\n // apiVersion: 'v2021-06-07',\n // requireUser: true,\n // })\n const response = await client.request<{key: string}>({\n body: {\n label: `${label} (${Date.now()})`,\n roleName: type === 'read' ? API_READ_TOKEN_ROLE : API_WRITE_TOKEN_ROLE,\n },\n method: 'POST',\n uri: `/projects/${projectId}/tokens`,\n })\n return response.key\n}\n\nexport async function setCorsOrigin(\n client: SanityClient,\n origin: string,\n projectId: string,\n): Promise<void> {\n try {\n // const client = await getGlobalCliClient({\n // apiVersion: 'v2021-06-07',\n // requireUser: true,\n // })\n\n await client.withConfig({projectId}).request({\n body: {allowCredentials: true, origin: origin}, // allowCredentials is true to allow for embedded studios if needed\n method: 'POST',\n url: '/cors',\n })\n } catch (error) {\n // Silent fail, it most likely means that the origin is already set\n debug('Failed to set CORS origin', error)\n }\n}\n"],"names":["access","readFile","writeFile","join","posix","sep","Readable","pipeline","subdebug","ENV_TEMPLATE_FILES","REQUIRED_ENV_VAR","x","readPackageJson","debug","DISALLOWED_PATHS","ENV_VAR","READ_TOKEN","WRITE_TOKEN","API_READ_TOKEN_ROLE","API_WRITE_TOKEN_ROLE","getGitHubRawContentUrl","repoInfo","branch","filePath","name","username","isGitHubRepoShorthand","value","URL","canParse","test","isGitHubRepoUrl","url","pathSegments","pathname","slice","split","protocol","hostname","length","downloadTarStream","bearerToken","headers","Authorization","res","fetch","body","Error","fromWeb","checkIsRemoteTemplate","templateName","includes","getGitHubRepoInfo","parts","tokenMessage","infoResponse","status","info","json","default_branch","downloadAndExtractRepo","root","rootPath","cwd","filter","p","posixPath","disallowedPath","startsWith","strip","checkIfNeedsApiToken","type","templatePath","Promise","any","map","file","templateContent","applyEnvVariables","envData","targetName","catch","dataset","projectId","readToken","writeToken","findAndReplaceVariable","content","varRegex","useQuotes","varPattern","source","pattern","RegExp","matches","matchAll","result","match","varName","trim","replaceAll","envContent","vars","PROJECT_ID","DATASET","err","tryApplyPackageName","pkg","JSON","stringify","generateSanityApiToken","client","label","response","request","Date","now","roleName","method","uri","key","setCorsOrigin","origin","withConfig","allowCredentials","error"],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ import { type DeployFlags } from '../deploy/types.js';
2
+ import { type AppManifest } from './types.js';
3
+ interface ExtractAppManifestOptions {
4
+ flags: DeployFlags;
5
+ workDir: string;
6
+ }
7
+ /**
8
+ *
9
+ * This functions slightly differently from the studio manifest extraction function.
10
+ * We don't need to parse very complicated information like schemas and tools,
11
+ * and we submit the manifest as a multipart form field instead of writing a file.
12
+ */
13
+ export declare function extractAppManifest(options: ExtractAppManifestOptions): Promise<AppManifest | undefined>;
14
+ /**
15
+ * App manifests aren't required right now.
16
+ * This function just ensures we're not uploading empty manifests
17
+ * (so we can reduce noise in user-applications)
18
+ */
19
+ export declare function appManifestHasData(manifest?: AppManifest | null): boolean;
20
+ export {};
@@ -0,0 +1,51 @@
1
+ import { getCliConfig } from '@sanity/cli-core';
2
+ import { spinner } from '@sanity/cli-core/ux';
3
+ import { getErrorMessage } from '../../util/getErrorMessage.js';
4
+ /**
5
+ *
6
+ * This functions slightly differently from the studio manifest extraction function.
7
+ * We don't need to parse very complicated information like schemas and tools,
8
+ * and we submit the manifest as a multipart form field instead of writing a file.
9
+ */ export async function extractAppManifest(options) {
10
+ const { workDir } = options;
11
+ const spin = spinner('Extracting manifest').start();
12
+ try {
13
+ const { app } = await getCliConfig(workDir);
14
+ if (!app) {
15
+ // this is probably a problem for deployment, but not an issue for manifest extraction
16
+ spin.succeed('No app configuration found');
17
+ return undefined;
18
+ }
19
+ const manifest = {
20
+ version: '1',
21
+ ...app.icon ? {
22
+ icon: app.icon
23
+ } : {},
24
+ ...app.title ? {
25
+ title: app.title
26
+ } : {}
27
+ };
28
+ spin.succeed(`Extracted manifest`);
29
+ return manifest;
30
+ } catch (err) {
31
+ const message = getErrorMessage(err);
32
+ spin.fail(message);
33
+ throw err;
34
+ }
35
+ }
36
+ /**
37
+ * App manifests aren't required right now.
38
+ * This function just ensures we're not uploading empty manifests
39
+ * (so we can reduce noise in user-applications)
40
+ */ export function appManifestHasData(manifest) {
41
+ if (!manifest || typeof manifest !== 'object' || Object.keys(manifest).length === 0) {
42
+ return false;
43
+ }
44
+ const validAppManifestKeys = [
45
+ 'icon',
46
+ 'title'
47
+ ];
48
+ return validAppManifestKeys.some((key)=>!!manifest[key]);
49
+ }
50
+
51
+ //# sourceMappingURL=extractAppManifest.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/actions/manifest/extractAppManifest.ts"],"sourcesContent":["import {getCliConfig} from '@sanity/cli-core'\nimport {spinner} from '@sanity/cli-core/ux'\n\nimport {getErrorMessage} from '../../util/getErrorMessage.js'\nimport {type DeployFlags} from '../deploy/types.js'\nimport {type AppManifest} from './types.js'\n\ninterface ExtractAppManifestOptions {\n flags: DeployFlags\n workDir: string\n}\n\n/**\n *\n * This functions slightly differently from the studio manifest extraction function.\n * We don't need to parse very complicated information like schemas and tools,\n * and we submit the manifest as a multipart form field instead of writing a file.\n */\nexport async function extractAppManifest(options: ExtractAppManifestOptions): Promise<AppManifest | undefined> {\n const {workDir} = options\n\n const spin = spinner('Extracting manifest').start()\n\n try {\n const {app} = await getCliConfig(workDir)\n if (!app) {\n // this is probably a problem for deployment, but not an issue for manifest extraction\n spin.succeed('No app configuration found')\n return undefined\n }\n const manifest: AppManifest = {\n version: '1',\n ...(app.icon ? {icon: app.icon} : {}),\n ...(app.title ? {title: app.title} : {}),\n }\n\n spin.succeed(`Extracted manifest`)\n\n return manifest\n } catch (err) {\n const message = getErrorMessage(err)\n spin.fail(message)\n throw err\n }\n}\n\n/**\n * App manifests aren't required right now.\n * This function just ensures we're not uploading empty manifests\n * (so we can reduce noise in user-applications)\n */\nexport function appManifestHasData(manifest?: AppManifest | null): boolean {\n if (!manifest || typeof manifest !== 'object' || Object.keys(manifest).length === 0) {\n return false\n }\n const validAppManifestKeys = ['icon', 'title']\n return validAppManifestKeys.some((key) => !!manifest[key as keyof AppManifest])\n}\n"],"names":["getCliConfig","spinner","getErrorMessage","extractAppManifest","options","workDir","spin","start","app","succeed","undefined","manifest","version","icon","title","err","message","fail","appManifestHasData","Object","keys","length","validAppManifestKeys","some","key"],"mappings":"AAAA,SAAQA,YAAY,QAAO,mBAAkB;AAC7C,SAAQC,OAAO,QAAO,sBAAqB;AAE3C,SAAQC,eAAe,QAAO,gCAA+B;AAS7D;;;;;CAKC,GACD,OAAO,eAAeC,mBAAmBC,OAAkC;IACzE,MAAM,EAACC,OAAO,EAAC,GAAGD;IAElB,MAAME,OAAOL,QAAQ,uBAAuBM,KAAK;IAEjD,IAAI;QACF,MAAM,EAACC,GAAG,EAAC,GAAG,MAAMR,aAAaK;QACjC,IAAI,CAACG,KAAK;YACR,sFAAsF;YACtFF,KAAKG,OAAO,CAAC;YACb,OAAOC;QACT;QACA,MAAMC,WAAwB;YAC5BC,SAAS;YACT,GAAIJ,IAAIK,IAAI,GAAG;gBAACA,MAAML,IAAIK,IAAI;YAAA,IAAI,CAAC,CAAC;YACpC,GAAIL,IAAIM,KAAK,GAAG;gBAACA,OAAON,IAAIM,KAAK;YAAA,IAAI,CAAC,CAAC;QACzC;QAEAR,KAAKG,OAAO,CAAC,CAAC,kBAAkB,CAAC;QAEjC,OAAOE;IACT,EAAE,OAAOI,KAAK;QACZ,MAAMC,UAAUd,gBAAgBa;QAChCT,KAAKW,IAAI,CAACD;QACV,MAAMD;IACR;AACF;AAEA;;;;CAIC,GACD,OAAO,SAASG,mBAAmBP,QAA6B;IAC9D,IAAI,CAACA,YAAY,OAAOA,aAAa,YAAYQ,OAAOC,IAAI,CAACT,UAAUU,MAAM,KAAK,GAAG;QACnF,OAAO;IACT;IACA,MAAMC,uBAAuB;QAAC;QAAQ;KAAQ;IAC9C,OAAOA,qBAAqBC,IAAI,CAAC,CAACC,MAAQ,CAAC,CAACb,QAAQ,CAACa,IAAyB;AAChF"}
@@ -27,15 +27,12 @@ const CREATE_TIMER = 'create-manifest';
27
27
  if (EXTRACT_MANIFEST_LOG_ERRORS) {
28
28
  options.output.error(err);
29
29
  }
30
- throw err;
30
+ return err;
31
31
  }
32
32
  }
33
33
  async function extractManifest(options) {
34
34
  const { flags, workDir } = options;
35
- const defaultOutputDir = resolve(join(workDir, 'dist'));
36
- const outputDir = resolve(defaultOutputDir);
37
- const defaultStaticPath = join(outputDir, 'static');
38
- const staticPath = `.${flags.path ?? defaultStaticPath}`;
35
+ const staticPath = resolve(join(workDir, flags.path));
39
36
  const path = join(staticPath, MANIFEST_FILENAME);
40
37
  const timer = getTimer();
41
38
  timer.start(CREATE_TIMER);
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/actions/manifest/extractManifest.ts"],"sourcesContent":["import {createHash} from 'node:crypto'\nimport {mkdir, writeFile} from 'node:fs/promises'\nimport {join, resolve} from 'node:path'\n\nimport {getTimer, Output} from '@sanity/cli-core'\nimport {spinner} from '@sanity/cli-core/ux'\nimport {type Workspace} from 'sanity'\n\nimport {type ExtractManifestCommand} from '../../commands/manifest/extract'\nimport {importStudioConfig} from '../../util/importStudioConfig.js'\nimport {readModuleVersion} from '../../util/readModuleVersion.js'\nimport {extractWorkspaceManifest} from './extractWorkspaceManifest.js'\nimport {\n type CreateManifest,\n type CreateWorkspaceManifest,\n type ManifestWorkspaceFile,\n} from './types'\n\nexport const MANIFEST_FILENAME = 'create-manifest.json'\nconst SCHEMA_FILENAME_SUFFIX = '.create-schema.json'\nconst TOOLS_FILENAME_SUFFIX = '.create-tools.json'\n\n/** Escape-hatch env flags to change action behavior */\nconst FEATURE_ENABLED_ENV_NAME = 'SANITY_CLI_EXTRACT_MANIFEST_ENABLED'\nconst EXTRACT_MANIFEST_ENABLED = process.env[FEATURE_ENABLED_ENV_NAME] !== 'false'\nconst EXTRACT_MANIFEST_LOG_ERRORS = process.env.SANITY_CLI_EXTRACT_MANIFEST_LOG_ERRORS === 'true'\n\nconst CREATE_TIMER = 'create-manifest'\n\ninterface ExtractManifestOptions {\n flags: ExtractManifestCommand['flags']\n output: Output\n workDir: string\n}\n\n/**\n * This function will never throw.\n * @returns `undefined` if extract succeeded - caught error if it failed\n */\nexport async function extractManifestSafe(\n options: ExtractManifestOptions,\n): Promise<Error | undefined> {\n if (!EXTRACT_MANIFEST_ENABLED) {\n return undefined\n }\n\n try {\n await extractManifest(options)\n return undefined\n } catch (err) {\n if (EXTRACT_MANIFEST_LOG_ERRORS) {\n options.output.error(err)\n }\n throw err\n }\n}\n\nasync function extractManifest(options: ExtractManifestOptions): Promise<void> {\n const {flags, workDir} = options\n const defaultOutputDir = resolve(join(workDir, 'dist'))\n const outputDir = resolve(defaultOutputDir)\n const defaultStaticPath = join(outputDir, 'static')\n const staticPath = `.${flags.path ?? defaultStaticPath}`\n const path = join(staticPath, MANIFEST_FILENAME)\n\n const timer = getTimer()\n timer.start(CREATE_TIMER)\n const spin = spinner('Extracting manifest').start()\n\n try {\n const workspaceManifests = await getWorkspaceManifests(workDir)\n await mkdir(staticPath, {recursive: true})\n\n const workspaceFiles = await writeWorkspaceFiles(workspaceManifests, staticPath)\n\n const manifest: CreateManifest = {\n /**\n * Version history:\n * 1: Initial release.\n * 2: Added tools file.\n * 3. Added studioVersion field.\n */\n createdAt: new Date().toISOString(),\n studioVersion: await readModuleVersion(workDir, 'sanity'),\n version: 3,\n workspaces: workspaceFiles,\n }\n\n await writeFile(path, JSON.stringify(manifest, null, 2))\n const manifestDuration = timer.end(CREATE_TIMER)\n\n spin.succeed(`Extracted manifest (${manifestDuration.toFixed(0)}ms)`)\n } catch (err) {\n spin.fail(err.message)\n throw err\n }\n}\n\nasync function getWorkspaceManifests(workDir: string): Promise<CreateWorkspaceManifest[]> {\n const workspaces = await importStudioConfig(workDir)\n return await extractWorkspaceManifest(workspaces as unknown as Workspace[])\n}\n\nfunction writeWorkspaceFiles(\n manifestWorkspaces: CreateWorkspaceManifest[],\n staticPath: string,\n): Promise<ManifestWorkspaceFile[]> {\n const output = manifestWorkspaces.map((workspace) => writeWorkspaceFile(workspace, staticPath))\n\n return Promise.all(output)\n}\n\nasync function writeWorkspaceFile(\n workspace: CreateWorkspaceManifest,\n staticPath: string,\n): Promise<ManifestWorkspaceFile> {\n const [schemaFilename, toolsFilename] = await Promise.all([\n createFile(staticPath, workspace.schema, SCHEMA_FILENAME_SUFFIX),\n createFile(staticPath, workspace.tools, TOOLS_FILENAME_SUFFIX),\n ])\n\n return {\n ...workspace,\n schema: schemaFilename,\n tools: toolsFilename,\n }\n}\n\nconst createFile = async (path: string, content: unknown, filenameSuffix: string) => {\n const stringifiedContent = JSON.stringify(content, null, 2)\n const hash = createHash('sha1').update(stringifiedContent).digest('hex')\n const filename = `${hash.slice(0, 8)}${filenameSuffix}`\n\n // workspaces with identical data will overwrite each others file. This is ok, since they are identical and can be shared\n await writeFile(join(path, filename), stringifiedContent)\n\n return filename\n}\n"],"names":["createHash","mkdir","writeFile","join","resolve","getTimer","spinner","importStudioConfig","readModuleVersion","extractWorkspaceManifest","MANIFEST_FILENAME","SCHEMA_FILENAME_SUFFIX","TOOLS_FILENAME_SUFFIX","FEATURE_ENABLED_ENV_NAME","EXTRACT_MANIFEST_ENABLED","process","env","EXTRACT_MANIFEST_LOG_ERRORS","SANITY_CLI_EXTRACT_MANIFEST_LOG_ERRORS","CREATE_TIMER","extractManifestSafe","options","undefined","extractManifest","err","output","error","flags","workDir","defaultOutputDir","outputDir","defaultStaticPath","staticPath","path","timer","start","spin","workspaceManifests","getWorkspaceManifests","recursive","workspaceFiles","writeWorkspaceFiles","manifest","createdAt","Date","toISOString","studioVersion","version","workspaces","JSON","stringify","manifestDuration","end","succeed","toFixed","fail","message","manifestWorkspaces","map","workspace","writeWorkspaceFile","Promise","all","schemaFilename","toolsFilename","createFile","schema","tools","content","filenameSuffix","stringifiedContent","hash","update","digest","filename","slice"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../src/actions/manifest/extractManifest.ts"],"sourcesContent":["import {createHash} from 'node:crypto'\nimport {mkdir, writeFile} from 'node:fs/promises'\nimport {join, resolve} from 'node:path'\n\nimport {getTimer, Output} from '@sanity/cli-core'\nimport {spinner} from '@sanity/cli-core/ux'\nimport {type Workspace} from 'sanity'\n\nimport {type ExtractManifestCommand} from '../../commands/manifest/extract'\nimport {importStudioConfig} from '../../util/importStudioConfig.js'\nimport {readModuleVersion} from '../../util/readModuleVersion.js'\nimport {extractWorkspaceManifest} from './extractWorkspaceManifest.js'\nimport {\n type CreateManifest,\n type CreateWorkspaceManifest,\n type ManifestWorkspaceFile,\n} from './types'\n\nexport const MANIFEST_FILENAME = 'create-manifest.json'\nconst SCHEMA_FILENAME_SUFFIX = '.create-schema.json'\nconst TOOLS_FILENAME_SUFFIX = '.create-tools.json'\n\n/** Escape-hatch env flags to change action behavior */\nconst FEATURE_ENABLED_ENV_NAME = 'SANITY_CLI_EXTRACT_MANIFEST_ENABLED'\nconst EXTRACT_MANIFEST_ENABLED = process.env[FEATURE_ENABLED_ENV_NAME] !== 'false'\nconst EXTRACT_MANIFEST_LOG_ERRORS = process.env.SANITY_CLI_EXTRACT_MANIFEST_LOG_ERRORS === 'true'\n\nconst CREATE_TIMER = 'create-manifest'\n\ninterface ExtractManifestOptions {\n flags: ExtractManifestCommand['flags']\n output: Output\n workDir: string\n}\n\n/**\n * This function will never throw.\n * @returns `undefined` if extract succeeded - caught error if it failed\n */\nexport async function extractManifestSafe(\n options: ExtractManifestOptions,\n): Promise<Error | undefined> {\n if (!EXTRACT_MANIFEST_ENABLED) {\n return undefined\n }\n\n try {\n await extractManifest(options)\n return undefined\n } catch (err) {\n if (EXTRACT_MANIFEST_LOG_ERRORS) {\n options.output.error(err)\n }\n return err\n }\n}\n\nasync function extractManifest(options: ExtractManifestOptions): Promise<void> {\n const {flags, workDir} = options\n const staticPath = resolve(join(workDir, flags.path))\n const path = join(staticPath, MANIFEST_FILENAME)\n\n const timer = getTimer()\n timer.start(CREATE_TIMER)\n const spin = spinner('Extracting manifest').start()\n\n try {\n const workspaceManifests = await getWorkspaceManifests(workDir)\n await mkdir(staticPath, {recursive: true})\n\n const workspaceFiles = await writeWorkspaceFiles(workspaceManifests, staticPath)\n\n const manifest: CreateManifest = {\n /**\n * Version history:\n * 1: Initial release.\n * 2: Added tools file.\n * 3. Added studioVersion field.\n */\n createdAt: new Date().toISOString(),\n studioVersion: await readModuleVersion(workDir, 'sanity'),\n version: 3,\n workspaces: workspaceFiles,\n }\n\n await writeFile(path, JSON.stringify(manifest, null, 2))\n const manifestDuration = timer.end(CREATE_TIMER)\n\n spin.succeed(`Extracted manifest (${manifestDuration.toFixed(0)}ms)`)\n } catch (err) {\n spin.fail(err.message)\n throw err\n }\n}\n\nasync function getWorkspaceManifests(workDir: string): Promise<CreateWorkspaceManifest[]> {\n const workspaces = await importStudioConfig(workDir)\n return await extractWorkspaceManifest(workspaces as unknown as Workspace[])\n}\n\nfunction writeWorkspaceFiles(\n manifestWorkspaces: CreateWorkspaceManifest[],\n staticPath: string,\n): Promise<ManifestWorkspaceFile[]> {\n const output = manifestWorkspaces.map((workspace) => writeWorkspaceFile(workspace, staticPath))\n\n return Promise.all(output)\n}\n\nasync function writeWorkspaceFile(\n workspace: CreateWorkspaceManifest,\n staticPath: string,\n): Promise<ManifestWorkspaceFile> {\n const [schemaFilename, toolsFilename] = await Promise.all([\n createFile(staticPath, workspace.schema, SCHEMA_FILENAME_SUFFIX),\n createFile(staticPath, workspace.tools, TOOLS_FILENAME_SUFFIX),\n ])\n\n return {\n ...workspace,\n schema: schemaFilename,\n tools: toolsFilename,\n }\n}\n\nconst createFile = async (path: string, content: unknown, filenameSuffix: string) => {\n const stringifiedContent = JSON.stringify(content, null, 2)\n const hash = createHash('sha1').update(stringifiedContent).digest('hex')\n const filename = `${hash.slice(0, 8)}${filenameSuffix}`\n\n // workspaces with identical data will overwrite each others file. This is ok, since they are identical and can be shared\n await writeFile(join(path, filename), stringifiedContent)\n\n return filename\n}\n"],"names":["createHash","mkdir","writeFile","join","resolve","getTimer","spinner","importStudioConfig","readModuleVersion","extractWorkspaceManifest","MANIFEST_FILENAME","SCHEMA_FILENAME_SUFFIX","TOOLS_FILENAME_SUFFIX","FEATURE_ENABLED_ENV_NAME","EXTRACT_MANIFEST_ENABLED","process","env","EXTRACT_MANIFEST_LOG_ERRORS","SANITY_CLI_EXTRACT_MANIFEST_LOG_ERRORS","CREATE_TIMER","extractManifestSafe","options","undefined","extractManifest","err","output","error","flags","workDir","staticPath","path","timer","start","spin","workspaceManifests","getWorkspaceManifests","recursive","workspaceFiles","writeWorkspaceFiles","manifest","createdAt","Date","toISOString","studioVersion","version","workspaces","JSON","stringify","manifestDuration","end","succeed","toFixed","fail","message","manifestWorkspaces","map","workspace","writeWorkspaceFile","Promise","all","schemaFilename","toolsFilename","createFile","schema","tools","content","filenameSuffix","stringifiedContent","hash","update","digest","filename","slice"],"mappings":"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"}
@@ -12,6 +12,11 @@ export interface CreateManifest {
12
12
  version: number;
13
13
  workspaces: ManifestWorkspaceFile[];
14
14
  }
15
+ export interface AppManifest {
16
+ version: '1';
17
+ icon?: string;
18
+ title?: string;
19
+ }
15
20
  export interface ManifestWorkspaceFile extends Omit<CreateWorkspaceManifest, 'schema' | 'tools'> {
16
21
  schema: string;
17
22
  tools: string;
@@ -94,7 +99,7 @@ export interface ManifestTool {
94
99
  type: string | null;
95
100
  }
96
101
  export type DefaultWorkspaceSchemaId = `${typeof SANITY_WORKSPACE_SCHEMA_ID_PREFIX}.${string}`;
97
- export type PrefixedWorkspaceSchemaId = `${DefaultWorkspaceSchemaId}.${string}`;
102
+ type PrefixedWorkspaceSchemaId = `${DefaultWorkspaceSchemaId}.${string}`;
98
103
  export type WorkspaceSchemaId = DefaultWorkspaceSchemaId | PrefixedWorkspaceSchemaId;
99
104
  export interface StoredWorkspaceSchema extends SanityDocumentLike {
100
105
  _id: WorkspaceSchemaId;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/actions/manifest/types.ts"],"sourcesContent":["import {type SanityDocumentLike} from '@sanity/types'\nimport {type MediaLibraryConfig} from 'sanity'\n\nexport const SANITY_WORKSPACE_SCHEMA_ID_PREFIX = '_.schemas'\nexport const SANITY_WORKSPACE_SCHEMA_TYPE = 'system.schema'\nexport const CURRENT_WORKSPACE_SCHEMA_VERSION = '2025-05-01'\n\nexport type ManifestSerializable =\n | boolean\n | ManifestSerializable[]\n | number\n | string\n | {[k: string]: ManifestSerializable}\n\nexport interface CreateManifest {\n createdAt: string\n studioVersion: string | null\n version: number\n workspaces: ManifestWorkspaceFile[]\n}\n\nexport interface ManifestWorkspaceFile extends Omit<CreateWorkspaceManifest, 'schema' | 'tools'> {\n schema: string // filename\n tools: string // filename\n}\n\nexport interface CreateWorkspaceManifest {\n basePath: string\n dataset: string\n /**\n * returns null in the case of the icon not being able to be stringified\n */\n icon: string | null\n name: string\n projectId: string\n schema: ManifestSchemaType[]\n tools: ManifestTool[]\n\n mediaLibrary?: MediaLibraryConfig\n subtitle?: string\n title?: string\n}\n\nexport interface ManifestSchemaType {\n name: string\n type: string\n\n deprecated?: {\n reason: string\n }\n fields?: ManifestField[]\n fieldsets?: ManifestFieldset[]\n hidden?: 'conditional' | boolean\n lists?: ManifestTitledValue[]\n //portable text\n marks?: {\n annotations?: ManifestArrayMember[]\n decorators?: ManifestTitledValue[]\n }\n of?: ManifestArrayMember[]\n options?: Record<string, ManifestSerializable>\n preview?: {\n select: Record<string, string>\n }\n readOnly?: 'conditional' | boolean\n styles?: ManifestTitledValue[]\n title?: string\n to?: ManifestReferenceMember[]\n validation?: ManifestValidationGroup[]\n\n // userland (assignable to ManifestSerializable | undefined)\n // not included to add some typesafty to extractManifest\n // [index: string]: unknown\n}\n\nexport interface ManifestFieldset {\n [index: string]: ManifestSerializable | undefined\n name: string\n\n title?: string\n}\n\nexport interface ManifestTitledValue {\n value: string\n\n title?: string\n}\n\ntype ManifestArrayMember = Omit<ManifestSchemaType, 'name'> & {name?: string}\ntype ManifestReferenceMember = Omit<ManifestSchemaType, 'name'> & {name?: string}\nexport type ManifestField = ManifestSchemaType & {fieldset?: string}\n\nexport interface ManifestValidationGroup {\n rules: ManifestValidationRule[]\n\n level?: 'error' | 'info' | 'warning'\n message?: string\n}\n\nexport type ManifestValidationRule = {\n [index: string]: ManifestSerializable | undefined\n constraint?: ManifestSerializable\n flag: string\n}\n\nexport interface ManifestTool {\n /**\n * returns null in the case of the icon not being able to be stringified\n */\n icon: string | null\n name: string\n title: string\n type: string | null\n}\n\nexport type DefaultWorkspaceSchemaId = `${typeof SANITY_WORKSPACE_SCHEMA_ID_PREFIX}.${string}`\nexport type PrefixedWorkspaceSchemaId = `${DefaultWorkspaceSchemaId}.${string}`\nexport type WorkspaceSchemaId = DefaultWorkspaceSchemaId | PrefixedWorkspaceSchemaId\n\nexport interface StoredWorkspaceSchema extends SanityDocumentLike {\n _id: WorkspaceSchemaId\n _type: typeof SANITY_WORKSPACE_SCHEMA_TYPE\n /**\n * The API expects JSON coming in, but will store a string to save on attribute paths.\n * Consumers must use JSON.parse on the value, put we deploy to the API using ManifestSchemaType[]\n */\n schema: ManifestSchemaType[] | string\n /* api-like version string: date at which the format had a meaningful change */\n version: typeof CURRENT_WORKSPACE_SCHEMA_VERSION | undefined\n workspace: {\n name: string\n title?: string\n }\n\n tag?: string\n}\n"],"names":["SANITY_WORKSPACE_SCHEMA_ID_PREFIX","SANITY_WORKSPACE_SCHEMA_TYPE","CURRENT_WORKSPACE_SCHEMA_VERSION"],"mappings":"AAGA,OAAO,MAAMA,oCAAoC,YAAW;AAC5D,OAAO,MAAMC,+BAA+B,gBAAe;AAC3D,OAAO,MAAMC,mCAAmC,aAAY"}
1
+ {"version":3,"sources":["../../../src/actions/manifest/types.ts"],"sourcesContent":["import {type SanityDocumentLike} from '@sanity/types'\nimport {type MediaLibraryConfig} from 'sanity'\n\nexport const SANITY_WORKSPACE_SCHEMA_ID_PREFIX = '_.schemas'\nexport const SANITY_WORKSPACE_SCHEMA_TYPE = 'system.schema'\nexport const CURRENT_WORKSPACE_SCHEMA_VERSION = '2025-05-01'\n\nexport type ManifestSerializable =\n | boolean\n | ManifestSerializable[]\n | number\n | string\n | {[k: string]: ManifestSerializable}\n\nexport interface CreateManifest {\n createdAt: string\n studioVersion: string | null\n version: number\n workspaces: ManifestWorkspaceFile[]\n}\n\nexport interface AppManifest {\n version: '1'\n\n icon?: string\n title?: string\n}\n\nexport interface ManifestWorkspaceFile extends Omit<CreateWorkspaceManifest, 'schema' | 'tools'> {\n schema: string // filename\n tools: string // filename\n}\n\nexport interface CreateWorkspaceManifest {\n basePath: string\n dataset: string\n /**\n * returns null in the case of the icon not being able to be stringified\n */\n icon: string | null\n name: string\n projectId: string\n schema: ManifestSchemaType[]\n tools: ManifestTool[]\n\n mediaLibrary?: MediaLibraryConfig\n subtitle?: string\n title?: string\n}\n\nexport interface ManifestSchemaType {\n name: string\n type: string\n\n deprecated?: {\n reason: string\n }\n fields?: ManifestField[]\n fieldsets?: ManifestFieldset[]\n hidden?: 'conditional' | boolean\n lists?: ManifestTitledValue[]\n //portable text\n marks?: {\n annotations?: ManifestArrayMember[]\n decorators?: ManifestTitledValue[]\n }\n of?: ManifestArrayMember[]\n options?: Record<string, ManifestSerializable>\n preview?: {\n select: Record<string, string>\n }\n readOnly?: 'conditional' | boolean\n styles?: ManifestTitledValue[]\n title?: string\n to?: ManifestReferenceMember[]\n validation?: ManifestValidationGroup[]\n\n // userland (assignable to ManifestSerializable | undefined)\n // not included to add some typesafty to extractManifest\n // [index: string]: unknown\n}\n\nexport interface ManifestFieldset {\n [index: string]: ManifestSerializable | undefined\n name: string\n\n title?: string\n}\n\nexport interface ManifestTitledValue {\n value: string\n\n title?: string\n}\n\ntype ManifestArrayMember = Omit<ManifestSchemaType, 'name'> & {name?: string}\ntype ManifestReferenceMember = Omit<ManifestSchemaType, 'name'> & {name?: string}\nexport type ManifestField = ManifestSchemaType & {fieldset?: string}\n\nexport interface ManifestValidationGroup {\n rules: ManifestValidationRule[]\n\n level?: 'error' | 'info' | 'warning'\n message?: string\n}\n\nexport type ManifestValidationRule = {\n [index: string]: ManifestSerializable | undefined\n constraint?: ManifestSerializable\n flag: string\n}\n\nexport interface ManifestTool {\n /**\n * returns null in the case of the icon not being able to be stringified\n */\n icon: string | null\n name: string\n title: string\n type: string | null\n}\n\nexport type DefaultWorkspaceSchemaId = `${typeof SANITY_WORKSPACE_SCHEMA_ID_PREFIX}.${string}`\ntype PrefixedWorkspaceSchemaId = `${DefaultWorkspaceSchemaId}.${string}`\nexport type WorkspaceSchemaId = DefaultWorkspaceSchemaId | PrefixedWorkspaceSchemaId\n\nexport interface StoredWorkspaceSchema extends SanityDocumentLike {\n _id: WorkspaceSchemaId\n _type: typeof SANITY_WORKSPACE_SCHEMA_TYPE\n /**\n * The API expects JSON coming in, but will store a string to save on attribute paths.\n * Consumers must use JSON.parse on the value, put we deploy to the API using ManifestSchemaType[]\n */\n schema: ManifestSchemaType[] | string\n /* api-like version string: date at which the format had a meaningful change */\n version: typeof CURRENT_WORKSPACE_SCHEMA_VERSION | undefined\n workspace: {\n name: string\n title?: string\n }\n\n tag?: string\n}\n"],"names":["SANITY_WORKSPACE_SCHEMA_ID_PREFIX","SANITY_WORKSPACE_SCHEMA_TYPE","CURRENT_WORKSPACE_SCHEMA_VERSION"],"mappings":"AAGA,OAAO,MAAMA,oCAAoC,YAAW;AAC5D,OAAO,MAAMC,+BAA+B,gBAAe;AAC3D,OAAO,MAAMC,mCAAmC,aAAY"}
@@ -1,5 +1,6 @@
1
1
  import { access, readdir } from 'node:fs/promises';
2
2
  import path from 'node:path';
3
+ import { tryGetDefaultExport } from '@sanity/cli-core';
3
4
  import { validateMediaLibraryAssetAspect } from '@sanity/schema/_internal';
4
5
  import { isAssetAspect } from '@sanity/types';
5
6
  import { getTsconfig } from 'get-tsconfig';
@@ -52,7 +53,7 @@ import { tsImport } from 'tsx/esm/api';
52
53
  tsconfig: tsconfig?.path
53
54
  });
54
55
  // Get the default export
55
- const maybeAspect = aspectModule.default;
56
+ const maybeAspect = tryGetDefaultExport(aspectModule);
56
57
  // Check if user wants to filter this aspect
57
58
  if (!filterAspects(maybeAspect)) {
58
59
  continue;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/actions/media/importAspects.ts"],"sourcesContent":["import {access, readdir} from 'node:fs/promises'\nimport path from 'node:path'\n\nimport {validateMediaLibraryAssetAspect} from '@sanity/schema/_internal'\nimport {\n isAssetAspect,\n type MediaLibraryAssetAspectDocument,\n type SchemaValidationProblem,\n} from '@sanity/types'\nimport {getTsconfig} from 'get-tsconfig'\nimport {tsImport} from 'tsx/esm/api'\n\n/**\n * File extensions that are considered valid aspect definition files\n */\nconst ASPECT_FILE_EXTENSIONS = new Set(['.js', '.jsx', '.mjs', '.mts', '.ts', '.tsx'])\n\n/**\n * Type for an aspect that has been validated\n */\ninterface ValidAspect {\n aspect: MediaLibraryAssetAspectDocument\n filename: string\n status: 'valid'\n validationErrors: never[]\n}\n\n/**\n * Type for an aspect that failed validation\n */\ninterface InvalidAspect {\n aspect: unknown\n filename: string\n status: 'invalid'\n validationErrors: SchemaValidationProblem[][]\n}\n\n/**\n * Union type for aspect containers\n */\ntype AspectContainer = InvalidAspect | ValidAspect\n\n/**\n * Options for importing aspects\n */\ninterface ImportAspectsOptions {\n /**\n * Path to the directory containing aspect definition files\n */\n aspectsPath: string\n\n /**\n * Optional filter function to determine which aspects to include\n */\n filterAspects?: (aspect: unknown) => boolean\n}\n\n/**\n * Result of importing aspects, grouped by validation status\n */\ninterface ImportAspectsResult {\n invalid: InvalidAspect[]\n valid: ValidAspect[]\n}\n\n/**\n * Import and validate aspect definition files from a directory\n *\n * This function reads all TypeScript/JavaScript files from the specified directory,\n * dynamically imports them using tsx for TypeScript support, validates them,\n * and returns them grouped by validation status.\n *\n * @param options - Options for importing aspects\n * @returns Promise resolving to valid and invalid aspects\n * @internal\n */\nexport async function importAspects(options: ImportAspectsOptions): Promise<ImportAspectsResult> {\n const {aspectsPath, filterAspects = () => true} = options\n\n // Check if directory exists\n try {\n await access(aspectsPath)\n } catch {\n throw new Error(`Aspects directory does not exist: ${aspectsPath}`)\n }\n\n // Read directory entries\n const entries = await readdir(aspectsPath, {withFileTypes: true})\n\n // Filter for valid aspect files\n const aspectFiles = entries.filter(\n (entry) => entry.isFile() && ASPECT_FILE_EXTENSIONS.has(path.extname(entry.name)),\n )\n\n // Get tsconfig for TypeScript compilation\n const tsconfig = getTsconfig(aspectsPath)\n\n // Import and validate all aspect files\n const aspects: AspectContainer[] = []\n\n for (const file of aspectFiles) {\n const filename = file.name\n const filePath = path.resolve(aspectsPath, filename)\n\n try {\n // Dynamically import the aspect file with TypeScript support\n const aspectModule = await tsImport(filePath, {\n parentURL: import.meta.url,\n tsconfig: tsconfig?.path,\n })\n\n // Get the default export\n const maybeAspect = aspectModule.default\n\n // Check if user wants to filter this aspect\n if (!filterAspects(maybeAspect)) {\n continue\n }\n\n // Validate that it's an asset aspect\n if (!isAssetAspect(maybeAspect)) {\n aspects.push({\n aspect: maybeAspect,\n filename,\n status: 'invalid',\n validationErrors: [],\n })\n continue\n }\n\n // Validate the aspect schema\n const [valid, errors] = validateMediaLibraryAssetAspect(maybeAspect.definition)\n\n if (!valid) {\n aspects.push({\n aspect: maybeAspect,\n filename,\n status: 'invalid',\n validationErrors: errors,\n })\n continue\n }\n\n aspects.push({\n aspect: maybeAspect,\n filename,\n status: 'valid',\n validationErrors: [],\n })\n } catch (error) {\n aspects.push({\n aspect: null,\n filename,\n status: 'invalid',\n validationErrors: [\n [\n {\n message: `Failed to import file: ${error instanceof Error ? error.message : 'Unknown error'}`,\n severity: 'error',\n },\n ],\n ],\n })\n }\n }\n\n // Group by validation status\n const result: ImportAspectsResult = {\n invalid: aspects.filter((a): a is InvalidAspect => a.status === 'invalid'),\n valid: aspects.filter((a): a is ValidAspect => a.status === 'valid'),\n }\n\n return result\n}\n"],"names":["access","readdir","path","validateMediaLibraryAssetAspect","isAssetAspect","getTsconfig","tsImport","ASPECT_FILE_EXTENSIONS","Set","importAspects","options","aspectsPath","filterAspects","Error","entries","withFileTypes","aspectFiles","filter","entry","isFile","has","extname","name","tsconfig","aspects","file","filename","filePath","resolve","aspectModule","parentURL","url","maybeAspect","default","push","aspect","status","validationErrors","valid","errors","definition","error","message","severity","result","invalid","a"],"mappings":"AAAA,SAAQA,MAAM,EAAEC,OAAO,QAAO,mBAAkB;AAChD,OAAOC,UAAU,YAAW;AAE5B,SAAQC,+BAA+B,QAAO,2BAA0B;AACxE,SACEC,aAAa,QAGR,gBAAe;AACtB,SAAQC,WAAW,QAAO,eAAc;AACxC,SAAQC,QAAQ,QAAO,cAAa;AAEpC;;CAEC,GACD,MAAMC,yBAAyB,IAAIC,IAAI;IAAC;IAAO;IAAQ;IAAQ;IAAQ;IAAO;CAAO;AAkDrF;;;;;;;;;;CAUC,GACD,OAAO,eAAeC,cAAcC,OAA6B;IAC/D,MAAM,EAACC,WAAW,EAAEC,gBAAgB,IAAM,IAAI,EAAC,GAAGF;IAElD,4BAA4B;IAC5B,IAAI;QACF,MAAMV,OAAOW;IACf,EAAE,OAAM;QACN,MAAM,IAAIE,MAAM,CAAC,kCAAkC,EAAEF,aAAa;IACpE;IAEA,yBAAyB;IACzB,MAAMG,UAAU,MAAMb,QAAQU,aAAa;QAACI,eAAe;IAAI;IAE/D,gCAAgC;IAChC,MAAMC,cAAcF,QAAQG,MAAM,CAChC,CAACC,QAAUA,MAAMC,MAAM,MAAMZ,uBAAuBa,GAAG,CAAClB,KAAKmB,OAAO,CAACH,MAAMI,IAAI;IAGjF,0CAA0C;IAC1C,MAAMC,WAAWlB,YAAYM;IAE7B,uCAAuC;IACvC,MAAMa,UAA6B,EAAE;IAErC,KAAK,MAAMC,QAAQT,YAAa;QAC9B,MAAMU,WAAWD,KAAKH,IAAI;QAC1B,MAAMK,WAAWzB,KAAK0B,OAAO,CAACjB,aAAae;QAE3C,IAAI;YACF,6DAA6D;YAC7D,MAAMG,eAAe,MAAMvB,SAASqB,UAAU;gBAC5CG,WAAW,YAAYC,GAAG;gBAC1BR,UAAUA,UAAUrB;YACtB;YAEA,yBAAyB;YACzB,MAAM8B,cAAcH,aAAaI,OAAO;YAExC,4CAA4C;YAC5C,IAAI,CAACrB,cAAcoB,cAAc;gBAC/B;YACF;YAEA,qCAAqC;YACrC,IAAI,CAAC5B,cAAc4B,cAAc;gBAC/BR,QAAQU,IAAI,CAAC;oBACXC,QAAQH;oBACRN;oBACAU,QAAQ;oBACRC,kBAAkB,EAAE;gBACtB;gBACA;YACF;YAEA,6BAA6B;YAC7B,MAAM,CAACC,OAAOC,OAAO,GAAGpC,gCAAgC6B,YAAYQ,UAAU;YAE9E,IAAI,CAACF,OAAO;gBACVd,QAAQU,IAAI,CAAC;oBACXC,QAAQH;oBACRN;oBACAU,QAAQ;oBACRC,kBAAkBE;gBACpB;gBACA;YACF;YAEAf,QAAQU,IAAI,CAAC;gBACXC,QAAQH;gBACRN;gBACAU,QAAQ;gBACRC,kBAAkB,EAAE;YACtB;QACF,EAAE,OAAOI,OAAO;YACdjB,QAAQU,IAAI,CAAC;gBACXC,QAAQ;gBACRT;gBACAU,QAAQ;gBACRC,kBAAkB;oBAChB;wBACE;4BACEK,SAAS,CAAC,uBAAuB,EAAED,iBAAiB5B,QAAQ4B,MAAMC,OAAO,GAAG,iBAAiB;4BAC7FC,UAAU;wBACZ;qBACD;iBACF;YACH;QACF;IACF;IAEA,6BAA6B;IAC7B,MAAMC,SAA8B;QAClCC,SAASrB,QAAQP,MAAM,CAAC,CAAC6B,IAA0BA,EAAEV,MAAM,KAAK;QAChEE,OAAOd,QAAQP,MAAM,CAAC,CAAC6B,IAAwBA,EAAEV,MAAM,KAAK;IAC9D;IAEA,OAAOQ;AACT"}
1
+ {"version":3,"sources":["../../../src/actions/media/importAspects.ts"],"sourcesContent":["import {access, readdir} from 'node:fs/promises'\nimport path from 'node:path'\n\nimport {tryGetDefaultExport} from '@sanity/cli-core'\nimport {validateMediaLibraryAssetAspect} from '@sanity/schema/_internal'\nimport {\n isAssetAspect,\n type MediaLibraryAssetAspectDocument,\n type SchemaValidationProblem,\n} from '@sanity/types'\nimport {getTsconfig} from 'get-tsconfig'\nimport {tsImport} from 'tsx/esm/api'\n\n/**\n * File extensions that are considered valid aspect definition files\n */\nconst ASPECT_FILE_EXTENSIONS = new Set(['.js', '.jsx', '.mjs', '.mts', '.ts', '.tsx'])\n\n/**\n * Type for an aspect that has been validated\n */\ninterface ValidAspect {\n aspect: MediaLibraryAssetAspectDocument\n filename: string\n status: 'valid'\n validationErrors: never[]\n}\n\n/**\n * Type for an aspect that failed validation\n */\ninterface InvalidAspect {\n aspect: unknown\n filename: string\n status: 'invalid'\n validationErrors: SchemaValidationProblem[][]\n}\n\n/**\n * Union type for aspect containers\n */\ntype AspectContainer = InvalidAspect | ValidAspect\n\n/**\n * Options for importing aspects\n */\ninterface ImportAspectsOptions {\n /**\n * Path to the directory containing aspect definition files\n */\n aspectsPath: string\n\n /**\n * Optional filter function to determine which aspects to include\n */\n filterAspects?: (aspect: unknown) => boolean\n}\n\n/**\n * Result of importing aspects, grouped by validation status\n */\ninterface ImportAspectsResult {\n invalid: InvalidAspect[]\n valid: ValidAspect[]\n}\n\n/**\n * Import and validate aspect definition files from a directory\n *\n * This function reads all TypeScript/JavaScript files from the specified directory,\n * dynamically imports them using tsx for TypeScript support, validates them,\n * and returns them grouped by validation status.\n *\n * @param options - Options for importing aspects\n * @returns Promise resolving to valid and invalid aspects\n * @internal\n */\nexport async function importAspects(options: ImportAspectsOptions): Promise<ImportAspectsResult> {\n const {aspectsPath, filterAspects = () => true} = options\n\n // Check if directory exists\n try {\n await access(aspectsPath)\n } catch {\n throw new Error(`Aspects directory does not exist: ${aspectsPath}`)\n }\n\n // Read directory entries\n const entries = await readdir(aspectsPath, {withFileTypes: true})\n\n // Filter for valid aspect files\n const aspectFiles = entries.filter(\n (entry) => entry.isFile() && ASPECT_FILE_EXTENSIONS.has(path.extname(entry.name)),\n )\n\n // Get tsconfig for TypeScript compilation\n const tsconfig = getTsconfig(aspectsPath)\n\n // Import and validate all aspect files\n const aspects: AspectContainer[] = []\n\n for (const file of aspectFiles) {\n const filename = file.name\n const filePath = path.resolve(aspectsPath, filename)\n\n try {\n // Dynamically import the aspect file with TypeScript support\n const aspectModule = await tsImport(filePath, {\n parentURL: import.meta.url,\n tsconfig: tsconfig?.path,\n })\n\n // Get the default export\n const maybeAspect = tryGetDefaultExport(aspectModule)\n\n // Check if user wants to filter this aspect\n if (!filterAspects(maybeAspect)) {\n continue\n }\n\n // Validate that it's an asset aspect\n if (!isAssetAspect(maybeAspect)) {\n aspects.push({\n aspect: maybeAspect,\n filename,\n status: 'invalid',\n validationErrors: [],\n })\n continue\n }\n\n // Validate the aspect schema\n const [valid, errors] = validateMediaLibraryAssetAspect(maybeAspect.definition)\n\n if (!valid) {\n aspects.push({\n aspect: maybeAspect,\n filename,\n status: 'invalid',\n validationErrors: errors,\n })\n continue\n }\n\n aspects.push({\n aspect: maybeAspect,\n filename,\n status: 'valid',\n validationErrors: [],\n })\n } catch (error) {\n aspects.push({\n aspect: null,\n filename,\n status: 'invalid',\n validationErrors: [\n [\n {\n message: `Failed to import file: ${error instanceof Error ? error.message : 'Unknown error'}`,\n severity: 'error',\n },\n ],\n ],\n })\n }\n }\n\n // Group by validation status\n const result: ImportAspectsResult = {\n invalid: aspects.filter((a): a is InvalidAspect => a.status === 'invalid'),\n valid: aspects.filter((a): a is ValidAspect => a.status === 'valid'),\n }\n\n return result\n}\n"],"names":["access","readdir","path","tryGetDefaultExport","validateMediaLibraryAssetAspect","isAssetAspect","getTsconfig","tsImport","ASPECT_FILE_EXTENSIONS","Set","importAspects","options","aspectsPath","filterAspects","Error","entries","withFileTypes","aspectFiles","filter","entry","isFile","has","extname","name","tsconfig","aspects","file","filename","filePath","resolve","aspectModule","parentURL","url","maybeAspect","push","aspect","status","validationErrors","valid","errors","definition","error","message","severity","result","invalid","a"],"mappings":"AAAA,SAAQA,MAAM,EAAEC,OAAO,QAAO,mBAAkB;AAChD,OAAOC,UAAU,YAAW;AAE5B,SAAQC,mBAAmB,QAAO,mBAAkB;AACpD,SAAQC,+BAA+B,QAAO,2BAA0B;AACxE,SACEC,aAAa,QAGR,gBAAe;AACtB,SAAQC,WAAW,QAAO,eAAc;AACxC,SAAQC,QAAQ,QAAO,cAAa;AAEpC;;CAEC,GACD,MAAMC,yBAAyB,IAAIC,IAAI;IAAC;IAAO;IAAQ;IAAQ;IAAQ;IAAO;CAAO;AAkDrF;;;;;;;;;;CAUC,GACD,OAAO,eAAeC,cAAcC,OAA6B;IAC/D,MAAM,EAACC,WAAW,EAAEC,gBAAgB,IAAM,IAAI,EAAC,GAAGF;IAElD,4BAA4B;IAC5B,IAAI;QACF,MAAMX,OAAOY;IACf,EAAE,OAAM;QACN,MAAM,IAAIE,MAAM,CAAC,kCAAkC,EAAEF,aAAa;IACpE;IAEA,yBAAyB;IACzB,MAAMG,UAAU,MAAMd,QAAQW,aAAa;QAACI,eAAe;IAAI;IAE/D,gCAAgC;IAChC,MAAMC,cAAcF,QAAQG,MAAM,CAChC,CAACC,QAAUA,MAAMC,MAAM,MAAMZ,uBAAuBa,GAAG,CAACnB,KAAKoB,OAAO,CAACH,MAAMI,IAAI;IAGjF,0CAA0C;IAC1C,MAAMC,WAAWlB,YAAYM;IAE7B,uCAAuC;IACvC,MAAMa,UAA6B,EAAE;IAErC,KAAK,MAAMC,QAAQT,YAAa;QAC9B,MAAMU,WAAWD,KAAKH,IAAI;QAC1B,MAAMK,WAAW1B,KAAK2B,OAAO,CAACjB,aAAae;QAE3C,IAAI;YACF,6DAA6D;YAC7D,MAAMG,eAAe,MAAMvB,SAASqB,UAAU;gBAC5CG,WAAW,YAAYC,GAAG;gBAC1BR,UAAUA,UAAUtB;YACtB;YAEA,yBAAyB;YACzB,MAAM+B,cAAc9B,oBAAoB2B;YAExC,4CAA4C;YAC5C,IAAI,CAACjB,cAAcoB,cAAc;gBAC/B;YACF;YAEA,qCAAqC;YACrC,IAAI,CAAC5B,cAAc4B,cAAc;gBAC/BR,QAAQS,IAAI,CAAC;oBACXC,QAAQF;oBACRN;oBACAS,QAAQ;oBACRC,kBAAkB,EAAE;gBACtB;gBACA;YACF;YAEA,6BAA6B;YAC7B,MAAM,CAACC,OAAOC,OAAO,GAAGnC,gCAAgC6B,YAAYO,UAAU;YAE9E,IAAI,CAACF,OAAO;gBACVb,QAAQS,IAAI,CAAC;oBACXC,QAAQF;oBACRN;oBACAS,QAAQ;oBACRC,kBAAkBE;gBACpB;gBACA;YACF;YAEAd,QAAQS,IAAI,CAAC;gBACXC,QAAQF;gBACRN;gBACAS,QAAQ;gBACRC,kBAAkB,EAAE;YACtB;QACF,EAAE,OAAOI,OAAO;YACdhB,QAAQS,IAAI,CAAC;gBACXC,QAAQ;gBACRR;gBACAS,QAAQ;gBACRC,kBAAkB;oBAChB;wBACE;4BACEK,SAAS,CAAC,uBAAuB,EAAED,iBAAiB3B,QAAQ2B,MAAMC,OAAO,GAAG,iBAAiB;4BAC7FC,UAAU;wBACZ;qBACD;iBACF;YACH;QACF;IACF;IAEA,6BAA6B;IAC7B,MAAMC,SAA8B;QAClCC,SAASpB,QAAQP,MAAM,CAAC,CAAC4B,IAA0BA,EAAEV,MAAM,KAAK;QAChEE,OAAOb,QAAQP,MAAM,CAAC,CAAC4B,IAAwBA,EAAEV,MAAM,KAAK;IAC9D;IAEA,OAAOQ;AACT"}
@@ -1,8 +1,15 @@
1
- import { type SchemaStoreActionResult, type SchemaStoreContext } from './schemaStoreTypes.js';
2
- import { type SchemaStoreCommonFlags } from './utils/schemaStoreValidation.js';
3
- export interface DeleteSchemaFlags extends SchemaStoreCommonFlags {
1
+ import { type Output } from '@sanity/cli-core';
2
+ import { type SchemaStoreActionResult } from './schemaStoreTypes.js';
3
+ import { type WorkspaceSchemaId } from './utils/schemaStoreValidation.js';
4
+ interface DeleteSchemasOptions {
5
+ extractManifest: boolean;
6
+ ids: WorkspaceSchemaId[];
7
+ manifestDir: string;
8
+ output: Output;
9
+ projectId: string;
10
+ verbose: boolean;
11
+ workDir: string;
4
12
  dataset?: string;
5
- ids?: string;
6
13
  }
7
14
  /**
8
15
  * Deletes all stored schemas matching --ids in workspace datasets.
@@ -12,4 +19,5 @@ export interface DeleteSchemaFlags extends SchemaStoreCommonFlags {
12
19
  * Manifest generation can be optionally disabled with --no-manifest-extract.
13
20
  * In this case the command uses and existing file or throws when missing.
14
21
  */
15
- export declare function deleteSchemaAction(flags: DeleteSchemaFlags, context: SchemaStoreContext): Promise<SchemaStoreActionResult>;
22
+ export declare function deleteSchemaAction(options: DeleteSchemasOptions): Promise<SchemaStoreActionResult>;
23
+ export {};
@@ -1,10 +1,10 @@
1
1
  import { chalk } from '@sanity/cli-core/ux';
2
+ import { deleteSchema } from '../../services/schemas.js';
2
3
  import { isDefined } from '../manifest/schemaTypeHelpers.js';
3
4
  import { ensureManifestExtractSatisfied } from './utils/manifestExtractor.js';
4
5
  import { createManifestReader } from './utils/manifestReader.js';
5
- import { createSchemaApiClient } from './utils/schemaApiClient.js';
6
6
  import { getDatasetsOutString, getStringList } from './utils/schemaStoreOutStrings.js';
7
- import { filterLogReadProjectIdMismatch, parseDeleteSchemasConfig } from './utils/schemaStoreValidation.js';
7
+ import { filterLogReadProjectIdMismatch } from './utils/schemaStoreValidation.js';
8
8
  // Native implementation instead of lodash/uniq
9
9
  function uniq(array) {
10
10
  return [
@@ -28,36 +28,31 @@ class DeleteIdError extends Error {
28
28
  * All schema store actions require a manifest to exist, so we regenerate it by default.
29
29
  * Manifest generation can be optionally disabled with --no-manifest-extract.
30
30
  * In this case the command uses and existing file or throws when missing.
31
- */ export async function deleteSchemaAction(flags, context) {
32
- const { dataset, extractManifest, ids, manifestDir, verbose } = parseDeleteSchemasConfig(flags, context);
33
- const { apiClient, jsonReader, manifestExtractor, output } = context;
34
- // prettier-ignore
31
+ */ export async function deleteSchemaAction(options) {
32
+ const { dataset, extractManifest, ids, manifestDir, output, projectId, verbose, workDir } = options;
35
33
  if (!await ensureManifestExtractSatisfied({
36
34
  extractManifest,
37
35
  manifestDir,
38
- manifestExtractor,
39
36
  output,
40
- schemaRequired: true
37
+ schemaRequired: true,
38
+ workDir
41
39
  })) {
42
40
  return 'failure';
43
41
  }
44
- const { client, projectId } = await createSchemaApiClient(apiClient);
45
42
  const manifest = await createManifestReader({
46
- jsonReader,
47
43
  manifestDir,
48
- output
44
+ output,
45
+ workDir
49
46
  }).getManifest();
50
47
  const workspaces = manifest.workspaces.filter((workspace)=>!dataset || workspace.dataset === dataset).filter((workspace)=>filterLogReadProjectIdMismatch(workspace, projectId, output));
51
48
  const datasets = uniq(workspaces.map((w)=>w.dataset));
52
49
  const results = await Promise.allSettled(datasets.flatMap((targetDataset)=>{
53
50
  return ids.map(async ({ schemaId })=>{
54
51
  try {
55
- const deletedSchema = await client.withConfig({
56
- dataset: targetDataset
57
- }).delete(schemaId);
52
+ const deletedSchema = await deleteSchema(targetDataset, projectId, schemaId);
58
53
  return {
59
54
  dataset: targetDataset,
60
- deleted: deletedSchema.results.length > 0,
55
+ deleted: deletedSchema.deleted,
61
56
  schemaId
62
57
  };
63
58
  } catch (err) {
@@ -72,11 +67,11 @@ class DeleteIdError extends Error {
72
67
  const deleteFailureIds = uniq(results.filter((r)=>r.status === 'rejected').map((result)=>{
73
68
  const error = result.reason;
74
69
  if (error instanceof DeleteIdError) {
75
- output.error(chalk.red([
70
+ output.warn(chalk.red([
76
71
  `Failed to delete schema "${error.id}" in dataset "${error.dataset}":`,
77
72
  error.message
78
73
  ].join('\n')));
79
- if (verbose) output.error(error);
74
+ if (verbose) output.warn(error);
80
75
  return error.id;
81
76
  }
82
77
  //hubris inc: given the try-catch wrapping the full promise "this should never happen"
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/actions/schema/deleteSchemaAction.ts"],"sourcesContent":["import {chalk} from '@sanity/cli-core/ux'\n\nimport {isDefined} from '../manifest/schemaTypeHelpers.js'\nimport {type SchemaStoreActionResult, type SchemaStoreContext} from './schemaStoreTypes.js'\nimport {ensureManifestExtractSatisfied} from './utils/manifestExtractor.js'\nimport {createManifestReader} from './utils/manifestReader.js'\nimport {createSchemaApiClient} from './utils/schemaApiClient.js'\nimport {getDatasetsOutString, getStringList} from './utils/schemaStoreOutStrings.js'\nimport {\n filterLogReadProjectIdMismatch,\n parseDeleteSchemasConfig,\n type SchemaStoreCommonFlags,\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\nexport interface DeleteSchemaFlags extends SchemaStoreCommonFlags {\n dataset?: string\n ids?: 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 flags: DeleteSchemaFlags,\n context: SchemaStoreContext,\n): Promise<SchemaStoreActionResult> {\n const {dataset, extractManifest, ids, manifestDir, verbose} = parseDeleteSchemasConfig(\n flags,\n context,\n )\n const {apiClient, jsonReader, manifestExtractor, output} = context\n\n // prettier-ignore\n if (!(await ensureManifestExtractSatisfied({extractManifest, manifestDir, manifestExtractor, output, schemaRequired: true,}))) {\n return 'failure'\n }\n\n const {client, projectId} = await createSchemaApiClient(apiClient)\n const manifest = await createManifestReader({jsonReader, manifestDir, output}).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 client.withConfig({dataset: targetDataset}).delete(schemaId)\n return {dataset: targetDataset, deleted: deletedSchema.results.length > 0, 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.error(\n chalk.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.error(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":["chalk","isDefined","ensureManifestExtractSatisfied","createManifestReader","createSchemaApiClient","getDatasetsOutString","getStringList","filterLogReadProjectIdMismatch","parseDeleteSchemasConfig","uniq","array","Set","DeleteIdError","Error","dataset","id","options","cause","message","name","deleteSchemaAction","flags","context","extractManifest","ids","manifestDir","verbose","apiClient","jsonReader","manifestExtractor","output","schemaRequired","client","projectId","manifest","getManifest","workspaces","filter","workspace","datasets","map","w","results","Promise","allSettled","flatMap","targetDataset","schemaId","deletedSchema","withConfig","delete","deleted","length","err","deletedIds","r","status","value","notFound","includes","deleteFailureIds","result","error","reason","red","join","uniqueDeletedSchemaIds","success","log","undefined","item"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../src/actions/schema/deleteSchemaAction.ts"],"sourcesContent":["import {type Output} from '@sanity/cli-core'\nimport {chalk} from '@sanity/cli-core/ux'\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 chalk.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":["chalk","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","red","join","uniqueDeletedSchemaIds","success","length","log","undefined","item"],"mappings":"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"}