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,204 @@
1
+ /**
2
+ * Storage Layer Types
3
+ *
4
+ * Defines the interface for S3-compatible storage backends.
5
+ * Works with R2, AWS S3, Minio, and other S3-compatible services.
6
+ */
7
+
8
+ /**
9
+ * Storage configuration for S3-compatible backends
10
+ */
11
+ export interface S3StorageConfig {
12
+ /** S3 endpoint URL (e.g., "https://xxx.r2.cloudflarestorage.com") */
13
+ endpoint: string;
14
+ /** Bucket name */
15
+ bucket: string;
16
+ /** AWS access key ID */
17
+ accessKeyId: string;
18
+ /** AWS secret access key */
19
+ secretAccessKey: string;
20
+ /** Optional region (defaults to "auto" for R2) */
21
+ region?: string;
22
+ /** Optional public URL prefix for generated URLs (e.g., CDN URL) */
23
+ publicUrl?: string;
24
+ }
25
+
26
+ /**
27
+ * Local filesystem storage for development
28
+ */
29
+ export interface LocalStorageConfig {
30
+ /** Directory path for storing files */
31
+ directory: string;
32
+ /** Base URL for serving files */
33
+ baseUrl: string;
34
+ }
35
+
36
+ /**
37
+ * Storage adapter descriptor (serializable config)
38
+ */
39
+ export interface StorageDescriptor {
40
+ /** Module path exporting createStorage function */
41
+ entrypoint: string;
42
+ /** Serializable config passed to createStorage at runtime */
43
+ config: Record<string, unknown>;
44
+ }
45
+
46
+ /**
47
+ * Factory function signature for storage adapters
48
+ *
49
+ * Each adapter accesses its own bindings directly:
50
+ * - R2: imports from cloudflare:workers
51
+ * - S3: uses credentials from config
52
+ * - Local: uses filesystem path from config
53
+ */
54
+ export type CreateStorageFn = (config: Record<string, unknown>) => Storage;
55
+
56
+ /**
57
+ * Upload result
58
+ */
59
+ export interface UploadResult {
60
+ /** Storage key (path within bucket) */
61
+ key: string;
62
+ /** Public URL to access the file */
63
+ url: string;
64
+ /** File size in bytes */
65
+ size: number;
66
+ }
67
+
68
+ /**
69
+ * Download result
70
+ */
71
+ export interface DownloadResult {
72
+ /** File content as readable stream */
73
+ body: ReadableStream<Uint8Array>;
74
+ /** MIME type */
75
+ contentType: string;
76
+ /** File size in bytes */
77
+ size: number;
78
+ }
79
+
80
+ /**
81
+ * Signed URL for direct upload
82
+ */
83
+ export interface SignedUploadUrl {
84
+ /** Signed URL for PUT request */
85
+ url: string;
86
+ /** HTTP method (always PUT) */
87
+ method: "PUT";
88
+ /** Headers to include in the upload request */
89
+ headers: Record<string, string>;
90
+ /** URL expiration time (ISO string) */
91
+ expiresAt: string;
92
+ }
93
+
94
+ /**
95
+ * Options for generating signed upload URL
96
+ */
97
+ export interface SignedUploadOptions {
98
+ /** Storage key (path within bucket) */
99
+ key: string;
100
+ /** MIME type of the file */
101
+ contentType: string;
102
+ /** File size in bytes (for content-length validation) */
103
+ size?: number;
104
+ /** URL expiration in seconds (default: 3600) */
105
+ expiresIn?: number;
106
+ }
107
+
108
+ /**
109
+ * File listing result
110
+ */
111
+ export interface ListResult {
112
+ /** List of files */
113
+ files: FileInfo[];
114
+ /** Cursor for next page (if more results) */
115
+ nextCursor?: string;
116
+ }
117
+
118
+ /**
119
+ * File info from listing
120
+ */
121
+ export interface FileInfo {
122
+ /** Storage key */
123
+ key: string;
124
+ /** File size in bytes */
125
+ size: number;
126
+ /** Last modified date */
127
+ lastModified: Date;
128
+ /** ETag (content hash) */
129
+ etag?: string;
130
+ }
131
+
132
+ /**
133
+ * Options for listing files
134
+ */
135
+ export interface ListOptions {
136
+ /** Filter by key prefix */
137
+ prefix?: string;
138
+ /** Maximum results per page */
139
+ limit?: number;
140
+ /** Cursor from previous list call */
141
+ cursor?: string;
142
+ }
143
+
144
+ /**
145
+ * Storage interface
146
+ *
147
+ * All storage backends must implement this interface.
148
+ */
149
+ export interface Storage {
150
+ /**
151
+ * Upload a file to storage
152
+ */
153
+ upload(options: {
154
+ key: string;
155
+ body: Buffer | Uint8Array | ReadableStream<Uint8Array>;
156
+ contentType: string;
157
+ }): Promise<UploadResult>;
158
+
159
+ /**
160
+ * Download a file from storage
161
+ */
162
+ download(key: string): Promise<DownloadResult>;
163
+
164
+ /**
165
+ * Delete a file from storage
166
+ * Idempotent - does not throw if file doesn't exist
167
+ */
168
+ delete(key: string): Promise<void>;
169
+
170
+ /**
171
+ * Check if a file exists
172
+ */
173
+ exists(key: string): Promise<boolean>;
174
+
175
+ /**
176
+ * List files in storage
177
+ */
178
+ list(options?: ListOptions): Promise<ListResult>;
179
+
180
+ /**
181
+ * Generate a signed URL for direct upload
182
+ * Client uploads directly to storage, bypassing the server
183
+ */
184
+ getSignedUploadUrl(options: SignedUploadOptions): Promise<SignedUploadUrl>;
185
+
186
+ /**
187
+ * Get public URL for a file
188
+ */
189
+ getPublicUrl(key: string): string;
190
+ }
191
+
192
+ /**
193
+ * Storage error with additional context
194
+ */
195
+ export class EmDashStorageError extends Error {
196
+ constructor(
197
+ message: string,
198
+ public code: string,
199
+ public override cause?: unknown,
200
+ ) {
201
+ super(message);
202
+ this.name = "EmDashStorageError";
203
+ }
204
+ }
@@ -0,0 +1,309 @@
1
+ /**
2
+ * Runtime API for taxonomies
3
+ *
4
+ * Provides functions to query taxonomy definitions and terms.
5
+ */
6
+
7
+ import { getDb } from "../loader.js";
8
+ import type { TaxonomyDef, TaxonomyTerm, TaxonomyTermRow } from "./types.js";
9
+
10
+ /**
11
+ * Get all taxonomy definitions
12
+ */
13
+ export async function getTaxonomyDefs(): Promise<TaxonomyDef[]> {
14
+ const db = await getDb();
15
+
16
+ const rows = await db.selectFrom("_emdash_taxonomy_defs").selectAll().execute();
17
+
18
+ return rows.map((row) => ({
19
+ id: row.id,
20
+ name: row.name,
21
+ label: row.label,
22
+ labelSingular: row.label_singular ?? undefined,
23
+ hierarchical: row.hierarchical === 1,
24
+ collections: row.collections ? JSON.parse(row.collections) : [],
25
+ }));
26
+ }
27
+
28
+ /**
29
+ * Get a single taxonomy definition by name
30
+ */
31
+ export async function getTaxonomyDef(name: string): Promise<TaxonomyDef | null> {
32
+ const db = await getDb();
33
+
34
+ const row = await db
35
+ .selectFrom("_emdash_taxonomy_defs")
36
+ .selectAll()
37
+ .where("name", "=", name)
38
+ .executeTakeFirst();
39
+
40
+ if (!row) return null;
41
+
42
+ return {
43
+ id: row.id,
44
+ name: row.name,
45
+ label: row.label,
46
+ labelSingular: row.label_singular ?? undefined,
47
+ hierarchical: row.hierarchical === 1,
48
+ collections: row.collections ? JSON.parse(row.collections) : [],
49
+ };
50
+ }
51
+
52
+ /**
53
+ * Get all terms for a taxonomy (as tree for hierarchical, flat for tags)
54
+ */
55
+ export async function getTaxonomyTerms(taxonomyName: string): Promise<TaxonomyTerm[]> {
56
+ const db = await getDb();
57
+
58
+ // Get taxonomy definition to check if hierarchical
59
+ const def = await getTaxonomyDef(taxonomyName);
60
+ if (!def) return [];
61
+
62
+ // Get all terms for this taxonomy
63
+ const rows = await db
64
+ .selectFrom("taxonomies")
65
+ .selectAll()
66
+ .where("name", "=", taxonomyName)
67
+ .orderBy("label", "asc")
68
+ .execute();
69
+
70
+ // Count entries for each term
71
+ const countsResult = await db
72
+ .selectFrom("content_taxonomies")
73
+ .select(["taxonomy_id"])
74
+ .select((eb) => eb.fn.count<number>("entry_id").as("count"))
75
+ .groupBy("taxonomy_id")
76
+ .execute();
77
+
78
+ const counts = new Map<string, number>();
79
+ for (const row of countsResult) {
80
+ counts.set(row.taxonomy_id, row.count);
81
+ }
82
+
83
+ const flatTerms: TaxonomyTermRow[] = rows.map((row) => ({
84
+ id: row.id,
85
+ name: row.name,
86
+ slug: row.slug,
87
+ label: row.label,
88
+ parent_id: row.parent_id,
89
+ data: row.data,
90
+ }));
91
+
92
+ // If hierarchical, build tree. Otherwise return flat
93
+ if (def.hierarchical) {
94
+ return buildTree(flatTerms, counts);
95
+ }
96
+
97
+ return flatTerms.map((term) => ({
98
+ id: term.id,
99
+ name: term.name,
100
+ slug: term.slug,
101
+ label: term.label,
102
+ children: [],
103
+ count: counts.get(term.id) ?? 0,
104
+ }));
105
+ }
106
+
107
+ /**
108
+ * Get a single term by taxonomy and slug
109
+ */
110
+ export async function getTerm(taxonomyName: string, slug: string): Promise<TaxonomyTerm | null> {
111
+ const db = await getDb();
112
+
113
+ const row = await db
114
+ .selectFrom("taxonomies")
115
+ .selectAll()
116
+ .where("name", "=", taxonomyName)
117
+ .where("slug", "=", slug)
118
+ .executeTakeFirst();
119
+
120
+ if (!row) return null;
121
+
122
+ // Get entry count
123
+ const countResult = await db
124
+ .selectFrom("content_taxonomies")
125
+ .select((eb) => eb.fn.count<number>("entry_id").as("count"))
126
+ .where("taxonomy_id", "=", row.id)
127
+ .executeTakeFirst();
128
+
129
+ const count = countResult?.count ?? 0;
130
+
131
+ // Get children if hierarchical
132
+ const childRows = await db
133
+ .selectFrom("taxonomies")
134
+ .selectAll()
135
+ .where("parent_id", "=", row.id)
136
+ .orderBy("label", "asc")
137
+ .execute();
138
+
139
+ const children = childRows.map((child) => ({
140
+ id: child.id,
141
+ name: child.name,
142
+ slug: child.slug,
143
+ label: child.label,
144
+ parentId: child.parent_id ?? undefined,
145
+ children: [],
146
+ }));
147
+
148
+ return {
149
+ id: row.id,
150
+ name: row.name,
151
+ slug: row.slug,
152
+ label: row.label,
153
+ parentId: row.parent_id ?? undefined,
154
+ description: row.data ? JSON.parse(row.data).description : undefined,
155
+ children,
156
+ count,
157
+ };
158
+ }
159
+
160
+ /**
161
+ * Get terms assigned to an entry
162
+ */
163
+ export async function getEntryTerms(
164
+ collection: string,
165
+ entryId: string,
166
+ taxonomyName?: string,
167
+ ): Promise<TaxonomyTerm[]> {
168
+ const db = await getDb();
169
+
170
+ let query = db
171
+ .selectFrom("content_taxonomies")
172
+ .innerJoin("taxonomies", "taxonomies.id", "content_taxonomies.taxonomy_id")
173
+ .selectAll("taxonomies")
174
+ .where("content_taxonomies.collection", "=", collection)
175
+ .where("content_taxonomies.entry_id", "=", entryId);
176
+
177
+ if (taxonomyName) {
178
+ query = query.where("taxonomies.name", "=", taxonomyName);
179
+ }
180
+
181
+ const rows = await query.execute();
182
+
183
+ return rows.map((row) => ({
184
+ id: row.id,
185
+ name: row.name,
186
+ slug: row.slug,
187
+ label: row.label,
188
+ parentId: row.parent_id ?? undefined,
189
+ children: [],
190
+ }));
191
+ }
192
+
193
+ /**
194
+ * Get terms for multiple entries in a single query (batched API)
195
+ *
196
+ * This is more efficient than calling getEntryTerms for each entry
197
+ * when you need terms for a list of entries.
198
+ *
199
+ * @param collection - The collection type (e.g., "posts")
200
+ * @param entryIds - Array of entry IDs
201
+ * @param taxonomyName - The taxonomy name (e.g., "categories")
202
+ * @returns Map from entry ID to array of terms
203
+ */
204
+ export async function getTermsForEntries(
205
+ collection: string,
206
+ entryIds: string[],
207
+ taxonomyName: string,
208
+ ): Promise<Map<string, TaxonomyTerm[]>> {
209
+ const result = new Map<string, TaxonomyTerm[]>();
210
+
211
+ // Initialize all entry IDs with empty arrays
212
+ for (const id of entryIds) {
213
+ result.set(id, []);
214
+ }
215
+
216
+ if (entryIds.length === 0) {
217
+ return result;
218
+ }
219
+
220
+ const db = await getDb();
221
+
222
+ const rows = await db
223
+ .selectFrom("content_taxonomies")
224
+ .innerJoin("taxonomies", "taxonomies.id", "content_taxonomies.taxonomy_id")
225
+ .select([
226
+ "content_taxonomies.entry_id",
227
+ "taxonomies.id",
228
+ "taxonomies.name",
229
+ "taxonomies.slug",
230
+ "taxonomies.label",
231
+ "taxonomies.parent_id",
232
+ ])
233
+ .where("content_taxonomies.collection", "=", collection)
234
+ .where("content_taxonomies.entry_id", "in", entryIds)
235
+ .where("taxonomies.name", "=", taxonomyName)
236
+ .execute();
237
+
238
+ for (const row of rows) {
239
+ const entryId = row.entry_id;
240
+ const term: TaxonomyTerm = {
241
+ id: row.id,
242
+ name: row.name,
243
+ slug: row.slug,
244
+ label: row.label,
245
+ parentId: row.parent_id ?? undefined,
246
+ children: [],
247
+ };
248
+
249
+ const terms = result.get(entryId);
250
+ if (terms) {
251
+ terms.push(term);
252
+ }
253
+ }
254
+
255
+ return result;
256
+ }
257
+
258
+ /**
259
+ * Get entries by term (wraps getEmDashCollection)
260
+ */
261
+ export async function getEntriesByTerm(
262
+ collection: string,
263
+ taxonomyName: string,
264
+ termSlug: string,
265
+ ): Promise<Array<{ id: string; data: Record<string, unknown> }>> {
266
+ const { getEmDashCollection } = await import("../query.js");
267
+
268
+ // Build options as the expected type — getEmDashCollection accepts
269
+ // a generic options object with `where` for filtering by taxonomy
270
+ const options: Record<string, unknown> = {
271
+ where: { [taxonomyName]: termSlug },
272
+ };
273
+ const { entries } = await getEmDashCollection(collection, options);
274
+
275
+ return entries;
276
+ }
277
+
278
+ /**
279
+ * Build tree structure from flat terms
280
+ */
281
+ function buildTree(flatTerms: TaxonomyTermRow[], counts: Map<string, number>): TaxonomyTerm[] {
282
+ const map = new Map<string, TaxonomyTerm>();
283
+ const roots: TaxonomyTerm[] = [];
284
+
285
+ // First pass: create nodes
286
+ for (const term of flatTerms) {
287
+ map.set(term.id, {
288
+ id: term.id,
289
+ name: term.name,
290
+ slug: term.slug,
291
+ label: term.label,
292
+ parentId: term.parent_id ?? undefined,
293
+ description: term.data ? JSON.parse(term.data).description : undefined,
294
+ children: [],
295
+ count: counts.get(term.id) ?? 0,
296
+ });
297
+ }
298
+
299
+ // Second pass: build tree
300
+ for (const term of map.values()) {
301
+ if (term.parentId && map.has(term.parentId)) {
302
+ map.get(term.parentId)!.children.push(term);
303
+ } else {
304
+ roots.push(term);
305
+ }
306
+ }
307
+
308
+ return roots;
309
+ }
@@ -0,0 +1,61 @@
1
+ /**
2
+ * Taxonomy types for EmDash CMS
3
+ */
4
+
5
+ /**
6
+ * Taxonomy definition - describes a taxonomy like "category" or "tag"
7
+ */
8
+ export interface TaxonomyDef {
9
+ id: string;
10
+ name: string; // 'category', 'tag', 'genre'
11
+ label: string; // 'Categories', 'Tags'
12
+ labelSingular?: string; // 'Category', 'Tag'
13
+ hierarchical: boolean;
14
+ collections: string[]; // ['posts', 'pages']
15
+ }
16
+
17
+ /**
18
+ * Taxonomy term - a specific term within a taxonomy (e.g., "News" in "category")
19
+ */
20
+ export interface TaxonomyTerm {
21
+ id: string;
22
+ name: string; // Taxonomy name ('category')
23
+ slug: string; // Term slug ('news')
24
+ label: string; // Display label ('News')
25
+ parentId?: string;
26
+ description?: string;
27
+ children: TaxonomyTerm[]; // For tree structure
28
+ count?: number; // Entry count
29
+ }
30
+
31
+ /**
32
+ * Flat version for DB row
33
+ */
34
+ export interface TaxonomyTermRow {
35
+ id: string;
36
+ name: string;
37
+ slug: string;
38
+ label: string;
39
+ parent_id: string | null;
40
+ data: string | null; // JSON
41
+ }
42
+
43
+ /**
44
+ * Input for creating a term
45
+ */
46
+ export interface CreateTermInput {
47
+ slug: string;
48
+ label: string;
49
+ parentId?: string;
50
+ description?: string;
51
+ }
52
+
53
+ /**
54
+ * Input for updating a term
55
+ */
56
+ export interface UpdateTermInput {
57
+ slug?: string;
58
+ label?: string;
59
+ parentId?: string | null;
60
+ description?: string;
61
+ }
package/src/ui.ts ADDED
@@ -0,0 +1,75 @@
1
+ /**
2
+ * EmDash UI Components
3
+ *
4
+ * Image component for rendering optimized images:
5
+ *
6
+ * ```astro
7
+ * ---
8
+ * import { Image } from "emdash/ui";
9
+ * ---
10
+ * <Image image={post.data.featured_image} />
11
+ * ```
12
+ *
13
+ * Portable Text component for rich content:
14
+ *
15
+ * ```astro
16
+ * ---
17
+ * import { PortableText } from "emdash/ui";
18
+ * ---
19
+ * <PortableText value={post.data.content} />
20
+ * ```
21
+ *
22
+ * Override specific Portable Text components:
23
+ *
24
+ * ```astro
25
+ * <PortableText value={content} components={{ type: { image: MyImage } }} />
26
+ * ```
27
+ */
28
+
29
+ // Re-export types and utilities from astro-portabletext
30
+ export {
31
+ type PortableTextProps,
32
+ type TypedObject,
33
+ type SomePortableTextComponents,
34
+ type Block,
35
+ type ArbitraryTypedObject,
36
+ type PortableTextBlock,
37
+ type PortableTextMarkDefinition,
38
+ type PortableTextSpan,
39
+ type PortableTextListItemBlock,
40
+ usePortableText,
41
+ mergeComponents,
42
+ } from "astro-portabletext";
43
+
44
+ // EmDash PortableText wrapper and components
45
+ export {
46
+ // Main Image component for EmDash media
47
+ EmDashImage as Image,
48
+ // Main component (wrapper with EmDash defaults)
49
+ PortableText,
50
+ // Comment components
51
+ Comments,
52
+ CommentForm,
53
+ // Widget components
54
+ WidgetArea,
55
+ // Components object for manual use
56
+ emdashComponents,
57
+ // Portable Text block types (prefixed to avoid collision with Image)
58
+ Image as PTImage,
59
+ Code,
60
+ Embed,
61
+ Gallery,
62
+ Columns,
63
+ Break,
64
+ HtmlBlock,
65
+ // Marks
66
+ Superscript,
67
+ Subscript,
68
+ Underline,
69
+ StrikeThrough,
70
+ Link,
71
+ // Public page contribution components
72
+ EmDashHead,
73
+ EmDashBodyStart,
74
+ EmDashBodyEnd,
75
+ } from "./components/index.js";
@@ -0,0 +1,73 @@
1
+ /**
2
+ * Base64 encoding/decoding utilities.
3
+ *
4
+ * Uses native Uint8Array.prototype.toBase64 / Uint8Array.fromBase64 when
5
+ * available (workerd, Node 26+, modern browsers), falls back to btoa/atob.
6
+ *
7
+ * All base64url encoding uses the { alphabet: "base64url" } option natively
8
+ * or manual character replacement as fallback.
9
+ *
10
+ * Delete the fallback paths when the minimum Node version supports these
11
+ * methods natively.
12
+ */
13
+
14
+ const hasNative =
15
+ typeof Uint8Array.prototype.toBase64 === "function" &&
16
+ typeof Uint8Array.fromBase64 === "function";
17
+
18
+ // Regex patterns for base64url character replacement
19
+ const BASE64_PLUS_PATTERN = /\+/g;
20
+ const BASE64_SLASH_PATTERN = /\//g;
21
+ const BASE64_PADDING_PATTERN = /=+$/;
22
+ const BASE64URL_DASH_PATTERN = /-/g;
23
+ const BASE64URL_UNDERSCORE_PATTERN = /_/g;
24
+
25
+ // ---------------------------------------------------------------------------
26
+ // Standard base64 (for opaque tokens, cursors, Basic Auth, etc.)
27
+ // ---------------------------------------------------------------------------
28
+
29
+ /** Encode a UTF-8 string as standard base64. */
30
+ export function encodeBase64(str: string): string {
31
+ const bytes = new TextEncoder().encode(str);
32
+ if (hasNative) return bytes.toBase64();
33
+ let binary = "";
34
+ for (const b of bytes) binary += String.fromCharCode(b);
35
+ return btoa(binary);
36
+ }
37
+
38
+ /** Decode a standard base64 string to a UTF-8 string. */
39
+ export function decodeBase64(base64: string): string {
40
+ if (hasNative) return new TextDecoder().decode(Uint8Array.fromBase64(base64));
41
+ const binary = atob(base64);
42
+ const bytes = new Uint8Array(binary.length);
43
+ for (let i = 0; i < binary.length; i++) bytes[i] = binary.charCodeAt(i);
44
+ return new TextDecoder().decode(bytes);
45
+ }
46
+
47
+ // ---------------------------------------------------------------------------
48
+ // Base64url (for tokens, HMAC signatures, PKCE, etc.)
49
+ // ---------------------------------------------------------------------------
50
+
51
+ /** Encode bytes as base64url without padding. */
52
+ export function encodeBase64url(bytes: Uint8Array): string {
53
+ if (hasNative) return bytes.toBase64({ alphabet: "base64url", omitPadding: true });
54
+ let binary = "";
55
+ for (const b of bytes) binary += String.fromCharCode(b);
56
+ return btoa(binary)
57
+ .replace(BASE64_PLUS_PATTERN, "-")
58
+ .replace(BASE64_SLASH_PATTERN, "_")
59
+ .replace(BASE64_PADDING_PATTERN, "");
60
+ }
61
+
62
+ /** Decode a base64url string (with or without padding) to bytes. */
63
+ export function decodeBase64url(encoded: string): Uint8Array {
64
+ if (hasNative) return Uint8Array.fromBase64(encoded, { alphabet: "base64url" });
65
+ const base64 = encoded
66
+ .replace(BASE64URL_DASH_PATTERN, "+")
67
+ .replace(BASE64URL_UNDERSCORE_PATTERN, "/");
68
+ const padded = base64 + "=".repeat((4 - (base64.length % 4)) % 4);
69
+ const binary = atob(padded);
70
+ const bytes = new Uint8Array(binary.length);
71
+ for (let i = 0; i < binary.length; i++) bytes[i] = binary.charCodeAt(i);
72
+ return bytes;
73
+ }