emdash 0.0.0-b → 0.0.2

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 -43
  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 +1336 -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-C0hCbYnD.mjs +1412 -0
  127. package/dist/runner-C0hCbYnD.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 +684 -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 +349 -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 +335 -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 +116 -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 +115 -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 +101 -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 +58 -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 +68 -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 +697 -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 +286 -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 +170 -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 +39 -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 +249 -0
  646. package/src/storage/s3.ts +263 -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,43 @@
1
+ import { type Kysely, sql } from "kysely";
2
+
3
+ /**
4
+ * Migration: Remove section categories
5
+ *
6
+ * Section categories had a complete backend but no UI to create or manage them.
7
+ * Rather than building the missing UI for a feature with very little need at this stage,
8
+ * we're removing the feature entirely.
9
+ */
10
+ export async function up(db: Kysely<unknown>): Promise<void> {
11
+ // Drop index before column — SQLite requires this order
12
+ await db.schema.dropIndex("idx_sections_category").ifExists().execute();
13
+
14
+ await db.schema.alterTable("_emdash_sections").dropColumn("category_id").execute();
15
+
16
+ await db.schema.dropTable("_emdash_section_categories").execute();
17
+ }
18
+
19
+ export async function down(db: Kysely<unknown>): Promise<void> {
20
+ // Recreate section categories table
21
+ await db.schema
22
+ .createTable("_emdash_section_categories")
23
+ .addColumn("id", "text", (col) => col.primaryKey())
24
+ .addColumn("slug", "text", (col) => col.notNull().unique())
25
+ .addColumn("label", "text", (col) => col.notNull())
26
+ .addColumn("sort_order", "integer", (col) => col.defaultTo(0))
27
+ .addColumn("created_at", "text", (col) => col.defaultTo(sql`CURRENT_TIMESTAMP`))
28
+ .execute();
29
+
30
+ // Re-add category_id column to sections
31
+ await db.schema
32
+ .alterTable("_emdash_sections")
33
+ .addColumn("category_id", "text", (col) =>
34
+ col.references("_emdash_section_categories.id").onDelete("set null"),
35
+ )
36
+ .execute();
37
+
38
+ await db.schema
39
+ .createIndex("idx_sections_category")
40
+ .on("_emdash_sections")
41
+ .columns(["category_id"])
42
+ .execute();
43
+ }
@@ -0,0 +1,46 @@
1
+ import type { Kysely } from "kysely";
2
+ import { sql } from "kysely";
3
+
4
+ /**
5
+ * Migration: Add marketplace fields to _plugin_state
6
+ *
7
+ * Adds `source` and `marketplace_version` columns to track
8
+ * whether a plugin was installed from config or marketplace,
9
+ * and which marketplace version is installed.
10
+ */
11
+ export async function up(db: Kysely<unknown>): Promise<void> {
12
+ // source: 'config' (declared in astro.config) or 'marketplace' (installed from registry)
13
+ await sql`
14
+ ALTER TABLE _plugin_state
15
+ ADD COLUMN source TEXT NOT NULL DEFAULT 'config'
16
+ `.execute(db);
17
+
18
+ // marketplace_version: tracks installed version for update checking
19
+ await sql`
20
+ ALTER TABLE _plugin_state
21
+ ADD COLUMN marketplace_version TEXT
22
+ `.execute(db);
23
+
24
+ // Index for efficient marketplace plugin queries on cold start
25
+ await sql`
26
+ CREATE INDEX idx_plugin_state_source
27
+ ON _plugin_state (source)
28
+ WHERE source = 'marketplace'
29
+ `.execute(db);
30
+ }
31
+
32
+ export async function down(db: Kysely<unknown>): Promise<void> {
33
+ await sql`
34
+ DROP INDEX IF EXISTS idx_plugin_state_source
35
+ `.execute(db);
36
+
37
+ await sql`
38
+ ALTER TABLE _plugin_state
39
+ DROP COLUMN marketplace_version
40
+ `.execute(db);
41
+
42
+ await sql`
43
+ ALTER TABLE _plugin_state
44
+ DROP COLUMN source
45
+ `.execute(db);
46
+ }
@@ -0,0 +1,33 @@
1
+ import type { Kysely } from "kysely";
2
+ import { sql } from "kysely";
3
+
4
+ /**
5
+ * Migration: Add display metadata to _plugin_state
6
+ *
7
+ * Stores display_name and description for marketplace plugins
8
+ * so the admin UI can show meaningful info without re-fetching
9
+ * from the marketplace on every page load.
10
+ */
11
+ export async function up(db: Kysely<unknown>): Promise<void> {
12
+ await sql`
13
+ ALTER TABLE _plugin_state
14
+ ADD COLUMN display_name TEXT
15
+ `.execute(db);
16
+
17
+ await sql`
18
+ ALTER TABLE _plugin_state
19
+ ADD COLUMN description TEXT
20
+ `.execute(db);
21
+ }
22
+
23
+ export async function down(db: Kysely<unknown>): Promise<void> {
24
+ await sql`
25
+ ALTER TABLE _plugin_state
26
+ DROP COLUMN description
27
+ `.execute(db);
28
+
29
+ await sql`
30
+ ALTER TABLE _plugin_state
31
+ DROP COLUMN display_name
32
+ `.execute(db);
33
+ }
@@ -0,0 +1,32 @@
1
+ import type { Kysely } from "kysely";
2
+ import { sql } from "kysely";
3
+
4
+ /**
5
+ * Migration: Add placeholder columns to media table
6
+ *
7
+ * Stores blurhash and dominant_color for LQIP (Low Quality Image Placeholder)
8
+ * support. Generated at upload time from image pixel data.
9
+ */
10
+ export async function up(db: Kysely<unknown>): Promise<void> {
11
+ await sql`
12
+ ALTER TABLE media
13
+ ADD COLUMN blurhash TEXT
14
+ `.execute(db);
15
+
16
+ await sql`
17
+ ALTER TABLE media
18
+ ADD COLUMN dominant_color TEXT
19
+ `.execute(db);
20
+ }
21
+
22
+ export async function down(db: Kysely<unknown>): Promise<void> {
23
+ await sql`
24
+ ALTER TABLE media
25
+ DROP COLUMN dominant_color
26
+ `.execute(db);
27
+
28
+ await sql`
29
+ ALTER TABLE media
30
+ DROP COLUMN blurhash
31
+ `.execute(db);
32
+ }
@@ -0,0 +1,28 @@
1
+ import type { Kysely } from "kysely";
2
+
3
+ import { currentTimestamp } from "../dialect-helpers.js";
4
+
5
+ /**
6
+ * Migration: Create OAuth clients table
7
+ *
8
+ * Implements the oauth_clients registry so that the authorization endpoint
9
+ * can validate client_id and enforce a per-client redirect URI allowlist.
10
+ *
11
+ * Each client has a set of pre-registered redirect URIs (JSON array).
12
+ * The authorize endpoint rejects any redirect_uri not in the client's list.
13
+ */
14
+ export async function up(db: Kysely<unknown>): Promise<void> {
15
+ await db.schema
16
+ .createTable("_emdash_oauth_clients")
17
+ .addColumn("id", "text", (col) => col.primaryKey()) // Client ID (e.g. URL or opaque string)
18
+ .addColumn("name", "text", (col) => col.notNull()) // Human-readable name
19
+ .addColumn("redirect_uris", "text", (col) => col.notNull()) // JSON array of allowed redirect URIs
20
+ .addColumn("scopes", "text") // JSON array of allowed scopes (null = all)
21
+ .addColumn("created_at", "text", (col) => col.defaultTo(currentTimestamp(db)))
22
+ .addColumn("updated_at", "text", (col) => col.defaultTo(currentTimestamp(db)))
23
+ .execute();
24
+ }
25
+
26
+ export async function down(db: Kysely<unknown>): Promise<void> {
27
+ await db.schema.dropTable("_emdash_oauth_clients").execute();
28
+ }
@@ -0,0 +1,49 @@
1
+ import type { Kysely } from "kysely";
2
+
3
+ import { currentTimestamp } from "../dialect-helpers.js";
4
+
5
+ /**
6
+ * Migration: Create cron tasks table for plugin scheduled tasks.
7
+ *
8
+ * Each plugin can register cron tasks (recurring or one-shot) which are
9
+ * stored here and executed by the platform-specific scheduler.
10
+ *
11
+ * The `next_run_at` + `status` + `enabled` index drives the "find overdue
12
+ * tasks" query used by CronExecutor.tick().
13
+ */
14
+ export async function up(db: Kysely<unknown>): Promise<void> {
15
+ await db.schema
16
+ .createTable("_emdash_cron_tasks")
17
+ .addColumn("id", "text", (col) => col.primaryKey())
18
+ .addColumn("plugin_id", "text", (col) => col.notNull())
19
+ .addColumn("task_name", "text", (col) => col.notNull())
20
+ .addColumn("schedule", "text", (col) => col.notNull())
21
+ .addColumn("is_oneshot", "integer", (col) => col.notNull().defaultTo(0))
22
+ .addColumn("data", "text") // JSON
23
+ .addColumn("next_run_at", "text", (col) => col.notNull())
24
+ .addColumn("last_run_at", "text")
25
+ .addColumn("status", "text", (col) => col.notNull().defaultTo("idle"))
26
+ .addColumn("locked_at", "text")
27
+ .addColumn("enabled", "integer", (col) => col.notNull().defaultTo(1))
28
+ .addColumn("created_at", "text", (col) => col.defaultTo(currentTimestamp(db)))
29
+ .addUniqueConstraint("uq_cron_tasks_plugin_task", ["plugin_id", "task_name"])
30
+ .execute();
31
+
32
+ // Equality columns first (enabled, status), then range column (next_run_at)
33
+ // for optimal B-tree index usage in the tick query.
34
+ await db.schema
35
+ .createIndex("idx_cron_tasks_due")
36
+ .on("_emdash_cron_tasks")
37
+ .columns(["enabled", "status", "next_run_at"])
38
+ .execute();
39
+
40
+ await db.schema
41
+ .createIndex("idx_cron_tasks_plugin")
42
+ .on("_emdash_cron_tasks")
43
+ .column("plugin_id")
44
+ .execute();
45
+ }
46
+
47
+ export async function down(db: Kysely<unknown>): Promise<void> {
48
+ await db.schema.dropTable("_emdash_cron_tasks").execute();
49
+ }
@@ -0,0 +1,87 @@
1
+ import type { Kysely } from "kysely";
2
+
3
+ import { currentTimestamp } from "../dialect-helpers.js";
4
+
5
+ export async function up(db: Kysely<unknown>): Promise<void> {
6
+ // Create the comments table
7
+ await db.schema
8
+ .createTable("_emdash_comments")
9
+ .addColumn("id", "text", (col) => col.primaryKey())
10
+ .addColumn("collection", "text", (col) => col.notNull())
11
+ .addColumn("content_id", "text", (col) => col.notNull())
12
+ .addColumn("parent_id", "text", (col) =>
13
+ col.references("_emdash_comments.id").onDelete("cascade"),
14
+ )
15
+ .addColumn("author_name", "text", (col) => col.notNull())
16
+ .addColumn("author_email", "text", (col) => col.notNull())
17
+ .addColumn("author_url", "text")
18
+ .addColumn("author_user_id", "text", (col) => col.references("users.id").onDelete("set null"))
19
+ .addColumn("body", "text", (col) => col.notNull())
20
+ .addColumn("status", "text", (col) => col.notNull().defaultTo("pending"))
21
+ .addColumn("ip_hash", "text")
22
+ .addColumn("user_agent", "text")
23
+ .addColumn("moderation_metadata", "text") // JSON
24
+ .addColumn("created_at", "text", (col) => col.defaultTo(currentTimestamp(db)))
25
+ .addColumn("updated_at", "text", (col) => col.defaultTo(currentTimestamp(db)))
26
+ .execute();
27
+
28
+ // Indexes
29
+ await db.schema
30
+ .createIndex("idx_comments_content")
31
+ .on("_emdash_comments")
32
+ .columns(["collection", "content_id", "status"])
33
+ .execute();
34
+
35
+ await db.schema
36
+ .createIndex("idx_comments_parent")
37
+ .on("_emdash_comments")
38
+ .column("parent_id")
39
+ .execute();
40
+
41
+ await db.schema
42
+ .createIndex("idx_comments_status")
43
+ .on("_emdash_comments")
44
+ .columns(["status", "created_at"])
45
+ .execute();
46
+
47
+ await db.schema
48
+ .createIndex("idx_comments_author_email")
49
+ .on("_emdash_comments")
50
+ .column("author_email")
51
+ .execute();
52
+
53
+ await db.schema
54
+ .createIndex("idx_comments_author_user")
55
+ .on("_emdash_comments")
56
+ .column("author_user_id")
57
+ .execute();
58
+
59
+ // Add collection-level comment settings columns
60
+ await db.schema
61
+ .alterTable("_emdash_collections")
62
+ .addColumn("comments_enabled", "integer", (col) => col.defaultTo(0))
63
+ .execute();
64
+
65
+ await db.schema
66
+ .alterTable("_emdash_collections")
67
+ .addColumn("comments_moderation", "text", (col) => col.defaultTo("first_time"))
68
+ .execute();
69
+
70
+ await db.schema
71
+ .alterTable("_emdash_collections")
72
+ .addColumn("comments_closed_after_days", "integer", (col) => col.defaultTo(90))
73
+ .execute();
74
+
75
+ await db.schema
76
+ .alterTable("_emdash_collections")
77
+ .addColumn("comments_auto_approve_users", "integer", (col) => col.defaultTo(1))
78
+ .execute();
79
+ }
80
+
81
+ export async function down(db: Kysely<unknown>): Promise<void> {
82
+ await db.schema.dropTable("_emdash_comments").execute();
83
+
84
+ // Note: SQLite doesn't support DROP COLUMN before 3.35.0.
85
+ // For down migrations on the collection settings columns, the table
86
+ // would need to be rebuilt. Skipping for simplicity in v0.
87
+ }
@@ -0,0 +1,9 @@
1
+ import { sql, type Kysely } from "kysely";
2
+
3
+ export async function up(db: Kysely<unknown>): Promise<void> {
4
+ await sql`ALTER TABLE _emdash_comments DROP COLUMN author_url`.execute(db);
5
+ }
6
+
7
+ export async function down(db: Kysely<unknown>): Promise<void> {
8
+ await db.schema.alterTable("_emdash_comments").addColumn("author_url", "text").execute();
9
+ }
@@ -0,0 +1,67 @@
1
+ import type { Kysely } from "kysely";
2
+
3
+ import { currentTimestamp } from "../dialect-helpers.js";
4
+
5
+ export async function up(db: Kysely<unknown>): Promise<void> {
6
+ // Redirect rules table
7
+ await db.schema
8
+ .createTable("_emdash_redirects")
9
+ .addColumn("id", "text", (col) => col.primaryKey())
10
+ .addColumn("source", "text", (col) => col.notNull())
11
+ .addColumn("destination", "text", (col) => col.notNull())
12
+ .addColumn("type", "integer", (col) => col.notNull().defaultTo(301))
13
+ .addColumn("is_pattern", "integer", (col) => col.notNull().defaultTo(0))
14
+ .addColumn("enabled", "integer", (col) => col.notNull().defaultTo(1))
15
+ .addColumn("hits", "integer", (col) => col.notNull().defaultTo(0))
16
+ .addColumn("last_hit_at", "text")
17
+ .addColumn("group_name", "text")
18
+ .addColumn("auto", "integer", (col) => col.notNull().defaultTo(0))
19
+ .addColumn("created_at", "text", (col) => col.defaultTo(currentTimestamp(db)))
20
+ .addColumn("updated_at", "text", (col) => col.defaultTo(currentTimestamp(db)))
21
+ .execute();
22
+
23
+ // Unique source for exact (non-pattern) rules
24
+ // SQLite doesn't support partial indexes with WHERE on all versions,
25
+ // so we use a regular index and enforce uniqueness in the application layer
26
+ await db.schema
27
+ .createIndex("idx_redirects_source")
28
+ .on("_emdash_redirects")
29
+ .column("source")
30
+ .execute();
31
+
32
+ await db.schema
33
+ .createIndex("idx_redirects_enabled")
34
+ .on("_emdash_redirects")
35
+ .column("enabled")
36
+ .execute();
37
+
38
+ await db.schema
39
+ .createIndex("idx_redirects_group")
40
+ .on("_emdash_redirects")
41
+ .column("group_name")
42
+ .execute();
43
+
44
+ // 404 log table
45
+ await db.schema
46
+ .createTable("_emdash_404_log")
47
+ .addColumn("id", "text", (col) => col.primaryKey())
48
+ .addColumn("path", "text", (col) => col.notNull())
49
+ .addColumn("referrer", "text")
50
+ .addColumn("user_agent", "text")
51
+ .addColumn("ip", "text")
52
+ .addColumn("created_at", "text", (col) => col.defaultTo(currentTimestamp(db)))
53
+ .execute();
54
+
55
+ await db.schema.createIndex("idx_404_log_path").on("_emdash_404_log").column("path").execute();
56
+
57
+ await db.schema
58
+ .createIndex("idx_404_log_created")
59
+ .on("_emdash_404_log")
60
+ .column("created_at")
61
+ .execute();
62
+ }
63
+
64
+ export async function down(db: Kysely<unknown>): Promise<void> {
65
+ await db.schema.dropTable("_emdash_404_log").execute();
66
+ await db.schema.dropTable("_emdash_redirects").execute();
67
+ }
@@ -0,0 +1,48 @@
1
+ import type { Kysely } from "kysely";
2
+ import { sql } from "kysely";
3
+
4
+ import { listTablesLike } from "../dialect-helpers.js";
5
+
6
+ /**
7
+ * Migration: Widen scheduled publishing index
8
+ *
9
+ * The original partial index (013) only covered status='scheduled'.
10
+ * Published posts can now have scheduled draft changes, so widen the
11
+ * index to cover all rows where scheduled_at IS NOT NULL.
12
+ */
13
+ export async function up(db: Kysely<unknown>): Promise<void> {
14
+ const tableNames = await listTablesLike(db, "ec_%");
15
+
16
+ for (const tableName of tableNames) {
17
+ const table = { name: tableName };
18
+
19
+ await sql`
20
+ DROP INDEX IF EXISTS ${sql.ref(`idx_${table.name}_scheduled`)}
21
+ `.execute(db);
22
+
23
+ await sql`
24
+ CREATE INDEX ${sql.ref(`idx_${table.name}_scheduled`)}
25
+ ON ${sql.ref(table.name)} (scheduled_at)
26
+ WHERE scheduled_at IS NOT NULL
27
+ `.execute(db);
28
+ }
29
+ }
30
+
31
+ export async function down(db: Kysely<unknown>): Promise<void> {
32
+ const tableNames = await listTablesLike(db, "ec_%");
33
+
34
+ for (const tableName of tableNames) {
35
+ const table = { name: tableName };
36
+
37
+ await sql`
38
+ DROP INDEX IF EXISTS ${sql.ref(`idx_${table.name}_scheduled`)}
39
+ `.execute(db);
40
+
41
+ // Restore the original narrower index
42
+ await sql`
43
+ CREATE INDEX ${sql.ref(`idx_${table.name}_scheduled`)}
44
+ ON ${sql.ref(table.name)} (scheduled_at)
45
+ WHERE scheduled_at IS NOT NULL AND status = 'scheduled'
46
+ `.execute(db);
47
+ }
48
+ }
@@ -0,0 +1,90 @@
1
+ import type { Kysely } from "kysely";
2
+ import { sql } from "kysely";
3
+
4
+ import { currentTimestamp, listTablesLike } from "../dialect-helpers.js";
5
+
6
+ export async function up(db: Kysely<unknown>): Promise<void> {
7
+ await db.schema
8
+ .createTable("_emdash_bylines")
9
+ .addColumn("id", "text", (col) => col.primaryKey())
10
+ .addColumn("slug", "text", (col) => col.notNull().unique())
11
+ .addColumn("display_name", "text", (col) => col.notNull())
12
+ .addColumn("bio", "text")
13
+ .addColumn("avatar_media_id", "text", (col) => col.references("media.id").onDelete("set null"))
14
+ .addColumn("website_url", "text")
15
+ .addColumn("user_id", "text", (col) => col.references("users.id").onDelete("set null"))
16
+ .addColumn("is_guest", "integer", (col) => col.notNull().defaultTo(0))
17
+ .addColumn("created_at", "text", (col) => col.defaultTo(currentTimestamp(db)))
18
+ .addColumn("updated_at", "text", (col) => col.defaultTo(currentTimestamp(db)))
19
+ .execute();
20
+
21
+ await sql`
22
+ CREATE UNIQUE INDEX ${sql.ref("idx_bylines_user_id_unique")}
23
+ ON ${sql.ref("_emdash_bylines")} (user_id)
24
+ WHERE user_id IS NOT NULL
25
+ `.execute(db);
26
+
27
+ await db.schema.createIndex("idx_bylines_slug").on("_emdash_bylines").column("slug").execute();
28
+
29
+ await db.schema
30
+ .createIndex("idx_bylines_display_name")
31
+ .on("_emdash_bylines")
32
+ .column("display_name")
33
+ .execute();
34
+
35
+ await db.schema
36
+ .createTable("_emdash_content_bylines")
37
+ .addColumn("id", "text", (col) => col.primaryKey())
38
+ .addColumn("collection_slug", "text", (col) => col.notNull())
39
+ .addColumn("content_id", "text", (col) => col.notNull())
40
+ .addColumn("byline_id", "text", (col) =>
41
+ col.notNull().references("_emdash_bylines.id").onDelete("cascade"),
42
+ )
43
+ .addColumn("sort_order", "integer", (col) => col.notNull().defaultTo(0))
44
+ .addColumn("role_label", "text")
45
+ .addColumn("created_at", "text", (col) => col.defaultTo(currentTimestamp(db)))
46
+ .addUniqueConstraint("content_bylines_unique", ["collection_slug", "content_id", "byline_id"])
47
+ .execute();
48
+
49
+ await db.schema
50
+ .createIndex("idx_content_bylines_content")
51
+ .on("_emdash_content_bylines")
52
+ .columns(["collection_slug", "content_id", "sort_order"])
53
+ .execute();
54
+
55
+ await db.schema
56
+ .createIndex("idx_content_bylines_byline")
57
+ .on("_emdash_content_bylines")
58
+ .column("byline_id")
59
+ .execute();
60
+
61
+ const tableNames = await listTablesLike(db, "ec_%");
62
+ for (const tableName of tableNames) {
63
+ await sql`
64
+ ALTER TABLE ${sql.ref(tableName)}
65
+ ADD COLUMN primary_byline_id TEXT
66
+ `.execute(db);
67
+
68
+ await sql`
69
+ CREATE INDEX ${sql.ref(`idx_${tableName}_primary_byline`)}
70
+ ON ${sql.ref(tableName)} (primary_byline_id)
71
+ `.execute(db);
72
+ }
73
+ }
74
+
75
+ export async function down(db: Kysely<unknown>): Promise<void> {
76
+ const tableNames = await listTablesLike(db, "ec_%");
77
+ for (const tableName of tableNames) {
78
+ await sql`
79
+ DROP INDEX IF EXISTS ${sql.ref(`idx_${tableName}_primary_byline`)}
80
+ `.execute(db);
81
+
82
+ await sql`
83
+ ALTER TABLE ${sql.ref(tableName)}
84
+ DROP COLUMN primary_byline_id
85
+ `.execute(db);
86
+ }
87
+
88
+ await db.schema.dropTable("_emdash_content_bylines").execute();
89
+ await db.schema.dropTable("_emdash_bylines").execute();
90
+ }
@@ -0,0 +1,39 @@
1
+ import type { Kysely } from "kysely";
2
+
3
+ /**
4
+ * Migration: Rate limits table + device code polling tracking.
5
+ *
6
+ * 1. Create _emdash_rate_limits for database-backed rate limiting
7
+ * of unauthenticated endpoints (device code, magic link, passkey).
8
+ *
9
+ * 2. Add last_polled_at column to _emdash_device_codes for
10
+ * RFC 8628 slow_down enforcement.
11
+ */
12
+ export async function up(db: Kysely<unknown>): Promise<void> {
13
+ // ── Rate limits table ────────────────────────────────────────────
14
+ await db.schema
15
+ .createTable("_emdash_rate_limits")
16
+ .addColumn("key", "text", (col) => col.notNull())
17
+ .addColumn("window", "text", (col) => col.notNull())
18
+ .addColumn("count", "integer", (col) => col.notNull().defaultTo(1))
19
+ .addPrimaryKeyConstraint("pk_rate_limits", ["key", "window"])
20
+ .execute();
21
+
22
+ // Index on window for efficient cleanup of expired entries
23
+ await db.schema
24
+ .createIndex("idx_rate_limits_window")
25
+ .on("_emdash_rate_limits")
26
+ .column("window")
27
+ .execute();
28
+
29
+ // ── Device code polling tracking ─────────────────────────────────
30
+ await db.schema.alterTable("_emdash_device_codes").addColumn("last_polled_at", "text").execute();
31
+ }
32
+
33
+ export async function down(db: Kysely<unknown>): Promise<void> {
34
+ await db.schema.dropTable("_emdash_rate_limits").execute();
35
+
36
+ // SQLite doesn't support DROP COLUMN before 3.35.0, but since this is
37
+ // dev-only (v0, no migrations in production), we accept the limitation.
38
+ await db.schema.alterTable("_emdash_device_codes").dropColumn("last_polled_at").execute();
39
+ }