emdash 0.0.0-a → 0.0.1

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 (661) hide show
  1. package/README.md +87 -1
  2. package/dist/adapters-BLMa4JGD.d.mts +106 -0
  3. package/dist/adapters-BLMa4JGD.d.mts.map +1 -0
  4. package/dist/apply-Bjfq_b4-.mjs +1293 -0
  5. package/dist/apply-Bjfq_b4-.mjs.map +1 -0
  6. package/dist/astro/index.d.mts +51 -0
  7. package/dist/astro/index.d.mts.map +1 -0
  8. package/dist/astro/index.mjs +1333 -0
  9. package/dist/astro/index.mjs.map +1 -0
  10. package/dist/astro/middleware/auth.d.mts +31 -0
  11. package/dist/astro/middleware/auth.d.mts.map +1 -0
  12. package/dist/astro/middleware/auth.mjs +654 -0
  13. package/dist/astro/middleware/auth.mjs.map +1 -0
  14. package/dist/astro/middleware/redirect.d.mts +22 -0
  15. package/dist/astro/middleware/redirect.d.mts.map +1 -0
  16. package/dist/astro/middleware/redirect.mjs +63 -0
  17. package/dist/astro/middleware/redirect.mjs.map +1 -0
  18. package/dist/astro/middleware/request-context.d.mts +18 -0
  19. package/dist/astro/middleware/request-context.d.mts.map +1 -0
  20. package/dist/astro/middleware/request-context.mjs +1310 -0
  21. package/dist/astro/middleware/request-context.mjs.map +1 -0
  22. package/dist/astro/middleware/setup.d.mts +20 -0
  23. package/dist/astro/middleware/setup.d.mts.map +1 -0
  24. package/dist/astro/middleware/setup.mjs +47 -0
  25. package/dist/astro/middleware/setup.mjs.map +1 -0
  26. package/dist/astro/middleware.d.mts +13 -0
  27. package/dist/astro/middleware.d.mts.map +1 -0
  28. package/dist/astro/middleware.mjs +1613 -0
  29. package/dist/astro/middleware.mjs.map +1 -0
  30. package/dist/astro/types.d.mts +250 -0
  31. package/dist/astro/types.d.mts.map +1 -0
  32. package/dist/astro/types.mjs +1 -0
  33. package/dist/base64-MBPo9ozB.mjs +59 -0
  34. package/dist/base64-MBPo9ozB.mjs.map +1 -0
  35. package/dist/byline-CL847F26.mjs +213 -0
  36. package/dist/byline-CL847F26.mjs.map +1 -0
  37. package/dist/bylines-C2a-2TGt.mjs +136 -0
  38. package/dist/bylines-C2a-2TGt.mjs.map +1 -0
  39. package/dist/chunk-ClPoSABd.mjs +21 -0
  40. package/dist/cli/index.d.mts +1 -0
  41. package/dist/cli/index.mjs +3909 -0
  42. package/dist/cli/index.mjs.map +1 -0
  43. package/dist/client/cf-access.d.mts +60 -0
  44. package/dist/client/cf-access.d.mts.map +1 -0
  45. package/dist/client/cf-access.mjs +179 -0
  46. package/dist/client/cf-access.mjs.map +1 -0
  47. package/dist/client/index.d.mts +398 -0
  48. package/dist/client/index.d.mts.map +1 -0
  49. package/dist/client/index.mjs +346 -0
  50. package/dist/client/index.mjs.map +1 -0
  51. package/dist/config-CKE8p9xM.mjs +55 -0
  52. package/dist/config-CKE8p9xM.mjs.map +1 -0
  53. package/dist/connection-B4zVnQIa.mjs +40 -0
  54. package/dist/connection-B4zVnQIa.mjs.map +1 -0
  55. package/dist/content-D6C2WsZC.mjs +824 -0
  56. package/dist/content-D6C2WsZC.mjs.map +1 -0
  57. package/dist/db/index.d.mts +4 -0
  58. package/dist/db/index.mjs +62 -0
  59. package/dist/db/index.mjs.map +1 -0
  60. package/dist/db/libsql.d.mts +11 -0
  61. package/dist/db/libsql.d.mts.map +1 -0
  62. package/dist/db/libsql.mjs +17 -0
  63. package/dist/db/libsql.mjs.map +1 -0
  64. package/dist/db/postgres.d.mts +11 -0
  65. package/dist/db/postgres.d.mts.map +1 -0
  66. package/dist/db/postgres.mjs +30 -0
  67. package/dist/db/postgres.mjs.map +1 -0
  68. package/dist/db/sqlite.d.mts +11 -0
  69. package/dist/db/sqlite.d.mts.map +1 -0
  70. package/dist/db/sqlite.mjs +16 -0
  71. package/dist/db/sqlite.mjs.map +1 -0
  72. package/dist/default-Cyi4aAxu.mjs +81 -0
  73. package/dist/default-Cyi4aAxu.mjs.map +1 -0
  74. package/dist/dialect-helpers-B9uSp2GJ.mjs +90 -0
  75. package/dist/dialect-helpers-B9uSp2GJ.mjs.map +1 -0
  76. package/dist/error-Cxz0tQeO.mjs +27 -0
  77. package/dist/error-Cxz0tQeO.mjs.map +1 -0
  78. package/dist/index-C1xF3OGh.d.mts +4527 -0
  79. package/dist/index-C1xF3OGh.d.mts.map +1 -0
  80. package/dist/index.d.mts +16 -0
  81. package/dist/index.mjs +30 -0
  82. package/dist/load-yOOlckBj.mjs +28 -0
  83. package/dist/load-yOOlckBj.mjs.map +1 -0
  84. package/dist/loader-fz8Q_3EO.mjs +447 -0
  85. package/dist/loader-fz8Q_3EO.mjs.map +1 -0
  86. package/dist/manifest-schema-Dcl0R6nM.mjs +184 -0
  87. package/dist/manifest-schema-Dcl0R6nM.mjs.map +1 -0
  88. package/dist/media/index.d.mts +26 -0
  89. package/dist/media/index.d.mts.map +1 -0
  90. package/dist/media/index.mjs +55 -0
  91. package/dist/media/index.mjs.map +1 -0
  92. package/dist/media/local-runtime.d.mts +39 -0
  93. package/dist/media/local-runtime.d.mts.map +1 -0
  94. package/dist/media/local-runtime.mjs +133 -0
  95. package/dist/media/local-runtime.mjs.map +1 -0
  96. package/dist/media-DqHVh136.mjs +200 -0
  97. package/dist/media-DqHVh136.mjs.map +1 -0
  98. package/dist/mode-C2EzN1uE.mjs +23 -0
  99. package/dist/mode-C2EzN1uE.mjs.map +1 -0
  100. package/dist/page/index.d.mts +140 -0
  101. package/dist/page/index.d.mts.map +1 -0
  102. package/dist/page/index.mjs +416 -0
  103. package/dist/page/index.mjs.map +1 -0
  104. package/dist/placeholder-CmGAmqeO.d.mts +276 -0
  105. package/dist/placeholder-CmGAmqeO.d.mts.map +1 -0
  106. package/dist/placeholder-SmpOx-_v.mjs +243 -0
  107. package/dist/placeholder-SmpOx-_v.mjs.map +1 -0
  108. package/dist/plugin-utils.d.mts +58 -0
  109. package/dist/plugin-utils.d.mts.map +1 -0
  110. package/dist/plugin-utils.mjs +78 -0
  111. package/dist/plugin-utils.mjs.map +1 -0
  112. package/dist/plugins/adapt-sandbox-entry.d.mts +22 -0
  113. package/dist/plugins/adapt-sandbox-entry.d.mts.map +1 -0
  114. package/dist/plugins/adapt-sandbox-entry.mjs +113 -0
  115. package/dist/plugins/adapt-sandbox-entry.mjs.map +1 -0
  116. package/dist/query-CS_iSj34.mjs +460 -0
  117. package/dist/query-CS_iSj34.mjs.map +1 -0
  118. package/dist/redirect-DIfIni3r.mjs +329 -0
  119. package/dist/redirect-DIfIni3r.mjs.map +1 -0
  120. package/dist/registry-D_w5HW4G.mjs +863 -0
  121. package/dist/registry-D_w5HW4G.mjs.map +1 -0
  122. package/dist/request-context.d.mts +49 -0
  123. package/dist/request-context.d.mts.map +1 -0
  124. package/dist/request-context.mjs +43 -0
  125. package/dist/request-context.mjs.map +1 -0
  126. package/dist/runner-B-u2F2b6.mjs +1412 -0
  127. package/dist/runner-B-u2F2b6.mjs.map +1 -0
  128. package/dist/runner-EAtf0ZIe.d.mts +27 -0
  129. package/dist/runner-EAtf0ZIe.d.mts.map +1 -0
  130. package/dist/runtime.d.mts +26 -0
  131. package/dist/runtime.d.mts.map +1 -0
  132. package/dist/runtime.mjs +42 -0
  133. package/dist/runtime.mjs.map +1 -0
  134. package/dist/search-DG603UrT.mjs +9211 -0
  135. package/dist/search-DG603UrT.mjs.map +1 -0
  136. package/dist/seed/index.d.mts +3 -0
  137. package/dist/seed/index.mjs +15 -0
  138. package/dist/seo/index.d.mts +70 -0
  139. package/dist/seo/index.d.mts.map +1 -0
  140. package/dist/seo/index.mjs +70 -0
  141. package/dist/seo/index.mjs.map +1 -0
  142. package/dist/storage/local.d.mts +39 -0
  143. package/dist/storage/local.d.mts.map +1 -0
  144. package/dist/storage/local.mjs +166 -0
  145. package/dist/storage/local.mjs.map +1 -0
  146. package/dist/storage/s3.d.mts +32 -0
  147. package/dist/storage/s3.d.mts.map +1 -0
  148. package/dist/storage/s3.mjs +175 -0
  149. package/dist/storage/s3.mjs.map +1 -0
  150. package/dist/tokens-DpgrkrXK.mjs +171 -0
  151. package/dist/tokens-DpgrkrXK.mjs.map +1 -0
  152. package/dist/transport-BFGblqwG.d.mts +42 -0
  153. package/dist/transport-BFGblqwG.d.mts.map +1 -0
  154. package/dist/transport-yxiQsi8I.mjs +418 -0
  155. package/dist/transport-yxiQsi8I.mjs.map +1 -0
  156. package/dist/types-BRuPJGdV.d.mts +102 -0
  157. package/dist/types-BRuPJGdV.d.mts.map +1 -0
  158. package/dist/types-C4-fAxN3.d.mts +182 -0
  159. package/dist/types-C4-fAxN3.d.mts.map +1 -0
  160. package/dist/types-CMMN0pNg.mjs +31 -0
  161. package/dist/types-CMMN0pNg.mjs.map +1 -0
  162. package/dist/types-CUBbjgmP.mjs +16 -0
  163. package/dist/types-CUBbjgmP.mjs.map +1 -0
  164. package/dist/types-DRjfYOEv.d.mts +426 -0
  165. package/dist/types-DRjfYOEv.d.mts.map +1 -0
  166. package/dist/types-DY5zk5HN.mjs +73 -0
  167. package/dist/types-DY5zk5HN.mjs.map +1 -0
  168. package/dist/types-DaNLHo_T.d.mts +184 -0
  169. package/dist/types-DaNLHo_T.d.mts.map +1 -0
  170. package/dist/types-DvhsUmSJ.d.mts +1111 -0
  171. package/dist/types-DvhsUmSJ.d.mts.map +1 -0
  172. package/dist/validate-CpBtVMsD.d.mts +378 -0
  173. package/dist/validate-CpBtVMsD.d.mts.map +1 -0
  174. package/dist/validate-CqRJb_xU.mjs +97 -0
  175. package/dist/validate-CqRJb_xU.mjs.map +1 -0
  176. package/dist/validate-O7PWmlnq.mjs +328 -0
  177. package/dist/validate-O7PWmlnq.mjs.map +1 -0
  178. package/locals.d.ts +46 -0
  179. package/package.json +233 -19
  180. package/src/api/authorize.ts +63 -0
  181. package/src/api/csrf.ts +48 -0
  182. package/src/api/error.ts +99 -0
  183. package/src/api/errors.ts +445 -0
  184. package/src/api/escape.ts +9 -0
  185. package/src/api/handlers/api-tokens.ts +240 -0
  186. package/src/api/handlers/comments.ts +314 -0
  187. package/src/api/handlers/content.ts +1315 -0
  188. package/src/api/handlers/dashboard.ts +205 -0
  189. package/src/api/handlers/device-flow.ts +687 -0
  190. package/src/api/handlers/index.ts +163 -0
  191. package/src/api/handlers/manifest.ts +158 -0
  192. package/src/api/handlers/marketplace.ts +930 -0
  193. package/src/api/handlers/media.ts +207 -0
  194. package/src/api/handlers/menus.ts +493 -0
  195. package/src/api/handlers/oauth-authorization.ts +429 -0
  196. package/src/api/handlers/oauth-clients.ts +353 -0
  197. package/src/api/handlers/oauth-user-lookup.ts +39 -0
  198. package/src/api/handlers/plugins.ts +254 -0
  199. package/src/api/handlers/redirects.ts +360 -0
  200. package/src/api/handlers/revision.ts +145 -0
  201. package/src/api/handlers/schema.ts +534 -0
  202. package/src/api/handlers/sections.ts +289 -0
  203. package/src/api/handlers/seo.ts +115 -0
  204. package/src/api/handlers/settings.ts +49 -0
  205. package/src/api/handlers/snapshot.ts +350 -0
  206. package/src/api/handlers/taxonomies.ts +523 -0
  207. package/src/api/index.ts +6 -0
  208. package/src/api/openapi/document.ts +2368 -0
  209. package/src/api/openapi/index.ts +1 -0
  210. package/src/api/parse.ts +139 -0
  211. package/src/api/redirect.ts +14 -0
  212. package/src/api/rev.ts +67 -0
  213. package/src/api/schemas/auth.ts +112 -0
  214. package/src/api/schemas/bylines.ts +85 -0
  215. package/src/api/schemas/comments.ts +117 -0
  216. package/src/api/schemas/common.ts +89 -0
  217. package/src/api/schemas/content.ts +191 -0
  218. package/src/api/schemas/import.ts +52 -0
  219. package/src/api/schemas/index.ts +17 -0
  220. package/src/api/schemas/media.ts +116 -0
  221. package/src/api/schemas/menus.ts +111 -0
  222. package/src/api/schemas/redirects.ts +155 -0
  223. package/src/api/schemas/schema.ts +203 -0
  224. package/src/api/schemas/search.ts +63 -0
  225. package/src/api/schemas/sections.ts +67 -0
  226. package/src/api/schemas/settings.ts +63 -0
  227. package/src/api/schemas/setup.ts +37 -0
  228. package/src/api/schemas/taxonomies.ts +113 -0
  229. package/src/api/schemas/users.ts +96 -0
  230. package/src/api/schemas/widgets.ts +80 -0
  231. package/src/api/site-url.ts +25 -0
  232. package/src/api/types.ts +82 -0
  233. package/src/astro/index.ts +27 -0
  234. package/src/astro/integration/index.ts +303 -0
  235. package/src/astro/integration/routes.ts +834 -0
  236. package/src/astro/integration/runtime.ts +338 -0
  237. package/src/astro/integration/virtual-modules.ts +469 -0
  238. package/src/astro/integration/vite-config.ts +328 -0
  239. package/src/astro/middleware/auth.ts +743 -0
  240. package/src/astro/middleware/redirect.ts +89 -0
  241. package/src/astro/middleware/request-context.ts +129 -0
  242. package/src/astro/middleware/setup.ts +89 -0
  243. package/src/astro/middleware.ts +398 -0
  244. package/src/astro/routes/PluginRegistry.tsx +15 -0
  245. package/src/astro/routes/admin.astro +81 -0
  246. package/src/astro/routes/api/admin/allowed-domains/[domain].ts +112 -0
  247. package/src/astro/routes/api/admin/allowed-domains/index.ts +108 -0
  248. package/src/astro/routes/api/admin/api-tokens/[id].ts +40 -0
  249. package/src/astro/routes/api/admin/api-tokens/index.ts +68 -0
  250. package/src/astro/routes/api/admin/bylines/[id]/index.ts +87 -0
  251. package/src/astro/routes/api/admin/bylines/index.ts +72 -0
  252. package/src/astro/routes/api/admin/comments/[id]/status.ts +120 -0
  253. package/src/astro/routes/api/admin/comments/[id].ts +64 -0
  254. package/src/astro/routes/api/admin/comments/bulk.ts +42 -0
  255. package/src/astro/routes/api/admin/comments/counts.ts +30 -0
  256. package/src/astro/routes/api/admin/comments/index.ts +46 -0
  257. package/src/astro/routes/api/admin/hooks/exclusive/[hookName].ts +91 -0
  258. package/src/astro/routes/api/admin/hooks/exclusive/index.ts +51 -0
  259. package/src/astro/routes/api/admin/oauth-clients/[id].ts +110 -0
  260. package/src/astro/routes/api/admin/oauth-clients/index.ts +71 -0
  261. package/src/astro/routes/api/admin/plugins/[id]/disable.ts +39 -0
  262. package/src/astro/routes/api/admin/plugins/[id]/enable.ts +39 -0
  263. package/src/astro/routes/api/admin/plugins/[id]/index.ts +38 -0
  264. package/src/astro/routes/api/admin/plugins/[id]/uninstall.ts +48 -0
  265. package/src/astro/routes/api/admin/plugins/[id]/update.ts +59 -0
  266. package/src/astro/routes/api/admin/plugins/index.ts +32 -0
  267. package/src/astro/routes/api/admin/plugins/marketplace/[id]/icon.ts +61 -0
  268. package/src/astro/routes/api/admin/plugins/marketplace/[id]/index.ts +33 -0
  269. package/src/astro/routes/api/admin/plugins/marketplace/[id]/install.ts +62 -0
  270. package/src/astro/routes/api/admin/plugins/marketplace/index.ts +38 -0
  271. package/src/astro/routes/api/admin/plugins/updates.ts +28 -0
  272. package/src/astro/routes/api/admin/themes/marketplace/[id]/index.ts +33 -0
  273. package/src/astro/routes/api/admin/themes/marketplace/[id]/thumbnail.ts +61 -0
  274. package/src/astro/routes/api/admin/themes/marketplace/index.ts +45 -0
  275. package/src/astro/routes/api/admin/users/[id]/disable.ts +69 -0
  276. package/src/astro/routes/api/admin/users/[id]/enable.ts +48 -0
  277. package/src/astro/routes/api/admin/users/[id]/index.ts +146 -0
  278. package/src/astro/routes/api/admin/users/[id]/send-recovery.ts +72 -0
  279. package/src/astro/routes/api/admin/users/index.ts +66 -0
  280. package/src/astro/routes/api/auth/dev-bypass.ts +139 -0
  281. package/src/astro/routes/api/auth/invite/accept.ts +52 -0
  282. package/src/astro/routes/api/auth/invite/complete.ts +84 -0
  283. package/src/astro/routes/api/auth/invite/index.ts +99 -0
  284. package/src/astro/routes/api/auth/logout.ts +40 -0
  285. package/src/astro/routes/api/auth/magic-link/send.ts +89 -0
  286. package/src/astro/routes/api/auth/magic-link/verify.ts +71 -0
  287. package/src/astro/routes/api/auth/me.ts +60 -0
  288. package/src/astro/routes/api/auth/oauth/[provider]/callback.ts +219 -0
  289. package/src/astro/routes/api/auth/oauth/[provider].ts +119 -0
  290. package/src/astro/routes/api/auth/passkey/[id].ts +124 -0
  291. package/src/astro/routes/api/auth/passkey/index.ts +54 -0
  292. package/src/astro/routes/api/auth/passkey/options.ts +82 -0
  293. package/src/astro/routes/api/auth/passkey/register/options.ts +86 -0
  294. package/src/astro/routes/api/auth/passkey/register/verify.ts +117 -0
  295. package/src/astro/routes/api/auth/passkey/verify.ts +66 -0
  296. package/src/astro/routes/api/auth/signup/complete.ts +85 -0
  297. package/src/astro/routes/api/auth/signup/request.ts +77 -0
  298. package/src/astro/routes/api/auth/signup/verify.ts +53 -0
  299. package/src/astro/routes/api/comments/[collection]/[contentId]/index.ts +312 -0
  300. package/src/astro/routes/api/content/[collection]/[id]/compare.ts +28 -0
  301. package/src/astro/routes/api/content/[collection]/[id]/discard-draft.ts +54 -0
  302. package/src/astro/routes/api/content/[collection]/[id]/duplicate.ts +61 -0
  303. package/src/astro/routes/api/content/[collection]/[id]/permanent.ts +33 -0
  304. package/src/astro/routes/api/content/[collection]/[id]/preview-url.ts +107 -0
  305. package/src/astro/routes/api/content/[collection]/[id]/publish.ts +56 -0
  306. package/src/astro/routes/api/content/[collection]/[id]/restore.ts +54 -0
  307. package/src/astro/routes/api/content/[collection]/[id]/revisions.ts +31 -0
  308. package/src/astro/routes/api/content/[collection]/[id]/schedule.ts +105 -0
  309. package/src/astro/routes/api/content/[collection]/[id]/terms/[taxonomy].ts +140 -0
  310. package/src/astro/routes/api/content/[collection]/[id]/translations.ts +30 -0
  311. package/src/astro/routes/api/content/[collection]/[id]/unpublish.ts +56 -0
  312. package/src/astro/routes/api/content/[collection]/[id].ts +137 -0
  313. package/src/astro/routes/api/content/[collection]/index.ts +59 -0
  314. package/src/astro/routes/api/content/[collection]/trash.ts +33 -0
  315. package/src/astro/routes/api/dashboard.ts +32 -0
  316. package/src/astro/routes/api/dev/emails.ts +36 -0
  317. package/src/astro/routes/api/import/probe.ts +47 -0
  318. package/src/astro/routes/api/import/wordpress/analyze.ts +510 -0
  319. package/src/astro/routes/api/import/wordpress/execute.ts +283 -0
  320. package/src/astro/routes/api/import/wordpress/media.ts +338 -0
  321. package/src/astro/routes/api/import/wordpress/prepare.ts +181 -0
  322. package/src/astro/routes/api/import/wordpress/rewrite-urls.ts +393 -0
  323. package/src/astro/routes/api/import/wordpress-plugin/analyze.ts +111 -0
  324. package/src/astro/routes/api/import/wordpress-plugin/callback.ts +58 -0
  325. package/src/astro/routes/api/import/wordpress-plugin/execute.ts +347 -0
  326. package/src/astro/routes/api/manifest.ts +62 -0
  327. package/src/astro/routes/api/mcp.ts +124 -0
  328. package/src/astro/routes/api/media/[id]/confirm.ts +93 -0
  329. package/src/astro/routes/api/media/[id].ts +145 -0
  330. package/src/astro/routes/api/media/file/[key].ts +79 -0
  331. package/src/astro/routes/api/media/providers/[providerId]/[itemId].ts +86 -0
  332. package/src/astro/routes/api/media/providers/[providerId]/index.ts +111 -0
  333. package/src/astro/routes/api/media/providers/index.ts +30 -0
  334. package/src/astro/routes/api/media/upload-url.ts +137 -0
  335. package/src/astro/routes/api/media.ts +190 -0
  336. package/src/astro/routes/api/menus/[name]/items.ts +87 -0
  337. package/src/astro/routes/api/menus/[name]/reorder.ts +33 -0
  338. package/src/astro/routes/api/menus/[name].ts +65 -0
  339. package/src/astro/routes/api/menus/index.ts +47 -0
  340. package/src/astro/routes/api/oauth/authorize.ts +412 -0
  341. package/src/astro/routes/api/oauth/device/authorize.ts +45 -0
  342. package/src/astro/routes/api/oauth/device/code.ts +51 -0
  343. package/src/astro/routes/api/oauth/device/token.ts +69 -0
  344. package/src/astro/routes/api/oauth/token/refresh.ts +38 -0
  345. package/src/astro/routes/api/oauth/token/revoke.ts +38 -0
  346. package/src/astro/routes/api/oauth/token.ts +184 -0
  347. package/src/astro/routes/api/openapi.json.ts +32 -0
  348. package/src/astro/routes/api/plugins/[pluginId]/[...path].ts +92 -0
  349. package/src/astro/routes/api/redirects/404s/index.ts +72 -0
  350. package/src/astro/routes/api/redirects/404s/summary.ts +33 -0
  351. package/src/astro/routes/api/redirects/[id].ts +84 -0
  352. package/src/astro/routes/api/redirects/index.ts +52 -0
  353. package/src/astro/routes/api/revisions/[revisionId]/index.ts +29 -0
  354. package/src/astro/routes/api/revisions/[revisionId]/restore.ts +62 -0
  355. package/src/astro/routes/api/schema/collections/[slug]/fields/[fieldSlug].ts +76 -0
  356. package/src/astro/routes/api/schema/collections/[slug]/fields/index.ts +52 -0
  357. package/src/astro/routes/api/schema/collections/[slug]/fields/reorder.ts +32 -0
  358. package/src/astro/routes/api/schema/collections/[slug]/index.ts +80 -0
  359. package/src/astro/routes/api/schema/collections/index.ts +47 -0
  360. package/src/astro/routes/api/schema/index.ts +109 -0
  361. package/src/astro/routes/api/schema/orphans/[slug].ts +36 -0
  362. package/src/astro/routes/api/schema/orphans/index.ts +26 -0
  363. package/src/astro/routes/api/search/enable.ts +64 -0
  364. package/src/astro/routes/api/search/index.ts +55 -0
  365. package/src/astro/routes/api/search/rebuild.ts +72 -0
  366. package/src/astro/routes/api/search/stats.ts +35 -0
  367. package/src/astro/routes/api/search/suggest.ts +53 -0
  368. package/src/astro/routes/api/sections/[slug].ts +84 -0
  369. package/src/astro/routes/api/sections/index.ts +52 -0
  370. package/src/astro/routes/api/settings/email.ts +150 -0
  371. package/src/astro/routes/api/settings.ts +67 -0
  372. package/src/astro/routes/api/setup/admin-verify.ts +100 -0
  373. package/src/astro/routes/api/setup/admin.ts +94 -0
  374. package/src/astro/routes/api/setup/dev-bypass.ts +199 -0
  375. package/src/astro/routes/api/setup/dev-reset.ts +40 -0
  376. package/src/astro/routes/api/setup/index.ts +126 -0
  377. package/src/astro/routes/api/setup/status.ts +122 -0
  378. package/src/astro/routes/api/snapshot.ts +75 -0
  379. package/src/astro/routes/api/taxonomies/[name]/terms/[slug].ts +95 -0
  380. package/src/astro/routes/api/taxonomies/[name]/terms/index.ts +69 -0
  381. package/src/astro/routes/api/taxonomies/index.ts +59 -0
  382. package/src/astro/routes/api/themes/preview.ts +77 -0
  383. package/src/astro/routes/api/typegen.ts +114 -0
  384. package/src/astro/routes/api/well-known/auth.ts +68 -0
  385. package/src/astro/routes/api/well-known/oauth-authorization-server.ts +44 -0
  386. package/src/astro/routes/api/well-known/oauth-protected-resource.ts +37 -0
  387. package/src/astro/routes/api/widget-areas/[name]/reorder.ts +72 -0
  388. package/src/astro/routes/api/widget-areas/[name]/widgets/[id].ts +127 -0
  389. package/src/astro/routes/api/widget-areas/[name]/widgets.ts +80 -0
  390. package/src/astro/routes/api/widget-areas/[name].ts +87 -0
  391. package/src/astro/routes/api/widget-areas/index.ts +99 -0
  392. package/src/astro/routes/api/widget-components.ts +22 -0
  393. package/src/astro/routes/robots.txt.ts +77 -0
  394. package/src/astro/routes/sitemap.xml.ts +97 -0
  395. package/src/astro/storage/adapters.ts +74 -0
  396. package/src/astro/storage/index.ts +19 -0
  397. package/src/astro/storage/types.ts +60 -0
  398. package/src/astro/types.ts +346 -0
  399. package/src/auth/api-tokens.ts +25 -0
  400. package/src/auth/challenge-store.ts +80 -0
  401. package/src/auth/mode.ts +96 -0
  402. package/src/auth/oauth-state-store.ts +96 -0
  403. package/src/auth/passkey-config.ts +27 -0
  404. package/src/auth/rate-limit.ts +158 -0
  405. package/src/auth/scopes.ts +33 -0
  406. package/src/auth/types.ts +104 -0
  407. package/src/aws-sdk.d.ts +100 -0
  408. package/src/bylines/index.ts +237 -0
  409. package/src/cleanup.ts +153 -0
  410. package/src/cli/client-factory.ts +100 -0
  411. package/src/cli/commands/auth.ts +46 -0
  412. package/src/cli/commands/bundle-utils.ts +247 -0
  413. package/src/cli/commands/bundle.ts +609 -0
  414. package/src/cli/commands/content.ts +442 -0
  415. package/src/cli/commands/dev.ts +191 -0
  416. package/src/cli/commands/doctor.ts +211 -0
  417. package/src/cli/commands/export-seed.ts +630 -0
  418. package/src/cli/commands/import/wordpress.ts +1056 -0
  419. package/src/cli/commands/init.ts +192 -0
  420. package/src/cli/commands/login.ts +547 -0
  421. package/src/cli/commands/media.ts +165 -0
  422. package/src/cli/commands/menu.ts +67 -0
  423. package/src/cli/commands/plugin-init.ts +291 -0
  424. package/src/cli/commands/plugin-validate.ts +31 -0
  425. package/src/cli/commands/plugin.ts +33 -0
  426. package/src/cli/commands/publish.ts +699 -0
  427. package/src/cli/commands/schema.ts +233 -0
  428. package/src/cli/commands/search-cmd.ts +54 -0
  429. package/src/cli/commands/seed.ts +288 -0
  430. package/src/cli/commands/taxonomy.ts +128 -0
  431. package/src/cli/commands/types.ts +68 -0
  432. package/src/cli/credentials.ts +236 -0
  433. package/src/cli/index.ts +70 -0
  434. package/src/cli/output.ts +75 -0
  435. package/src/cli/wxr/parser.ts +969 -0
  436. package/src/client/cf-access.ts +193 -0
  437. package/src/client/index.ts +854 -0
  438. package/src/client/portable-text.ts +413 -0
  439. package/src/client/transport.ts +200 -0
  440. package/src/comments/moderator.ts +46 -0
  441. package/src/comments/notifications.ts +144 -0
  442. package/src/comments/query.ts +105 -0
  443. package/src/comments/service.ts +213 -0
  444. package/src/components/Break.astro +45 -0
  445. package/src/components/Button.astro +71 -0
  446. package/src/components/Buttons.astro +49 -0
  447. package/src/components/Code.astro +59 -0
  448. package/src/components/Columns.astro +59 -0
  449. package/src/components/CommentForm.astro +315 -0
  450. package/src/components/Comments.astro +232 -0
  451. package/src/components/Cover.astro +128 -0
  452. package/src/components/EmDashBodyEnd.astro +32 -0
  453. package/src/components/EmDashBodyStart.astro +32 -0
  454. package/src/components/EmDashHead.astro +53 -0
  455. package/src/components/EmDashImage.astro +178 -0
  456. package/src/components/EmDashMedia.astro +167 -0
  457. package/src/components/Embed.astro +128 -0
  458. package/src/components/File.astro +122 -0
  459. package/src/components/Gallery.astro +93 -0
  460. package/src/components/HtmlBlock.astro +33 -0
  461. package/src/components/Image.astro +178 -0
  462. package/src/components/InlineEditor.astro +27 -0
  463. package/src/components/InlinePortableTextEditor.tsx +1905 -0
  464. package/src/components/LiveSearch.astro +614 -0
  465. package/src/components/PortableText.astro +51 -0
  466. package/src/components/Pullquote.astro +51 -0
  467. package/src/components/Table.astro +108 -0
  468. package/src/components/WidgetArea.astro +22 -0
  469. package/src/components/WidgetRenderer.astro +72 -0
  470. package/src/components/index.ts +116 -0
  471. package/src/components/marks/Link.astro +31 -0
  472. package/src/components/marks/StrikeThrough.astro +7 -0
  473. package/src/components/marks/Subscript.astro +7 -0
  474. package/src/components/marks/Superscript.astro +7 -0
  475. package/src/components/marks/Underline.astro +7 -0
  476. package/src/components/widgets/Archives.astro +65 -0
  477. package/src/components/widgets/Categories.astro +35 -0
  478. package/src/components/widgets/RecentPosts.astro +51 -0
  479. package/src/components/widgets/Search.astro +18 -0
  480. package/src/components/widgets/Tags.astro +38 -0
  481. package/src/content/converters/index.ts +9 -0
  482. package/src/content/converters/portable-text-to-prosemirror.ts +385 -0
  483. package/src/content/converters/prosemirror-to-portable-text.ts +413 -0
  484. package/src/content/converters/types.ts +120 -0
  485. package/src/content/index.ts +5 -0
  486. package/src/database/connection.ts +67 -0
  487. package/src/database/dialect-helpers.ts +138 -0
  488. package/src/database/index.ts +5 -0
  489. package/src/database/migrations/001_initial.ts +136 -0
  490. package/src/database/migrations/002_media_status.ts +26 -0
  491. package/src/database/migrations/003_schema_registry.ts +79 -0
  492. package/src/database/migrations/004_plugins.ts +62 -0
  493. package/src/database/migrations/005_menus.ts +67 -0
  494. package/src/database/migrations/006_taxonomy_defs.ts +51 -0
  495. package/src/database/migrations/007_widgets.ts +42 -0
  496. package/src/database/migrations/008_auth.ts +194 -0
  497. package/src/database/migrations/009_user_disabled.ts +27 -0
  498. package/src/database/migrations/011_sections.ts +65 -0
  499. package/src/database/migrations/012_search.ts +25 -0
  500. package/src/database/migrations/013_scheduled_publishing.ts +51 -0
  501. package/src/database/migrations/014_draft_revisions.ts +72 -0
  502. package/src/database/migrations/015_indexes.ts +82 -0
  503. package/src/database/migrations/016_api_tokens.ts +89 -0
  504. package/src/database/migrations/017_authorization_codes.ts +45 -0
  505. package/src/database/migrations/018_seo.ts +56 -0
  506. package/src/database/migrations/019_i18n.ts +618 -0
  507. package/src/database/migrations/020_collection_url_pattern.ts +23 -0
  508. package/src/database/migrations/021_remove_section_categories.ts +43 -0
  509. package/src/database/migrations/022_marketplace_plugin_state.ts +46 -0
  510. package/src/database/migrations/023_plugin_metadata.ts +33 -0
  511. package/src/database/migrations/024_media_placeholders.ts +32 -0
  512. package/src/database/migrations/025_oauth_clients.ts +28 -0
  513. package/src/database/migrations/026_cron_tasks.ts +49 -0
  514. package/src/database/migrations/027_comments.ts +87 -0
  515. package/src/database/migrations/028_drop_author_url.ts +9 -0
  516. package/src/database/migrations/029_redirects.ts +67 -0
  517. package/src/database/migrations/030_widen_scheduled_index.ts +48 -0
  518. package/src/database/migrations/031_bylines.ts +90 -0
  519. package/src/database/migrations/032_rate_limits.ts +42 -0
  520. package/src/database/migrations/runner.ts +170 -0
  521. package/src/database/repositories/audit.ts +294 -0
  522. package/src/database/repositories/byline.ts +387 -0
  523. package/src/database/repositories/comment.ts +458 -0
  524. package/src/database/repositories/content.ts +1144 -0
  525. package/src/database/repositories/index.ts +30 -0
  526. package/src/database/repositories/media.ts +347 -0
  527. package/src/database/repositories/options.ts +150 -0
  528. package/src/database/repositories/plugin-storage.ts +373 -0
  529. package/src/database/repositories/redirect.ts +480 -0
  530. package/src/database/repositories/revision.ts +200 -0
  531. package/src/database/repositories/seo.ts +176 -0
  532. package/src/database/repositories/taxonomy.ts +294 -0
  533. package/src/database/repositories/types.ts +132 -0
  534. package/src/database/repositories/user.ts +258 -0
  535. package/src/database/transaction.ts +54 -0
  536. package/src/database/types.ts +501 -0
  537. package/src/database/validate.ts +138 -0
  538. package/src/db/adapters.ts +125 -0
  539. package/src/db/index.ts +37 -0
  540. package/src/db/libsql.ts +23 -0
  541. package/src/db/postgres.ts +30 -0
  542. package/src/db/sqlite.ts +27 -0
  543. package/src/emdash-runtime.ts +2096 -0
  544. package/src/fields/boolean.ts +34 -0
  545. package/src/fields/datetime.ts +44 -0
  546. package/src/fields/file.ts +41 -0
  547. package/src/fields/image.ts +34 -0
  548. package/src/fields/index.ts +42 -0
  549. package/src/fields/integer.ts +50 -0
  550. package/src/fields/json.ts +37 -0
  551. package/src/fields/multiselect.ts +48 -0
  552. package/src/fields/number.ts +52 -0
  553. package/src/fields/portable-text.ts +33 -0
  554. package/src/fields/reference.ts +29 -0
  555. package/src/fields/richtext.ts +31 -0
  556. package/src/fields/select.ts +46 -0
  557. package/src/fields/slug.ts +38 -0
  558. package/src/fields/text.ts +55 -0
  559. package/src/fields/textarea.ts +52 -0
  560. package/src/fields/types.ts +64 -0
  561. package/src/i18n/config.ts +68 -0
  562. package/src/import/index.ts +90 -0
  563. package/src/import/menus.ts +436 -0
  564. package/src/import/registry.ts +111 -0
  565. package/src/import/sections.ts +103 -0
  566. package/src/import/settings.ts +281 -0
  567. package/src/import/sources/wordpress-plugin.ts +641 -0
  568. package/src/import/sources/wordpress-rest.ts +191 -0
  569. package/src/import/sources/wxr.ts +330 -0
  570. package/src/import/ssrf.ts +260 -0
  571. package/src/import/types.ts +418 -0
  572. package/src/import/utils.ts +412 -0
  573. package/src/index.ts +481 -0
  574. package/src/loader.ts +770 -0
  575. package/src/mcp/server.ts +1463 -0
  576. package/src/media/index.ts +32 -0
  577. package/src/media/local-runtime.ts +213 -0
  578. package/src/media/local.ts +46 -0
  579. package/src/media/normalize.ts +190 -0
  580. package/src/media/placeholder.ts +150 -0
  581. package/src/media/provider-loader.ts +78 -0
  582. package/src/media/types.ts +279 -0
  583. package/src/menus/index.ts +324 -0
  584. package/src/menus/types.ts +112 -0
  585. package/src/page/context.ts +93 -0
  586. package/src/page/fragments.ts +89 -0
  587. package/src/page/index.ts +58 -0
  588. package/src/page/jsonld.ts +94 -0
  589. package/src/page/metadata.ts +185 -0
  590. package/src/page/seo-contributions.ts +136 -0
  591. package/src/plugin-utils.ts +80 -0
  592. package/src/plugins/adapt-sandbox-entry.ts +207 -0
  593. package/src/plugins/context.ts +833 -0
  594. package/src/plugins/cron.ts +361 -0
  595. package/src/plugins/define-plugin.ts +259 -0
  596. package/src/plugins/email-console.ts +73 -0
  597. package/src/plugins/email.ts +209 -0
  598. package/src/plugins/hooks.ts +1273 -0
  599. package/src/plugins/index.ts +193 -0
  600. package/src/plugins/manager.ts +595 -0
  601. package/src/plugins/manifest-schema.ts +230 -0
  602. package/src/plugins/marketplace.ts +460 -0
  603. package/src/plugins/request-meta.ts +139 -0
  604. package/src/plugins/routes.ts +302 -0
  605. package/src/plugins/sandbox/index.ts +18 -0
  606. package/src/plugins/sandbox/noop.ts +76 -0
  607. package/src/plugins/sandbox/types.ts +173 -0
  608. package/src/plugins/scheduler/node.ts +122 -0
  609. package/src/plugins/scheduler/piggyback.ts +71 -0
  610. package/src/plugins/scheduler/types.ts +27 -0
  611. package/src/plugins/state.ts +208 -0
  612. package/src/plugins/storage-indexes.ts +326 -0
  613. package/src/plugins/storage-query.ts +240 -0
  614. package/src/plugins/types.ts +1284 -0
  615. package/src/preview/helpers.ts +27 -0
  616. package/src/preview/index.ts +40 -0
  617. package/src/preview/tokens.ts +279 -0
  618. package/src/preview/urls.ts +118 -0
  619. package/src/query.ts +674 -0
  620. package/src/redirects/patterns.ts +224 -0
  621. package/src/request-context.ts +67 -0
  622. package/src/runtime.ts +21 -0
  623. package/src/schema/index.ts +29 -0
  624. package/src/schema/query.ts +44 -0
  625. package/src/schema/registry.ts +965 -0
  626. package/src/schema/types.ts +276 -0
  627. package/src/schema/zod-generator.ts +413 -0
  628. package/src/search/fts-manager.ts +452 -0
  629. package/src/search/index.ts +26 -0
  630. package/src/search/query.ts +396 -0
  631. package/src/search/text-extraction.ts +162 -0
  632. package/src/search/types.ts +114 -0
  633. package/src/sections/index.ts +226 -0
  634. package/src/sections/types.ts +86 -0
  635. package/src/seed/apply.ts +1141 -0
  636. package/src/seed/default.ts +86 -0
  637. package/src/seed/index.ts +28 -0
  638. package/src/seed/load.ts +35 -0
  639. package/src/seed/types.ts +341 -0
  640. package/src/seed/validate.ts +642 -0
  641. package/src/seo/index.ts +179 -0
  642. package/src/settings/index.ts +203 -0
  643. package/src/settings/types.ts +58 -0
  644. package/src/storage/index.ts +28 -0
  645. package/src/storage/local.ts +253 -0
  646. package/src/storage/s3.ts +271 -0
  647. package/src/storage/types.ts +204 -0
  648. package/src/taxonomies/index.ts +309 -0
  649. package/src/taxonomies/types.ts +61 -0
  650. package/src/ui.ts +75 -0
  651. package/src/utils/base64.ts +73 -0
  652. package/src/utils/hash.ts +36 -0
  653. package/src/utils/sanitize.ts +20 -0
  654. package/src/utils/slugify.ts +29 -0
  655. package/src/utils/url.ts +48 -0
  656. package/src/virtual-modules.d.ts +111 -0
  657. package/src/visual-editing/editable.ts +108 -0
  658. package/src/visual-editing/toolbar.ts +1229 -0
  659. package/src/widgets/components.ts +105 -0
  660. package/src/widgets/index.ts +131 -0
  661. package/src/widgets/types.ts +81 -0
@@ -0,0 +1,398 @@
1
+ /**
2
+ * EmDash middleware
3
+ *
4
+ * Thin wrapper that initializes EmDashRuntime and attaches it to locals.
5
+ * All heavy lifting happens in EmDashRuntime.
6
+ */
7
+
8
+ import { defineMiddleware } from "astro:middleware";
9
+ import { Kysely } from "kysely";
10
+ // Import from virtual modules (populated by integration at build time)
11
+ // @ts-ignore - virtual module
12
+ import virtualConfig from "virtual:emdash/config";
13
+ // @ts-ignore - virtual module
14
+ import {
15
+ createDialect as virtualCreateDialect,
16
+ isSessionEnabled as virtualIsSessionEnabled,
17
+ getD1Binding as virtualGetD1Binding,
18
+ getDefaultConstraint as virtualGetDefaultConstraint,
19
+ getBookmarkCookieName as virtualGetBookmarkCookieName,
20
+ createSessionDialect as virtualCreateSessionDialect,
21
+ } from "virtual:emdash/dialect";
22
+ // @ts-ignore - virtual module
23
+ import { mediaProviders as virtualMediaProviders } from "virtual:emdash/media-providers";
24
+ // @ts-ignore - virtual module
25
+ import { plugins as virtualPlugins } from "virtual:emdash/plugins";
26
+ import {
27
+ createSandboxRunner as virtualCreateSandboxRunner,
28
+ sandboxEnabled as virtualSandboxEnabled,
29
+ // @ts-ignore - virtual module
30
+ } from "virtual:emdash/sandbox-runner";
31
+ // @ts-ignore - virtual module
32
+ import { sandboxedPlugins as virtualSandboxedPlugins } from "virtual:emdash/sandboxed-plugins";
33
+ // @ts-ignore - virtual module
34
+ import { createStorage as virtualCreateStorage } from "virtual:emdash/storage";
35
+
36
+ import {
37
+ EmDashRuntime,
38
+ type RuntimeDependencies,
39
+ type SandboxedPluginEntry,
40
+ type MediaProviderEntry,
41
+ } from "../emdash-runtime.js";
42
+ import { setI18nConfig } from "../i18n/config.js";
43
+ import type { Database, Storage } from "../index.js";
44
+ import type { SandboxRunner } from "../plugins/sandbox/types.js";
45
+ import type { ResolvedPlugin } from "../plugins/types.js";
46
+ import { runWithContext } from "../request-context.js";
47
+ import type { EmDashConfig } from "./integration/runtime.js";
48
+
49
+ // Cached runtime instance (persists across requests within worker)
50
+ let runtimeInstance: EmDashRuntime | null = null;
51
+ // Whether initialization is in progress (prevents concurrent init attempts)
52
+ let runtimeInitializing = false;
53
+
54
+ /** Whether i18n config has been initialized from the virtual module */
55
+ let i18nInitialized = false;
56
+
57
+ /**
58
+ * Get EmDash configuration from virtual module
59
+ */
60
+ function getConfig(): EmDashConfig | null {
61
+ if (virtualConfig && typeof virtualConfig === "object") {
62
+ // Initialize i18n config on first access (once per worker lifetime)
63
+ if (!i18nInitialized) {
64
+ i18nInitialized = true;
65
+ // eslint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- virtual module checked as object above
66
+ const config = virtualConfig as Record<string, unknown>;
67
+ if (config.i18n && typeof config.i18n === "object") {
68
+ setI18nConfig(
69
+ // eslint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- runtime-checked above
70
+ config.i18n as {
71
+ defaultLocale: string;
72
+ locales: string[];
73
+ fallback?: Record<string, string>;
74
+ },
75
+ );
76
+ } else {
77
+ setI18nConfig(null);
78
+ }
79
+ }
80
+
81
+ // eslint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- virtual module import is untyped (@ts-ignore above)
82
+ return virtualConfig as EmDashConfig;
83
+ }
84
+ return null;
85
+ }
86
+
87
+ /**
88
+ * Get plugins from virtual module
89
+ */
90
+ function getPlugins(): ResolvedPlugin[] {
91
+ // eslint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- virtual module import is untyped (@ts-ignore above)
92
+ return (virtualPlugins as ResolvedPlugin[]) || [];
93
+ }
94
+
95
+ /**
96
+ * Build runtime dependencies from virtual modules
97
+ */
98
+ function buildDependencies(config: EmDashConfig): RuntimeDependencies {
99
+ return {
100
+ config,
101
+ plugins: getPlugins(),
102
+ // eslint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- virtual module import is untyped (@ts-ignore above)
103
+ createDialect: virtualCreateDialect as (config: Record<string, unknown>) => unknown,
104
+ // eslint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- virtual module import is untyped (@ts-ignore above)
105
+ createStorage: virtualCreateStorage as ((config: Record<string, unknown>) => Storage) | null,
106
+ // eslint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- virtual module import is untyped (@ts-ignore above)
107
+ sandboxEnabled: virtualSandboxEnabled as boolean,
108
+ // eslint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- virtual module import is untyped (@ts-ignore above)
109
+ sandboxedPluginEntries: (virtualSandboxedPlugins as SandboxedPluginEntry[]) || [],
110
+ // eslint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- virtual module import is untyped (@ts-ignore above)
111
+ createSandboxRunner: virtualCreateSandboxRunner as
112
+ | ((opts: { db: Kysely<Database> }) => SandboxRunner)
113
+ | null,
114
+ // eslint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- virtual module import is untyped (@ts-ignore above)
115
+ mediaProviderEntries: (virtualMediaProviders as MediaProviderEntry[]) || [],
116
+ };
117
+ }
118
+
119
+ /**
120
+ * Get or create the runtime instance
121
+ */
122
+ async function getRuntime(config: EmDashConfig): Promise<EmDashRuntime> {
123
+ // Return cached instance if available
124
+ if (runtimeInstance) {
125
+ return runtimeInstance;
126
+ }
127
+
128
+ // If another request is already initializing, wait and retry.
129
+ // We don't share the promise across requests because workerd flags
130
+ // cross-request promise resolution (causes warnings + potential hangs).
131
+ if (runtimeInitializing) {
132
+ // Poll until the initializing request finishes
133
+ await new Promise((resolve) => setTimeout(resolve, 50));
134
+ return getRuntime(config);
135
+ }
136
+
137
+ runtimeInitializing = true;
138
+ try {
139
+ const deps = buildDependencies(config);
140
+ const runtime = await EmDashRuntime.create(deps);
141
+ runtimeInstance = runtime;
142
+ return runtime;
143
+ } finally {
144
+ runtimeInitializing = false;
145
+ }
146
+ }
147
+
148
+ /**
149
+ * Baseline security headers applied to all responses.
150
+ * Admin routes get additional headers (strict CSP) from auth middleware.
151
+ */
152
+ function setBaselineSecurityHeaders(response: Response): void {
153
+ // Prevent MIME type sniffing
154
+ response.headers.set("X-Content-Type-Options", "nosniff");
155
+ // Control referrer information
156
+ response.headers.set("Referrer-Policy", "strict-origin-when-cross-origin");
157
+ // Restrict access to sensitive browser APIs
158
+ response.headers.set(
159
+ "Permissions-Policy",
160
+ "camera=(), microphone=(), geolocation=(), payment=()",
161
+ );
162
+ // Prevent clickjacking (non-admin routes; admin CSP uses frame-ancestors)
163
+ if (!response.headers.has("Content-Security-Policy")) {
164
+ response.headers.set("X-Frame-Options", "SAMEORIGIN");
165
+ }
166
+ }
167
+
168
+ /** Public routes that require the runtime (sitemap, robots.txt, etc.) */
169
+ const PUBLIC_RUNTIME_ROUTES = new Set(["/sitemap.xml", "/robots.txt"]);
170
+
171
+ export const onRequest = defineMiddleware(async (context, next) => {
172
+ const { request, locals, cookies } = context;
173
+ const url = context.url;
174
+
175
+ // Process /_emdash routes and public routes with an active session
176
+ // (logged-in editors need the runtime for toolbar/visual editing on public pages)
177
+ const isEmDashRoute = url.pathname.startsWith("/_emdash");
178
+ const isPublicRuntimeRoute = PUBLIC_RUNTIME_ROUTES.has(url.pathname);
179
+
180
+ // Check for edit mode cookie - editors viewing public pages need the runtime
181
+ // so auth middleware can verify their session for visual editing
182
+ const hasEditCookie = cookies.get("emdash-edit-mode")?.value === "true";
183
+ const hasPreviewToken = url.searchParams.has("_preview");
184
+
185
+ // Playground mode: the playground middleware stashes the per-session DO database
186
+ // on locals.__playgroundDb. When present, use runWithContext() to make it
187
+ // available to getDb() and the runtime's db getter via the correct ALS instance.
188
+ const playgroundDb = locals.__playgroundDb;
189
+
190
+ if (!isEmDashRoute && !isPublicRuntimeRoute && !hasEditCookie && !hasPreviewToken) {
191
+ const sessionUser = await context.session?.get("user");
192
+ if (!sessionUser && !playgroundDb) {
193
+ const response = await next();
194
+ setBaselineSecurityHeaders(response);
195
+ return response;
196
+ }
197
+ }
198
+
199
+ const config = getConfig();
200
+ if (!config) {
201
+ console.error("EmDash: No configuration found");
202
+ return next();
203
+ }
204
+
205
+ // In playground mode, wrap the entire runtime init + request handling in
206
+ // runWithContext so that getDatabase() and all init queries use the real
207
+ // DO database via the same AsyncLocalStorage instance as the loader.
208
+ const doInit = async () => {
209
+ try {
210
+ // Get or create runtime
211
+ const runtime = await getRuntime(config);
212
+
213
+ // Get manifest (cached after first call)
214
+ const manifest = await runtime.getManifest();
215
+
216
+ // Attach to locals for route handlers
217
+ locals.emdashManifest = manifest;
218
+ locals.emdash = {
219
+ // Content handlers
220
+ handleContentList: runtime.handleContentList.bind(runtime),
221
+ handleContentGet: runtime.handleContentGet.bind(runtime),
222
+ handleContentCreate: runtime.handleContentCreate.bind(runtime),
223
+ handleContentUpdate: runtime.handleContentUpdate.bind(runtime),
224
+ handleContentDelete: runtime.handleContentDelete.bind(runtime),
225
+
226
+ // Trash handlers
227
+ handleContentListTrashed: runtime.handleContentListTrashed.bind(runtime),
228
+ handleContentRestore: runtime.handleContentRestore.bind(runtime),
229
+ handleContentPermanentDelete: runtime.handleContentPermanentDelete.bind(runtime),
230
+ handleContentCountTrashed: runtime.handleContentCountTrashed.bind(runtime),
231
+ handleContentGetIncludingTrashed: runtime.handleContentGetIncludingTrashed.bind(runtime),
232
+
233
+ // Duplicate handler
234
+ handleContentDuplicate: runtime.handleContentDuplicate.bind(runtime),
235
+
236
+ // Publishing & Scheduling handlers
237
+ handleContentPublish: runtime.handleContentPublish.bind(runtime),
238
+ handleContentUnpublish: runtime.handleContentUnpublish.bind(runtime),
239
+ handleContentSchedule: runtime.handleContentSchedule.bind(runtime),
240
+ handleContentUnschedule: runtime.handleContentUnschedule.bind(runtime),
241
+ handleContentCountScheduled: runtime.handleContentCountScheduled.bind(runtime),
242
+ handleContentDiscardDraft: runtime.handleContentDiscardDraft.bind(runtime),
243
+ handleContentCompare: runtime.handleContentCompare.bind(runtime),
244
+ handleContentTranslations: runtime.handleContentTranslations.bind(runtime),
245
+
246
+ // Media handlers
247
+ handleMediaList: runtime.handleMediaList.bind(runtime),
248
+ handleMediaGet: runtime.handleMediaGet.bind(runtime),
249
+ handleMediaCreate: runtime.handleMediaCreate.bind(runtime),
250
+ handleMediaUpdate: runtime.handleMediaUpdate.bind(runtime),
251
+ handleMediaDelete: runtime.handleMediaDelete.bind(runtime),
252
+
253
+ // Revision handlers
254
+ handleRevisionList: runtime.handleRevisionList.bind(runtime),
255
+ handleRevisionGet: runtime.handleRevisionGet.bind(runtime),
256
+ handleRevisionRestore: runtime.handleRevisionRestore.bind(runtime),
257
+
258
+ // Plugin routes
259
+ handlePluginApiRoute: runtime.handlePluginApiRoute.bind(runtime),
260
+ getPluginRouteMeta: runtime.getPluginRouteMeta.bind(runtime),
261
+
262
+ // Media provider methods
263
+ getMediaProvider: runtime.getMediaProvider.bind(runtime),
264
+ getMediaProviderList: runtime.getMediaProviderList.bind(runtime),
265
+
266
+ // Direct access (for advanced use cases)
267
+ storage: runtime.storage,
268
+ db: runtime.db,
269
+ hooks: runtime.hooks,
270
+ email: runtime.email,
271
+ configuredPlugins: runtime.configuredPlugins,
272
+
273
+ // Configuration (for checking database type, auth mode, etc.)
274
+ config,
275
+
276
+ // Manifest invalidation (call after schema changes)
277
+ invalidateManifest: runtime.invalidateManifest.bind(runtime),
278
+
279
+ // Sandbox runner (for marketplace plugin install/update)
280
+ getSandboxRunner: runtime.getSandboxRunner.bind(runtime),
281
+
282
+ // Sync marketplace plugin states (after install/update/uninstall)
283
+ syncMarketplacePlugins: runtime.syncMarketplacePlugins.bind(runtime),
284
+
285
+ // Update plugin enabled/disabled status and rebuild hook pipeline
286
+ setPluginStatus: runtime.setPluginStatus.bind(runtime),
287
+ };
288
+ } catch (error) {
289
+ console.error("EmDash middleware error:", error);
290
+ }
291
+
292
+ // =========================================================================
293
+ // D1 Read Replica Session Management
294
+ //
295
+ // When D1 sessions are enabled, we create a per-request D1 session and
296
+ // Kysely instance. The session is wrapped in ALS so `runtime.db` (a getter)
297
+ // picks up the per-request instance instead of the singleton.
298
+ //
299
+ // After the response, we extract the bookmark from the session and set
300
+ // it as a cookie for authenticated users (read-your-writes consistency).
301
+ // =========================================================================
302
+ const dbConfig = config?.database?.config;
303
+ const sessionEnabled =
304
+ dbConfig &&
305
+ typeof virtualIsSessionEnabled === "function" &&
306
+ // eslint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- virtual module functions are untyped
307
+ (virtualIsSessionEnabled as (config: unknown) => boolean)(dbConfig);
308
+
309
+ if (
310
+ sessionEnabled &&
311
+ typeof virtualGetD1Binding === "function" &&
312
+ virtualCreateSessionDialect
313
+ ) {
314
+ // eslint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- virtual module functions are untyped
315
+ const d1Binding = (virtualGetD1Binding as (config: unknown) => unknown)(dbConfig);
316
+
317
+ if (d1Binding && typeof d1Binding === "object" && "withSession" in d1Binding) {
318
+ const isAuthenticated = !!(await context.session?.get("user"));
319
+ const isWrite = request.method !== "GET" && request.method !== "HEAD";
320
+
321
+ // Determine session constraint:
322
+ // - Config says "primary-first" → always "first-primary"
323
+ // - Authenticated writes → "first-primary" (need to hit primary)
324
+ // - Authenticated reads with bookmark → resume from bookmark
325
+ // - Otherwise → "first-unconstrained" (nearest replica)
326
+ // eslint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- virtual module functions are untyped
327
+ const configConstraint = (virtualGetDefaultConstraint as (config: unknown) => string)(
328
+ dbConfig,
329
+ );
330
+ // eslint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- virtual module functions are untyped
331
+ const cookieName = (virtualGetBookmarkCookieName as (config: unknown) => string)(dbConfig);
332
+
333
+ let constraint: string = configConstraint;
334
+ if (isAuthenticated && isWrite) {
335
+ constraint = "first-primary";
336
+ } else if (isAuthenticated) {
337
+ const bookmarkCookie = context.cookies.get(cookieName);
338
+ if (bookmarkCookie?.value) {
339
+ constraint = bookmarkCookie.value;
340
+ }
341
+ }
342
+
343
+ // Create the D1 session and per-request Kysely instance.
344
+ // D1DatabaseSession has the same prepare()/batch() interface as D1Database,
345
+ // so createSessionDialect passes it straight to D1Dialect.
346
+ // eslint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- D1 binding with Sessions API, checked via "withSession" in d1Binding above
347
+ const withSession = (d1Binding as { withSession: (c: string) => unknown }).withSession;
348
+ const session = withSession.call(d1Binding, constraint);
349
+ const sessionDialect =
350
+ // eslint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- virtual module functions are untyped
351
+ (virtualCreateSessionDialect as (db: unknown) => import("kysely").Dialect)(session);
352
+ const sessionDb = new Kysely<Database>({ dialect: sessionDialect });
353
+
354
+ // Wrap the request in ALS with the per-request db
355
+ return runWithContext({ editMode: false, db: sessionDb }, async () => {
356
+ const response = await next();
357
+ setBaselineSecurityHeaders(response);
358
+
359
+ // Set bookmark cookie for authenticated users only — they need
360
+ // read-your-writes consistency across requests. Anonymous visitors
361
+ // don't write, so they get "first-unconstrained" every time.
362
+ if (
363
+ isAuthenticated &&
364
+ session &&
365
+ typeof session === "object" &&
366
+ "getBookmark" in session
367
+ ) {
368
+ // eslint-disable-next-line typescript-eslint(no-unsafe-type-assertion) -- D1DatabaseSession with getBookmark()
369
+ const getBookmark = (session as { getBookmark: () => string | null }).getBookmark;
370
+ const newBookmark = getBookmark.call(session);
371
+ if (newBookmark) {
372
+ response.headers.append(
373
+ "Set-Cookie",
374
+ `${cookieName}=${newBookmark}; Path=/; HttpOnly; SameSite=Lax; Secure`,
375
+ );
376
+ }
377
+ }
378
+
379
+ return response;
380
+ });
381
+ }
382
+ }
383
+
384
+ const response = await next();
385
+ setBaselineSecurityHeaders(response);
386
+ return response;
387
+ }; // end doInit
388
+
389
+ if (playgroundDb) {
390
+ // Read the edit-mode cookie to determine if visual editing is active.
391
+ // Default to false -- editing is opt-in via the playground toolbar toggle.
392
+ const editMode = context.cookies.get("emdash-edit-mode")?.value === "true";
393
+ return runWithContext({ editMode, db: playgroundDb }, doInit);
394
+ }
395
+ return doInit();
396
+ });
397
+
398
+ export default onRequest;
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Admin Wrapper
3
+ *
4
+ * Imports plugin admin modules from the virtual module and passes them
5
+ * to AdminApp via props. This ensures plugin components are bundled
6
+ * together with the admin app and available via React context.
7
+ */
8
+
9
+ import { AdminApp } from "@emdash-cms/admin";
10
+ // @ts-ignore - virtual module generated by integration
11
+ import { pluginAdmins } from "virtual:emdash/admin-registry";
12
+
13
+ export default function AdminWrapper() {
14
+ return <AdminApp pluginAdmins={pluginAdmins} />;
15
+ }
@@ -0,0 +1,81 @@
1
+ ---
2
+ /**
3
+ * Admin shell route - injected by EmDash integration
4
+ *
5
+ * This page serves the EmDash admin React SPA.
6
+ * AdminWrapper imports plugin admin modules and passes them to AdminApp.
7
+ */
8
+ import "@emdash-cms/admin/styles.css";
9
+ // Use package-qualified import so Astro generates a proper module URL
10
+ // (relative imports resolve to absolute paths which break client hydration)
11
+ import AdminWrapper from "emdash/routes/PluginRegistry";
12
+
13
+ export const prerender = false;
14
+ ---
15
+
16
+ <!doctype html>
17
+ <html lang="en">
18
+ <head>
19
+ <meta charset="UTF-8" />
20
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
21
+ <link
22
+ rel="icon"
23
+ href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Ctext y='.9em' font-size='90'%3E%F0%9F%92%AB%3C/text%3E%3C/svg%3E"
24
+ />
25
+ <title>EmDash Admin</title>
26
+ </head>
27
+ <body>
28
+ <div id="admin-root" class="min-h-screen">
29
+ <div id="emdash-boot-loader">
30
+ <style>
31
+ #emdash-boot-loader {
32
+ display: flex;
33
+ align-items: center;
34
+ justify-content: center;
35
+ min-height: 100vh;
36
+ color-scheme: light dark;
37
+ background: light-dark(hsl(0 0% 100%), hsl(222.2 84% 4.9%));
38
+ }
39
+ #emdash-boot-loader .loader-inner {
40
+ text-align: center;
41
+ }
42
+ #emdash-boot-loader .spinner {
43
+ width: 24px;
44
+ height: 24px;
45
+ margin: 0 auto;
46
+ border: 2.5px solid
47
+ light-dark(
48
+ hsl(215.4 16.3% 46.9% / 0.3),
49
+ hsl(215 20.2% 65.1% / 0.3)
50
+ );
51
+ border-top-color: light-dark(
52
+ hsl(215.4 16.3% 46.9%),
53
+ hsl(215 20.2% 65.1%)
54
+ );
55
+ border-radius: 50%;
56
+ animation: emdash-spin 0.8s linear infinite;
57
+ }
58
+ #emdash-boot-loader p {
59
+ margin-top: 1rem;
60
+ font-family:
61
+ system-ui,
62
+ -apple-system,
63
+ sans-serif;
64
+ font-size: 0.875rem;
65
+ color: light-dark(hsl(215.4 16.3% 46.9%), hsl(215 20.2% 65.1%));
66
+ }
67
+ @keyframes emdash-spin {
68
+ to {
69
+ transform: rotate(360deg);
70
+ }
71
+ }
72
+ </style>
73
+ <div class="loader-inner">
74
+ <div class="spinner"></div>
75
+ <p>Loading EmDash...</p>
76
+ </div>
77
+ </div>
78
+ <AdminWrapper client:only="react" />
79
+ </div>
80
+ </body>
81
+ </html>
@@ -0,0 +1,112 @@
1
+ /**
2
+ * PATCH/DELETE /_emdash/api/admin/allowed-domains/[domain]
3
+ *
4
+ * Admin endpoints for managing a specific allowed domain.
5
+ * PATCH - Update domain settings (enabled, defaultRole)
6
+ * DELETE - Remove an allowed domain
7
+ */
8
+
9
+ import type { APIRoute } from "astro";
10
+
11
+ export const prerender = false;
12
+
13
+ import { Role, roleFromLevel } from "@emdash-cms/auth";
14
+ import { createKyselyAdapter } from "@emdash-cms/auth/adapters/kysely";
15
+
16
+ import { apiError, apiSuccess, handleError } from "#api/error.js";
17
+ import { isParseError, parseBody } from "#api/parse.js";
18
+ import { allowedDomainUpdateBody } from "#api/schemas.js";
19
+
20
+ /**
21
+ * PATCH - Update domain settings
22
+ */
23
+ export const PATCH: APIRoute = async ({ params, request, locals }) => {
24
+ const { emdash, user } = locals;
25
+ const { domain } = params;
26
+
27
+ if (!emdash?.db) {
28
+ return apiError("NOT_CONFIGURED", "Database not configured", 500);
29
+ }
30
+
31
+ if (!domain) {
32
+ return apiError("VALIDATION_ERROR", "Domain is required", 400);
33
+ }
34
+
35
+ if (!user || user.role < Role.ADMIN) {
36
+ return apiError("FORBIDDEN", "Admin privileges required", 403);
37
+ }
38
+
39
+ const adapter = createKyselyAdapter(emdash.db);
40
+
41
+ try {
42
+ const body = await parseBody(request, allowedDomainUpdateBody);
43
+ if (isParseError(body)) return body;
44
+
45
+ // Check if domain exists
46
+ const existing = await adapter.getAllowedDomain(domain);
47
+ if (!existing) {
48
+ return apiError("NOT_FOUND", "Domain not found", 404);
49
+ }
50
+
51
+ // Role is already validated as RoleLevel by Zod schema
52
+ const defaultRole = body.defaultRole;
53
+
54
+ // Update domain
55
+ const enabled = body.enabled ?? existing.enabled;
56
+ await adapter.updateAllowedDomain(domain, enabled, defaultRole);
57
+
58
+ // Fetch updated domain
59
+ const updated = await adapter.getAllowedDomain(domain);
60
+
61
+ return apiSuccess({
62
+ success: true,
63
+ domain: updated
64
+ ? {
65
+ domain: updated.domain,
66
+ defaultRole: updated.defaultRole,
67
+ roleName: roleFromLevel(updated.defaultRole),
68
+ enabled: updated.enabled,
69
+ createdAt: updated.createdAt.toISOString(),
70
+ }
71
+ : null,
72
+ });
73
+ } catch (error) {
74
+ return handleError(error, "Failed to update allowed domain", "DOMAIN_UPDATE_ERROR");
75
+ }
76
+ };
77
+
78
+ /**
79
+ * DELETE - Remove an allowed domain
80
+ */
81
+ export const DELETE: APIRoute = async ({ params, locals }) => {
82
+ const { emdash, user } = locals;
83
+ const { domain } = params;
84
+
85
+ if (!emdash?.db) {
86
+ return apiError("NOT_CONFIGURED", "Database not configured", 500);
87
+ }
88
+
89
+ if (!domain) {
90
+ return apiError("VALIDATION_ERROR", "Domain is required", 400);
91
+ }
92
+
93
+ if (!user || user.role < Role.ADMIN) {
94
+ return apiError("FORBIDDEN", "Admin privileges required", 403);
95
+ }
96
+
97
+ const adapter = createKyselyAdapter(emdash.db);
98
+
99
+ try {
100
+ // Check if domain exists (optional - delete is idempotent)
101
+ const existing = await adapter.getAllowedDomain(domain);
102
+ if (!existing) {
103
+ return apiError("NOT_FOUND", "Domain not found", 404);
104
+ }
105
+
106
+ await adapter.deleteAllowedDomain(domain);
107
+
108
+ return apiSuccess({ success: true });
109
+ } catch (error) {
110
+ return handleError(error, "Failed to delete allowed domain", "DOMAIN_DELETE_ERROR");
111
+ }
112
+ };