emdash 0.26.0 → 0.27.0

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 (366) hide show
  1. package/dist/{adapters-DAAjOID4.d.mts → adapters-u037EnTR.d.mts} +1 -1
  2. package/dist/{adapters-DAAjOID4.d.mts.map → adapters-u037EnTR.d.mts.map} +1 -1
  3. package/dist/api/route-utils.mjs +10 -10
  4. package/dist/api/schemas/index.d.mts +1 -1
  5. package/dist/{api-BMfveMoB.mjs → api-80kycR9o.mjs} +84 -28
  6. package/dist/api-80kycR9o.mjs.map +1 -0
  7. package/dist/{apply--IVNSdXn.mjs → apply-DSypk6Iu.mjs} +19 -19
  8. package/dist/apply-DSypk6Iu.mjs.map +1 -0
  9. package/dist/astro/index.d.mts +7 -6
  10. package/dist/astro/index.d.mts.map +1 -1
  11. package/dist/astro/index.mjs +11 -3
  12. package/dist/astro/index.mjs.map +1 -1
  13. package/dist/astro/middleware/auth.d.mts +6 -5
  14. package/dist/astro/middleware/auth.d.mts.map +1 -1
  15. package/dist/astro/middleware/auth.mjs +4 -3
  16. package/dist/astro/middleware/auth.mjs.map +1 -1
  17. package/dist/astro/middleware/redirect.mjs +4 -4
  18. package/dist/astro/middleware.d.mts +1 -8
  19. package/dist/astro/middleware.d.mts.map +1 -1
  20. package/dist/astro/middleware.mjs +44 -43
  21. package/dist/astro/middleware.mjs.map +1 -1
  22. package/dist/astro/routes/api/admin/allowed-domains/_domain_.mjs +3 -3
  23. package/dist/astro/routes/api/admin/allowed-domains/index.mjs +3 -3
  24. package/dist/astro/routes/api/admin/api-tokens/_id_.mjs +2 -2
  25. package/dist/astro/routes/api/admin/api-tokens/index.mjs +3 -3
  26. package/dist/astro/routes/api/admin/byline-fields/_slug_/usage.mjs +3 -3
  27. package/dist/astro/routes/api/admin/byline-fields/_slug_.mjs +4 -4
  28. package/dist/astro/routes/api/admin/byline-fields/index.mjs +4 -4
  29. package/dist/astro/routes/api/admin/byline-fields/reorder.mjs +4 -4
  30. package/dist/astro/routes/api/admin/bylines/_id_/index.mjs +9 -9
  31. package/dist/astro/routes/api/admin/bylines/_id_/translations.mjs +9 -9
  32. package/dist/astro/routes/api/admin/bylines/index.mjs +9 -9
  33. package/dist/astro/routes/api/admin/comments/_id_/status.mjs +7 -7
  34. package/dist/astro/routes/api/admin/comments/_id_.mjs +5 -5
  35. package/dist/astro/routes/api/admin/comments/bulk.mjs +6 -6
  36. package/dist/astro/routes/api/admin/comments/counts.mjs +5 -5
  37. package/dist/astro/routes/api/admin/comments/index.mjs +6 -6
  38. package/dist/astro/routes/api/admin/hooks/exclusive/_hookName_.mjs +4 -4
  39. package/dist/astro/routes/api/admin/hooks/exclusive/index.mjs +3 -3
  40. package/dist/astro/routes/api/admin/oauth-clients/_id_.mjs +3 -3
  41. package/dist/astro/routes/api/admin/oauth-clients/index.mjs +3 -3
  42. package/dist/astro/routes/api/admin/plugins/_id_/disable.mjs +27 -27
  43. package/dist/astro/routes/api/admin/plugins/_id_/disable.mjs.map +1 -1
  44. package/dist/astro/routes/api/admin/plugins/_id_/enable.mjs +27 -27
  45. package/dist/astro/routes/api/admin/plugins/_id_/enable.mjs.map +1 -1
  46. package/dist/astro/routes/api/admin/plugins/_id_/index.mjs +27 -27
  47. package/dist/astro/routes/api/admin/plugins/_id_/index.mjs.map +1 -1
  48. package/dist/astro/routes/api/admin/plugins/_id_/uninstall.mjs +26 -26
  49. package/dist/astro/routes/api/admin/plugins/_id_/update.mjs +26 -26
  50. package/dist/astro/routes/api/admin/plugins/index.mjs +27 -27
  51. package/dist/astro/routes/api/admin/plugins/index.mjs.map +1 -1
  52. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/icon.mjs +3 -3
  53. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/index.mjs +26 -26
  54. package/dist/astro/routes/api/admin/plugins/marketplace/_id_/install.mjs +26 -26
  55. package/dist/astro/routes/api/admin/plugins/marketplace/index.mjs +26 -26
  56. package/dist/astro/routes/api/admin/plugins/registry/_id_/uninstall.mjs +26 -26
  57. package/dist/astro/routes/api/admin/plugins/registry/_id_/update.mjs +27 -27
  58. package/dist/astro/routes/api/admin/plugins/registry/artifact.mjs +26 -26
  59. package/dist/astro/routes/api/admin/plugins/registry/install.mjs +27 -27
  60. package/dist/astro/routes/api/admin/plugins/updates.mjs +26 -26
  61. package/dist/astro/routes/api/admin/themes/marketplace/_id_/index.mjs +26 -26
  62. package/dist/astro/routes/api/admin/themes/marketplace/_id_/thumbnail.mjs +3 -3
  63. package/dist/astro/routes/api/admin/themes/marketplace/index.mjs +26 -26
  64. package/dist/astro/routes/api/admin/users/_id_/disable.mjs +2 -2
  65. package/dist/astro/routes/api/admin/users/_id_/enable.mjs +2 -2
  66. package/dist/astro/routes/api/admin/users/_id_/index.mjs +3 -3
  67. package/dist/astro/routes/api/admin/users/_id_/send-recovery.mjs +2 -2
  68. package/dist/astro/routes/api/admin/users/index.mjs +3 -3
  69. package/dist/astro/routes/api/auth/dev-bypass.mjs +3 -3
  70. package/dist/astro/routes/api/auth/invite/accept.mjs +2 -2
  71. package/dist/astro/routes/api/auth/invite/complete.mjs +3 -3
  72. package/dist/astro/routes/api/auth/invite/index.mjs +3 -3
  73. package/dist/astro/routes/api/auth/invite/register-options.mjs +3 -3
  74. package/dist/astro/routes/api/auth/logout.mjs +2 -2
  75. package/dist/astro/routes/api/auth/magic-link/send.mjs +4 -4
  76. package/dist/astro/routes/api/auth/magic-link/verify.mjs +2 -2
  77. package/dist/astro/routes/api/auth/me.mjs +4 -4
  78. package/dist/astro/routes/api/auth/passkey/_id_.mjs +3 -3
  79. package/dist/astro/routes/api/auth/passkey/index.mjs +2 -2
  80. package/dist/astro/routes/api/auth/passkey/options.mjs +4 -4
  81. package/dist/astro/routes/api/auth/passkey/register/options.mjs +3 -3
  82. package/dist/astro/routes/api/auth/passkey/register/verify.mjs +3 -3
  83. package/dist/astro/routes/api/auth/passkey/verify.mjs +3 -3
  84. package/dist/astro/routes/api/auth/signup/complete.mjs +3 -3
  85. package/dist/astro/routes/api/auth/signup/request.mjs +4 -4
  86. package/dist/astro/routes/api/auth/signup/verify.mjs +2 -2
  87. package/dist/astro/routes/api/comments/_collection_/_contentId_/index.mjs +6 -6
  88. package/dist/astro/routes/api/comments/_collection_/_contentId_/reactions.mjs +6 -6
  89. package/dist/astro/routes/api/content/_collection_/_id_/compare.mjs +3 -3
  90. package/dist/astro/routes/api/content/_collection_/_id_/discard-draft.mjs +3 -3
  91. package/dist/astro/routes/api/content/_collection_/_id_/duplicate.mjs +3 -3
  92. package/dist/astro/routes/api/content/_collection_/_id_/permanent.mjs +3 -3
  93. package/dist/astro/routes/api/content/_collection_/_id_/preview-url.mjs +4 -4
  94. package/dist/astro/routes/api/content/_collection_/_id_/publish.mjs +4 -4
  95. package/dist/astro/routes/api/content/_collection_/_id_/restore.mjs +3 -3
  96. package/dist/astro/routes/api/content/_collection_/_id_/revisions.mjs +3 -3
  97. package/dist/astro/routes/api/content/_collection_/_id_/schedule.mjs +4 -4
  98. package/dist/astro/routes/api/content/_collection_/_id_/terms/_taxonomy_.mjs +8 -8
  99. package/dist/astro/routes/api/content/_collection_/_id_/translations.mjs +3 -3
  100. package/dist/astro/routes/api/content/_collection_/_id_/unpublish.mjs +3 -3
  101. package/dist/astro/routes/api/content/_collection_/_id_.mjs +4 -4
  102. package/dist/astro/routes/api/content/_collection_/authors.mjs +3 -3
  103. package/dist/astro/routes/api/content/_collection_/index.mjs +4 -4
  104. package/dist/astro/routes/api/content/_collection_/trash.mjs +4 -4
  105. package/dist/astro/routes/api/dashboard.mjs +7 -7
  106. package/dist/astro/routes/api/dev/emails.mjs +2 -2
  107. package/dist/astro/routes/api/import/probe.d.mts +2 -2
  108. package/dist/astro/routes/api/import/probe.mjs +4 -4
  109. package/dist/astro/routes/api/import/wordpress/analyze.mjs +3 -3
  110. package/dist/astro/routes/api/import/wordpress/execute.d.mts +6 -5
  111. package/dist/astro/routes/api/import/wordpress/execute.d.mts.map +1 -1
  112. package/dist/astro/routes/api/import/wordpress/execute.mjs +8 -8
  113. package/dist/astro/routes/api/import/wordpress/media.d.mts +6 -5
  114. package/dist/astro/routes/api/import/wordpress/media.d.mts.map +1 -1
  115. package/dist/astro/routes/api/import/wordpress/media.mjs +4 -4
  116. package/dist/astro/routes/api/import/wordpress/prepare.mjs +6 -6
  117. package/dist/astro/routes/api/import/wordpress/rewrite-urls.mjs +5 -5
  118. package/dist/astro/routes/api/import/wordpress-plugin/analyze.d.mts +1 -1
  119. package/dist/astro/routes/api/import/wordpress-plugin/analyze.mjs +4 -4
  120. package/dist/astro/routes/api/import/wordpress-plugin/execute.d.mts +1 -1
  121. package/dist/astro/routes/api/import/wordpress-plugin/execute.mjs +6 -6
  122. package/dist/astro/routes/api/manifest.d.mts.map +1 -1
  123. package/dist/astro/routes/api/manifest.mjs +13 -4
  124. package/dist/astro/routes/api/manifest.mjs.map +1 -1
  125. package/dist/astro/routes/api/mcp.mjs +34 -34
  126. package/dist/astro/routes/api/media/_id_/confirm.mjs +4 -4
  127. package/dist/astro/routes/api/media/_id_.mjs +4 -4
  128. package/dist/astro/routes/api/media/file/_...key_.mjs +2 -2
  129. package/dist/astro/routes/api/media/providers/_providerId_/_itemId_.mjs +3 -3
  130. package/dist/astro/routes/api/media/providers/_providerId_/index.mjs +3 -3
  131. package/dist/astro/routes/api/media/providers/index.mjs +3 -3
  132. package/dist/astro/routes/api/media/upload-url.mjs +4 -4
  133. package/dist/astro/routes/api/media.mjs +5 -5
  134. package/dist/astro/routes/api/menus/_name_/items/_id_.mjs +5 -5
  135. package/dist/astro/routes/api/menus/_name_/items.mjs +5 -5
  136. package/dist/astro/routes/api/menus/_name_/reorder.mjs +5 -5
  137. package/dist/astro/routes/api/menus/_name_/translations.mjs +5 -5
  138. package/dist/astro/routes/api/menus/_name_.mjs +5 -5
  139. package/dist/astro/routes/api/menus/index.mjs +5 -5
  140. package/dist/astro/routes/api/oauth/device/authorize.mjs +3 -3
  141. package/dist/astro/routes/api/oauth/device/code.mjs +4 -4
  142. package/dist/astro/routes/api/oauth/device/token.mjs +4 -4
  143. package/dist/astro/routes/api/oauth/register.mjs +2 -2
  144. package/dist/astro/routes/api/oauth/token/refresh.mjs +3 -3
  145. package/dist/astro/routes/api/oauth/token/revoke.mjs +3 -3
  146. package/dist/astro/routes/api/oauth/token.mjs +2 -2
  147. package/dist/astro/routes/api/openapi.json.mjs +2 -2
  148. package/dist/astro/routes/api/plugins/_pluginId_/_...path_.mjs +3 -3
  149. package/dist/astro/routes/api/redirects/404s/index.mjs +6 -6
  150. package/dist/astro/routes/api/redirects/404s/summary.mjs +6 -6
  151. package/dist/astro/routes/api/redirects/_id_.mjs +7 -7
  152. package/dist/astro/routes/api/redirects/index.mjs +7 -7
  153. package/dist/astro/routes/api/revisions/_revisionId_/index.mjs +3 -3
  154. package/dist/astro/routes/api/revisions/_revisionId_/restore.mjs +3 -3
  155. package/dist/astro/routes/api/schema/collections/_slug_/fields/_fieldSlug_.mjs +26 -26
  156. package/dist/astro/routes/api/schema/collections/_slug_/fields/index.mjs +26 -26
  157. package/dist/astro/routes/api/schema/collections/_slug_/fields/reorder.mjs +26 -26
  158. package/dist/astro/routes/api/schema/collections/_slug_/index.mjs +26 -26
  159. package/dist/astro/routes/api/schema/collections/index.mjs +26 -26
  160. package/dist/astro/routes/api/schema/index.mjs +6 -6
  161. package/dist/astro/routes/api/schema/orphans/_slug_.mjs +26 -26
  162. package/dist/astro/routes/api/schema/orphans/index.mjs +26 -26
  163. package/dist/astro/routes/api/search/enable.mjs +7 -7
  164. package/dist/astro/routes/api/search/index.mjs +6 -6
  165. package/dist/astro/routes/api/search/rebuild.mjs +7 -7
  166. package/dist/astro/routes/api/search/stats.mjs +6 -6
  167. package/dist/astro/routes/api/search/suggest.mjs +6 -6
  168. package/dist/astro/routes/api/sections/_slug_.mjs +6 -6
  169. package/dist/astro/routes/api/sections/index.mjs +6 -6
  170. package/dist/astro/routes/api/settings/email.mjs +4 -4
  171. package/dist/astro/routes/api/settings.mjs +8 -8
  172. package/dist/astro/routes/api/setup/admin-verify.mjs +3 -3
  173. package/dist/astro/routes/api/setup/admin.mjs +3 -3
  174. package/dist/astro/routes/api/setup/dev-bypass.d.mts.map +1 -1
  175. package/dist/astro/routes/api/setup/dev-bypass.mjs +19 -17
  176. package/dist/astro/routes/api/setup/dev-bypass.mjs.map +1 -1
  177. package/dist/astro/routes/api/setup/dev-reset.mjs +2 -2
  178. package/dist/astro/routes/api/setup/index.mjs +17 -17
  179. package/dist/astro/routes/api/setup/status.mjs +3 -3
  180. package/dist/astro/routes/api/snapshot.mjs +3 -3
  181. package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_/translations.mjs +8 -8
  182. package/dist/astro/routes/api/taxonomies/_name_/terms/_slug_.mjs +8 -8
  183. package/dist/astro/routes/api/taxonomies/_name_/terms/index.mjs +8 -8
  184. package/dist/astro/routes/api/taxonomies/index.mjs +8 -8
  185. package/dist/astro/routes/api/themes/preview.mjs +3 -3
  186. package/dist/astro/routes/api/typegen.mjs +5 -5
  187. package/dist/astro/routes/api/widget-areas/_name_/reorder.mjs +4 -4
  188. package/dist/astro/routes/api/widget-areas/_name_/widgets/_id_.mjs +6 -6
  189. package/dist/astro/routes/api/widget-areas/_name_/widgets.mjs +6 -6
  190. package/dist/astro/routes/api/widget-areas/_name_.mjs +5 -5
  191. package/dist/astro/routes/api/widget-areas/index.mjs +6 -6
  192. package/dist/astro/routes/api/widget-components.mjs +2 -2
  193. package/dist/astro/routes/robots.txt.mjs +4 -4
  194. package/dist/astro/routes/sitemap-_collection_.xml.mjs +4 -4
  195. package/dist/astro/routes/sitemap.xml.mjs +4 -4
  196. package/dist/astro/types.d.mts +8 -6
  197. package/dist/astro/types.d.mts.map +1 -1
  198. package/dist/auth/providers/github.d.mts +1 -1
  199. package/dist/auth/providers/google.d.mts +1 -1
  200. package/dist/{authorize-BZnOGJFo.mjs → authorize-C3a_zGsM.mjs} +2 -2
  201. package/dist/{authorize-BZnOGJFo.mjs.map → authorize-C3a_zGsM.mjs.map} +1 -1
  202. package/dist/{byline-LL8lyqdb.mjs → byline-DEKSVPTy.mjs} +5 -5
  203. package/dist/{byline-LL8lyqdb.mjs.map → byline-DEKSVPTy.mjs.map} +1 -1
  204. package/dist/{byline-fields-KD3JFRuH.d.mts → byline-fields-CtQ6blXd.d.mts} +32 -32
  205. package/dist/{byline-fields-KD3JFRuH.d.mts.map → byline-fields-CtQ6blXd.d.mts.map} +1 -1
  206. package/dist/{bylines-DE47vP8d.mjs → bylines-CiqgTHWF.mjs} +5 -5
  207. package/dist/{bylines-DE47vP8d.mjs.map → bylines-CiqgTHWF.mjs.map} +1 -1
  208. package/dist/{bylines-BmJ7Vg7J.mjs → bylines-Ds4-otXl.mjs} +4 -4
  209. package/dist/{bylines-BmJ7Vg7J.mjs.map → bylines-Ds4-otXl.mjs.map} +1 -1
  210. package/dist/{cache-D9jF5bYw.mjs → cache-Ciu3e3AF.mjs} +2 -2
  211. package/dist/{cache-D9jF5bYw.mjs.map → cache-Ciu3e3AF.mjs.map} +1 -1
  212. package/dist/{chunks-OCG163rN.mjs → chunks-CZFiauig.mjs} +2 -2
  213. package/dist/{chunks-OCG163rN.mjs.map → chunks-CZFiauig.mjs.map} +1 -1
  214. package/dist/cli/index.mjs +15 -15
  215. package/dist/cli/index.mjs.map +1 -1
  216. package/dist/client/cf-access.d.mts +1 -1
  217. package/dist/client/index.d.mts +1 -1
  218. package/dist/{comment-D9BLDpZI.mjs → comment-CH1IrFFs.mjs} +2 -2
  219. package/dist/{comment-D9BLDpZI.mjs.map → comment-CH1IrFFs.mjs.map} +1 -1
  220. package/dist/{comment-reaction-Drl9SkNu.mjs → comment-reaction-kruNY-kP.mjs} +2 -2
  221. package/dist/{comment-reaction-Drl9SkNu.mjs.map → comment-reaction-kruNY-kP.mjs.map} +1 -1
  222. package/dist/{comments-BjJ9SKGU.mjs → comments-BUJyXbgq.mjs} +3 -3
  223. package/dist/{comments-BjJ9SKGU.mjs.map → comments-BUJyXbgq.mjs.map} +1 -1
  224. package/dist/{content-ncUWWjna.mjs → content-RmfHoWqK.mjs} +3 -3
  225. package/dist/{content-ncUWWjna.mjs.map → content-RmfHoWqK.mjs.map} +1 -1
  226. package/dist/{context-C_g-iJVA.mjs → context-CzUU_WzL.mjs} +7 -7
  227. package/dist/{context-C_g-iJVA.mjs.map → context-CzUU_WzL.mjs.map} +1 -1
  228. package/dist/{dashboard-CotyqQrW.mjs → dashboard-CVyGhift.mjs} +4 -4
  229. package/dist/{dashboard-CotyqQrW.mjs.map → dashboard-CVyGhift.mjs.map} +1 -1
  230. package/dist/db/index.d.mts +1 -1
  231. package/dist/db/index.mjs +1 -1
  232. package/dist/db/libsql.d.mts +1 -1
  233. package/dist/db/postgres.d.mts +1 -1
  234. package/dist/db/sqlite.d.mts +1 -1
  235. package/dist/{error-rVGiqWDt.mjs → error-BHkLZk-w.mjs} +2 -2
  236. package/dist/{error-rVGiqWDt.mjs.map → error-BHkLZk-w.mjs.map} +1 -1
  237. package/dist/{field-defs-cache-ljXzJCfc.mjs → field-defs-cache-BA-8ZPiT.mjs} +2 -2
  238. package/dist/{field-defs-cache-ljXzJCfc.mjs.map → field-defs-cache-BA-8ZPiT.mjs.map} +1 -1
  239. package/dist/{fts-manager-BbCCbEKA.mjs → fts-manager-Db9jGavf.mjs} +2 -2
  240. package/dist/{fts-manager-BbCCbEKA.mjs.map → fts-manager-Db9jGavf.mjs.map} +1 -1
  241. package/dist/{index-BRNabKrx.d.mts → index-CDZZjrLT.d.mts} +2407 -2365
  242. package/dist/index-CDZZjrLT.d.mts.map +1 -0
  243. package/dist/{index-Dt0OKJB4.d.mts → index-DGIjmUXQ.d.mts} +2 -2
  244. package/dist/{index-Dt0OKJB4.d.mts.map → index-DGIjmUXQ.d.mts.map} +1 -1
  245. package/dist/index.d.mts +11 -10
  246. package/dist/index.mjs +36 -36
  247. package/dist/{load-DMjXghbZ.mjs → load-DpHICVPh.mjs} +2 -2
  248. package/dist/{load-DMjXghbZ.mjs.map → load-DpHICVPh.mjs.map} +1 -1
  249. package/dist/{loader-BA_zhkS_.mjs → loader-4K37qA-y.mjs} +3 -3
  250. package/dist/{loader-BA_zhkS_.mjs.map → loader-4K37qA-y.mjs.map} +1 -1
  251. package/dist/media/local-runtime.d.mts +7 -6
  252. package/dist/media/local-runtime.d.mts.map +1 -1
  253. package/dist/media/local-runtime.mjs +4 -4
  254. package/dist/{media-C5t_eCnk.mjs → media-C0nRRfs1.mjs} +2 -2
  255. package/dist/{media-C5t_eCnk.mjs.map → media-C0nRRfs1.mjs.map} +1 -1
  256. package/dist/{menus-CYH09a41.mjs → menus-DzRyC1ID.mjs} +5 -5
  257. package/dist/{menus-CYH09a41.mjs.map → menus-DzRyC1ID.mjs.map} +1 -1
  258. package/dist/{menus-CBb6UrMU.mjs → menus-SL2K0xq2.mjs} +2 -2
  259. package/dist/{menus-CBb6UrMU.mjs.map → menus-SL2K0xq2.mjs.map} +1 -1
  260. package/dist/object-cache/memory.d.mts +1 -1
  261. package/dist/page/index.d.mts +1 -1
  262. package/dist/{parse-BwAdS7FZ.mjs → parse-CqyZj3Hp.mjs} +2 -2
  263. package/dist/{parse-BwAdS7FZ.mjs.map → parse-CqyZj3Hp.mjs.map} +1 -1
  264. package/dist/plugin-utils.d.mts +6 -5
  265. package/dist/plugin-utils.d.mts.map +1 -1
  266. package/dist/plugins/adapt-sandbox-entry.d.mts +6 -5
  267. package/dist/plugins/adapt-sandbox-entry.d.mts.map +1 -1
  268. package/dist/{query-BpQb-blG.mjs → query-B0M-9LYR.mjs} +13 -13
  269. package/dist/{query-BpQb-blG.mjs.map → query-B0M-9LYR.mjs.map} +1 -1
  270. package/dist/{rate-limit-Dap6HMNM.mjs → rate-limit-BwoUdIpC.mjs} +2 -2
  271. package/dist/{rate-limit-Dap6HMNM.mjs.map → rate-limit-BwoUdIpC.mjs.map} +1 -1
  272. package/dist/{redirect-_M0trWoo.mjs → redirect-lMOzG04S.mjs} +2 -2
  273. package/dist/{redirect-_M0trWoo.mjs.map → redirect-lMOzG04S.mjs.map} +1 -1
  274. package/dist/{redirects-w0V9vj_j.mjs → redirects-9218MmYl.mjs} +3 -3
  275. package/dist/{redirects-w0V9vj_j.mjs.map → redirects-9218MmYl.mjs.map} +1 -1
  276. package/dist/{registry-g8yYt4cC.mjs → registry-DP-iEtdR.mjs} +4 -4
  277. package/dist/{registry-g8yYt4cC.mjs.map → registry-DP-iEtdR.mjs.map} +1 -1
  278. package/dist/runner-BbR3DfrL.d.mts.map +1 -1
  279. package/dist/{runner-DPdt_Wpa.mjs → runner-CFngB4WZ.mjs} +232 -199
  280. package/dist/runner-CFngB4WZ.mjs.map +1 -0
  281. package/dist/runtime.d.mts +6 -5
  282. package/dist/runtime.d.mts.map +1 -1
  283. package/dist/runtime.mjs +2 -2
  284. package/dist/scheduled-publish-BMljtY5G.d.mts +11 -0
  285. package/dist/scheduled-publish-BMljtY5G.d.mts.map +1 -0
  286. package/dist/{schema-DoLd3j2e.mjs → schema-BfJ7bIXH.mjs} +4 -4
  287. package/dist/{schema-DoLd3j2e.mjs.map → schema-BfJ7bIXH.mjs.map} +1 -1
  288. package/dist/{search-BR0ZeZmh.mjs → search-C7t3PH1J.mjs} +6 -4
  289. package/dist/search-C7t3PH1J.mjs.map +1 -0
  290. package/dist/{sections-5J2YJPqJ.mjs → sections-Dm0CVX23.mjs} +3 -3
  291. package/dist/{sections-5J2YJPqJ.mjs.map → sections-Dm0CVX23.mjs.map} +1 -1
  292. package/dist/seed/index.d.mts +1 -1
  293. package/dist/seed/index.mjs +14 -14
  294. package/dist/{seo-DKeXHkzE.mjs → seo-Dd3tbY_k.mjs} +2 -2
  295. package/dist/{seo-DKeXHkzE.mjs.map → seo-Dd3tbY_k.mjs.map} +1 -1
  296. package/dist/{service-BbO2s8gT.mjs → service-CTrqp_Jy.mjs} +2 -2
  297. package/dist/{service-BbO2s8gT.mjs.map → service-CTrqp_Jy.mjs.map} +1 -1
  298. package/dist/{settings-DJeki-97.mjs → settings-BX8cWBus.mjs} +3 -3
  299. package/dist/{settings-DJeki-97.mjs.map → settings-BX8cWBus.mjs.map} +1 -1
  300. package/dist/{settings-BMNr9Dmi.mjs → settings-CZ7ZP9cW.mjs} +3 -3
  301. package/dist/{settings-BMNr9Dmi.mjs.map → settings-CZ7ZP9cW.mjs.map} +1 -1
  302. package/dist/storage/local.d.mts +1 -1
  303. package/dist/storage/s3.d.mts +1 -1
  304. package/dist/{taxonomies-CM_fUqLU.mjs → taxonomies-DChKcVxf.mjs} +4 -4
  305. package/dist/{taxonomies-CM_fUqLU.mjs.map → taxonomies-DChKcVxf.mjs.map} +1 -1
  306. package/dist/{taxonomies-D13i2ctt.mjs → taxonomies-ckPjz-6d.mjs} +5 -5
  307. package/dist/{taxonomies-D13i2ctt.mjs.map → taxonomies-ckPjz-6d.mjs.map} +1 -1
  308. package/dist/{taxonomy-BU0LjdVb.mjs → taxonomy-Cru-he6s.mjs} +3 -3
  309. package/dist/{taxonomy-BU0LjdVb.mjs.map → taxonomy-Cru-he6s.mjs.map} +1 -1
  310. package/dist/{transport-BZ-03aFT.d.mts → transport-Blrl2k_o.d.mts} +1 -1
  311. package/dist/{transport-BZ-03aFT.d.mts.map → transport-Blrl2k_o.d.mts.map} +1 -1
  312. package/dist/{types-BG8_XTLj.d.mts → types-BkZ8DUEI.d.mts} +1 -1
  313. package/dist/{types-BG8_XTLj.d.mts.map → types-BkZ8DUEI.d.mts.map} +1 -1
  314. package/dist/{types-DrYMm9s5.d.mts → types-ByChcBgE.d.mts} +1 -1
  315. package/dist/{types-DrYMm9s5.d.mts.map → types-ByChcBgE.d.mts.map} +1 -1
  316. package/dist/{types-BWqGVhFn.d.mts → types-CvuKO5Pn.d.mts} +1 -1
  317. package/dist/{types-BWqGVhFn.d.mts.map → types-CvuKO5Pn.d.mts.map} +1 -1
  318. package/dist/{types-CZgK3EMW.mjs → types-DU4TSFS5.mjs} +2 -2
  319. package/dist/{types-CZgK3EMW.mjs.map → types-DU4TSFS5.mjs.map} +1 -1
  320. package/dist/{types-CUsXGRVj.d.mts → types-Dbqff978.d.mts} +1 -1
  321. package/dist/{types-CUsXGRVj.d.mts.map → types-Dbqff978.d.mts.map} +1 -1
  322. package/dist/{types-fS7-VTdR.d.mts → types-Y09-wtyU.d.mts} +1 -1
  323. package/dist/{types-fS7-VTdR.d.mts.map → types-Y09-wtyU.d.mts.map} +1 -1
  324. package/dist/{user-DkG2jKCp.mjs → user-DgGbKL9s.mjs} +3 -3
  325. package/dist/{user-DkG2jKCp.mjs.map → user-DgGbKL9s.mjs.map} +1 -1
  326. package/dist/{validate-CG0V0wNR.d.mts → validate-9ECmtEpJ.d.mts} +9 -4
  327. package/dist/{validate-CG0V0wNR.d.mts.map → validate-9ECmtEpJ.d.mts.map} +1 -1
  328. package/dist/{validate-CuJ1Ps9j.mjs → validate-CRkcYZAR.mjs} +2 -2
  329. package/dist/{validate-CuJ1Ps9j.mjs.map → validate-CRkcYZAR.mjs.map} +1 -1
  330. package/dist/{validation-CwUfTdGF.mjs → validation-sR26SOwD.mjs} +5 -5
  331. package/dist/{validation-CwUfTdGF.mjs.map → validation-sR26SOwD.mjs.map} +1 -1
  332. package/dist/version-CrqhKGWn.mjs +7 -0
  333. package/dist/{version-BoNBItP_.mjs.map → version-CrqhKGWn.mjs.map} +1 -1
  334. package/dist/{widgets-BfOZ-ajY.mjs → widgets-DRgtn7Cl.mjs} +2 -2
  335. package/dist/{widgets-BfOZ-ajY.mjs.map → widgets-DRgtn7Cl.mjs.map} +1 -1
  336. package/dist/{zod-generator-gFsRuNNy.mjs → zod-generator-C5JaV--i.mjs} +2 -2
  337. package/dist/{zod-generator-gFsRuNNy.mjs.map → zod-generator-C5JaV--i.mjs.map} +1 -1
  338. package/package.json +8 -8
  339. package/src/api/handlers/content.ts +59 -16
  340. package/src/api/handlers/plugins.ts +77 -10
  341. package/src/astro/integration/vite-config.ts +19 -1
  342. package/src/astro/middleware/auth.ts +1 -0
  343. package/src/astro/middleware.ts +1 -0
  344. package/src/astro/routes/api/admin/plugins/[id]/disable.ts +6 -1
  345. package/src/astro/routes/api/admin/plugins/[id]/enable.ts +6 -1
  346. package/src/astro/routes/api/admin/plugins/[id]/index.ts +1 -0
  347. package/src/astro/routes/api/admin/plugins/index.ts +1 -0
  348. package/src/astro/routes/api/manifest.ts +20 -1
  349. package/src/astro/routes/api/setup/dev-bypass.ts +7 -2
  350. package/src/astro/types.ts +4 -0
  351. package/src/cli/commands/seed.ts +1 -1
  352. package/src/components/LiveSearch.astro +40 -4
  353. package/src/components/live-search-routing.ts +30 -0
  354. package/src/database/migrations/036_i18n_menus_and_taxonomies.ts +23 -18
  355. package/src/database/migrations/048_restore_content_taxonomies_term_index.ts +32 -0
  356. package/src/database/migrations/runner.ts +2 -0
  357. package/src/search/query.ts +3 -0
  358. package/src/search/types.ts +2 -0
  359. package/src/seed/apply.ts +2 -2
  360. package/src/seed/types.ts +6 -1
  361. package/dist/api-BMfveMoB.mjs.map +0 -1
  362. package/dist/apply--IVNSdXn.mjs.map +0 -1
  363. package/dist/index-BRNabKrx.d.mts.map +0 -1
  364. package/dist/runner-DPdt_Wpa.mjs.map +0 -1
  365. package/dist/search-BR0ZeZmh.mjs.map +0 -1
  366. package/dist/version-BoNBItP_.mjs +0 -7
@@ -1 +0,0 @@
1
- {"version":3,"file":"search-BR0ZeZmh.mjs","names":[],"sources":["../src/search/query.ts","../src/search/text-extraction.ts","../src/search/index.ts"],"sourcesContent":["/**\n * Search Query Functions\n *\n * Programmatic API for searching content using FTS5.\n */\n\nimport type { Kysely } from \"kysely\";\nimport { sql } from \"kysely\";\n\nimport type { Database } from \"../database/types.js\";\nimport { validateIdentifier } from \"../database/validate.js\";\nimport { getDb } from \"../loader.js\";\nimport { FTSManager } from \"./fts-manager.js\";\nimport type {\n\tSearchOptions,\n\tCollectionSearchOptions,\n\tSearchResult,\n\tSearchResponse,\n\tSuggestOptions,\n\tSuggestion,\n\tSearchStats,\n} from \"./types.js\";\n\n/** Pattern to split on whitespace for query term extraction */\nconst WHITESPACE_SPLIT_PATTERN = /\\s+/;\nconst FTS_OPERATORS_PATTERN = /\\b(AND|OR|NOT|NEAR)\\b/i;\nconst DOUBLE_QUOTE_PATTERN = /\"/g;\n\n/**\n * Detect FTS5 query syntax errors. Match specifically on the SQLite FTS5\n * error fingerprints rather than a broad \"fts5\" / \"syntax error\" filter\n * (which would also swallow internal table-corruption errors). The two\n * fingerprints we care about are:\n *\n * - \"fts5: syntax error near …\" — unbalanced quotes, stray operators,\n * other malformed user input\n * - \"unknown special query: …\" — bare special tokens like `^*` that\n * parse but don't resolve to a real FTS5 directive\n */\nfunction isFts5SyntaxError(error: unknown): boolean {\n\tif (!(error instanceof Error)) return false;\n\tconst message = error.message.toLowerCase();\n\treturn message.includes(\"fts5: syntax error\") || message.includes(\"unknown special query\");\n}\n\n/**\n * Search across multiple collections\n *\n * Public API that auto-injects the database.\n *\n * @param query - Search query (FTS5 syntax supported)\n * @param options - Search options\n * @returns Search results with pagination\n *\n * @example\n * ```typescript\n * import { search } from \"emdash\";\n *\n * const results = await search(\"hello world\", {\n * collections: [\"posts\", \"pages\"],\n * limit: 20\n * });\n * ```\n */\nexport async function search(query: string, options: SearchOptions = {}): Promise<SearchResponse> {\n\tconst db = await getDb();\n\treturn searchWithDb(db, query, options);\n}\n\n/**\n * Search across multiple collections (with explicit db)\n *\n * @internal Use `search()` in templates. This variant is for admin routes\n * that already have a database handle.\n *\n * @param db - Kysely database instance\n * @param query - Search query (FTS5 syntax supported)\n * @param options - Search options\n * @returns Search results with pagination\n */\nexport async function searchWithDb(\n\tdb: Kysely<Database>,\n\tquery: string,\n\toptions: SearchOptions = {},\n): Promise<SearchResponse> {\n\tconst ftsManager = new FTSManager(db);\n\tconst limit = options.limit ?? 20;\n\tconst status = options.status ?? \"published\";\n\n\t// Get searchable collections\n\tlet collections = options.collections;\n\tif (!collections || collections.length === 0) {\n\t\tcollections = await getSearchableCollections(db);\n\t}\n\n\tif (collections.length === 0) {\n\t\treturn { items: [] };\n\t}\n\n\t// Search each collection and merge results\n\tconst allResults: SearchResult[] = [];\n\n\tfor (const collection of collections) {\n\t\tconst config = await ftsManager.getSearchConfig(collection);\n\t\tif (!config?.enabled) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst collectionResults = await searchSingleCollection(\n\t\t\tdb,\n\t\t\tcollection,\n\t\t\tquery,\n\t\t\t{\n\t\t\t\tstatus,\n\t\t\t\tlocale: options.locale,\n\t\t\t\tlimit: limit * 2, // Get extra for merging\n\t\t\t},\n\t\t\tconfig.weights,\n\t\t);\n\n\t\tallResults.push(...collectionResults);\n\t}\n\n\t// Sort by score descending\n\tallResults.sort((a, b) => b.score - a.score);\n\n\t// Apply limit\n\tconst items = allResults.slice(0, limit);\n\n\treturn { items };\n}\n\n/**\n * Search within a single collection\n *\n * @param db - Kysely database instance\n * @param collection - Collection slug\n * @param query - Search query (FTS5 syntax supported)\n * @param options - Search options\n * @returns Search results with pagination\n *\n * @example\n * ```typescript\n * const results = await searchCollection(db, \"posts\", \"hello world\", {\n * limit: 10\n * });\n * ```\n */\nexport async function searchCollection(\n\tdb: Kysely<Database>,\n\tcollection: string,\n\tquery: string,\n\toptions: CollectionSearchOptions = {},\n): Promise<SearchResponse> {\n\tconst ftsManager = new FTSManager(db);\n\tconst config = await ftsManager.getSearchConfig(collection);\n\n\tif (!config?.enabled) {\n\t\treturn { items: [] };\n\t}\n\n\tconst items = await searchSingleCollection(db, collection, query, options, config.weights);\n\n\treturn { items };\n}\n\n/**\n * Internal function to search a single collection\n */\nasync function searchSingleCollection(\n\tdb: Kysely<Database>,\n\tcollection: string,\n\tquery: string,\n\toptions: CollectionSearchOptions,\n\tweights?: Record<string, number>,\n): Promise<SearchResult[]> {\n\t// Validate before any raw SQL interpolation\n\tvalidateIdentifier(collection, \"collection slug\");\n\n\tconst ftsManager = new FTSManager(db);\n\tconst ftsTable = ftsManager.getFtsTableName(collection);\n\tconst contentTable = ftsManager.getContentTableName(collection);\n\tconst limit = options.limit ?? 20;\n\tconst status = options.status ?? \"published\";\n\tconst locale = options.locale;\n\n\t// Check if FTS table exists\n\tif (!(await ftsManager.ftsTableExists(collection))) {\n\t\treturn [];\n\t}\n\n\t// Escape the query for FTS5\n\tconst escapedQuery = escapeQuery(query);\n\tif (!escapedQuery) {\n\t\treturn [];\n\t}\n\n\t// Get searchable fields for snippet generation\n\tconst searchableFields = await ftsManager.getSearchableFields(collection);\n\n\t// Build weight string for bm25 if weights provided\n\t// Format: bm25(table, weight1, weight2, ...)\n\t// First two weights are for 'id' and 'locale' columns (UNINDEXED, so 0)\n\tlet bm25Args = \"\";\n\tif (weights && searchableFields.length > 0) {\n\t\tconst weightValues = [\"0\", \"0\"]; // id column, locale column\n\t\tfor (const field of searchableFields) {\n\t\t\tweightValues.push(String(weights[field] ?? 1));\n\t\t}\n\t\tbm25Args = weightValues.join(\", \");\n\t}\n\n\t// Build and execute the search query\n\t// Using raw SQL because Kysely doesn't have FTS5 support\n\tconst bm25Expr = bm25Args ? `bm25(\"${ftsTable}\", ${bm25Args})` : `bm25(\"${ftsTable}\")`;\n\n\t// Snippet column index is 2 (after id=0, locale=1, first searchable field=2)\n\tlet results;\n\ttry {\n\t\tresults = await sql<{\n\t\t\tid: string;\n\t\t\tslug: string | null;\n\t\t\tlocale: string;\n\t\t\ttitle: string | null;\n\t\t\tsnippet: string | null;\n\t\t\tscore: number;\n\t\t}>`\n\t\tSELECT \n\t\t\tc.id,\n\t\t\tc.slug,\n\t\t\tc.locale,\n\t\t\tc.title,\n\t\t\tsnippet(\"${sql.raw(ftsTable)}\", 2, '<mark>', '</mark>', '...', 32) as snippet,\n\t\t\t${sql.raw(bm25Expr)} as score\n\t\tFROM \"${sql.raw(ftsTable)}\" f\n\t\tJOIN \"${sql.raw(contentTable)}\" c ON f.id = c.id\n\t\tWHERE \"${sql.raw(ftsTable)}\" MATCH ${escapedQuery}\n\t\tAND c.status = ${status}\n\t\tAND c.deleted_at IS NULL\n\t\t${locale ? sql`AND c.locale = ${locale}` : sql``}\n\t\tORDER BY score\n\t\tLIMIT ${limit}\n\t`.execute(db);\n\t} catch (error) {\n\t\t// FTS5 returns syntax errors for queries with unbalanced quotes,\n\t\t// stray operators, or other malformed input. Treat these as\n\t\t// \"no matches\" so the user gets an empty result rather than an\n\t\t// internals-leaking error. Other errors (table missing, IO) still\n\t\t// propagate. Intentionally not logged: any anonymous client can\n\t\t// trigger this path, and the underlying error message embeds the\n\t\t// raw query, so logging would be both noisy and a log-injection\n\t\t// vector.\n\t\tif (isFts5SyntaxError(error)) {\n\t\t\treturn [];\n\t\t}\n\t\tthrow error;\n\t}\n\n\treturn results.rows.map((row) => ({\n\t\tcollection,\n\t\tid: row.id,\n\t\tslug: row.slug,\n\t\tlocale: row.locale,\n\t\ttitle: row.title ?? undefined,\n\t\t// SQLite's snippet() returns NULL when the targeted column is\n\t\t// NULL for that row — even if the row matched via a different\n\t\t// searchable column. Skip sanitization in that case so we don't\n\t\t// throw on `null.replace`. The SearchResult.snippet field is\n\t\t// already optional, so omitting it is the documented contract.\n\t\tsnippet: row.snippet === null ? undefined : sanitizeSnippet(row.snippet),\n\t\tscore: Math.abs(row.score), // bm25 returns negative scores\n\t}));\n}\n\n// Module-scope regexes so the engine doesn't recompile per call —\n// snippet sanitization runs on every search result.\nconst SNIPPET_AMP_RE = /&/g;\nconst SNIPPET_LT_RE = /</g;\nconst SNIPPET_GT_RE = />/g;\nconst SNIPPET_QUOT_RE = /\"/g;\nconst SNIPPET_APOS_RE = /'/g;\n\n/**\n * Make an FTS5 snippet safe to render with `set:html` / `innerHTML`.\n *\n * SQLite's `snippet()` function splices literal `<mark>` and `</mark>`\n * markers around matched terms but does not escape the surrounding\n * source text. Posts that legitimately contain `<`, `>`, `&`, `\"` or\n * `'` would render as broken markup, and a `<script>` literal in a\n * title (or any other indexed field) would execute when displayed.\n *\n * The fix: HTML-escape the whole string, which turns the markers into\n * `&lt;mark&gt;` / `&lt;/mark&gt;`. Then restore those two patterns to\n * their original tag form. The result is \"the indexed text with all\n * HTML metacharacters escaped, plus a small set of literal `<mark>`\n * highlight tags around matched terms\" — which matches the API's\n * documented contract.\n */\nfunction sanitizeSnippet(snippet: string): string {\n\treturn snippet\n\t\t.replace(SNIPPET_AMP_RE, \"&amp;\")\n\t\t.replace(SNIPPET_LT_RE, \"&lt;\")\n\t\t.replace(SNIPPET_GT_RE, \"&gt;\")\n\t\t.replace(SNIPPET_QUOT_RE, \"&quot;\")\n\t\t.replace(SNIPPET_APOS_RE, \"&#39;\")\n\t\t.replaceAll(\"&lt;mark&gt;\", \"<mark>\")\n\t\t.replaceAll(\"&lt;/mark&gt;\", \"</mark>\");\n}\n\n/**\n * Get search suggestions for autocomplete\n *\n * @param db - Kysely database instance\n * @param query - Partial search query\n * @param options - Suggestion options\n * @returns Array of suggestions\n */\nexport async function getSuggestions(\n\tdb: Kysely<Database>,\n\tquery: string,\n\toptions: SuggestOptions = {},\n): Promise<Suggestion[]> {\n\tconst limit = options.limit ?? 5;\n\tconst locale = options.locale;\n\n\t// Get searchable collections\n\tlet collections = options.collections;\n\tif (!collections || collections.length === 0) {\n\t\tcollections = await getSearchableCollections(db);\n\t}\n\n\tif (collections.length === 0) {\n\t\treturn [];\n\t}\n\n\tconst suggestions: Suggestion[] = [];\n\n\tfor (const collection of collections) {\n\t\tconst ftsManager = new FTSManager(db);\n\t\tconst config = await ftsManager.getSearchConfig(collection);\n\t\tif (!config?.enabled) {\n\t\t\tcontinue;\n\t\t}\n\n\t\t// Validate before raw SQL interpolation\n\t\tvalidateIdentifier(collection, \"collection slug\");\n\n\t\tconst ftsTable = ftsManager.getFtsTableName(collection);\n\t\tconst contentTable = ftsManager.getContentTableName(collection);\n\n\t\t// Use prefix search for autocomplete. `escapeQuery` already appends `*`\n\t\t// to each term for prefix matching, so we must not append another one.\n\t\tconst prefixQuery = escapeQuery(query);\n\t\tif (!prefixQuery) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tlet results;\n\t\ttry {\n\t\t\tresults = await sql<{\n\t\t\t\tid: string;\n\t\t\t\ttitle: string;\n\t\t\t}>`\n\t\t\t\tSELECT \n\t\t\t\t\tc.id,\n\t\t\t\t\tc.title\n\t\t\t\tFROM \"${sql.raw(ftsTable)}\" f\n\t\t\t\tJOIN \"${sql.raw(contentTable)}\" c ON f.id = c.id\n\t\t\t\tWHERE \"${sql.raw(ftsTable)}\" MATCH ${prefixQuery}\n\t\t\t\tAND c.status = 'published'\n\t\t\t\tAND c.deleted_at IS NULL\n\t\t\t\tAND c.title IS NOT NULL\n\t\t\t\t${locale ? sql`AND c.locale = ${locale}` : sql``}\n\t\t\t\tORDER BY bm25(\"${sql.raw(ftsTable)}\")\n\t\t\t\tLIMIT ${limit}\n\t\t\t`.execute(db);\n\t\t} catch (error) {\n\t\t\t// Same swallow as searchSingleCollection: malformed prefix\n\t\t\t// queries should yield no suggestions, not surface DB errors.\n\t\t\t// Intentionally not logged (anonymous-triggerable, echoes\n\t\t\t// user input -- see searchSingleCollection for rationale).\n\t\t\tif (isFts5SyntaxError(error)) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tthrow error;\n\t\t}\n\n\t\tfor (const row of results.rows) {\n\t\t\tsuggestions.push({\n\t\t\t\tcollection,\n\t\t\t\tid: row.id,\n\t\t\t\ttitle: row.title,\n\t\t\t});\n\t\t}\n\t}\n\n\treturn suggestions.slice(0, limit);\n}\n\n/**\n * Get search statistics for all collections\n */\nexport async function getSearchStats(db: Kysely<Database>): Promise<SearchStats> {\n\tconst ftsManager = new FTSManager(db);\n\tconst collections = await getSearchableCollections(db);\n\tconst stats: SearchStats = { collections: {} };\n\n\tfor (const collection of collections) {\n\t\tconst collectionStats = await ftsManager.getIndexStats(collection);\n\t\tif (collectionStats) {\n\t\t\tstats.collections[collection] = collectionStats;\n\t\t}\n\t}\n\n\treturn stats;\n}\n\n/**\n * Get list of collections with search enabled\n */\nasync function getSearchableCollections(db: Kysely<Database>): Promise<string[]> {\n\tconst results = await db\n\t\t.selectFrom(\"_emdash_collections\")\n\t\t.select([\"slug\", \"search_config\"])\n\t\t.execute();\n\n\treturn results\n\t\t.filter((r) => {\n\t\t\tif (!r.search_config) return false;\n\t\t\ttry {\n\t\t\t\tconst config = JSON.parse(r.search_config);\n\t\t\t\treturn config.enabled === true;\n\t\t\t} catch {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t})\n\t\t.map((r) => r.slug);\n}\n\n/**\n * Escape a query string for FTS5\n *\n * Handles special characters and prevents injection.\n */\nfunction escapeQuery(query: string): string {\n\tif (!query || typeof query !== \"string\") {\n\t\treturn \"\";\n\t}\n\n\t// Trim whitespace\n\tquery = query.trim();\n\n\tif (query.length === 0) {\n\t\treturn \"\";\n\t}\n\n\t// If already a quoted phrase, escape only interior quotes and preserve phrase syntax\n\tif (query.startsWith('\"') && query.endsWith('\"') && query.length >= 2) {\n\t\tconst inner = query.slice(1, -1);\n\t\treturn `\"${inner.replace(DOUBLE_QUOTE_PATTERN, '\"\"')}\"`;\n\t}\n\n\t// Escape any existing quotes\n\tconst escaped = query.replace(DOUBLE_QUOTE_PATTERN, '\"\"');\n\n\t// If the query contains FTS5 operators (AND, OR, NOT, NEAR),\n\t// pass through with quotes escaped but operators preserved\n\tif (FTS_OPERATORS_PATTERN.test(query)) {\n\t\treturn escaped;\n\t}\n\n\t// For simple queries, wrap each word to handle special chars\n\tconst terms = escaped.split(WHITESPACE_SPLIT_PATTERN).filter((t) => t.length > 0);\n\tif (terms.length === 0) {\n\t\treturn \"\";\n\t}\n\n\t// Join with implicit AND, add prefix matching (*) to all terms\n\t// This allows \"hel wor\" to match \"hello world\"\n\treturn terms.map((t) => `\"${t}\"*`).join(\" \");\n}\n","/**\n * Text Extraction\n *\n * Extracts plain text from Portable Text blocks for FTS indexing.\n * Uses @portabletext/toolkit as base with extensions for custom block types.\n */\n\nimport { toPlainText } from \"@portabletext/toolkit\";\n\nimport type { PortableTextBlock } from \"../content/converters/types.js\";\n\n/**\n * Validate that a value looks like a Portable Text block array.\n * Each element must have at least a `_type` string property.\n */\nfunction isPortableTextArray(value: unknown[]): value is PortableTextBlock[] {\n\treturn value.every(\n\t\t(item) =>\n\t\t\ttypeof item === \"object\" &&\n\t\t\titem !== null &&\n\t\t\t\"_type\" in item &&\n\t\t\ttypeof item._type === \"string\",\n\t);\n}\n\n/**\n * Extract additional text from custom block types that toPlainText doesn't handle\n */\nfunction extractCustomBlockText(block: PortableTextBlock): string {\n\t// Code blocks - include the code content\n\tif (block._type === \"code\" && \"code\" in block && typeof block.code === \"string\") {\n\t\treturn block.code;\n\t}\n\n\t// Image blocks - include alt text and caption\n\tif (block._type === \"image\") {\n\t\tconst parts: string[] = [];\n\t\tif (\"alt\" in block && typeof block.alt === \"string\" && block.alt) {\n\t\t\tparts.push(block.alt);\n\t\t}\n\t\tif (\"caption\" in block && typeof block.caption === \"string\" && block.caption) {\n\t\t\tparts.push(block.caption);\n\t\t}\n\t\treturn parts.join(\" \");\n\t}\n\n\treturn \"\";\n}\n\n/**\n * Extract plain text from Portable Text blocks\n *\n * Uses @portabletext/toolkit's toPlainText for standard blocks,\n * plus extracts text from custom block types (code, images with alt/caption).\n *\n * @param blocks - Array of Portable Text blocks (or a JSON string)\n * @returns Plain text content\n *\n * @example\n * ```typescript\n * const text = extractPlainText([\n * {\n * _type: \"block\",\n * _key: \"abc\",\n * children: [{ _type: \"span\", _key: \"s1\", text: \"Hello World\" }]\n * }\n * ]);\n * // Returns: \"Hello World\"\n * ```\n */\nexport function extractPlainText(blocks: PortableTextBlock[] | string | null | undefined): string {\n\tif (!blocks) {\n\t\treturn \"\";\n\t}\n\n\t// Handle JSON string input\n\tlet parsedBlocks: PortableTextBlock[];\n\tif (typeof blocks === \"string\") {\n\t\ttry {\n\t\t\tparsedBlocks = JSON.parse(blocks);\n\t\t} catch {\n\t\t\t// If it's not valid JSON, treat as plain text\n\t\t\treturn blocks;\n\t\t}\n\t} else {\n\t\tparsedBlocks = blocks;\n\t}\n\n\tif (!Array.isArray(parsedBlocks)) {\n\t\treturn \"\";\n\t}\n\n\t// Use official toPlainText for standard blocks.\n\t// toPlainText expects `{ _type: string; [key: string]: any }[]` but our blocks use\n\t// `unknown` index sigs. They're structurally compatible at runtime — spread each block\n\t// to satisfy the wider index signature without an unsafe cast.\n\tconst toolkitBlocks = parsedBlocks.map((b) => {\n\t\tconst obj: Record<string, unknown> & { _type: string } = { _type: b._type };\n\t\tfor (const [key, val] of Object.entries(b)) {\n\t\t\tobj[key] = val;\n\t\t}\n\t\treturn obj;\n\t});\n\tconst standardText = toPlainText(toolkitBlocks);\n\n\t// Extract text from custom block types that toPlainText doesn't handle\n\tconst customTexts = parsedBlocks.map(extractCustomBlockText).filter((text) => text.length > 0);\n\n\t// Combine both\n\tconst allTexts = [standardText, ...customTexts].filter((t) => t.length > 0);\n\treturn allTexts.join(\"\\n\");\n}\n\n/**\n * Extract searchable text from a content entry\n *\n * Extracts text from specified fields, handling both plain text and Portable Text.\n *\n * @param entry - Content entry data\n * @param fields - Field names to extract text from\n * @returns Object mapping field names to extracted text\n */\nexport function extractSearchableFields(\n\tentry: Record<string, unknown>,\n\tfields: string[],\n): Record<string, string> {\n\tconst result: Record<string, string> = {};\n\n\tfor (const field of fields) {\n\t\tconst value = entry[field];\n\n\t\tif (value === null || value === undefined) {\n\t\t\tresult[field] = \"\";\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (typeof value === \"string\") {\n\t\t\t// Could be plain text or JSON Portable Text\n\t\t\tif (value.startsWith(\"[\")) {\n\t\t\t\tresult[field] = extractPlainText(value);\n\t\t\t} else {\n\t\t\t\tresult[field] = value;\n\t\t\t}\n\t\t} else if (Array.isArray(value)) {\n\t\t\t// Validate the array looks like Portable Text before treating it as such\n\t\t\tif (isPortableTextArray(value)) {\n\t\t\t\tresult[field] = extractPlainText(value);\n\t\t\t} else {\n\t\t\t\tresult[field] = JSON.stringify(value);\n\t\t\t}\n\t\t} else if (typeof value === \"object\") {\n\t\t\t// Object — serialize to JSON for searchable text\n\t\t\tresult[field] = JSON.stringify(value);\n\t\t} else if (typeof value === \"number\" || typeof value === \"boolean\") {\n\t\t\tresult[field] = `${value}`;\n\t\t} else {\n\t\t\tresult[field] = \"\";\n\t\t}\n\t}\n\n\treturn result;\n}\n","/**\n * Search Module\n *\n * Full-text search for EmDash using SQLite FTS5.\n */\n\n// Types\nexport type {\n\tSearchConfig,\n\tSearchOptions,\n\tCollectionSearchOptions,\n\tSearchResult,\n\tSearchResponse,\n\tSuggestOptions,\n\tSuggestion,\n\tSearchStats,\n} from \"./types.js\";\n\n// FTS Manager\nexport { FTSManager } from \"./fts-manager.js\";\n\n// Query functions (public API uses getDb() internally)\nexport { search, searchWithDb, searchCollection, getSuggestions, getSearchStats } from \"./query.js\";\n\n// Text extraction\nexport { extractPlainText, extractSearchableFields } from \"./text-extraction.js\";\n"],"mappings":";;;;;;;;;AAwBA,MAAM,2BAA2B;AACjC,MAAM,wBAAwB;AAC9B,MAAM,uBAAuB;;;;;;;;;;;;AAa7B,SAAS,kBAAkB,OAAyB;AACnD,KAAI,EAAE,iBAAiB,OAAQ,QAAO;CACtC,MAAM,UAAU,MAAM,QAAQ,aAAa;AAC3C,QAAO,QAAQ,SAAS,qBAAqB,IAAI,QAAQ,SAAS,wBAAwB;;;;;;;;;;;;;;;;;;;;;AAsB3F,eAAsB,OAAO,OAAe,UAAyB,EAAE,EAA2B;AAEjG,QAAO,aADI,MAAM,OAAO,EACA,OAAO,QAAQ;;;;;;;;;;;;;AAcxC,eAAsB,aACrB,IACA,OACA,UAAyB,EAAE,EACD;CAC1B,MAAM,aAAa,IAAI,WAAW,GAAG;CACrC,MAAM,QAAQ,QAAQ,SAAS;CAC/B,MAAM,SAAS,QAAQ,UAAU;CAGjC,IAAI,cAAc,QAAQ;AAC1B,KAAI,CAAC,eAAe,YAAY,WAAW,EAC1C,eAAc,MAAM,yBAAyB,GAAG;AAGjD,KAAI,YAAY,WAAW,EAC1B,QAAO,EAAE,OAAO,EAAE,EAAE;CAIrB,MAAM,aAA6B,EAAE;AAErC,MAAK,MAAM,cAAc,aAAa;EACrC,MAAM,SAAS,MAAM,WAAW,gBAAgB,WAAW;AAC3D,MAAI,CAAC,QAAQ,QACZ;EAGD,MAAM,oBAAoB,MAAM,uBAC/B,IACA,YACA,OACA;GACC;GACA,QAAQ,QAAQ;GAChB,OAAO,QAAQ;GACf,EACD,OAAO,QACP;AAED,aAAW,KAAK,GAAG,kBAAkB;;AAItC,YAAW,MAAM,GAAG,MAAM,EAAE,QAAQ,EAAE,MAAM;AAK5C,QAAO,EAAE,OAFK,WAAW,MAAM,GAAG,MAAM,EAExB;;;;;;;;;;;;;;;;;;AAmBjB,eAAsB,iBACrB,IACA,YACA,OACA,UAAmC,EAAE,EACX;CAE1B,MAAM,SAAS,MADI,IAAI,WAAW,GAAG,CACL,gBAAgB,WAAW;AAE3D,KAAI,CAAC,QAAQ,QACZ,QAAO,EAAE,OAAO,EAAE,EAAE;AAKrB,QAAO,EAAE,OAFK,MAAM,uBAAuB,IAAI,YAAY,OAAO,SAAS,OAAO,QAAQ,EAE1E;;;;;AAMjB,eAAe,uBACd,IACA,YACA,OACA,SACA,SAC0B;AAE1B,oBAAmB,YAAY,kBAAkB;CAEjD,MAAM,aAAa,IAAI,WAAW,GAAG;CACrC,MAAM,WAAW,WAAW,gBAAgB,WAAW;CACvD,MAAM,eAAe,WAAW,oBAAoB,WAAW;CAC/D,MAAM,QAAQ,QAAQ,SAAS;CAC/B,MAAM,SAAS,QAAQ,UAAU;CACjC,MAAM,SAAS,QAAQ;AAGvB,KAAI,CAAE,MAAM,WAAW,eAAe,WAAW,CAChD,QAAO,EAAE;CAIV,MAAM,eAAe,YAAY,MAAM;AACvC,KAAI,CAAC,aACJ,QAAO,EAAE;CAIV,MAAM,mBAAmB,MAAM,WAAW,oBAAoB,WAAW;CAKzE,IAAI,WAAW;AACf,KAAI,WAAW,iBAAiB,SAAS,GAAG;EAC3C,MAAM,eAAe,CAAC,KAAK,IAAI;AAC/B,OAAK,MAAM,SAAS,iBACnB,cAAa,KAAK,OAAO,QAAQ,UAAU,EAAE,CAAC;AAE/C,aAAW,aAAa,KAAK,KAAK;;CAKnC,MAAM,WAAW,WAAW,SAAS,SAAS,KAAK,SAAS,KAAK,SAAS,SAAS;CAGnF,IAAI;AACJ,KAAI;AACH,YAAU,MAAM,GAOd;;;;;;cAMU,IAAI,IAAI,SAAS,CAAC;KAC3B,IAAI,IAAI,SAAS,CAAC;UACb,IAAI,IAAI,SAAS,CAAC;UAClB,IAAI,IAAI,aAAa,CAAC;WACrB,IAAI,IAAI,SAAS,CAAC,UAAU,aAAa;mBACjC,OAAO;;IAEtB,SAAS,GAAG,kBAAkB,WAAW,GAAG,GAAG;;UAEzC,MAAM;GACb,QAAQ,GAAG;UACJ,OAAO;AASf,MAAI,kBAAkB,MAAM,CAC3B,QAAO,EAAE;AAEV,QAAM;;AAGP,QAAO,QAAQ,KAAK,KAAK,SAAS;EACjC;EACA,IAAI,IAAI;EACR,MAAM,IAAI;EACV,QAAQ,IAAI;EACZ,OAAO,IAAI,SAAS;EAMpB,SAAS,IAAI,YAAY,OAAO,SAAY,gBAAgB,IAAI,QAAQ;EACxE,OAAO,KAAK,IAAI,IAAI,MAAM;EAC1B,EAAE;;AAKJ,MAAM,iBAAiB;AACvB,MAAM,gBAAgB;AACtB,MAAM,gBAAgB;AACtB,MAAM,kBAAkB;AACxB,MAAM,kBAAkB;;;;;;;;;;;;;;;;;AAkBxB,SAAS,gBAAgB,SAAyB;AACjD,QAAO,QACL,QAAQ,gBAAgB,QAAQ,CAChC,QAAQ,eAAe,OAAO,CAC9B,QAAQ,eAAe,OAAO,CAC9B,QAAQ,iBAAiB,SAAS,CAClC,QAAQ,iBAAiB,QAAQ,CACjC,WAAW,gBAAgB,SAAS,CACpC,WAAW,iBAAiB,UAAU;;;;;;;;;;AAWzC,eAAsB,eACrB,IACA,OACA,UAA0B,EAAE,EACJ;CACxB,MAAM,QAAQ,QAAQ,SAAS;CAC/B,MAAM,SAAS,QAAQ;CAGvB,IAAI,cAAc,QAAQ;AAC1B,KAAI,CAAC,eAAe,YAAY,WAAW,EAC1C,eAAc,MAAM,yBAAyB,GAAG;AAGjD,KAAI,YAAY,WAAW,EAC1B,QAAO,EAAE;CAGV,MAAM,cAA4B,EAAE;AAEpC,MAAK,MAAM,cAAc,aAAa;EACrC,MAAM,aAAa,IAAI,WAAW,GAAG;AAErC,MAAI,EADW,MAAM,WAAW,gBAAgB,WAAW,GAC9C,QACZ;AAID,qBAAmB,YAAY,kBAAkB;EAEjD,MAAM,WAAW,WAAW,gBAAgB,WAAW;EACvD,MAAM,eAAe,WAAW,oBAAoB,WAAW;EAI/D,MAAM,cAAc,YAAY,MAAM;AACtC,MAAI,CAAC,YACJ;EAGD,IAAI;AACJ,MAAI;AACH,aAAU,MAAM,GAGd;;;;YAIO,IAAI,IAAI,SAAS,CAAC;YAClB,IAAI,IAAI,aAAa,CAAC;aACrB,IAAI,IAAI,SAAS,CAAC,UAAU,YAAY;;;;MAI/C,SAAS,GAAG,kBAAkB,WAAW,GAAG,GAAG;qBAChC,IAAI,IAAI,SAAS,CAAC;YAC3B,MAAM;KACb,QAAQ,GAAG;WACL,OAAO;AAKf,OAAI,kBAAkB,MAAM,CAC3B;AAED,SAAM;;AAGP,OAAK,MAAM,OAAO,QAAQ,KACzB,aAAY,KAAK;GAChB;GACA,IAAI,IAAI;GACR,OAAO,IAAI;GACX,CAAC;;AAIJ,QAAO,YAAY,MAAM,GAAG,MAAM;;;;;AAMnC,eAAsB,eAAe,IAA4C;CAChF,MAAM,aAAa,IAAI,WAAW,GAAG;CACrC,MAAM,cAAc,MAAM,yBAAyB,GAAG;CACtD,MAAM,QAAqB,EAAE,aAAa,EAAE,EAAE;AAE9C,MAAK,MAAM,cAAc,aAAa;EACrC,MAAM,kBAAkB,MAAM,WAAW,cAAc,WAAW;AAClE,MAAI,gBACH,OAAM,YAAY,cAAc;;AAIlC,QAAO;;;;;AAMR,eAAe,yBAAyB,IAAyC;AAMhF,SALgB,MAAM,GACpB,WAAW,sBAAsB,CACjC,OAAO,CAAC,QAAQ,gBAAgB,CAAC,CACjC,SAAS,EAGT,QAAQ,MAAM;AACd,MAAI,CAAC,EAAE,cAAe,QAAO;AAC7B,MAAI;AAEH,UADe,KAAK,MAAM,EAAE,cAAc,CAC5B,YAAY;UACnB;AACP,UAAO;;GAEP,CACD,KAAK,MAAM,EAAE,KAAK;;;;;;;AAQrB,SAAS,YAAY,OAAuB;AAC3C,KAAI,CAAC,SAAS,OAAO,UAAU,SAC9B,QAAO;AAIR,SAAQ,MAAM,MAAM;AAEpB,KAAI,MAAM,WAAW,EACpB,QAAO;AAIR,KAAI,MAAM,WAAW,KAAI,IAAI,MAAM,SAAS,KAAI,IAAI,MAAM,UAAU,EAEnE,QAAO,IADO,MAAM,MAAM,GAAG,GAAG,CACf,QAAQ,sBAAsB,OAAK,CAAC;CAItD,MAAM,UAAU,MAAM,QAAQ,sBAAsB,OAAK;AAIzD,KAAI,sBAAsB,KAAK,MAAM,CACpC,QAAO;CAIR,MAAM,QAAQ,QAAQ,MAAM,yBAAyB,CAAC,QAAQ,MAAM,EAAE,SAAS,EAAE;AACjF,KAAI,MAAM,WAAW,EACpB,QAAO;AAKR,QAAO,MAAM,KAAK,MAAM,IAAI,EAAE,IAAI,CAAC,KAAK,IAAI;;;;;;;;;;;;;;;AChd7C,SAAS,oBAAoB,OAAgD;AAC5E,QAAO,MAAM,OACX,SACA,OAAO,SAAS,YAChB,SAAS,QACT,WAAW,QACX,OAAO,KAAK,UAAU,SACvB;;;;;AAMF,SAAS,uBAAuB,OAAkC;AAEjE,KAAI,MAAM,UAAU,UAAU,UAAU,SAAS,OAAO,MAAM,SAAS,SACtE,QAAO,MAAM;AAId,KAAI,MAAM,UAAU,SAAS;EAC5B,MAAM,QAAkB,EAAE;AAC1B,MAAI,SAAS,SAAS,OAAO,MAAM,QAAQ,YAAY,MAAM,IAC5D,OAAM,KAAK,MAAM,IAAI;AAEtB,MAAI,aAAa,SAAS,OAAO,MAAM,YAAY,YAAY,MAAM,QACpE,OAAM,KAAK,MAAM,QAAQ;AAE1B,SAAO,MAAM,KAAK,IAAI;;AAGvB,QAAO;;;;;;;;;;;;;;;;;;;;;;;AAwBR,SAAgB,iBAAiB,QAAiE;AACjG,KAAI,CAAC,OACJ,QAAO;CAIR,IAAI;AACJ,KAAI,OAAO,WAAW,SACrB,KAAI;AACH,iBAAe,KAAK,MAAM,OAAO;SAC1B;AAEP,SAAO;;KAGR,gBAAe;AAGhB,KAAI,CAAC,MAAM,QAAQ,aAAa,CAC/B,QAAO;AAqBR,QADiB,CANI,YAPC,aAAa,KAAK,MAAM;EAC7C,MAAM,MAAmD,EAAE,OAAO,EAAE,OAAO;AAC3E,OAAK,MAAM,CAAC,KAAK,QAAQ,OAAO,QAAQ,EAAE,CACzC,KAAI,OAAO;AAEZ,SAAO;GACN,CAC6C,EAMf,GAHZ,aAAa,IAAI,uBAAuB,CAAC,QAAQ,SAAS,KAAK,SAAS,EAAE,CAG/C,CAAC,QAAQ,MAAM,EAAE,SAAS,EAAE,CAC3D,KAAK,KAAK;;;;;;;;;;;AAY3B,SAAgB,wBACf,OACA,QACyB;CACzB,MAAM,SAAiC,EAAE;AAEzC,MAAK,MAAM,SAAS,QAAQ;EAC3B,MAAM,QAAQ,MAAM;AAEpB,MAAI,UAAU,QAAQ,UAAU,QAAW;AAC1C,UAAO,SAAS;AAChB;;AAGD,MAAI,OAAO,UAAU,SAEpB,KAAI,MAAM,WAAW,IAAI,CACxB,QAAO,SAAS,iBAAiB,MAAM;MAEvC,QAAO,SAAS;WAEP,MAAM,QAAQ,MAAM,CAE9B,KAAI,oBAAoB,MAAM,CAC7B,QAAO,SAAS,iBAAiB,MAAM;MAEvC,QAAO,SAAS,KAAK,UAAU,MAAM;WAE5B,OAAO,UAAU,SAE3B,QAAO,SAAS,KAAK,UAAU,MAAM;WAC3B,OAAO,UAAU,YAAY,OAAO,UAAU,UACxD,QAAO,SAAS,GAAG;MAEnB,QAAO,SAAS;;AAIlB,QAAO"}
@@ -1,7 +0,0 @@
1
- //#region src/version.ts
2
- const VERSION = "0.26.0";
3
- const COMMIT = "71a148db";
4
-
5
- //#endregion
6
- export { VERSION as n, COMMIT as t };
7
- //# sourceMappingURL=version-BoNBItP_.mjs.map