@sonicjs-cms/core 2.18.1 → 3.0.0-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -3
- package/dist/admin-documents-form.template-KN7JF66Q.cjs +19 -0
- package/dist/{admin-layout-catalyst.template-UMTIN66R.js.map → admin-documents-form.template-KN7JF66Q.cjs.map} +1 -1
- package/dist/admin-documents-form.template-NLSI6Z42.js +6 -0
- package/dist/{admin-layout-catalyst.template-HFD37TY5.cjs.map → admin-documents-form.template-NLSI6Z42.js.map} +1 -1
- package/dist/admin-layout-catalyst.template-WHJGSWWD.js +7 -0
- package/dist/admin-layout-catalyst.template-WHJGSWWD.js.map +1 -0
- package/dist/admin-layout-catalyst.template-ZK5HD545.cjs +17 -0
- package/dist/admin-layout-catalyst.template-ZK5HD545.cjs.map +1 -0
- package/dist/app-Bo0X1OWX.d.ts +1268 -0
- package/dist/app-Do66yCcV.d.cts +1268 -0
- package/dist/cache-DDARE4QE.js +4 -0
- package/dist/cache-DDARE4QE.js.map +1 -0
- package/dist/cache-LVYS4BPL.cjs +33 -0
- package/dist/cache-LVYS4BPL.cjs.map +1 -0
- package/dist/chunk-2CB4KY7I.cjs +771 -0
- package/dist/chunk-2CB4KY7I.cjs.map +1 -0
- package/dist/{chunk-55RDMDOP.js → chunk-3TB6AT6X.js} +148 -55
- package/dist/chunk-3TB6AT6X.js.map +1 -0
- package/dist/{chunk-ON5ZMSU4.js → chunk-6JQOUUOB.js} +3 -3
- package/dist/chunk-6JQOUUOB.js.map +1 -0
- package/dist/chunk-6OUHGKFD.js +387 -0
- package/dist/chunk-6OUHGKFD.js.map +1 -0
- package/dist/{chunk-DSUJ5YQH.cjs → chunk-AAWNRBRB.cjs} +537 -92
- package/dist/chunk-AAWNRBRB.cjs.map +1 -0
- package/dist/chunk-AI663NBO.js +821 -0
- package/dist/chunk-AI663NBO.js.map +1 -0
- package/dist/chunk-BDDABDAB.cjs +1149 -0
- package/dist/chunk-BDDABDAB.cjs.map +1 -0
- package/dist/chunk-BLMTL57B.js +767 -0
- package/dist/chunk-BLMTL57B.js.map +1 -0
- package/dist/chunk-DNQCEKUK.cjs +327 -0
- package/dist/chunk-DNQCEKUK.cjs.map +1 -0
- package/dist/chunk-DSA4UX5B.cjs +276 -0
- package/dist/chunk-DSA4UX5B.cjs.map +1 -0
- package/dist/chunk-EF2NQUIQ.js +323 -0
- package/dist/chunk-EF2NQUIQ.js.map +1 -0
- package/dist/chunk-GCDZZNIN.js +192 -0
- package/dist/chunk-GCDZZNIN.js.map +1 -0
- package/dist/{chunk-ABB34XUS.cjs → chunk-H2AXVCLS.cjs} +667 -19
- package/dist/chunk-H2AXVCLS.cjs.map +1 -0
- package/dist/{chunk-XWIA3HVX.js → chunk-HDWE5FRJ.js} +6 -1249
- package/dist/chunk-HDWE5FRJ.js.map +1 -0
- package/dist/chunk-HIKBY7MS.cjs +70 -0
- package/dist/chunk-HIKBY7MS.cjs.map +1 -0
- package/dist/chunk-IESEVHXL.js +66 -0
- package/dist/chunk-IESEVHXL.js.map +1 -0
- package/dist/chunk-IVPRUGTY.js +242 -0
- package/dist/chunk-IVPRUGTY.js.map +1 -0
- package/dist/{chunk-SQ6FNXU2.cjs → chunk-IXUHXTHW.cjs} +2 -151
- package/dist/chunk-IXUHXTHW.cjs.map +1 -0
- package/dist/chunk-J6JTWD2A.cjs +100 -0
- package/dist/chunk-J6JTWD2A.cjs.map +1 -0
- package/dist/chunk-JEQ7FLOD.cjs +199 -0
- package/dist/chunk-JEQ7FLOD.cjs.map +1 -0
- package/dist/chunk-K25XHMM3.js +566 -0
- package/dist/chunk-K25XHMM3.js.map +1 -0
- package/dist/chunk-LRZIAW7U.cjs +158 -0
- package/dist/chunk-LRZIAW7U.cjs.map +1 -0
- package/dist/{chunk-OHYBNCVL.cjs → chunk-MVIZJOO5.cjs} +10 -1256
- package/dist/chunk-MVIZJOO5.cjs.map +1 -0
- package/dist/{chunk-UYJ6TJHX.cjs → chunk-NAVPFIG5.cjs} +148 -55
- package/dist/chunk-NAVPFIG5.cjs.map +1 -0
- package/dist/chunk-NLJVSER2.js +273 -0
- package/dist/chunk-NLJVSER2.js.map +1 -0
- package/dist/chunk-NMPEMSU4.js +154 -0
- package/dist/chunk-NMPEMSU4.js.map +1 -0
- package/dist/chunk-NUKJ54GA.cjs +245 -0
- package/dist/chunk-NUKJ54GA.cjs.map +1 -0
- package/dist/{chunk-T3Q5V33G.cjs → chunk-QAYFOER6.cjs} +621 -829
- package/dist/chunk-QAYFOER6.cjs.map +1 -0
- package/dist/{chunk-MGFRZO24.js → chunk-QZGABF2M.js} +3 -149
- package/dist/chunk-QZGABF2M.js.map +1 -0
- package/dist/chunk-RNZFGN4R.js +88 -0
- package/dist/chunk-RNZFGN4R.js.map +1 -0
- package/dist/chunk-RZ6H7OZK.js +1134 -0
- package/dist/chunk-RZ6H7OZK.js.map +1 -0
- package/dist/{chunk-XXDFQERJ.js → chunk-VD2EA3WT.js} +7192 -9806
- package/dist/chunk-VD2EA3WT.js.map +1 -0
- package/dist/{chunk-SXXTQETM.cjs → chunk-VXE42MYF.cjs} +8722 -11323
- package/dist/chunk-VXE42MYF.cjs.map +1 -0
- package/dist/{chunk-4ZSNJDLS.cjs → chunk-WULONYGB.cjs} +9 -9
- package/dist/chunk-WULONYGB.cjs.map +1 -0
- package/dist/chunk-XW56B23A.cjs +408 -0
- package/dist/chunk-XW56B23A.cjs.map +1 -0
- package/dist/chunk-YA3TJ65D.cjs +575 -0
- package/dist/chunk-YA3TJ65D.cjs.map +1 -0
- package/dist/{chunk-TFNTM3OA.js → chunk-YHSQVQXX.js} +645 -15
- package/dist/chunk-YHSQVQXX.js.map +1 -0
- package/dist/chunk-YP7GW2G5.cjs +866 -0
- package/dist/chunk-YP7GW2G5.cjs.map +1 -0
- package/dist/{chunk-QFWHAFEO.js → chunk-ZEZ245PW.js} +148 -858
- package/dist/chunk-ZEZ245PW.js.map +1 -0
- package/dist/{chunk-EW5NOBVU.js → chunk-ZGGXCFR6.js} +611 -817
- package/dist/chunk-ZGGXCFR6.js.map +1 -0
- package/dist/{collection-config-B4PG-AaF.d.cts → collection-config-JgHOpFCG.d.cts} +30 -2
- package/dist/{collection-config-B4PG-AaF.d.ts → collection-config-JgHOpFCG.d.ts} +30 -2
- package/dist/config-HFXANXCC.js +6 -0
- package/dist/config-HFXANXCC.js.map +1 -0
- package/dist/config-ON6FNMYX.cjs +19 -0
- package/dist/config-ON6FNMYX.cjs.map +1 -0
- package/dist/define-plugin-BzNHc1ZI.d.ts +1321 -0
- package/dist/define-plugin-IWDKYaVm.d.cts +1321 -0
- package/dist/document-projection-TDWRJX3Z.cjs +13 -0
- package/dist/document-projection-TDWRJX3Z.cjs.map +1 -0
- package/dist/document-projection-YYMC6I4U.js +4 -0
- package/dist/document-projection-YYMC6I4U.js.map +1 -0
- package/dist/index.cjs +13735 -4329
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +329 -492
- package/dist/index.d.ts +329 -492
- package/dist/index.js +13386 -3999
- package/dist/index.js.map +1 -1
- package/dist/middleware.cjs +36 -32
- package/dist/middleware.d.cts +69 -7
- package/dist/middleware.d.ts +69 -7
- package/dist/middleware.js +7 -3
- package/dist/migrations-NJJWQUKK.cjs +13 -0
- package/dist/{migrations-IYNTWDC6.cjs.map → migrations-NJJWQUKK.cjs.map} +1 -1
- package/dist/migrations-WCAVBD7C.js +4 -0
- package/dist/{migrations-R337UD46.js.map → migrations-WCAVBD7C.js.map} +1 -1
- package/dist/{plugin-bootstrap-DfVerYV4.d.cts → plugin-bootstrap-B8ThJU21.d.cts} +4315 -1661
- package/dist/{plugin-bootstrap-P_ciLp_C.d.ts → plugin-bootstrap-qu8hJgUt.d.ts} +4315 -1661
- package/dist/plugins.cjs +171 -12
- package/dist/plugins.d.cts +36 -2
- package/dist/plugins.d.ts +36 -2
- package/dist/plugins.js +5 -2
- package/dist/rbac-O73MFKDA.js +5 -0
- package/dist/rbac-O73MFKDA.js.map +1 -0
- package/dist/rbac-VONLJJKB.cjs +14 -0
- package/dist/rbac-VONLJJKB.cjs.map +1 -0
- package/dist/routes.cjs +41 -45
- package/dist/routes.d.cts +56 -146
- package/dist/routes.d.ts +56 -146
- package/dist/routes.js +17 -9
- package/dist/services.cjs +39 -72
- package/dist/services.d.cts +79 -54
- package/dist/services.d.ts +79 -54
- package/dist/services.js +6 -3
- package/dist/templates.cjs +17 -29
- package/dist/templates.d.cts +1 -66
- package/dist/templates.d.ts +1 -66
- package/dist/templates.js +3 -3
- package/dist/types-Dea1eNxU.d.cts +286 -0
- package/dist/types-Dea1eNxU.d.ts +286 -0
- package/dist/types.d.cts +1 -1
- package/dist/types.d.ts +1 -1
- package/dist/utils.cjs +18 -17
- package/dist/utils.d.cts +1 -1
- package/dist/utils.d.ts +1 -1
- package/dist/utils.js +2 -1
- package/migrations/0001_core.sql +184 -0
- package/migrations/0002_documents.sql +163 -0
- package/package.json +12 -7
- package/dist/admin-layout-catalyst.template-HFD37TY5.cjs +0 -17
- package/dist/admin-layout-catalyst.template-UMTIN66R.js +0 -7
- package/dist/app-C9esKLmh.d.cts +0 -112
- package/dist/app-C9esKLmh.d.ts +0 -112
- package/dist/chunk-4R3NOOL3.js +0 -2217
- package/dist/chunk-4R3NOOL3.js.map +0 -1
- package/dist/chunk-4ZSNJDLS.cjs.map +0 -1
- package/dist/chunk-55RDMDOP.js.map +0 -1
- package/dist/chunk-635JAMSE.cjs +0 -653
- package/dist/chunk-635JAMSE.cjs.map +0 -1
- package/dist/chunk-ABB34XUS.cjs.map +0 -1
- package/dist/chunk-C54YUA23.cjs +0 -2219
- package/dist/chunk-C54YUA23.cjs.map +0 -1
- package/dist/chunk-DSUJ5YQH.cjs.map +0 -1
- package/dist/chunk-EW5NOBVU.js.map +0 -1
- package/dist/chunk-EXNEW5US.js +0 -648
- package/dist/chunk-EXNEW5US.js.map +0 -1
- package/dist/chunk-I2H5NGJQ.js +0 -692
- package/dist/chunk-I2H5NGJQ.js.map +0 -1
- package/dist/chunk-MGFRZO24.js.map +0 -1
- package/dist/chunk-OHYBNCVL.cjs.map +0 -1
- package/dist/chunk-ON5ZMSU4.js.map +0 -1
- package/dist/chunk-QFWHAFEO.js.map +0 -1
- package/dist/chunk-SQ6FNXU2.cjs.map +0 -1
- package/dist/chunk-SXXTQETM.cjs.map +0 -1
- package/dist/chunk-T3Q5V33G.cjs.map +0 -1
- package/dist/chunk-TFNTM3OA.js.map +0 -1
- package/dist/chunk-UYJ6TJHX.cjs.map +0 -1
- package/dist/chunk-WAEQXGCX.cjs +0 -1898
- package/dist/chunk-WAEQXGCX.cjs.map +0 -1
- package/dist/chunk-XWIA3HVX.js.map +0 -1
- package/dist/chunk-XXDFQERJ.js.map +0 -1
- package/dist/migrations-IYNTWDC6.cjs +0 -13
- package/dist/migrations-R337UD46.js +0 -4
- package/dist/plugin-manager-BoM3Q7o7.d.cts +0 -328
- package/dist/plugin-manager-Efx9RyDX.d.ts +0 -328
- package/migrations/001_initial_schema.sql +0 -170
- package/migrations/002_faq_plugin.sql +0 -86
- package/migrations/003_stage5_enhancements.sql +0 -121
- package/migrations/004_stage6_user_management.sql +0 -183
- package/migrations/005_stage7_workflow_automation.sql +0 -294
- package/migrations/006_plugin_system.sql +0 -155
- package/migrations/007_demo_login_plugin.sql +0 -23
- package/migrations/008_fix_slug_validation.sql +0 -22
- package/migrations/009_system_logging.sql +0 -57
- package/migrations/011_config_managed_collections.sql +0 -15
- package/migrations/012_testimonials_plugin.sql +0 -80
- package/migrations/013_code_examples_plugin.sql +0 -177
- package/migrations/014_fix_plugin_registry.sql +0 -88
- package/migrations/015_add_remaining_plugins.sql +0 -89
- package/migrations/016_remove_duplicate_cache_plugin.sql +0 -17
- package/migrations/017_auth_configurable_fields.sql +0 -49
- package/migrations/018_settings_table.sql +0 -23
- package/migrations/019_remove_blog_posts_collection.sql +0 -15
- package/migrations/020_add_email_plugin.sql +0 -22
- package/migrations/021_add_magic_link_auth_plugin.sql +0 -42
- package/migrations/022_add_tinymce_plugin.sql +0 -25
- package/migrations/023_add_easy_mdx_plugin.sql +0 -25
- package/migrations/024_add_quill_editor_plugin.sql +0 -25
- package/migrations/025_add_easymde_plugin.sql +0 -25
- package/migrations/026_add_otp_login.sql +0 -42
- package/migrations/027_fix_slug_field_type.sql +0 -18
- package/migrations/028_fix_slug_field_type_in_schemas.sql +0 -30
- package/migrations/029_add_forms_system.sql +0 -184
- package/migrations/030_add_turnstile_to_forms.sql +0 -14
- package/migrations/031_ai_search_plugin.sql +0 -45
- package/migrations/032_user_profiles.sql +0 -37
- package/migrations/033_form_content_integration.sql +0 -19
- package/migrations/034_security_audit_plugin.sql +0 -27
- package/migrations/035_user_profiles_data_column.sql +0 -16
- package/migrations/036_analytics_events.sql +0 -22
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/plugins/hooks/catalog.ts","../src/plugins/hooks/typed-hooks.ts","../src/plugins/hooks/hook-system-singleton.ts"],"names":[],"mappings":";;;AAkHO,IAAM,gBAAA,GAAmB;AAAA,EAC9B,cAAA;AAAA,EACA,uBAAA;AAAA,EACA,uBAAA;AAAA,EACA,uBAAA;AAAA,EACA,sBAAA;AAAA,EACA,sBAAA;AAAA,EACA,sBAAA;AAAA,EACA,uBAAA;AAAA,EACA,6BAAA;AAAA,EACA,+BAAA;AAAA,EACA,+BAAA;AAAA,EACA,0BAAA;AAAA,EACA;AACF;AAGO,SAAS,iBAAiB,IAAA,EAAqC;AACpE,EAAA,OAAQ,gBAAA,CAAuC,SAAS,IAAI,CAAA;AAC9D;AAmBO,IAAM,oBAAA,GAAuB;AAAA,EAClC,gBAAA,EAAkB,sBAAA;AAAA,EAClB,gBAAA,EAAkB,sBAAA;AAAA,EAClB,gBAAA,EAAkB,sBAAA;AAAA,EAClB,iBAAA,EAAmB,uBAAA;AAAA,EACnB,cAAA,EAAgB;AAClB;AAOO,SAAS,kBAAkB,IAAA,EAA2C;AAC3E,EAAA,OAAO,MAAA,CAAO,SAAA,CAAU,cAAA,CAAe,IAAA,CAAK,sBAAsB,IAAI,CAAA;AACxE;AAOO,SAAS,qBAAqB,IAAA,EAAyC;AAC5E,EAAA,IAAI,gBAAA,CAAiB,IAAI,CAAA,EAAG,OAAO,IAAA;AACnC,EAAA,IAAI,iBAAA,CAAkB,IAAI,CAAA,EAAG,OAAO,qBAAqB,IAAI,CAAA;AAC7D,EAAA,OAAO,MAAA;AACT;;;AC9FA,IAAM,kBAAA,uBAAyB,GAAA,EAAY;AAWpC,SAAS,iBAAiB,UAAA,EAAwC;AACvE,EAAA,OAAO;AAAA,IACL,EAAA,CAAG,KAAA,EAAO,OAAA,EAAS,QAAA,EAAU;AAC3B,MAAA,MAAM,SAAA,GAAY,oBAAA,CAAqB,KAAK,CAAA,IAAK,KAAA;AACjD,MAAA,IAAI,kBAAkB,KAAK,CAAA,IAAK,CAAC,kBAAA,CAAmB,GAAA,CAAI,KAAK,CAAA,EAAG;AAC9D,QAAA,kBAAA,CAAmB,IAAI,KAAK,CAAA;AAE5B,QAAA,OAAA,CAAQ,IAAA;AAAA,UACN,CAAA,eAAA,EAAkB,KAAK,CAAA,+BAAA,EAAkC,SAAS,CAAA,yDAAA;AAAA,SAEpE;AAAA,MACF;AACA,MAAA,UAAA,CAAW,QAAA;AAAA,QACT,SAAA;AAAA,QACA,OAAO,MAAW,OAAA,KAAiB;AACjC,UAAA,MAAM,SAAS,MAAM,OAAA,CAAQ,IAAA,EAAM,OAAA,IAAW,EAAE,CAAA;AAChD,UAAA,OAAO,MAAA,KAAW,SAAY,IAAA,GAAO,MAAA;AAAA,QACvC,CAAA;AAAA,QACA;AAAA,OACF;AAAA,IACF,CAAA;AAAA,IACA,MAAM,QAAA,CAAS,KAAA,EAAO,OAAA,EAAS,OAAA,EAAS;AACtC,MAAA,OAAQ,MAAM,UAAA,CAAW,OAAA,CAAQ,KAAA,EAAO,SAAS,OAAO,CAAA;AAAA,IAC1D;AAAA,GACF;AACF;;;ACrGA,IAAI,OAAA;AAGG,SAAS,cAAc,UAAA,EAAkC;AAC9D,EAAA,OAAA,GAAU,UAAA;AACZ;AAMO,SAAS,aAAA,GAAgC;AAC9C,EAAA,IAAI,CAAC,OAAA,EAAS;AACZ,IAAA,MAAM,IAAI,KAAA;AAAA,MACR;AAAA,KAEF;AAAA,EACF;AACA,EAAA,OAAO,OAAA;AACT;AAGO,SAAS,aAAA,GAAyB;AACvC,EAAA,OAAO,OAAA,KAAY,MAAA;AACrB;AAGO,SAAS,eAAA,GAAwB;AACtC,EAAA,OAAA,GAAU,MAAA;AACZ;AAGO,SAAS,aAAA,GAA4B;AAC1C,EAAA,OAAO,gBAAA,CAAiB,eAAe,CAAA;AACzC","file":"chunk-J6JTWD2A.cjs","sourcesContent":["/**\n * Typed hook event catalog\n *\n * The single source of truth for which lifecycle events a plugin may subscribe\n * to, and the payload shape each one carries. Subscribing through the typed\n * facade (`createTypedHooks`) gives a plugin the narrowed payload type with no\n * casting — TypeScript rejects a wrong field name at the `.on()` call site.\n *\n * Scope note: this catalog lists the events that are (or are being) dispatched\n * in production. The legacy string-keyed `HOOKS` map in `../types` declared many\n * more events than were ever fired; reconciling that list down to what actually\n * dispatches is tracked in the plugin-overhaul plan. Add an event here only when\n * a real dispatch site exists (or is landing in the same change).\n */\n\n/**\n * The acting user on a hook event. ONE canonical shape across every event —\n * always `id` (never `userId`), so a plugin reading `payload.user.id` works on\n * content events and auth events alike.\n */\nexport interface HookActor {\n id: string\n email: string\n role?: string\n}\n\n/** Common shape for content lifecycle events. */\nexport interface ContentEventPayload {\n /** Collection / content-type slug the event is about. */\n collection: string\n /** Content row id, when known (absent for pre-create events). */\n id?: string\n /** The content data being read/written. Mutable by `before` handlers in the chain. */\n data: Record<string, unknown>\n /** The acting user, when the event originates from an authenticated request. */\n user?: HookActor\n}\n\n/** Emitted after a user completes self-registration. */\nexport interface AuthRegistrationCompletedPayload {\n user: HookActor\n}\n\n/** Emitted when a password reset is requested (carries the reset token internally). */\nexport interface AuthPasswordResetRequestedPayload {\n user: HookActor\n /** Single-use reset token. Never expose this in an API response. */\n resetToken: string\n}\n\n/** Emitted after a password reset is confirmed. */\nexport interface AuthPasswordResetCompletedPayload {\n user: HookActor\n}\n\n/** Emitted after a magic-link sign-in link is successfully consumed. */\nexport interface AuthMagicLinkConsumedPayload {\n user: HookActor\n}\n\n/** Emitted after an OTP code is successfully verified. */\nexport interface AuthOtpVerifiedPayload {\n user: HookActor\n}\n\n/**\n * The catalog: event name → payload type.\n *\n * Keep keys in sync with `HookEventName` (derived below) and with the dispatch\n * sites. This is an interface (not a const) so it participates in type-level\n * lookups and can be augmented via declaration merging if a downstream package\n * needs to extend it.\n */\n/* eslint-disable @typescript-eslint/naming-convention -- event names are domain identifiers that contain colons (e.g. content:after:create) */\nexport interface HookEventPayloads {\n // Content lifecycle — read\n 'content:read': ContentEventPayload\n\n // Content lifecycle — before (gate/transform; handlers may mutate the payload\n // or throw to cancel the write)\n 'content:before:create': ContentEventPayload\n 'content:before:update': ContentEventPayload\n 'content:before:delete': ContentEventPayload\n\n // Content lifecycle — after (side effects; the write has happened)\n 'content:after:create': ContentEventPayload\n 'content:after:update': ContentEventPayload\n 'content:after:delete': ContentEventPayload\n 'content:after:publish': ContentEventPayload\n\n // Auth events\n 'auth:registration:completed': AuthRegistrationCompletedPayload\n 'auth:password-reset:requested': AuthPasswordResetRequestedPayload\n 'auth:password-reset:completed': AuthPasswordResetCompletedPayload\n 'auth:magic-link:consumed': AuthMagicLinkConsumedPayload\n 'auth:otp:verified': AuthOtpVerifiedPayload\n}\n/* eslint-enable @typescript-eslint/naming-convention */\n\n/** Union of all catalog event names. */\nexport type HookEventName = keyof HookEventPayloads\n\n/** The payload type for a given event name. */\nexport type HookPayload<E extends HookEventName> = HookEventPayloads[E]\n\n/**\n * Runtime list of catalog event names.\n *\n * Useful for validation (e.g. \"is this a known event?\") and for diagnostics.\n * Kept as a typed tuple so it can't silently drift from the interface: any new\n * key added to `HookEventPayloads` should be added here too, and the\n * `satisfies` check below fails the build if the list references an unknown\n * event.\n */\nexport const HOOK_EVENT_NAMES = [\n 'content:read',\n 'content:before:create',\n 'content:before:update',\n 'content:before:delete',\n 'content:after:create',\n 'content:after:update',\n 'content:after:delete',\n 'content:after:publish',\n 'auth:registration:completed',\n 'auth:password-reset:requested',\n 'auth:password-reset:completed',\n 'auth:magic-link:consumed',\n 'auth:otp:verified',\n] as const satisfies readonly HookEventName[]\n\n/** True if `name` is a canonical catalog event. */\nexport function isKnownHookEvent(name: string): name is HookEventName {\n return (HOOK_EVENT_NAMES as readonly string[]).includes(name)\n}\n\n// ── Legacy event aliases (one-release deprecation window) ────────────────────\n// The pre-before/after names. Subscribing to one still works but resolves to the\n// canonical name and emits a one-time deprecation warning (see typed-hooks `on`).\n// Dispatch is canonical-only — the host controls dispatch sites.\n\n/** Deprecated event names mapped to their canonical payload type. */\n/* eslint-disable @typescript-eslint/naming-convention -- legacy event identifiers contain colons */\nexport interface LegacyHookEventPayloads {\n 'content:create': ContentEventPayload\n 'content:update': ContentEventPayload\n 'content:delete': ContentEventPayload\n 'content:publish': ContentEventPayload\n /** No after-only successor; folded into update. */\n 'content:save': ContentEventPayload\n}\n\n/** Map each deprecated name to the canonical name it resolves to. */\nexport const LEGACY_EVENT_ALIASES = {\n 'content:create': 'content:after:create',\n 'content:update': 'content:after:update',\n 'content:delete': 'content:after:delete',\n 'content:publish': 'content:after:publish',\n 'content:save': 'content:after:update',\n} as const satisfies Record<keyof LegacyHookEventPayloads, HookEventName>\n/* eslint-enable @typescript-eslint/naming-convention */\n\n/** A deprecated event name accepted (with a warning) at subscribe time. */\nexport type LegacyHookEventName = keyof LegacyHookEventPayloads\n\n/** True if `name` is a deprecated alias. */\nexport function isLegacyHookEvent(name: string): name is LegacyHookEventName {\n return Object.prototype.hasOwnProperty.call(LEGACY_EVENT_ALIASES, name)\n}\n\n/**\n * Resolve a subscribe-time event name to its canonical form: returns the name\n * itself if canonical, the aliased canonical name if deprecated, or `undefined`\n * if unknown.\n */\nexport function resolveHookEventName(name: string): HookEventName | undefined {\n if (isKnownHookEvent(name)) return name\n if (isLegacyHookEvent(name)) return LEGACY_EVENT_ALIASES[name]\n return undefined\n}\n","/**\n * Typed hook facade\n *\n * Wraps the (string-keyed, untyped) hook system in a catalog-aware API:\n *\n * const hooks = createTypedHooks(hookSystem)\n * hooks.on('auth:registration:completed', (payload) => {\n * payload.user.email // ✓ narrowed — no cast\n * payload.user.nope // ✗ type error\n * })\n * await hooks.dispatch('auth:registration:completed', { user: {...} })\n *\n * The facade is intentionally structural about the underlying hook system (see\n * `HookSystemLike`) so both `HookSystemImpl` and `ScopedHookSystem` — and the\n * `src`/`dist` duplicate type identities — all satisfy it without casts.\n */\n\nimport type { HookEventName, HookPayload, LegacyHookEventName, LegacyHookEventPayloads } from './catalog'\nimport { isLegacyHookEvent, resolveHookEventName } from './catalog'\n\n/** A name accepted at subscribe time: a canonical event or a deprecated alias. */\nexport type SubscribableEvent = HookEventName | LegacyHookEventName\n\n/** The payload type for a subscribable name — canonical payload, even for aliases. */\nexport type PayloadForEvent<E extends SubscribableEvent> = E extends HookEventName\n ? HookPayload<E>\n : E extends LegacyHookEventName\n ? LegacyHookEventPayloads[E]\n : never\n\n/**\n * Minimal structural contract the typed facade needs from a hook system.\n * Satisfied by `HookSystemImpl` and `ScopedHookSystem`.\n */\nexport interface HookSystemLike {\n register(hookName: string, handler: (data: any, context: any) => any, priority?: number): void\n execute(hookName: string, data: any, context?: any): Promise<any>\n unregister?(hookName: string, handler: (data: any, context: any) => any): void\n}\n\n/** Context passed to a typed hook handler (kept loose; mirrors the legacy HookContext). */\nexport interface TypedHookContext {\n /** Plugin that registered the hook, if known. */\n plugin?: string\n /** Cancel the remaining hook chain. */\n cancel?: () => void\n [key: string]: unknown\n}\n\n/**\n * A typed hook handler. May mutate and return the payload (threaded to the next\n * handler), or return nothing (the current payload is preserved).\n */\nexport type TypedHookHandler<E extends HookEventName> = (\n payload: HookPayload<E>,\n context: TypedHookContext\n) => HookPayload<E> | void | Promise<HookPayload<E> | void>\n\nexport interface TypedHooks {\n /**\n * Subscribe to a catalog event. Accepts canonical names and (for one release)\n * deprecated aliases — an alias resolves to its canonical name and emits a\n * one-time deprecation warning. Lower priority runs earlier (default 10).\n */\n on<E extends SubscribableEvent>(\n event: E,\n handler: (\n payload: PayloadForEvent<E>,\n context: TypedHookContext\n ) => PayloadForEvent<E> | void | Promise<PayloadForEvent<E> | void>,\n priority?: number\n ): void\n /**\n * Dispatch a catalog event through the handler chain. Canonical names only —\n * the host owns dispatch sites. Returns the (possibly mutated) payload.\n */\n dispatch<E extends HookEventName>(\n event: E,\n payload: HookPayload<E>,\n context?: TypedHookContext\n ): Promise<HookPayload<E>>\n}\n\n// One-time deprecation warnings, keyed by the deprecated name (process-wide).\nconst warnedLegacyEvents = new Set<string>()\n\n/**\n * Build a typed facade over a hook system.\n *\n * `on()` resolves deprecated aliases to canonical names (warning once), then\n * registers under the canonical name so a legacy subscriber fires when the host\n * dispatches the canonical event. Returning `void` from a handler preserves the\n * current payload in the chain (the underlying `execute()` threads whatever each\n * handler returns, so we coalesce `undefined` back to the incoming data).\n */\nexport function createTypedHooks(hookSystem: HookSystemLike): TypedHooks {\n return {\n on(event, handler, priority) {\n const canonical = resolveHookEventName(event) ?? event\n if (isLegacyHookEvent(event) && !warnedLegacyEvents.has(event)) {\n warnedLegacyEvents.add(event)\n // eslint-disable-next-line no-console\n console.warn(\n `[hooks] event \"${event}\" is deprecated; subscribe to \"${canonical}\" instead. ` +\n `The alias will be removed in a future release.`\n )\n }\n hookSystem.register(\n canonical,\n async (data: any, context: any) => {\n const result = await handler(data, context ?? {})\n return result === undefined ? data : result\n },\n priority\n )\n },\n async dispatch(event, payload, context) {\n return (await hookSystem.execute(event, payload, context)) as any\n },\n }\n}\n","/**\n * Hook-system singleton\n *\n * Gives env-independent access to the app's hook system. Code that runs outside\n * the HTTP request context — most importantly scheduled (cron) handlers, which\n * have no per-request `c.env` — needs a way to reach the hook system without\n * threading it through every call. The app sets the singleton eagerly at\n * construction; everything else reads it.\n *\n * Contract: `getHookSystem()` throws if read before the app has set one\n * (throw-before-get), which surfaces wiring-order bugs loudly instead of\n * silently no-oping. `setHookSystem()` is idempotent (last write wins) so that\n * constructing multiple apps in one process — e.g. across tests — does not\n * throw; call `resetHookSystem()` in test teardown for isolation.\n */\n\nimport type { HookSystemLike, TypedHooks } from './typed-hooks'\nimport { createTypedHooks } from './typed-hooks'\n\nlet current: HookSystemLike | undefined\n\n/** Set the process-wide hook system. Last write wins. */\nexport function setHookSystem(hookSystem: HookSystemLike): void {\n current = hookSystem\n}\n\n/**\n * Get the process-wide hook system.\n * @throws if no hook system has been set yet.\n */\nexport function getHookSystem(): HookSystemLike {\n if (!current) {\n throw new Error(\n 'Hook system has not been initialized. ' +\n 'setHookSystem() must be called (the app factory does this at construction) before getHookSystem().'\n )\n }\n return current\n}\n\n/** True if a hook system has been set. */\nexport function hasHookSystem(): boolean {\n return current !== undefined\n}\n\n/** Clear the singleton. Intended for test isolation. */\nexport function resetHookSystem(): void {\n current = undefined\n}\n\n/** Convenience: a typed facade over the current singleton hook system. */\nexport function getTypedHooks(): TypedHooks {\n return createTypedHooks(getHookSystem())\n}\n"]}
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var crypto = require('crypto');
|
|
4
|
+
|
|
5
|
+
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
6
|
+
|
|
7
|
+
var crypto__default = /*#__PURE__*/_interopDefault(crypto);
|
|
8
|
+
|
|
9
|
+
// ../../node_modules/nanoid/index.js
|
|
10
|
+
|
|
11
|
+
// ../../node_modules/nanoid/url-alphabet/index.js
|
|
12
|
+
var urlAlphabet = "useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict";
|
|
13
|
+
|
|
14
|
+
// ../../node_modules/nanoid/index.js
|
|
15
|
+
var POOL_SIZE_MULTIPLIER = 128;
|
|
16
|
+
var pool;
|
|
17
|
+
var poolOffset;
|
|
18
|
+
var fillPool = (bytes) => {
|
|
19
|
+
if (bytes < 0 || bytes > 1024) throw new RangeError("Wrong ID size");
|
|
20
|
+
if (!pool || pool.length < bytes) {
|
|
21
|
+
pool = Buffer.allocUnsafe(bytes * POOL_SIZE_MULTIPLIER);
|
|
22
|
+
crypto__default.default.randomFillSync(pool);
|
|
23
|
+
poolOffset = 0;
|
|
24
|
+
} else if (poolOffset + bytes > pool.length) {
|
|
25
|
+
crypto__default.default.randomFillSync(pool);
|
|
26
|
+
poolOffset = 0;
|
|
27
|
+
}
|
|
28
|
+
poolOffset += bytes;
|
|
29
|
+
};
|
|
30
|
+
var nanoid = (size = 21) => {
|
|
31
|
+
fillPool(size |= 0);
|
|
32
|
+
let id = "";
|
|
33
|
+
for (let i = poolOffset - size; i < poolOffset; i++) {
|
|
34
|
+
id += urlAlphabet[pool[i] & 63];
|
|
35
|
+
}
|
|
36
|
+
return id;
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
// src/services/document-projection.ts
|
|
40
|
+
var MAX_PARAMS = 90;
|
|
41
|
+
function chunkArray(arr, size) {
|
|
42
|
+
const chunks = [];
|
|
43
|
+
for (let i = 0; i < arr.length; i += size) {
|
|
44
|
+
chunks.push(arr.slice(i, i + size));
|
|
45
|
+
}
|
|
46
|
+
return chunks;
|
|
47
|
+
}
|
|
48
|
+
var DocumentProjection = class {
|
|
49
|
+
constructor(db) {
|
|
50
|
+
this.db = db;
|
|
51
|
+
}
|
|
52
|
+
// Build D1 PreparedStatement arrays for inserting facets/references for a document.
|
|
53
|
+
// Returns raw D1 PreparedStatement objects suitable for inclusion in db.batch([...]).
|
|
54
|
+
buildDerivedInsertStatements(doc, queryableFields, now) {
|
|
55
|
+
const statements = [];
|
|
56
|
+
const facets = [];
|
|
57
|
+
const refs = [];
|
|
58
|
+
for (const field of queryableFields) {
|
|
59
|
+
const rawValue = this.extractPath(doc.data, field.path ?? `$.${field.name}`);
|
|
60
|
+
if (field.kind === "facet") {
|
|
61
|
+
const values = Array.isArray(rawValue) ? rawValue : rawValue != null ? [rawValue] : [];
|
|
62
|
+
values.forEach((v, ordinal) => {
|
|
63
|
+
const isNum = typeof v === "number";
|
|
64
|
+
facets.push({
|
|
65
|
+
id: nanoid(),
|
|
66
|
+
tenant_id: doc.tenantId,
|
|
67
|
+
document_id: doc.id,
|
|
68
|
+
root_id: doc.rootId,
|
|
69
|
+
type_id: doc.typeId,
|
|
70
|
+
field_name: field.name,
|
|
71
|
+
ordinal,
|
|
72
|
+
value_text: isNum ? null : String(v),
|
|
73
|
+
value_number: isNum ? v : null,
|
|
74
|
+
now
|
|
75
|
+
});
|
|
76
|
+
});
|
|
77
|
+
} else if (field.kind === "reference") {
|
|
78
|
+
const roots = Array.isArray(rawValue) ? rawValue : rawValue != null ? [rawValue] : [];
|
|
79
|
+
roots.forEach((rootId, ordinal) => {
|
|
80
|
+
refs.push({
|
|
81
|
+
id: nanoid(),
|
|
82
|
+
tenant_id: doc.tenantId,
|
|
83
|
+
from_root_id: doc.rootId,
|
|
84
|
+
from_document_id: doc.id,
|
|
85
|
+
field_name: field.name,
|
|
86
|
+
ordinal,
|
|
87
|
+
to_root_id: String(rootId),
|
|
88
|
+
ref_strength: field.refStrength ?? "weak",
|
|
89
|
+
now
|
|
90
|
+
});
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
const FACET_COLS = 10;
|
|
95
|
+
for (const chunk of chunkArray(facets, Math.floor(MAX_PARAMS / FACET_COLS))) {
|
|
96
|
+
const placeholders = chunk.map(() => "(?,?,?,?,?,?,?,?,?,?)").join(",");
|
|
97
|
+
const params = [];
|
|
98
|
+
for (const f of chunk) {
|
|
99
|
+
params.push(f.id, f.tenant_id, f.document_id, f.root_id, f.type_id, f.field_name, f.ordinal, f.value_text, f.value_number, f.now);
|
|
100
|
+
}
|
|
101
|
+
statements.push(
|
|
102
|
+
this.db.prepare(
|
|
103
|
+
`INSERT INTO document_facets (id, tenant_id, document_id, root_id, type_id, field_name, ordinal, value_text, value_number, created_at) VALUES ${placeholders}`
|
|
104
|
+
).bind(...params)
|
|
105
|
+
);
|
|
106
|
+
}
|
|
107
|
+
const REF_COLS = 9;
|
|
108
|
+
for (const chunk of chunkArray(refs, Math.floor(MAX_PARAMS / REF_COLS))) {
|
|
109
|
+
const placeholders = chunk.map(() => "(?,?,?,?,?,?,?,?,?)").join(",");
|
|
110
|
+
const params = [];
|
|
111
|
+
for (const r of chunk) {
|
|
112
|
+
params.push(r.id, r.tenant_id, r.from_root_id, r.from_document_id, r.field_name, r.ordinal, r.to_root_id, r.ref_strength, r.now);
|
|
113
|
+
}
|
|
114
|
+
statements.push(
|
|
115
|
+
this.db.prepare(
|
|
116
|
+
`INSERT INTO document_references (id, tenant_id, from_root_id, from_document_id, field_name, ordinal, to_root_id, ref_strength, created_at) VALUES ${placeholders}`
|
|
117
|
+
).bind(...params)
|
|
118
|
+
);
|
|
119
|
+
}
|
|
120
|
+
return statements;
|
|
121
|
+
}
|
|
122
|
+
buildDerivedDeleteStatements(documentId) {
|
|
123
|
+
return [
|
|
124
|
+
this.db.prepare("DELETE FROM document_facets WHERE document_id = ?").bind(documentId),
|
|
125
|
+
this.db.prepare("DELETE FROM document_references WHERE from_document_id = ?").bind(documentId)
|
|
126
|
+
];
|
|
127
|
+
}
|
|
128
|
+
// Rebuild derived rows for all current-draft and published rows of a type.
|
|
129
|
+
// One bounded admin action; not chunked cron orchestration.
|
|
130
|
+
async reindexType(typeId, tenantId, queryableFields) {
|
|
131
|
+
const result = await this.db.prepare(
|
|
132
|
+
`SELECT * FROM documents
|
|
133
|
+
WHERE type_id = ? AND tenant_id = ? AND (is_current_draft = 1 OR is_published = 1) AND deleted_at IS NULL`
|
|
134
|
+
).bind(typeId, tenantId).all();
|
|
135
|
+
const rows = result.results ?? [];
|
|
136
|
+
if (rows.length === 0) return 0;
|
|
137
|
+
const now = Math.floor(Date.now() / 1e3);
|
|
138
|
+
let rebuilt = 0;
|
|
139
|
+
for (const chunk of chunkArray(rows, 20)) {
|
|
140
|
+
const statements = [];
|
|
141
|
+
for (const row of chunk) {
|
|
142
|
+
const doc = rowToDocument(row);
|
|
143
|
+
statements.push(...this.buildDerivedDeleteStatements(doc.id));
|
|
144
|
+
statements.push(...this.buildDerivedInsertStatements(doc, queryableFields, now));
|
|
145
|
+
}
|
|
146
|
+
if (statements.length > 0) {
|
|
147
|
+
await this.db.batch(statements);
|
|
148
|
+
rebuilt += chunk.length;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
return rebuilt;
|
|
152
|
+
}
|
|
153
|
+
extractPath(data, path) {
|
|
154
|
+
if (path.startsWith("$.")) {
|
|
155
|
+
const key = path.slice(2);
|
|
156
|
+
return data[key] ?? null;
|
|
157
|
+
}
|
|
158
|
+
return null;
|
|
159
|
+
}
|
|
160
|
+
};
|
|
161
|
+
function rowToDocument(row) {
|
|
162
|
+
return {
|
|
163
|
+
id: row.id,
|
|
164
|
+
rootId: row.root_id,
|
|
165
|
+
typeId: row.type_id,
|
|
166
|
+
typeVersion: row.type_version,
|
|
167
|
+
versionOfId: row.version_of_id,
|
|
168
|
+
versionNumber: row.version_number,
|
|
169
|
+
isCurrentDraft: row.is_current_draft === 1,
|
|
170
|
+
isPublished: row.is_published === 1,
|
|
171
|
+
status: row.status,
|
|
172
|
+
parentRootId: row.parent_root_id,
|
|
173
|
+
slug: row.slug,
|
|
174
|
+
path: row.path,
|
|
175
|
+
title: row.title,
|
|
176
|
+
zone: row.zone,
|
|
177
|
+
sortOrder: row.sort_order,
|
|
178
|
+
visible: row.visible === 1,
|
|
179
|
+
publishedAt: row.published_at,
|
|
180
|
+
scheduledAt: row.scheduled_at,
|
|
181
|
+
expiresAt: row.expires_at,
|
|
182
|
+
deletedAt: row.deleted_at,
|
|
183
|
+
tenantId: row.tenant_id,
|
|
184
|
+
locale: row.locale,
|
|
185
|
+
translationGroupId: row.translation_group_id,
|
|
186
|
+
data: JSON.parse(row.data),
|
|
187
|
+
metadata: JSON.parse(row.metadata),
|
|
188
|
+
ownerId: row.owner_id,
|
|
189
|
+
createdBy: row.created_by,
|
|
190
|
+
updatedBy: row.updated_by,
|
|
191
|
+
createdAt: row.created_at,
|
|
192
|
+
updatedAt: row.updated_at
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
exports.DocumentProjection = DocumentProjection;
|
|
197
|
+
exports.nanoid = nanoid;
|
|
198
|
+
//# sourceMappingURL=chunk-JEQ7FLOD.cjs.map
|
|
199
|
+
//# sourceMappingURL=chunk-JEQ7FLOD.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../node_modules/nanoid/url-alphabet/index.js","../../../node_modules/nanoid/index.js","../src/services/document-projection.ts"],"names":["crypto"],"mappings":"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","file":"chunk-JEQ7FLOD.cjs","sourcesContent":["let urlAlphabet =\n 'useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict'\nexport { urlAlphabet }\n","import crypto from 'crypto'\nimport { urlAlphabet } from './url-alphabet/index.js'\nconst POOL_SIZE_MULTIPLIER = 128\nlet pool, poolOffset\nlet fillPool = bytes => {\n if (bytes < 0 || bytes > 1024) throw new RangeError('Wrong ID size')\n if (!pool || pool.length < bytes) {\n pool = Buffer.allocUnsafe(bytes * POOL_SIZE_MULTIPLIER)\n crypto.randomFillSync(pool)\n poolOffset = 0\n } else if (poolOffset + bytes > pool.length) {\n crypto.randomFillSync(pool)\n poolOffset = 0\n }\n poolOffset += bytes\n}\nlet random = bytes => {\n fillPool((bytes |= 0))\n return pool.subarray(poolOffset - bytes, poolOffset)\n}\nlet customRandom = (alphabet, defaultSize, getRandom) => {\n let mask = (2 << (31 - Math.clz32((alphabet.length - 1) | 1))) - 1\n let step = Math.ceil((1.6 * mask * defaultSize) / alphabet.length)\n return (size = defaultSize) => {\n let id = ''\n while (true) {\n let bytes = getRandom(step)\n let i = step\n while (i--) {\n id += alphabet[bytes[i] & mask] || ''\n if (id.length === size) return id\n }\n }\n }\n}\nlet customAlphabet = (alphabet, size = 21) =>\n customRandom(alphabet, size, random)\nlet nanoid = (size = 21) => {\n fillPool((size |= 0))\n let id = ''\n for (let i = poolOffset - size; i < poolOffset; i++) {\n id += urlAlphabet[pool[i] & 63]\n }\n return id\n}\nexport { nanoid, customAlphabet, customRandom, urlAlphabet, random }\n","import { D1Database } from '@cloudflare/workers-types'\nimport { nanoid } from 'nanoid'\nimport type { Document, QueryableField, DocumentRow } from '../schemas/document'\n\n// D1 hard limit: 100 bound parameters per statement. Keep under 90 for safety.\nconst MAX_PARAMS = 90\n\nfunction chunkArray<T>(arr: T[], size: number): T[][] {\n const chunks: T[][] = []\n for (let i = 0; i < arr.length; i += size) {\n chunks.push(arr.slice(i, i + size))\n }\n return chunks\n}\n\ninterface FacetInsert {\n id: string\n tenant_id: string\n document_id: string\n root_id: string\n type_id: string\n field_name: string\n ordinal: number\n value_text: string | null\n value_number: number | null\n now: number\n}\n\ninterface ReferenceInsert {\n id: string\n tenant_id: string\n from_root_id: string\n from_document_id: string\n field_name: string\n ordinal: number\n to_root_id: string\n ref_strength: string\n now: number\n}\n\nexport class DocumentProjection {\n constructor(private db: D1Database) {}\n\n // Build D1 PreparedStatement arrays for inserting facets/references for a document.\n // Returns raw D1 PreparedStatement objects suitable for inclusion in db.batch([...]).\n buildDerivedInsertStatements(\n doc: Document,\n queryableFields: QueryableField[],\n now: number,\n ): D1PreparedStatement[] {\n const statements: D1PreparedStatement[] = []\n const facets: FacetInsert[] = []\n const refs: ReferenceInsert[] = []\n\n for (const field of queryableFields) {\n const rawValue = this.extractPath(doc.data, field.path ?? `$.${field.name}`)\n\n if (field.kind === 'facet') {\n const values = Array.isArray(rawValue) ? rawValue : rawValue != null ? [rawValue] : []\n values.forEach((v, ordinal) => {\n const isNum = typeof v === 'number'\n facets.push({\n id: nanoid(),\n tenant_id: doc.tenantId,\n document_id: doc.id,\n root_id: doc.rootId,\n type_id: doc.typeId,\n field_name: field.name,\n ordinal,\n value_text: isNum ? null : String(v),\n value_number: isNum ? v : null,\n now,\n })\n })\n } else if (field.kind === 'reference') {\n const roots = Array.isArray(rawValue) ? rawValue : rawValue != null ? [rawValue] : []\n roots.forEach((rootId, ordinal) => {\n refs.push({\n id: nanoid(),\n tenant_id: doc.tenantId,\n from_root_id: doc.rootId,\n from_document_id: doc.id,\n field_name: field.name,\n ordinal,\n to_root_id: String(rootId),\n ref_strength: field.refStrength ?? 'weak',\n now,\n })\n })\n }\n // 'scalar' fields are VIRTUAL generated columns; no derived rows needed.\n }\n\n // Insert facets in chunks to respect the 100-param D1 limit (9 params per row).\n const FACET_COLS = 10\n for (const chunk of chunkArray(facets, Math.floor(MAX_PARAMS / FACET_COLS))) {\n const placeholders = chunk.map(() => '(?,?,?,?,?,?,?,?,?,?)').join(',')\n const params: (string | number | null)[] = []\n for (const f of chunk) {\n params.push(f.id, f.tenant_id, f.document_id, f.root_id, f.type_id, f.field_name, f.ordinal, f.value_text, f.value_number, f.now)\n }\n statements.push(\n this.db.prepare(\n `INSERT INTO document_facets (id, tenant_id, document_id, root_id, type_id, field_name, ordinal, value_text, value_number, created_at) VALUES ${placeholders}`,\n ).bind(...params),\n )\n }\n\n // Insert references in chunks (9 params per row).\n const REF_COLS = 9\n for (const chunk of chunkArray(refs, Math.floor(MAX_PARAMS / REF_COLS))) {\n const placeholders = chunk.map(() => '(?,?,?,?,?,?,?,?,?)').join(',')\n const params: (string | number | null)[] = []\n for (const r of chunk) {\n params.push(r.id, r.tenant_id, r.from_root_id, r.from_document_id, r.field_name, r.ordinal, r.to_root_id, r.ref_strength, r.now)\n }\n statements.push(\n this.db.prepare(\n `INSERT INTO document_references (id, tenant_id, from_root_id, from_document_id, field_name, ordinal, to_root_id, ref_strength, created_at) VALUES ${placeholders}`,\n ).bind(...params),\n )\n }\n\n return statements\n }\n\n buildDerivedDeleteStatements(documentId: string): D1PreparedStatement[] {\n return [\n this.db.prepare('DELETE FROM document_facets WHERE document_id = ?').bind(documentId),\n this.db.prepare('DELETE FROM document_references WHERE from_document_id = ?').bind(documentId),\n ]\n }\n\n // Rebuild derived rows for all current-draft and published rows of a type.\n // One bounded admin action; not chunked cron orchestration.\n async reindexType(typeId: string, tenantId: string, queryableFields: QueryableField[]): Promise<number> {\n // Only reindex rows that participate in queries (current-draft or published).\n const result = await this.db\n .prepare(\n `SELECT * FROM documents\n WHERE type_id = ? AND tenant_id = ? AND (is_current_draft = 1 OR is_published = 1) AND deleted_at IS NULL`,\n )\n .bind(typeId, tenantId)\n .all<DocumentRow>()\n\n const rows = result.results ?? []\n if (rows.length === 0) return 0\n\n const now = Math.floor(Date.now() / 1000)\n let rebuilt = 0\n\n // Process in batches of 20 documents to stay well under D1's 1000-rows-per-batch guidance.\n for (const chunk of chunkArray(rows, 20)) {\n const statements: D1PreparedStatement[] = []\n\n for (const row of chunk) {\n const doc = rowToDocument(row)\n statements.push(...this.buildDerivedDeleteStatements(doc.id))\n statements.push(...this.buildDerivedInsertStatements(doc, queryableFields, now))\n }\n\n if (statements.length > 0) {\n await this.db.batch(statements)\n rebuilt += chunk.length\n }\n }\n\n return rebuilt\n }\n\n private extractPath(data: Record<string, unknown>, path: string): unknown {\n // Supports simple $.<key> paths only; full JSONPath is overkill for the POC.\n if (path.startsWith('$.')) {\n const key = path.slice(2)\n return data[key] ?? null\n }\n return null\n }\n}\n\nfunction rowToDocument(row: DocumentRow): Document {\n return {\n id: row.id,\n rootId: row.root_id,\n typeId: row.type_id,\n typeVersion: row.type_version,\n versionOfId: row.version_of_id,\n versionNumber: row.version_number,\n isCurrentDraft: row.is_current_draft === 1,\n isPublished: row.is_published === 1,\n status: row.status,\n parentRootId: row.parent_root_id,\n slug: row.slug,\n path: row.path,\n title: row.title,\n zone: row.zone,\n sortOrder: row.sort_order,\n visible: row.visible === 1,\n publishedAt: row.published_at,\n scheduledAt: row.scheduled_at,\n expiresAt: row.expires_at,\n deletedAt: row.deleted_at,\n tenantId: row.tenant_id,\n locale: row.locale,\n translationGroupId: row.translation_group_id,\n data: JSON.parse(row.data),\n metadata: JSON.parse(row.metadata),\n ownerId: row.owner_id,\n createdBy: row.created_by,\n updatedBy: row.updated_by,\n createdAt: row.created_at,\n updatedAt: row.updated_at,\n }\n}\n"]}
|