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,654 @@
1
+ import { t as apiError } from "../../error-Cxz0tQeO.mjs";
2
+ import { t as getAuthMode } from "../../mode-C2EzN1uE.mjs";
3
+ import { ulid } from "ulidx";
4
+ import { defineMiddleware } from "astro:middleware";
5
+ import { createKyselyAdapter } from "@emdash-cms/auth/adapters/kysely";
6
+ import { authenticate } from "virtual:emdash/auth";
7
+ import { hasScope, hashPrefixedToken as hashApiToken } from "@emdash-cms/auth";
8
+
9
+ //#region src/api/csrf.ts
10
+ /**
11
+ * CSRF protection utilities.
12
+ *
13
+ * Two mechanisms:
14
+ * 1. Custom header check (X-EmDash-Request: 1) — used for authenticated API routes.
15
+ * Browsers block cross-origin custom headers, so presence proves same-origin.
16
+ * 2. Origin check — used for public API routes that skip auth. Compares the Origin
17
+ * header against the request origin. Same approach as Astro's `checkOrigin`.
18
+ */
19
+ /**
20
+ * Origin-based CSRF check for public API routes that skip auth.
21
+ *
22
+ * State-changing requests (POST/PUT/DELETE) to public endpoints must either:
23
+ * 1. Include the X-EmDash-Request: 1 header (custom header blocked cross-origin), OR
24
+ * 2. Have an Origin header matching the request origin
25
+ *
26
+ * This prevents cross-origin form submissions (which can't set custom headers)
27
+ * and cross-origin fetch (blocked by CORS unless allowed). Same-origin requests
28
+ * always include a matching Origin header.
29
+ *
30
+ * Returns a 403 Response if the check fails, or null if allowed.
31
+ */
32
+ function checkPublicCsrf(request, url) {
33
+ if (request.headers.get("X-EmDash-Request") === "1") return null;
34
+ const origin = request.headers.get("Origin");
35
+ if (origin) {
36
+ try {
37
+ if (new URL(origin).origin === url.origin) return null;
38
+ } catch {}
39
+ return apiError("CSRF_REJECTED", "Cross-origin request blocked", 403);
40
+ }
41
+ return null;
42
+ }
43
+
44
+ //#endregion
45
+ //#region src/api/handlers/api-tokens.ts
46
+ /**
47
+ * Resolve a raw API token (ec_pat_...) to a user ID and scopes.
48
+ * Updates last_used_at on successful lookup.
49
+ * Returns null if the token is invalid or expired.
50
+ */
51
+ async function resolveApiToken(db, rawToken) {
52
+ const hash = hashApiToken(rawToken);
53
+ const row = await db.selectFrom("_emdash_api_tokens").select([
54
+ "id",
55
+ "user_id",
56
+ "scopes",
57
+ "expires_at"
58
+ ]).where("token_hash", "=", hash).executeTakeFirst();
59
+ if (!row) return null;
60
+ if (row.expires_at && new Date(row.expires_at) < /* @__PURE__ */ new Date()) return null;
61
+ db.updateTable("_emdash_api_tokens").set({ last_used_at: (/* @__PURE__ */ new Date()).toISOString() }).where("id", "=", row.id).execute().catch(() => {});
62
+ return {
63
+ userId: row.user_id,
64
+ scopes: JSON.parse(row.scopes)
65
+ };
66
+ }
67
+ /**
68
+ * Resolve an OAuth access token (ec_oat_...) to a user ID and scopes.
69
+ * Returns null if the token is invalid or expired.
70
+ */
71
+ async function resolveOAuthToken(db, rawToken) {
72
+ const hash = hashApiToken(rawToken);
73
+ const row = await db.selectFrom("_emdash_oauth_tokens").select([
74
+ "user_id",
75
+ "scopes",
76
+ "expires_at",
77
+ "token_type"
78
+ ]).where("token_hash", "=", hash).where("token_type", "=", "access").executeTakeFirst();
79
+ if (!row) return null;
80
+ if (new Date(row.expires_at) < /* @__PURE__ */ new Date()) return null;
81
+ return {
82
+ userId: row.user_id,
83
+ scopes: JSON.parse(row.scopes)
84
+ };
85
+ }
86
+
87
+ //#endregion
88
+ //#region src/astro/middleware/auth.ts
89
+ /** Cache headers for middleware error responses (matches API_CACHE_HEADERS in api/error.ts) */
90
+ const MW_CACHE_HEADERS = { "Cache-Control": "private, no-store" };
91
+ const ROLE_ADMIN = 50;
92
+ /**
93
+ * Strict Content-Security-Policy for /_emdash routes (admin + API).
94
+ *
95
+ * Applied via middleware header rather than Astro's built-in CSP because
96
+ * Astro's auto-hashing defeats 'unsafe-inline' (CSP3 ignores 'unsafe-inline'
97
+ * when hashes are present), which would break user-facing pages.
98
+ */
99
+ function buildEmDashCsp(marketplaceUrl) {
100
+ const imgSources = [
101
+ "'self'",
102
+ "data:",
103
+ "blob:"
104
+ ];
105
+ if (marketplaceUrl) try {
106
+ imgSources.push(new URL(marketplaceUrl).origin);
107
+ } catch {}
108
+ return [
109
+ "default-src 'self'",
110
+ "script-src 'self' 'unsafe-inline'",
111
+ "style-src 'self' 'unsafe-inline'",
112
+ "connect-src 'self'",
113
+ "form-action 'self'",
114
+ "frame-ancestors 'none'",
115
+ `img-src ${imgSources.join(" ")}`,
116
+ "object-src 'none'",
117
+ "base-uri 'self'"
118
+ ].join("; ");
119
+ }
120
+ /**
121
+ * API routes that skip auth — each handles its own access control.
122
+ *
123
+ * Prefix entries match any path starting with that prefix.
124
+ * Exact entries (no trailing slash or wildcard) match that path only.
125
+ */
126
+ const PUBLIC_API_PREFIXES = [
127
+ "/_emdash/api/setup",
128
+ "/_emdash/api/auth/login",
129
+ "/_emdash/api/auth/register",
130
+ "/_emdash/api/auth/dev-bypass",
131
+ "/_emdash/api/auth/signup/",
132
+ "/_emdash/api/auth/magic-link/",
133
+ "/_emdash/api/auth/invite/accept",
134
+ "/_emdash/api/auth/invite/complete",
135
+ "/_emdash/api/auth/oauth/",
136
+ "/_emdash/api/oauth/device/token",
137
+ "/_emdash/api/oauth/device/code",
138
+ "/_emdash/api/oauth/token",
139
+ "/_emdash/api/comments/",
140
+ "/_emdash/api/media/file/",
141
+ "/_emdash/.well-known/"
142
+ ];
143
+ const PUBLIC_API_EXACT = new Set([
144
+ "/_emdash/api/auth/passkey/options",
145
+ "/_emdash/api/auth/passkey/verify",
146
+ "/_emdash/api/oauth/token",
147
+ "/_emdash/api/snapshot"
148
+ ]);
149
+ function isPublicEmDashRoute(pathname) {
150
+ if (PUBLIC_API_EXACT.has(pathname)) return true;
151
+ if (PUBLIC_API_PREFIXES.some((p) => pathname.startsWith(p))) return true;
152
+ if (import.meta.env.DEV && pathname === "/_emdash/api/typegen") return true;
153
+ return false;
154
+ }
155
+ const onRequest = defineMiddleware(async (context, next) => {
156
+ const { url } = context;
157
+ const isAdminRoute = url.pathname.startsWith("/_emdash/admin");
158
+ const isSetupRoute = url.pathname.startsWith("/_emdash/admin/setup");
159
+ const isApiRoute = url.pathname.startsWith("/_emdash/api");
160
+ const isPublicApiRoute = isPublicEmDashRoute(url.pathname);
161
+ const isPublicRoute = !isAdminRoute && !isApiRoute;
162
+ if (isPublicApiRoute) {
163
+ const method = context.request.method.toUpperCase();
164
+ if (method !== "GET" && method !== "HEAD" && method !== "OPTIONS") {
165
+ const csrfError = checkPublicCsrf(context.request, url);
166
+ if (csrfError) return csrfError;
167
+ }
168
+ return next();
169
+ }
170
+ if (url.pathname.startsWith("/_emdash/api/plugins/")) {
171
+ const method = context.request.method.toUpperCase();
172
+ if (method !== "GET" && method !== "HEAD" && method !== "OPTIONS") {
173
+ const csrfError = checkPublicCsrf(context.request, url);
174
+ if (csrfError) return csrfError;
175
+ }
176
+ return handlePluginRouteAuth(context, next);
177
+ }
178
+ if (isSetupRoute) {
179
+ const method = context.request.method.toUpperCase();
180
+ if (method !== "GET" && method !== "HEAD" && method !== "OPTIONS") {
181
+ if (context.request.headers.get("X-EmDash-Request") !== "1") return new Response(JSON.stringify({ error: {
182
+ code: "CSRF_REJECTED",
183
+ message: "Missing required header"
184
+ } }), {
185
+ status: 403,
186
+ headers: {
187
+ "Content-Type": "application/json",
188
+ ...MW_CACHE_HEADERS
189
+ }
190
+ });
191
+ }
192
+ return next();
193
+ }
194
+ if (isPublicRoute) return handlePublicRouteAuth(context, next);
195
+ const bearerResult = await handleBearerAuth(context);
196
+ if (bearerResult === "invalid") {
197
+ const headers = {
198
+ "Content-Type": "application/json",
199
+ ...MW_CACHE_HEADERS
200
+ };
201
+ if (url.pathname === "/_emdash/api/mcp") headers["WWW-Authenticate"] = `Bearer resource_metadata="${url.origin}/.well-known/oauth-protected-resource"`;
202
+ return new Response(JSON.stringify({ error: {
203
+ code: "INVALID_TOKEN",
204
+ message: "Invalid or expired token"
205
+ } }), {
206
+ status: 401,
207
+ headers
208
+ });
209
+ }
210
+ const isTokenAuth = bearerResult === "authenticated";
211
+ const method = context.request.method.toUpperCase();
212
+ const isOAuthConsent = url.pathname.startsWith("/_emdash/oauth/authorize");
213
+ if (isApiRoute && !isTokenAuth && !isOAuthConsent && method !== "GET" && method !== "HEAD" && method !== "OPTIONS" && !isPublicApiRoute) {
214
+ if (context.request.headers.get("X-EmDash-Request") !== "1") return new Response(JSON.stringify({ error: {
215
+ code: "CSRF_REJECTED",
216
+ message: "Missing required header"
217
+ } }), {
218
+ status: 403,
219
+ headers: {
220
+ "Content-Type": "application/json",
221
+ ...MW_CACHE_HEADERS
222
+ }
223
+ });
224
+ }
225
+ if (isTokenAuth) {
226
+ const scopeError = enforceTokenScope(url.pathname, method, context.locals.tokenScopes);
227
+ if (scopeError) return scopeError;
228
+ const response = await next();
229
+ if (!import.meta.env.DEV) {
230
+ const marketplaceUrl = context.locals.emdash?.config.marketplace;
231
+ response.headers.set("Content-Security-Policy", buildEmDashCsp(marketplaceUrl));
232
+ }
233
+ return response;
234
+ }
235
+ const response = await handleEmDashAuth(context, next);
236
+ if (!import.meta.env.DEV) {
237
+ const marketplaceUrl = context.locals.emdash?.config.marketplace;
238
+ response.headers.set("Content-Security-Policy", buildEmDashCsp(marketplaceUrl));
239
+ }
240
+ return response;
241
+ });
242
+ /**
243
+ * Auth handling for /_emdash routes. Returns a Response from either
244
+ * an auth error/redirect or the downstream route handler.
245
+ */
246
+ async function handleEmDashAuth(context, next) {
247
+ const { url, locals } = context;
248
+ const { emdash } = locals;
249
+ const isLoginRoute = url.pathname.startsWith("/_emdash/admin/login");
250
+ const isApiRoute = url.pathname.startsWith("/_emdash/api");
251
+ if (!emdash?.db) return next();
252
+ const authMode = getAuthMode(emdash.config);
253
+ if (authMode.type === "external") {
254
+ if (import.meta.env.DEV) {
255
+ if (isLoginRoute) return next();
256
+ return handlePasskeyAuth(context, next, isApiRoute);
257
+ }
258
+ return handleExternalAuth(context, next, authMode, isApiRoute);
259
+ }
260
+ if (isLoginRoute) return next();
261
+ return handlePasskeyAuth(context, next, isApiRoute);
262
+ }
263
+ /**
264
+ * Soft auth for plugin routes: resolve user from Bearer token or session if present,
265
+ * but never block unauthenticated requests. The catch-all handler checks route
266
+ * metadata to decide whether auth is required (public vs private routes).
267
+ */
268
+ async function handlePluginRouteAuth(context, next) {
269
+ const { locals } = context;
270
+ const { emdash } = locals;
271
+ try {
272
+ const bearerResult = await handleBearerAuth(context);
273
+ if (bearerResult === "authenticated") return next();
274
+ if (bearerResult === "invalid") return new Response(JSON.stringify({ error: {
275
+ code: "INVALID_TOKEN",
276
+ message: "Invalid or expired token"
277
+ } }), {
278
+ status: 401,
279
+ headers: {
280
+ "Content-Type": "application/json",
281
+ ...MW_CACHE_HEADERS
282
+ }
283
+ });
284
+ } catch (error) {
285
+ console.error("Plugin route bearer auth error:", error);
286
+ }
287
+ try {
288
+ const { session } = context;
289
+ const sessionUser = await session?.get("user");
290
+ if (sessionUser?.id && emdash?.db) {
291
+ const user = await createKyselyAdapter(emdash.db).getUserById(sessionUser.id);
292
+ if (user && !user.disabled) locals.user = user;
293
+ }
294
+ } catch (error) {
295
+ console.error("Plugin route session auth error:", error);
296
+ }
297
+ return next();
298
+ }
299
+ /**
300
+ * Soft auth check for public routes with edit mode cookie.
301
+ * Checks the session and sets locals.user if valid, but never blocks the request.
302
+ */
303
+ async function handlePublicRouteAuth(context, next) {
304
+ const { locals, session } = context;
305
+ const { emdash } = locals;
306
+ try {
307
+ const sessionUser = await session?.get("user");
308
+ if (sessionUser?.id && emdash?.db) {
309
+ const user = await createKyselyAdapter(emdash.db).getUserById(sessionUser.id);
310
+ if (user && !user.disabled) locals.user = user;
311
+ }
312
+ } catch {}
313
+ return next();
314
+ }
315
+ /**
316
+ * Handle external auth provider authentication (Cloudflare Access, etc.)
317
+ */
318
+ async function handleExternalAuth(context, next, authMode, _isApiRoute) {
319
+ const { locals, request } = context;
320
+ const { emdash } = locals;
321
+ try {
322
+ if (typeof authenticate !== "function") throw new Error(`Auth provider ${authMode.entrypoint} does not export an authenticate function`);
323
+ const authResult = await authenticate(request, authMode.config);
324
+ const externalConfig = authMode.config;
325
+ const adapter = createKyselyAdapter(emdash.db);
326
+ let user = await adapter.getUserByEmail(authResult.email);
327
+ if (!user) {
328
+ if (externalConfig.autoProvision === false) return new Response("User not authorized", {
329
+ status: 403,
330
+ headers: {
331
+ "Content-Type": "text/plain",
332
+ ...MW_CACHE_HEADERS
333
+ }
334
+ });
335
+ const userCount = await emdash.db.selectFrom("users").select(emdash.db.fn.count("id").as("count")).executeTakeFirst();
336
+ const isFirstUser = Number(userCount?.count ?? 0) === 0;
337
+ const role = isFirstUser ? ROLE_ADMIN : authResult.role;
338
+ const now = (/* @__PURE__ */ new Date()).toISOString();
339
+ const newUser = {
340
+ id: ulid(),
341
+ email: authResult.email,
342
+ name: authResult.name,
343
+ role,
344
+ email_verified: 1,
345
+ created_at: now,
346
+ updated_at: now
347
+ };
348
+ await emdash.db.insertInto("users").values(newUser).execute();
349
+ user = await adapter.getUserByEmail(authResult.email);
350
+ console.log(`[external-auth] Provisioned user: ${authResult.email} (role: ${role}, first: ${isFirstUser})`);
351
+ } else {
352
+ const updates = {};
353
+ let newName;
354
+ let newRole;
355
+ if (authResult.name && user.name !== authResult.name) {
356
+ newName = authResult.name;
357
+ updates.name = newName;
358
+ }
359
+ if (externalConfig.syncRoles && user.role !== authResult.role) {
360
+ newRole = authResult.role;
361
+ updates.role = newRole;
362
+ }
363
+ if (Object.keys(updates).length > 0) {
364
+ updates.updated_at = (/* @__PURE__ */ new Date()).toISOString();
365
+ await emdash.db.updateTable("users").set(updates).where("id", "=", user.id).execute();
366
+ user = {
367
+ ...user,
368
+ ...newName ? { name: newName } : {},
369
+ ...newRole ? { role: newRole } : {}
370
+ };
371
+ console.log(`[external-auth] Updated user ${authResult.email}:`, Object.keys(updates).filter((k) => k !== "updated_at"));
372
+ }
373
+ }
374
+ if (!user) return new Response("Failed to provision user", {
375
+ status: 500,
376
+ headers: {
377
+ "Content-Type": "text/plain",
378
+ ...MW_CACHE_HEADERS
379
+ }
380
+ });
381
+ if (user.disabled) return new Response("Account disabled", {
382
+ status: 403,
383
+ headers: {
384
+ "Content-Type": "text/plain",
385
+ ...MW_CACHE_HEADERS
386
+ }
387
+ });
388
+ locals.user = user;
389
+ const { session } = context;
390
+ session?.set("user", { id: user.id });
391
+ return next();
392
+ } catch (error) {
393
+ console.error("[external-auth] Auth error:", error);
394
+ return new Response("Authentication failed", {
395
+ status: 401,
396
+ headers: {
397
+ "Content-Type": "text/plain",
398
+ ...MW_CACHE_HEADERS
399
+ }
400
+ });
401
+ }
402
+ }
403
+ /**
404
+ * Try to authenticate via Bearer token (API token or OAuth token).
405
+ *
406
+ * Returns:
407
+ * - "authenticated" if token is valid and user is resolved
408
+ * - "invalid" if a token was provided but is invalid/expired
409
+ * - "none" if no Bearer token was provided
410
+ */
411
+ async function handleBearerAuth(context) {
412
+ const authHeader = context.request.headers.get("Authorization");
413
+ if (!authHeader?.startsWith("Bearer ")) return "none";
414
+ const token = authHeader.slice(7);
415
+ if (!token) return "none";
416
+ const { locals } = context;
417
+ const { emdash } = locals;
418
+ if (!emdash?.db) return "none";
419
+ let resolved = null;
420
+ if (token.startsWith("ec_pat_")) resolved = await resolveApiToken(emdash.db, token);
421
+ else if (token.startsWith("ec_oat_")) resolved = await resolveOAuthToken(emdash.db, token);
422
+ else return "invalid";
423
+ if (!resolved) return "invalid";
424
+ const user = await createKyselyAdapter(emdash.db).getUserById(resolved.userId);
425
+ if (!user || user.disabled) return "invalid";
426
+ locals.user = user;
427
+ locals.tokenScopes = resolved.scopes;
428
+ return "authenticated";
429
+ }
430
+ /**
431
+ * Handle passkey (session-based) authentication
432
+ */
433
+ async function handlePasskeyAuth(context, next, isApiRoute) {
434
+ const { url, locals, session } = context;
435
+ const { emdash } = locals;
436
+ try {
437
+ const sessionUser = await session?.get("user");
438
+ if (!sessionUser?.id) {
439
+ if (isApiRoute) {
440
+ const headers = { ...MW_CACHE_HEADERS };
441
+ if (url.pathname === "/_emdash/api/mcp") headers["WWW-Authenticate"] = `Bearer resource_metadata="${url.origin}/.well-known/oauth-protected-resource"`;
442
+ return Response.json({ error: {
443
+ code: "NOT_AUTHENTICATED",
444
+ message: "Not authenticated"
445
+ } }, {
446
+ status: 401,
447
+ headers
448
+ });
449
+ }
450
+ const loginUrl = new URL("/_emdash/admin/login", url.origin);
451
+ loginUrl.searchParams.set("redirect", url.pathname);
452
+ return context.redirect(loginUrl.toString());
453
+ }
454
+ const user = await createKyselyAdapter(emdash.db).getUserById(sessionUser.id);
455
+ if (!user) {
456
+ session?.destroy();
457
+ if (isApiRoute) return Response.json({ error: {
458
+ code: "NOT_FOUND",
459
+ message: "User not found"
460
+ } }, {
461
+ status: 401,
462
+ headers: MW_CACHE_HEADERS
463
+ });
464
+ return context.redirect("/_emdash/admin/login");
465
+ }
466
+ if (user.disabled) {
467
+ session?.destroy();
468
+ if (isApiRoute) return apiError("ACCOUNT_DISABLED", "Account disabled", 403);
469
+ const loginUrl = new URL("/_emdash/admin/login", url.origin);
470
+ loginUrl.searchParams.set("error", "account_disabled");
471
+ return context.redirect(loginUrl.toString());
472
+ }
473
+ locals.user = user;
474
+ } catch (error) {
475
+ console.error("Auth middleware error:", error);
476
+ return context.redirect("/_emdash/admin/login");
477
+ }
478
+ return next();
479
+ }
480
+ /**
481
+ * Scope rules: ordered list of (pathPrefix, method, requiredScope) tuples.
482
+ * First matching rule wins. Methods: "*" = any, "WRITE" = POST/PUT/PATCH/DELETE.
483
+ *
484
+ * Routes not matched by any rule default to "admin" scope (fail-closed).
485
+ */
486
+ const SCOPE_RULES = [
487
+ [
488
+ "/_emdash/api/content",
489
+ "GET",
490
+ "content:read"
491
+ ],
492
+ [
493
+ "/_emdash/api/content",
494
+ "WRITE",
495
+ "content:write"
496
+ ],
497
+ [
498
+ "/_emdash/api/media/file",
499
+ "*",
500
+ "media:read"
501
+ ],
502
+ [
503
+ "/_emdash/api/media",
504
+ "GET",
505
+ "media:read"
506
+ ],
507
+ [
508
+ "/_emdash/api/media",
509
+ "WRITE",
510
+ "media:write"
511
+ ],
512
+ [
513
+ "/_emdash/api/schema",
514
+ "GET",
515
+ "schema:read"
516
+ ],
517
+ [
518
+ "/_emdash/api/schema",
519
+ "WRITE",
520
+ "schema:write"
521
+ ],
522
+ [
523
+ "/_emdash/api/taxonomies",
524
+ "GET",
525
+ "content:read"
526
+ ],
527
+ [
528
+ "/_emdash/api/taxonomies",
529
+ "WRITE",
530
+ "content:write"
531
+ ],
532
+ [
533
+ "/_emdash/api/menus",
534
+ "GET",
535
+ "content:read"
536
+ ],
537
+ [
538
+ "/_emdash/api/menus",
539
+ "WRITE",
540
+ "content:write"
541
+ ],
542
+ [
543
+ "/_emdash/api/sections",
544
+ "GET",
545
+ "content:read"
546
+ ],
547
+ [
548
+ "/_emdash/api/sections",
549
+ "WRITE",
550
+ "content:write"
551
+ ],
552
+ [
553
+ "/_emdash/api/widget-areas",
554
+ "GET",
555
+ "content:read"
556
+ ],
557
+ [
558
+ "/_emdash/api/widget-areas",
559
+ "WRITE",
560
+ "content:write"
561
+ ],
562
+ [
563
+ "/_emdash/api/revisions",
564
+ "GET",
565
+ "content:read"
566
+ ],
567
+ [
568
+ "/_emdash/api/revisions",
569
+ "WRITE",
570
+ "content:write"
571
+ ],
572
+ [
573
+ "/_emdash/api/search",
574
+ "GET",
575
+ "content:read"
576
+ ],
577
+ [
578
+ "/_emdash/api/search",
579
+ "WRITE",
580
+ "admin"
581
+ ],
582
+ [
583
+ "/_emdash/api/import",
584
+ "*",
585
+ "admin"
586
+ ],
587
+ [
588
+ "/_emdash/api/admin",
589
+ "*",
590
+ "admin"
591
+ ],
592
+ [
593
+ "/_emdash/api/settings",
594
+ "*",
595
+ "admin"
596
+ ],
597
+ [
598
+ "/_emdash/api/plugins",
599
+ "*",
600
+ "admin"
601
+ ],
602
+ [
603
+ "/_emdash/api/mcp",
604
+ "*",
605
+ "content:read"
606
+ ]
607
+ ];
608
+ const WRITE_METHODS = new Set([
609
+ "POST",
610
+ "PUT",
611
+ "PATCH",
612
+ "DELETE"
613
+ ]);
614
+ /**
615
+ * Enforce API token scopes based on the request URL and HTTP method.
616
+ * Returns a 403 Response if the scope is insufficient, or null if allowed.
617
+ *
618
+ * Session-authenticated requests (tokenScopes === undefined) are never checked.
619
+ */
620
+ function enforceTokenScope(pathname, method, tokenScopes) {
621
+ if (!tokenScopes) return null;
622
+ const isWrite = WRITE_METHODS.has(method);
623
+ for (const [prefix, ruleMethod, scope] of SCOPE_RULES) {
624
+ if (pathname !== prefix && !pathname.startsWith(prefix + "/")) continue;
625
+ if (ruleMethod === "*" || ruleMethod === "WRITE" && isWrite || ruleMethod === method) {
626
+ if (hasScope(tokenScopes, scope)) return null;
627
+ return new Response(JSON.stringify({ error: {
628
+ code: "INSUFFICIENT_SCOPE",
629
+ message: `Token lacks required scope: ${scope}`
630
+ } }), {
631
+ status: 403,
632
+ headers: {
633
+ "Content-Type": "application/json",
634
+ ...MW_CACHE_HEADERS
635
+ }
636
+ });
637
+ }
638
+ }
639
+ if (hasScope(tokenScopes, "admin")) return null;
640
+ return new Response(JSON.stringify({ error: {
641
+ code: "INSUFFICIENT_SCOPE",
642
+ message: "Token lacks required scope: admin"
643
+ } }), {
644
+ status: 403,
645
+ headers: {
646
+ "Content-Type": "application/json",
647
+ ...MW_CACHE_HEADERS
648
+ }
649
+ });
650
+ }
651
+
652
+ //#endregion
653
+ export { onRequest };
654
+ //# sourceMappingURL=auth.mjs.map