dineway 0.1.3 → 0.1.5

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 (296) hide show
  1. package/README.md +6 -3
  2. package/dist/{apply-CAPvMfoU.mjs → apply-iVSqz2qs.mjs} +132 -39
  3. package/dist/astro/index.d.mts +18 -9
  4. package/dist/astro/index.mjs +238 -16
  5. package/dist/astro/middleware/auth.d.mts +16 -5
  6. package/dist/astro/middleware/auth.mjs +74 -37
  7. package/dist/astro/middleware/redirect.mjs +24 -8
  8. package/dist/astro/middleware/request-context.mjs +18 -5
  9. package/dist/astro/middleware/setup.mjs +1 -1
  10. package/dist/astro/middleware.mjs +411 -169
  11. package/dist/astro/types.d.mts +25 -8
  12. package/dist/{byline-DeWCMU_i.mjs → byline-OhH2dlRu.mjs} +6 -21
  13. package/dist/{bylines-DyqBV9EQ.mjs → bylines-BGpD9_hy.mjs} +16 -6
  14. package/dist/cache-BdSY-gQN.mjs +42 -0
  15. package/dist/chunks--4F8ddV4.mjs +18 -0
  16. package/dist/cli/index.mjs +935 -15
  17. package/dist/client/external-auth-headers.d.mts +1 -1
  18. package/dist/client/index.d.mts +11 -3
  19. package/dist/client/index.mjs +4 -3
  20. package/dist/{connection-C9pxzuag.mjs → connection-BCNICDWN.mjs} +22 -5
  21. package/dist/{content-zSgdNmnt.mjs → content-DWi4d0rT.mjs} +41 -2
  22. package/dist/database/instrumentation.d.mts +34 -0
  23. package/dist/database/instrumentation.mjs +53 -0
  24. package/dist/db/index.d.mts +3 -3
  25. package/dist/db/index.mjs +2 -2
  26. package/dist/db/libsql.d.mts +1 -1
  27. package/dist/db/libsql.mjs +11 -5
  28. package/dist/db/postgres.d.mts +1 -1
  29. package/dist/db/sqlite.d.mts +1 -1
  30. package/dist/db/sqlite.mjs +7 -1
  31. package/dist/db-errors-CEqD7qH9.mjs +23 -0
  32. package/dist/{default-WYlzADZL.mjs → default-VjJyuuG9.mjs} +2 -0
  33. package/dist/{dialect-helpers-B9uSp2GJ.mjs → dialect-helpers-DhTzaUxP.mjs} +3 -0
  34. package/dist/{error-DrxtnGPg.mjs → error-BmL6QipT.mjs} +7 -3
  35. package/dist/{index-C-jx21qs.d.mts → index-yvc6E_17.d.mts} +157 -30
  36. package/dist/index.d.mts +11 -11
  37. package/dist/index.mjs +24 -22
  38. package/dist/{loader-qKmo0wAY.mjs → loader-sMG4TZ-u.mjs} +9 -3
  39. package/dist/media/index.d.mts +1 -1
  40. package/dist/media/index.mjs +1 -1
  41. package/dist/media/local-runtime.d.mts +7 -7
  42. package/dist/page/index.d.mts +10 -2
  43. package/dist/page/index.mjs +22 -1
  44. package/dist/patterns-CrCYkMBb.mjs +92 -0
  45. package/dist/{placeholder-bOx1xCTY.d.mts → placeholder--wOi4TbO.d.mts} +1 -1
  46. package/dist/{placeholder-B3knXwNc.mjs → placeholder-Cp8g5Emj.mjs} +1 -1
  47. package/dist/plugins/adapt-sandbox-entry.d.mts +5 -5
  48. package/dist/plugins/adapt-sandbox-entry.mjs +1 -1
  49. package/dist/{query-BiaPl_g2.mjs → query-kDmwCsHh.mjs} +118 -50
  50. package/dist/{redirect-JPqLAbxa.mjs → redirect-DnEWAkVg.mjs} +43 -99
  51. package/dist/{registry-DSd1GWB8.mjs → registry-C0zjeB9P.mjs} +191 -123
  52. package/dist/request-cache-Dk5qPSOx.mjs +66 -0
  53. package/dist/request-context.d.mts +4 -16
  54. package/dist/{runner-B5l1JfOj.d.mts → runner-CFI6B6J2.d.mts} +1 -1
  55. package/dist/{runner-BGUGywgG.mjs → runner-DWZm2KQm.mjs} +589 -137
  56. package/dist/runtime.d.mts +6 -6
  57. package/dist/runtime.mjs +2 -2
  58. package/dist/{search-BNruJHDL.mjs → search-ByRGV2pq.mjs} +570 -424
  59. package/dist/seed/index.d.mts +2 -2
  60. package/dist/seed/index.mjs +11 -10
  61. package/dist/seo/index.d.mts +1 -1
  62. package/dist/storage/local.d.mts +1 -1
  63. package/dist/storage/local.mjs +1 -1
  64. package/dist/storage/s3.d.mts +11 -3
  65. package/dist/storage/s3.mjs +78 -15
  66. package/dist/taxonomies-1s5PaS_8.mjs +266 -0
  67. package/dist/transaction-Cn2rjY78.mjs +27 -0
  68. package/dist/{types-BgQeVaPj.d.mts → types-BuMDPy5C.d.mts} +52 -3
  69. package/dist/{types-DuNbGKjF.mjs → types-COeOq9nK.mjs} +6 -1
  70. package/dist/{types-ju-_ORz7.d.mts → types-CWbdtiux.d.mts} +13 -5
  71. package/dist/{types-D38djUXv.d.mts → types-Cj0KMIZV.d.mts} +16 -3
  72. package/dist/{types-DkvMXalq.d.mts → types-DOrVigru.d.mts} +159 -0
  73. package/dist/{validate-CXnRKfJK.mjs → validate-BZ5wnLLp.mjs} +2 -1
  74. package/dist/{validate-DVKJJ-M_.d.mts → validate-IPf8n4Fj.d.mts} +4 -51
  75. package/dist/{validate-CqRJb_xU.mjs → validate-VPnKoIzW.mjs} +10 -10
  76. package/dist/version-BKXPsfmJ.mjs +6 -0
  77. package/package.json +53 -39
  78. package/src/astro/routes/PluginRegistry.tsx +21 -0
  79. package/src/astro/routes/admin.astro +99 -0
  80. package/src/astro/routes/api/admin/allowed-domains/[domain].ts +112 -0
  81. package/src/astro/routes/api/admin/allowed-domains/index.ts +108 -0
  82. package/src/astro/routes/api/admin/api-tokens/[id].ts +44 -0
  83. package/src/astro/routes/api/admin/api-tokens/index.ts +90 -0
  84. package/src/astro/routes/api/admin/briefing.ts +76 -0
  85. package/src/astro/routes/api/admin/bylines/[id]/index.ts +90 -0
  86. package/src/astro/routes/api/admin/bylines/index.ts +74 -0
  87. package/src/astro/routes/api/admin/comments/[id]/status.ts +120 -0
  88. package/src/astro/routes/api/admin/comments/[id].ts +64 -0
  89. package/src/astro/routes/api/admin/comments/bulk.ts +42 -0
  90. package/src/astro/routes/api/admin/comments/counts.ts +30 -0
  91. package/src/astro/routes/api/admin/comments/index.ts +46 -0
  92. package/src/astro/routes/api/admin/context/[id]/history.ts +35 -0
  93. package/src/astro/routes/api/admin/context/[id]/index.ts +35 -0
  94. package/src/astro/routes/api/admin/context/[id]/review.ts +57 -0
  95. package/src/astro/routes/api/admin/context/[id]/supersede.ts +58 -0
  96. package/src/astro/routes/api/admin/context/diff.ts +35 -0
  97. package/src/astro/routes/api/admin/context/index.ts +69 -0
  98. package/src/astro/routes/api/admin/context/stale.ts +35 -0
  99. package/src/astro/routes/api/admin/hitl-requests/[id]/index.ts +38 -0
  100. package/src/astro/routes/api/admin/hitl-requests/[id]/resolve.ts +54 -0
  101. package/src/astro/routes/api/admin/hitl-requests/index.ts +38 -0
  102. package/src/astro/routes/api/admin/hooks/exclusive/[hookName].ts +132 -0
  103. package/src/astro/routes/api/admin/hooks/exclusive/index.ts +51 -0
  104. package/src/astro/routes/api/admin/oauth-clients/[id].ts +137 -0
  105. package/src/astro/routes/api/admin/oauth-clients/index.ts +95 -0
  106. package/src/astro/routes/api/admin/plugins/[id]/disable.ts +91 -0
  107. package/src/astro/routes/api/admin/plugins/[id]/enable.ts +91 -0
  108. package/src/astro/routes/api/admin/plugins/[id]/index.ts +38 -0
  109. package/src/astro/routes/api/admin/plugins/[id]/uninstall.ts +98 -0
  110. package/src/astro/routes/api/admin/plugins/[id]/update.ts +154 -0
  111. package/src/astro/routes/api/admin/plugins/index.ts +32 -0
  112. package/src/astro/routes/api/admin/plugins/marketplace/[id]/icon.ts +62 -0
  113. package/src/astro/routes/api/admin/plugins/marketplace/[id]/index.ts +33 -0
  114. package/src/astro/routes/api/admin/plugins/marketplace/[id]/install.ts +135 -0
  115. package/src/astro/routes/api/admin/plugins/marketplace/index.ts +38 -0
  116. package/src/astro/routes/api/admin/plugins/updates.ts +28 -0
  117. package/src/astro/routes/api/admin/review-requests/[id]/index.ts +35 -0
  118. package/src/astro/routes/api/admin/review-requests/[id]/resolve.ts +52 -0
  119. package/src/astro/routes/api/admin/review-requests/index.ts +35 -0
  120. package/src/astro/routes/api/admin/themes/marketplace/[id]/index.ts +33 -0
  121. package/src/astro/routes/api/admin/themes/marketplace/[id]/thumbnail.ts +62 -0
  122. package/src/astro/routes/api/admin/themes/marketplace/index.ts +45 -0
  123. package/src/astro/routes/api/admin/users/[id]/disable.ts +72 -0
  124. package/src/astro/routes/api/admin/users/[id]/enable.ts +48 -0
  125. package/src/astro/routes/api/admin/users/[id]/index.ts +166 -0
  126. package/src/astro/routes/api/admin/users/[id]/send-recovery.ts +72 -0
  127. package/src/astro/routes/api/admin/users/index.ts +66 -0
  128. package/src/astro/routes/api/auth/dev-bypass.ts +139 -0
  129. package/src/astro/routes/api/auth/invite/accept.ts +52 -0
  130. package/src/astro/routes/api/auth/invite/complete.ts +86 -0
  131. package/src/astro/routes/api/auth/invite/index.ts +99 -0
  132. package/src/astro/routes/api/auth/invite/register-options.ts +73 -0
  133. package/src/astro/routes/api/auth/logout.ts +40 -0
  134. package/src/astro/routes/api/auth/magic-link/send.ts +90 -0
  135. package/src/astro/routes/api/auth/magic-link/verify.ts +71 -0
  136. package/src/astro/routes/api/auth/me.ts +60 -0
  137. package/src/astro/routes/api/auth/oauth/[provider]/callback.ts +221 -0
  138. package/src/astro/routes/api/auth/oauth/[provider].ts +120 -0
  139. package/src/astro/routes/api/auth/passkey/[id].ts +124 -0
  140. package/src/astro/routes/api/auth/passkey/index.ts +54 -0
  141. package/src/astro/routes/api/auth/passkey/options.ts +85 -0
  142. package/src/astro/routes/api/auth/passkey/register/options.ts +88 -0
  143. package/src/astro/routes/api/auth/passkey/register/verify.ts +119 -0
  144. package/src/astro/routes/api/auth/passkey/verify.ts +72 -0
  145. package/src/astro/routes/api/auth/signup/complete.ts +87 -0
  146. package/src/astro/routes/api/auth/signup/request.ts +89 -0
  147. package/src/astro/routes/api/auth/signup/verify.ts +53 -0
  148. package/src/astro/routes/api/comments/[collection]/[contentId]/index.ts +310 -0
  149. package/src/astro/routes/api/content/[collection]/[id]/compare.ts +28 -0
  150. package/src/astro/routes/api/content/[collection]/[id]/discard-draft.ts +68 -0
  151. package/src/astro/routes/api/content/[collection]/[id]/duplicate.ts +77 -0
  152. package/src/astro/routes/api/content/[collection]/[id]/permanent.ts +42 -0
  153. package/src/astro/routes/api/content/[collection]/[id]/preview-url.ts +107 -0
  154. package/src/astro/routes/api/content/[collection]/[id]/publish.ts +100 -0
  155. package/src/astro/routes/api/content/[collection]/[id]/restore.ts +64 -0
  156. package/src/astro/routes/api/content/[collection]/[id]/revisions.ts +31 -0
  157. package/src/astro/routes/api/content/[collection]/[id]/schedule.ts +129 -0
  158. package/src/astro/routes/api/content/[collection]/[id]/terms/[taxonomy].ts +143 -0
  159. package/src/astro/routes/api/content/[collection]/[id]/translations.ts +50 -0
  160. package/src/astro/routes/api/content/[collection]/[id]/unpublish.ts +69 -0
  161. package/src/astro/routes/api/content/[collection]/[id].ts +173 -0
  162. package/src/astro/routes/api/content/[collection]/index.ts +103 -0
  163. package/src/astro/routes/api/content/[collection]/trash.ts +33 -0
  164. package/src/astro/routes/api/dashboard.ts +32 -0
  165. package/src/astro/routes/api/dev/emails.ts +36 -0
  166. package/src/astro/routes/api/health.ts +54 -0
  167. package/src/astro/routes/api/import/probe.ts +47 -0
  168. package/src/astro/routes/api/import/wordpress/analyze.ts +523 -0
  169. package/src/astro/routes/api/import/wordpress/execute.ts +330 -0
  170. package/src/astro/routes/api/import/wordpress/media.ts +338 -0
  171. package/src/astro/routes/api/import/wordpress/prepare.ts +212 -0
  172. package/src/astro/routes/api/import/wordpress/rewrite-urls.ts +425 -0
  173. package/src/astro/routes/api/import/wordpress-plugin/analyze.ts +111 -0
  174. package/src/astro/routes/api/import/wordpress-plugin/callback.ts +58 -0
  175. package/src/astro/routes/api/import/wordpress-plugin/execute.ts +399 -0
  176. package/src/astro/routes/api/manifest.ts +75 -0
  177. package/src/astro/routes/api/mcp.ts +125 -0
  178. package/src/astro/routes/api/media/[id]/confirm.ts +93 -0
  179. package/src/astro/routes/api/media/[id].ts +145 -0
  180. package/src/astro/routes/api/media/file/[...key].ts +79 -0
  181. package/src/astro/routes/api/media/providers/[providerId]/[itemId].ts +91 -0
  182. package/src/astro/routes/api/media/providers/[providerId]/index.ts +111 -0
  183. package/src/astro/routes/api/media/providers/index.ts +30 -0
  184. package/src/astro/routes/api/media/upload-url.ts +146 -0
  185. package/src/astro/routes/api/media.ts +204 -0
  186. package/src/astro/routes/api/menus/[name]/items.ts +206 -0
  187. package/src/astro/routes/api/menus/[name]/reorder.ts +79 -0
  188. package/src/astro/routes/api/menus/[name].ts +145 -0
  189. package/src/astro/routes/api/menus/index.ts +91 -0
  190. package/src/astro/routes/api/oauth/authorize.ts +430 -0
  191. package/src/astro/routes/api/oauth/device/authorize.ts +45 -0
  192. package/src/astro/routes/api/oauth/device/code.ts +56 -0
  193. package/src/astro/routes/api/oauth/device/token.ts +70 -0
  194. package/src/astro/routes/api/oauth/register.ts +182 -0
  195. package/src/astro/routes/api/oauth/token/refresh.ts +38 -0
  196. package/src/astro/routes/api/oauth/token/revoke.ts +38 -0
  197. package/src/astro/routes/api/oauth/token.ts +195 -0
  198. package/src/astro/routes/api/openapi.json.ts +33 -0
  199. package/src/astro/routes/api/plugins/[pluginId]/[...path].ts +109 -0
  200. package/src/astro/routes/api/redirects/404s/index.ts +72 -0
  201. package/src/astro/routes/api/redirects/404s/summary.ts +33 -0
  202. package/src/astro/routes/api/redirects/[id].ts +183 -0
  203. package/src/astro/routes/api/redirects/index.ts +100 -0
  204. package/src/astro/routes/api/revisions/[revisionId]/index.ts +29 -0
  205. package/src/astro/routes/api/revisions/[revisionId]/restore.ts +62 -0
  206. package/src/astro/routes/api/schema/collections/[slug]/fields/[fieldSlug].ts +104 -0
  207. package/src/astro/routes/api/schema/collections/[slug]/fields/index.ts +67 -0
  208. package/src/astro/routes/api/schema/collections/[slug]/fields/reorder.ts +45 -0
  209. package/src/astro/routes/api/schema/collections/[slug]/index.ts +107 -0
  210. package/src/astro/routes/api/schema/collections/index.ts +61 -0
  211. package/src/astro/routes/api/schema/index.ts +109 -0
  212. package/src/astro/routes/api/schema/orphans/[slug].ts +36 -0
  213. package/src/astro/routes/api/schema/orphans/index.ts +26 -0
  214. package/src/astro/routes/api/search/enable.ts +64 -0
  215. package/src/astro/routes/api/search/index.ts +52 -0
  216. package/src/astro/routes/api/search/rebuild.ts +72 -0
  217. package/src/astro/routes/api/search/stats.ts +35 -0
  218. package/src/astro/routes/api/search/suggest.ts +50 -0
  219. package/src/astro/routes/api/sections/[slug].ts +203 -0
  220. package/src/astro/routes/api/sections/index.ts +107 -0
  221. package/src/astro/routes/api/settings/email.ts +150 -0
  222. package/src/astro/routes/api/settings.ts +116 -0
  223. package/src/astro/routes/api/setup/admin-verify.ts +122 -0
  224. package/src/astro/routes/api/setup/admin.ts +104 -0
  225. package/src/astro/routes/api/setup/dev-bypass.ts +200 -0
  226. package/src/astro/routes/api/setup/dev-reset.ts +40 -0
  227. package/src/astro/routes/api/setup/index.ts +128 -0
  228. package/src/astro/routes/api/setup/status.ts +122 -0
  229. package/src/astro/routes/api/snapshot.ts +76 -0
  230. package/src/astro/routes/api/taxonomies/[name]/terms/[slug].ts +232 -0
  231. package/src/astro/routes/api/taxonomies/[name]/terms/index.ts +131 -0
  232. package/src/astro/routes/api/taxonomies/index.ts +114 -0
  233. package/src/astro/routes/api/themes/preview.ts +78 -0
  234. package/src/astro/routes/api/typegen.ts +114 -0
  235. package/src/astro/routes/api/well-known/auth.ts +71 -0
  236. package/src/astro/routes/api/well-known/oauth-authorization-server.ts +48 -0
  237. package/src/astro/routes/api/well-known/oauth-protected-resource.ts +39 -0
  238. package/src/astro/routes/api/widget-areas/[name]/reorder.ts +114 -0
  239. package/src/astro/routes/api/widget-areas/[name]/widgets/[id].ts +213 -0
  240. package/src/astro/routes/api/widget-areas/[name]/widgets.ts +126 -0
  241. package/src/astro/routes/api/widget-areas/[name].ts +135 -0
  242. package/src/astro/routes/api/widget-areas/index.ts +149 -0
  243. package/src/astro/routes/api/widget-components.ts +22 -0
  244. package/src/astro/routes/robots.txt.ts +81 -0
  245. package/src/astro/routes/sitemap-[collection].xml.ts +104 -0
  246. package/src/astro/routes/sitemap.xml.ts +92 -0
  247. package/src/components/Break.astro +45 -0
  248. package/src/components/Button.astro +71 -0
  249. package/src/components/Buttons.astro +49 -0
  250. package/src/components/Code.astro +59 -0
  251. package/src/components/Columns.astro +59 -0
  252. package/src/components/CommentForm.astro +315 -0
  253. package/src/components/Comments.astro +232 -0
  254. package/src/components/Cover.astro +128 -0
  255. package/src/components/DinewayBodyEnd.astro +32 -0
  256. package/src/components/DinewayBodyStart.astro +32 -0
  257. package/src/components/DinewayHead.astro +61 -0
  258. package/src/components/DinewayImage.astro +178 -0
  259. package/src/components/DinewayMedia.astro +167 -0
  260. package/src/components/Embed.astro +128 -0
  261. package/src/components/File.astro +122 -0
  262. package/src/components/Gallery.astro +93 -0
  263. package/src/components/HtmlBlock.astro +33 -0
  264. package/src/components/Image.astro +178 -0
  265. package/src/components/InlineEditor.astro +27 -0
  266. package/src/components/InlinePortableTextEditor.tsx +1937 -0
  267. package/src/components/LiveSearch.astro +614 -0
  268. package/src/components/PortableText.astro +51 -0
  269. package/src/components/Pullquote.astro +51 -0
  270. package/src/components/Table.astro +135 -0
  271. package/src/components/WidgetArea.astro +22 -0
  272. package/src/components/WidgetRenderer.astro +72 -0
  273. package/src/components/index.ts +106 -0
  274. package/src/components/marks/Link.astro +31 -0
  275. package/src/components/marks/StrikeThrough.astro +7 -0
  276. package/src/components/marks/Subscript.astro +7 -0
  277. package/src/components/marks/Superscript.astro +7 -0
  278. package/src/components/marks/Underline.astro +7 -0
  279. package/src/components/marks.ts +19 -0
  280. package/src/components/widgets/Archives.astro +65 -0
  281. package/src/components/widgets/Categories.astro +35 -0
  282. package/src/components/widgets/RecentPosts.astro +51 -0
  283. package/src/components/widgets/Search.astro +18 -0
  284. package/src/components/widgets/Tags.astro +38 -0
  285. package/src/ui.ts +75 -0
  286. package/LICENSE +0 -9
  287. /package/dist/{adapters-BlzWJG82.d.mts → adapters-C2ypTrZZ.d.mts} +0 -0
  288. /package/dist/{config-Cq8H0SfX.mjs → config-BXwuX8Bx.mjs} +0 -0
  289. /package/dist/{load-C6FCD1FU.mjs → load-Coc9HpHH.mjs} +0 -0
  290. /package/dist/{manifest-schema-CTSEyIJ3.mjs → manifest-schema-D1MSVnoI.mjs} +0 -0
  291. /package/dist/{mode-BlyYtIFO.mjs → mode-47goXBBK.mjs} +0 -0
  292. /package/dist/{tokens-4vgYuXsZ.mjs → tokens-CJz9ubV6.mjs} +0 -0
  293. /package/dist/{transport-C5FYnid7.mjs → transport-DB5eDN4x.mjs} +0 -0
  294. /package/dist/{transport-gIL-e43D.d.mts → transport-Wge_IzKl.d.mts} +0 -0
  295. /package/dist/{types-CLLdsG3g.d.mts → types-BzcUjoqg.d.mts} +0 -0
  296. /package/dist/{types-DShnjzb6.mjs → types-griIBQOQ.mjs} +0 -0
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Plugin management single plugin endpoint
3
+ *
4
+ * GET /_dineway/api/admin/plugins/:id - Get plugin details
5
+ */
6
+
7
+ import type { APIRoute } from "astro";
8
+
9
+ import { requirePerm } from "#api/authorize.js";
10
+ import { apiError, unwrapResult } from "#api/error.js";
11
+ import { handlePluginGet } from "#api/index.js";
12
+
13
+ export const prerender = false;
14
+
15
+ export const GET: APIRoute = async ({ params, locals }) => {
16
+ const { dineway, user } = locals;
17
+ const { id } = params;
18
+
19
+ if (!dineway?.db) {
20
+ return apiError("NOT_CONFIGURED", "Dineway is not initialized", 500);
21
+ }
22
+
23
+ const denied = requirePerm(user, "plugins:read");
24
+ if (denied) return denied;
25
+
26
+ if (!id) {
27
+ return apiError("INVALID_REQUEST", "Plugin ID required", 400);
28
+ }
29
+
30
+ const result = await handlePluginGet(
31
+ dineway.db,
32
+ dineway.configuredPlugins,
33
+ id,
34
+ dineway.config.marketplace,
35
+ );
36
+
37
+ return unwrapResult(result);
38
+ };
@@ -0,0 +1,98 @@
1
+ /**
2
+ * Marketplace plugin uninstall endpoint
3
+ *
4
+ * POST /_dineway/api/admin/plugins/:id/uninstall - Uninstall a marketplace plugin
5
+ */
6
+
7
+ import type { APIRoute } from "astro";
8
+ import { z } from "zod";
9
+
10
+ import { requirePerm } from "#api/authorize.js";
11
+ import { apiError, unwrapResult } from "#api/error.js";
12
+ import {
13
+ ensureWorkflowHitlRouteRequest,
14
+ hitlRequiredRouteError,
15
+ resolveHitlRouteActor,
16
+ } from "#api/hitl-route-helpers.js";
17
+ import { handleMarketplaceUninstall, handlePluginList } from "#api/index.js";
18
+ import { isParseError, parseOptionalBody } from "#api/parse.js";
19
+ import {
20
+ logPluginActivity,
21
+ pluginApiRouteSource,
22
+ PluginHitlPayloadBuilder,
23
+ RiskPolicyEvaluator,
24
+ } from "#site-context/index.js";
25
+
26
+ export const prerender = false;
27
+
28
+ const uninstallBodySchema = z.object({
29
+ deleteData: z.boolean().optional(),
30
+ hitlRequestId: z.string().min(1).optional(),
31
+ });
32
+
33
+ export const POST: APIRoute = async ({ params, request, locals }) => {
34
+ const { dineway, user } = locals;
35
+ const { id } = params;
36
+
37
+ if (!dineway?.db) {
38
+ return apiError("NOT_CONFIGURED", "Dineway is not initialized", 500);
39
+ }
40
+
41
+ const denied = requirePerm(user, "plugins:manage");
42
+ if (denied) return denied;
43
+
44
+ if (!id) {
45
+ return apiError("INVALID_REQUEST", "Plugin ID required", 400);
46
+ }
47
+
48
+ const body = await parseOptionalBody(request, uninstallBodySchema, {});
49
+ if (isParseError(body)) return body;
50
+
51
+ const actor = resolveHitlRouteActor(locals);
52
+ let approvedHitlRequestId: string | null = null;
53
+ const current = await handlePluginList(
54
+ dineway.db,
55
+ dineway.configuredPlugins,
56
+ dineway.config.marketplace,
57
+ );
58
+ if (!current.success) return unwrapResult(current);
59
+ const plugin = current.data.items.find((item) => item.id === id && item.source === "marketplace");
60
+ if (plugin) {
61
+ const action = await new PluginHitlPayloadBuilder().buildUninstallRequest(plugin, {
62
+ deleteData: body.deleteData ?? false,
63
+ });
64
+ const decision = await new RiskPolicyEvaluator({
65
+ db: dineway.db,
66
+ handlers: dineway,
67
+ }).evaluateWorkflowHitl({
68
+ actor: actor.identity,
69
+ hitlRequestId: body.hitlRequestId,
70
+ action,
71
+ });
72
+ if (!decision.allowed) {
73
+ const ensured = await ensureWorkflowHitlRouteRequest(dineway.db, locals, decision.action);
74
+ return hitlRequiredRouteError(decision, ensured);
75
+ }
76
+ approvedHitlRequestId = decision.required ? decision.hitlRequest.id : null;
77
+ }
78
+
79
+ const result = await handleMarketplaceUninstall(dineway.db, dineway.storage, id, {
80
+ deleteData: body.deleteData ?? false,
81
+ });
82
+
83
+ if (!result.success) return unwrapResult(result);
84
+
85
+ await dineway.syncMarketplacePlugins();
86
+ await logPluginActivity(dineway.db, locals, {
87
+ action: "uninstalled",
88
+ pluginId: id,
89
+ ...pluginApiRouteSource("uninstalled"),
90
+ summary: `Uninstalled plugin ${id}`,
91
+ detail: {
92
+ deleteData: body.deleteData ?? false,
93
+ hitlRequestId: approvedHitlRequestId,
94
+ },
95
+ });
96
+
97
+ return unwrapResult(result);
98
+ };
@@ -0,0 +1,154 @@
1
+ /**
2
+ * Marketplace plugin update endpoint
3
+ *
4
+ * POST /_dineway/api/admin/plugins/:id/update - Update a marketplace plugin
5
+ */
6
+
7
+ import type { APIRoute } from "astro";
8
+ import { z } from "zod";
9
+
10
+ import { requirePerm } from "#api/authorize.js";
11
+ import { apiError, unwrapResult } from "#api/error.js";
12
+ import {
13
+ ensureWorkflowHitlRouteRequest,
14
+ hitlRequiredRouteError,
15
+ resolveHitlRouteActor,
16
+ } from "#api/hitl-route-helpers.js";
17
+ import { handleMarketplaceUpdate, handleMarketplaceUpdatePreview } from "#api/index.js";
18
+ import { isParseError, parseOptionalBody } from "#api/parse.js";
19
+ import {
20
+ logPluginActivity,
21
+ pluginApiRouteSource,
22
+ PluginHitlPayloadBuilder,
23
+ RiskPolicyEvaluator,
24
+ } from "#site-context/index.js";
25
+
26
+ export const prerender = false;
27
+
28
+ const updateBodySchema = z.object({
29
+ version: z.string().min(1).optional(),
30
+ confirmCapabilityChanges: z.boolean().optional(),
31
+ confirmRouteVisibilityChanges: z.boolean().optional(),
32
+ hitlRequestId: z.string().min(1).optional(),
33
+ });
34
+
35
+ export const POST: APIRoute = async ({ params, request, locals }) => {
36
+ const { dineway, user } = locals;
37
+ const { id } = params;
38
+
39
+ if (!dineway?.db) {
40
+ return apiError("NOT_CONFIGURED", "Dineway is not initialized", 500);
41
+ }
42
+
43
+ const denied = requirePerm(user, "plugins:manage");
44
+ if (denied) return denied;
45
+
46
+ if (!id) {
47
+ return apiError("INVALID_REQUEST", "Plugin ID required", 400);
48
+ }
49
+
50
+ const body = await parseOptionalBody(request, updateBodySchema, {});
51
+ if (isParseError(body)) return body;
52
+ const actor = resolveHitlRouteActor(locals);
53
+ const evaluator = new RiskPolicyEvaluator({
54
+ db: dineway.db,
55
+ handlers: dineway,
56
+ });
57
+ let approvedHitlRequestId: string | null = null;
58
+ let previewDiffs: { hasCapabilityChanges: boolean; hasNewPublicRoutes: boolean } | null = null;
59
+
60
+ if (evaluator.requiresWorkflowHitl(actor.identity)) {
61
+ if (!body.version) {
62
+ return apiError(
63
+ "VALIDATION_ERROR",
64
+ "API-token marketplace updates require an explicit version so the reviewed target is immutable.",
65
+ 400,
66
+ );
67
+ }
68
+
69
+ const preview = await handleMarketplaceUpdatePreview(
70
+ dineway.db,
71
+ dineway.storage,
72
+ dineway.config.marketplace,
73
+ id,
74
+ { version: body.version },
75
+ );
76
+ if (!preview.success) return unwrapResult(preview);
77
+
78
+ const action = await new PluginHitlPayloadBuilder().buildMarketplaceUpdateRequest({
79
+ id: preview.data.pluginId,
80
+ name: preview.data.name,
81
+ description: preview.data.description,
82
+ authorName: preview.data.authorName,
83
+ version: preview.data.version,
84
+ minDinewayVersion: preview.data.minDinewayVersion,
85
+ bundleSize: preview.data.bundleSize,
86
+ checksum: preview.data.checksum,
87
+ changelog: preview.data.changelog,
88
+ capabilities: preview.data.capabilities,
89
+ status: preview.data.status,
90
+ auditVerdict: preview.data.auditVerdict,
91
+ imageAuditVerdict: preview.data.imageAuditVerdict,
92
+ publishedAt: preview.data.publishedAt,
93
+ oldVersion: preview.data.oldVersion,
94
+ capabilityChanges: preview.data.capabilityChanges,
95
+ routeVisibilityChanges: preview.data.routeVisibilityChanges,
96
+ });
97
+ const decision = await evaluator.evaluateWorkflowHitl({
98
+ actor: actor.identity,
99
+ hitlRequestId: body.hitlRequestId,
100
+ action,
101
+ });
102
+ if (!decision.allowed) {
103
+ const ensured = await ensureWorkflowHitlRouteRequest(dineway.db, locals, decision.action);
104
+ return hitlRequiredRouteError(decision, ensured);
105
+ }
106
+ approvedHitlRequestId = decision.hitlRequest.id;
107
+ previewDiffs = {
108
+ hasCapabilityChanges:
109
+ preview.data.capabilityChanges.added.length > 0 ||
110
+ preview.data.capabilityChanges.removed.length > 0,
111
+ hasNewPublicRoutes: preview.data.routeVisibilityChanges.newlyPublic.length > 0,
112
+ };
113
+ }
114
+
115
+ const result = await handleMarketplaceUpdate(
116
+ dineway.db,
117
+ dineway.storage,
118
+ dineway.getSandboxRunner(),
119
+ dineway.config.marketplace,
120
+ id,
121
+ {
122
+ version: body.version,
123
+ confirmCapabilityChanges: previewDiffs
124
+ ? previewDiffs.hasCapabilityChanges || body.confirmCapabilityChanges === true
125
+ : body.confirmCapabilityChanges,
126
+ confirmRouteVisibilityChanges: previewDiffs
127
+ ? previewDiffs.hasNewPublicRoutes || body.confirmRouteVisibilityChanges === true
128
+ : body.confirmRouteVisibilityChanges,
129
+ },
130
+ );
131
+
132
+ if (!result.success) return unwrapResult(result);
133
+
134
+ await dineway.syncMarketplacePlugins();
135
+ await logPluginActivity(dineway.db, locals, {
136
+ action: "updated",
137
+ pluginId: id,
138
+ ...pluginApiRouteSource("updated"),
139
+ summary: `Updated plugin ${id}`,
140
+ detail: {
141
+ version: result.data.newVersion,
142
+ oldVersion: result.data.oldVersion,
143
+ confirmedCapabilityChanges: previewDiffs
144
+ ? previewDiffs.hasCapabilityChanges
145
+ : (body.confirmCapabilityChanges ?? false),
146
+ confirmedRouteVisibilityChanges: previewDiffs
147
+ ? previewDiffs.hasNewPublicRoutes
148
+ : (body.confirmRouteVisibilityChanges ?? false),
149
+ hitlRequestId: approvedHitlRequestId,
150
+ },
151
+ });
152
+
153
+ return unwrapResult(result);
154
+ };
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Plugin management list endpoint
3
+ *
4
+ * GET /_dineway/api/admin/plugins - List all configured plugins with state
5
+ */
6
+
7
+ import type { APIRoute } from "astro";
8
+
9
+ import { requirePerm } from "#api/authorize.js";
10
+ import { apiError, unwrapResult } from "#api/error.js";
11
+ import { handlePluginList } from "#api/index.js";
12
+
13
+ export const prerender = false;
14
+
15
+ export const GET: APIRoute = async ({ locals }) => {
16
+ const { dineway, user } = locals;
17
+
18
+ if (!dineway?.db) {
19
+ return apiError("NOT_CONFIGURED", "Dineway is not initialized", 500);
20
+ }
21
+
22
+ const denied = requirePerm(user, "plugins:read");
23
+ if (denied) return denied;
24
+
25
+ const result = await handlePluginList(
26
+ dineway.db,
27
+ dineway.configuredPlugins,
28
+ dineway.config.marketplace,
29
+ );
30
+
31
+ return unwrapResult(result);
32
+ };
@@ -0,0 +1,62 @@
1
+ /**
2
+ * Marketplace plugin icon proxy
3
+ *
4
+ * GET /_dineway/api/admin/plugins/marketplace/:id/icon - Proxy icon from marketplace
5
+ *
6
+ * Avoids CORS/auth issues when the marketplace service is behind
7
+ * external auth or on a different origin.
8
+ * The admin UI uses this instead of linking directly.
9
+ */
10
+
11
+ import type { APIRoute } from "astro";
12
+
13
+ import { requirePerm } from "#api/authorize.js";
14
+ import { apiError } from "#api/error.js";
15
+
16
+ export const prerender = false;
17
+
18
+ export const GET: APIRoute = async ({ params, url, locals }) => {
19
+ const { dineway, user } = locals;
20
+ const { id } = params;
21
+
22
+ if (!dineway?.db) {
23
+ return apiError("NOT_CONFIGURED", "Dineway is not initialized", 500);
24
+ }
25
+
26
+ const denied = requirePerm(user, "plugins:read");
27
+ if (denied) return denied;
28
+
29
+ const marketplaceUrl = dineway.config.marketplace;
30
+ if (!marketplaceUrl || !id) {
31
+ return apiError("NOT_CONFIGURED", "Marketplace not configured", 400);
32
+ }
33
+
34
+ const width = url.searchParams.get("w");
35
+ const target = new URL(`/api/v1/plugins/${encodeURIComponent(id)}/icon`, marketplaceUrl);
36
+ if (width) target.searchParams.set("w", width);
37
+
38
+ try {
39
+ const resp = await fetch(target.href);
40
+ if (!resp.ok) {
41
+ // Allowlist: only forward Content-Type from upstream.
42
+ // Never copy all upstream headers (denylist approach leaks
43
+ // headers we haven't anticipated).
44
+ return new Response(resp.body, {
45
+ status: resp.status,
46
+ headers: {
47
+ "Content-Type": resp.headers.get("Content-Type") ?? "application/octet-stream",
48
+ "Cache-Control": "private, no-store",
49
+ },
50
+ });
51
+ }
52
+
53
+ return new Response(resp.body, {
54
+ headers: {
55
+ "Content-Type": resp.headers.get("Content-Type") ?? "image/png",
56
+ "Cache-Control": "private, no-store",
57
+ },
58
+ });
59
+ } catch {
60
+ return apiError("PROXY_ERROR", "Failed to fetch icon", 502);
61
+ }
62
+ };
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Marketplace plugin detail proxy endpoint
3
+ *
4
+ * GET /_dineway/api/admin/plugins/marketplace/:id - Get plugin details
5
+ */
6
+
7
+ import type { APIRoute } from "astro";
8
+
9
+ import { requirePerm } from "#api/authorize.js";
10
+ import { apiError, unwrapResult } from "#api/error.js";
11
+ import { handleMarketplaceGetPlugin } from "#api/index.js";
12
+
13
+ export const prerender = false;
14
+
15
+ export const GET: APIRoute = async ({ params, locals }) => {
16
+ const { dineway, user } = locals;
17
+ const { id } = params;
18
+
19
+ if (!dineway?.db) {
20
+ return apiError("NOT_CONFIGURED", "Dineway is not initialized", 500);
21
+ }
22
+
23
+ const denied = requirePerm(user, "plugins:read");
24
+ if (denied) return denied;
25
+
26
+ if (!id) {
27
+ return apiError("INVALID_REQUEST", "Plugin ID required", 400);
28
+ }
29
+
30
+ const result = await handleMarketplaceGetPlugin(dineway.config.marketplace, id);
31
+
32
+ return unwrapResult(result);
33
+ };
@@ -0,0 +1,135 @@
1
+ /**
2
+ * Marketplace plugin install endpoint
3
+ *
4
+ * POST /_dineway/api/admin/plugins/marketplace/:id/install - Install a marketplace plugin
5
+ */
6
+
7
+ import type { APIRoute } from "astro";
8
+ import { z } from "zod";
9
+
10
+ import { requirePerm } from "#api/authorize.js";
11
+ import { apiError, handleError, unwrapResult } from "#api/error.js";
12
+ import {
13
+ ensureWorkflowHitlRouteRequest,
14
+ hitlRequiredRouteError,
15
+ resolveHitlRouteActor,
16
+ } from "#api/hitl-route-helpers.js";
17
+ import { handleMarketplaceInstall, handleMarketplaceInstallPreview } from "#api/index.js";
18
+ import { isParseError, parseOptionalBody } from "#api/parse.js";
19
+ import {
20
+ logPluginActivity,
21
+ pluginApiRouteSource,
22
+ PluginHitlPayloadBuilder,
23
+ RiskPolicyEvaluator,
24
+ } from "#site-context/index.js";
25
+
26
+ export const prerender = false;
27
+
28
+ const installBodySchema = z.object({
29
+ version: z.string().min(1).optional(),
30
+ hitlRequestId: z.string().min(1).optional(),
31
+ });
32
+
33
+ export const POST: APIRoute = async ({ params, request, locals }) => {
34
+ try {
35
+ const { dineway, user } = locals;
36
+ const { id } = params;
37
+
38
+ if (!dineway?.db) {
39
+ return apiError("NOT_CONFIGURED", "Dineway is not initialized", 500);
40
+ }
41
+
42
+ const denied = requirePerm(user, "plugins:manage");
43
+ if (denied) return denied;
44
+
45
+ if (!id) {
46
+ return apiError("INVALID_REQUEST", "Plugin ID required", 400);
47
+ }
48
+
49
+ const body = await parseOptionalBody(request, installBodySchema, {});
50
+ if (isParseError(body)) return body;
51
+ const actor = resolveHitlRouteActor(locals);
52
+ const evaluator = new RiskPolicyEvaluator({
53
+ db: dineway.db,
54
+ handlers: dineway,
55
+ });
56
+ let approvedHitlRequestId: string | null = null;
57
+
58
+ if (evaluator.requiresWorkflowHitl(actor.identity)) {
59
+ if (!body.version) {
60
+ return apiError(
61
+ "VALIDATION_ERROR",
62
+ "API-token marketplace installs require an explicit version so the reviewed target is immutable.",
63
+ 400,
64
+ );
65
+ }
66
+
67
+ const preview = await handleMarketplaceInstallPreview(dineway.config.marketplace, id, {
68
+ version: body.version,
69
+ siteOrigin: new URL(request.url).origin,
70
+ });
71
+ if (!preview.success) return unwrapResult(preview);
72
+
73
+ const action = await new PluginHitlPayloadBuilder().buildInstallRequest({
74
+ id: preview.data.pluginId,
75
+ name: preview.data.name,
76
+ description: preview.data.description,
77
+ authorName: preview.data.authorName,
78
+ version: preview.data.version,
79
+ minDinewayVersion: preview.data.minDinewayVersion,
80
+ bundleSize: preview.data.bundleSize,
81
+ checksum: preview.data.checksum,
82
+ changelog: preview.data.changelog,
83
+ capabilities: preview.data.capabilities,
84
+ status: preview.data.status,
85
+ auditVerdict: preview.data.auditVerdict,
86
+ imageAuditVerdict: preview.data.imageAuditVerdict,
87
+ publishedAt: preview.data.publishedAt,
88
+ });
89
+ const decision = await evaluator.evaluateWorkflowHitl({
90
+ actor: actor.identity,
91
+ hitlRequestId: body.hitlRequestId,
92
+ action,
93
+ });
94
+ if (!decision.allowed) {
95
+ const ensured = await ensureWorkflowHitlRouteRequest(dineway.db, locals, decision.action);
96
+ return hitlRequiredRouteError(decision, ensured);
97
+ }
98
+ approvedHitlRequestId = decision.hitlRequest.id;
99
+ }
100
+
101
+ const configuredPluginIds = new Set<string>(
102
+ dineway.configuredPlugins.map((p: { id: string }) => p.id),
103
+ );
104
+
105
+ const siteOrigin = new URL(request.url).origin;
106
+
107
+ const result = await handleMarketplaceInstall(
108
+ dineway.db,
109
+ dineway.storage,
110
+ dineway.getSandboxRunner(),
111
+ dineway.config.marketplace,
112
+ id,
113
+ { version: body.version, configuredPluginIds, siteOrigin },
114
+ );
115
+
116
+ if (!result.success) return unwrapResult(result);
117
+
118
+ await dineway.syncMarketplacePlugins();
119
+ await logPluginActivity(dineway.db, locals, {
120
+ action: "installed",
121
+ pluginId: id,
122
+ ...pluginApiRouteSource("installed"),
123
+ summary: `Installed plugin ${id}`,
124
+ detail: {
125
+ version: result.data.version,
126
+ hitlRequestId: approvedHitlRequestId,
127
+ },
128
+ });
129
+
130
+ return unwrapResult(result, 201);
131
+ } catch (error) {
132
+ console.error("[marketplace-install] Unhandled error:", error);
133
+ return handleError(error, "Failed to install plugin from marketplace", "INSTALL_FAILED");
134
+ }
135
+ };
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Marketplace search proxy endpoint
3
+ *
4
+ * GET /_dineway/api/admin/plugins/marketplace - Search marketplace plugins
5
+ */
6
+
7
+ import type { APIRoute } from "astro";
8
+
9
+ import { requirePerm } from "#api/authorize.js";
10
+ import { apiError, unwrapResult } from "#api/error.js";
11
+ import { handleMarketplaceSearch } from "#api/index.js";
12
+
13
+ export const prerender = false;
14
+
15
+ export const GET: APIRoute = async ({ url, locals }) => {
16
+ const { dineway, user } = locals;
17
+
18
+ if (!dineway?.db) {
19
+ return apiError("NOT_CONFIGURED", "Dineway is not initialized", 500);
20
+ }
21
+
22
+ const denied = requirePerm(user, "plugins:read");
23
+ if (denied) return denied;
24
+
25
+ const query = url.searchParams.get("q") ?? undefined;
26
+ const category = url.searchParams.get("category") ?? undefined;
27
+ const cursor = url.searchParams.get("cursor") ?? undefined;
28
+ const limitParam = url.searchParams.get("limit");
29
+ const limit = limitParam ? Math.min(Math.max(1, parseInt(limitParam, 10) || 50), 100) : undefined;
30
+
31
+ const result = await handleMarketplaceSearch(dineway.config.marketplace, query, {
32
+ category,
33
+ cursor,
34
+ limit,
35
+ });
36
+
37
+ return unwrapResult(result);
38
+ };
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Marketplace update check endpoint
3
+ *
4
+ * GET /_dineway/api/admin/plugins/updates - Check for marketplace plugin updates
5
+ */
6
+
7
+ import type { APIRoute } from "astro";
8
+
9
+ import { requirePerm } from "#api/authorize.js";
10
+ import { apiError, unwrapResult } from "#api/error.js";
11
+ import { handleMarketplaceUpdateCheck } from "#api/index.js";
12
+
13
+ export const prerender = false;
14
+
15
+ export const GET: APIRoute = async ({ locals }) => {
16
+ const { dineway, user } = locals;
17
+
18
+ if (!dineway?.db) {
19
+ return apiError("NOT_CONFIGURED", "Dineway is not initialized", 500);
20
+ }
21
+
22
+ const denied = requirePerm(user, "plugins:read");
23
+ if (denied) return denied;
24
+
25
+ const result = await handleMarketplaceUpdateCheck(dineway.db, dineway.config.marketplace);
26
+
27
+ return unwrapResult(result);
28
+ };
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Admin review request detail
3
+ *
4
+ * GET /_dineway/api/admin/review-requests/:id - Get a review request
5
+ */
6
+
7
+ import type { APIRoute } from "astro";
8
+
9
+ import { requirePerm } from "#api/authorize.js";
10
+ import { apiError, handleError, requireDb, unwrapResult } from "#api/error.js";
11
+ import { handleReviewRequestGet } from "#api/handlers/review-requests.js";
12
+
13
+ export const prerender = false;
14
+
15
+ export const GET: APIRoute = async ({ params, locals }) => {
16
+ const { dineway, user } = locals;
17
+ const { id } = params;
18
+
19
+ if (!id) {
20
+ return apiError("VALIDATION_ERROR", "Review request ID required", 400);
21
+ }
22
+
23
+ const dbErr = requireDb(dineway?.db);
24
+ if (dbErr) return dbErr;
25
+
26
+ const denied = requirePerm(user, "content:edit_any");
27
+ if (denied) return denied;
28
+
29
+ try {
30
+ const result = await handleReviewRequestGet(dineway.db, id);
31
+ return unwrapResult(result);
32
+ } catch (error) {
33
+ return handleError(error, "Failed to fetch review request", "REVIEW_REQUEST_GET_ERROR");
34
+ }
35
+ };