@omega.js/backend 0.1.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 (993) hide show
  1. package/LICENSE +98 -0
  2. package/README.md +1053 -0
  3. package/bin/omega +2 -0
  4. package/bin/omega-backend +2 -0
  5. package/bin/omg +2 -0
  6. package/cli.js +3 -0
  7. package/dist/cli/command-table.js +268 -0
  8. package/dist/cli/commands/auth.js +259 -0
  9. package/dist/cli/commands/base-command.js +451 -0
  10. package/dist/cli/commands/build.js +27 -0
  11. package/dist/cli/commands/clean.js +13 -0
  12. package/dist/cli/commands/clear.js +11 -0
  13. package/dist/cli/commands/cwd.js +9 -0
  14. package/dist/cli/commands/deploy.js +205 -0
  15. package/dist/cli/commands/emulator-orphans.js +440 -0
  16. package/dist/cli/commands/emulator.js +1829 -0
  17. package/dist/cli/commands/firebase-init.js +101 -0
  18. package/dist/cli/commands/firestore.js +261 -0
  19. package/dist/cli/commands/indexes.js +51 -0
  20. package/dist/cli/commands/install.js +151 -0
  21. package/dist/cli/commands/logs.js +358 -0
  22. package/dist/cli/commands/mcp.js +41 -0
  23. package/dist/cli/commands/migrate-markers.js +176 -0
  24. package/dist/cli/commands/migrate-rules.js +90 -0
  25. package/dist/cli/commands/migrate.js +59 -0
  26. package/dist/cli/commands/serve.js +208 -0
  27. package/dist/cli/commands/setup-tests/base-test.js +174 -0
  28. package/dist/cli/commands/setup-tests/emulator-config.js +109 -0
  29. package/dist/cli/commands/setup-tests/env-runtime-config-deprecated.js +47 -0
  30. package/dist/cli/commands/setup-tests/firebase-admin.js +49 -0
  31. package/dist/cli/commands/setup-tests/firebase-auth.js +26 -0
  32. package/dist/cli/commands/setup-tests/firebase-cli.js +26 -0
  33. package/dist/cli/commands/setup-tests/firebase-functions.js +49 -0
  34. package/dist/cli/commands/setup-tests/firestore-indexes-file.js +72 -0
  35. package/dist/cli/commands/setup-tests/firestore-indexes-in-json.js +20 -0
  36. package/dist/cli/commands/setup-tests/firestore-indexes-required.js +108 -0
  37. package/dist/cli/commands/setup-tests/firestore-indexes-synced.js +236 -0
  38. package/dist/cli/commands/setup-tests/firestore-rules-file.js +115 -0
  39. package/dist/cli/commands/setup-tests/firestore-rules-in-json.js +49 -0
  40. package/dist/cli/commands/setup-tests/functions-package.js +44 -0
  41. package/dist/cli/commands/setup-tests/gcloud-cli.js +26 -0
  42. package/dist/cli/commands/setup-tests/gitignore.js +122 -0
  43. package/dist/cli/commands/setup-tests/helpers/merge-line-files.js +28 -0
  44. package/dist/cli/commands/setup-tests/helpers/required-indexes.js +109 -0
  45. package/dist/cli/commands/setup-tests/helpers/seed-campaigns.js +246 -0
  46. package/dist/cli/commands/setup-tests/helpers.js +72 -0
  47. package/dist/cli/commands/setup-tests/hosting-folder.js +23 -0
  48. package/dist/cli/commands/setup-tests/hosting-rewrites.js +52 -0
  49. package/dist/cli/commands/setup-tests/index.js +111 -0
  50. package/dist/cli/commands/setup-tests/is-firebase-project.js +21 -0
  51. package/dist/cli/commands/setup-tests/java-installed.js +27 -0
  52. package/dist/cli/commands/setup-tests/legacy-tests-cleanup.js +43 -0
  53. package/dist/cli/commands/setup-tests/marketing-campaigns-seeded.js +230 -0
  54. package/dist/cli/commands/setup-tests/node-version.js +60 -0
  55. package/dist/cli/commands/setup-tests/npm-project-scripts.js +42 -0
  56. package/dist/cli/commands/setup-tests/nvmrc-version.js +36 -0
  57. package/dist/cli/commands/setup-tests/omega-backend.js +42 -0
  58. package/dist/cli/commands/setup-tests/omega-config.js +84 -0
  59. package/dist/cli/commands/setup-tests/project-directories.js +34 -0
  60. package/dist/cli/commands/setup-tests/project-id-consistency.js +201 -0
  61. package/dist/cli/commands/setup-tests/public-html-files.js +22 -0
  62. package/dist/cli/commands/setup-tests/realtime-rules-file.js +69 -0
  63. package/dist/cli/commands/setup-tests/realtime-rules-in-json.js +20 -0
  64. package/dist/cli/commands/setup-tests/remoteconfig-template-file.js +32 -0
  65. package/dist/cli/commands/setup-tests/remoteconfig-template-in-json.js +31 -0
  66. package/dist/cli/commands/setup-tests/service-account.js +86 -0
  67. package/dist/cli/commands/setup-tests/storage-lifecycle-policy.js +81 -0
  68. package/dist/cli/commands/setup-tests/storage-rules-file.js +32 -0
  69. package/dist/cli/commands/setup-tests/storage-rules-in-json.js +20 -0
  70. package/dist/cli/commands/stripe.js +14 -0
  71. package/dist/cli/commands/test-lanes/stripe-live.js +440 -0
  72. package/dist/cli/commands/test.js +976 -0
  73. package/dist/cli/commands/update.js +27 -0
  74. package/dist/cli/commands/version.js +10 -0
  75. package/dist/cli/commands/watch.js +196 -0
  76. package/dist/cli/flags.js +13 -0
  77. package/dist/cli/index.js +173 -0
  78. package/dist/cli/run.js +33 -0
  79. package/dist/cli/utils/attach-log-file.js +4 -0
  80. package/dist/cli/utils/compile-rules.js +1155 -0
  81. package/dist/cli/utils/ensure-target.js +314 -0
  82. package/dist/cli/utils/project-type.js +140 -0
  83. package/dist/cli/utils/public-files.js +49 -0
  84. package/dist/cli/utils/safe-install.js +4 -0
  85. package/dist/cli/utils/spawn-shell.js +94 -0
  86. package/dist/cli/utils/stage-functions.js +338 -0
  87. package/dist/cli/utils/stage-local-packages.js +210 -0
  88. package/dist/cli/utils/target-checks.js +161 -0
  89. package/dist/cli/utils/target.js +24 -0
  90. package/dist/cli/utils/ui.js +292 -0
  91. package/dist/defaults/AGENTS.md +125 -0
  92. package/dist/defaults/CHANGELOG.md +15 -0
  93. package/dist/defaults/CLAUDE.md +1 -0
  94. package/dist/defaults/_.gitignore +65 -0
  95. package/dist/defaults/docs/README.md +17 -0
  96. package/dist/defaults/test/README.md +65 -0
  97. package/dist/defaults/test/_init.js +14 -0
  98. package/dist/defaults/test/helpers/connect-trap.js +72 -0
  99. package/dist/defaults/test/unit/registration.test.js +143 -0
  100. package/dist/defaults/test/unit/rules-posture.test.js +101 -0
  101. package/dist/defaults/test/unit/socket-free.test.js +43 -0
  102. package/dist/manager/events/auth/before-create.js +89 -0
  103. package/dist/manager/events/auth/before-signin.js +76 -0
  104. package/dist/manager/events/auth/on-create.js +112 -0
  105. package/dist/manager/events/auth/on-delete.js +141 -0
  106. package/dist/manager/events/auth/utils.js +93 -0
  107. package/dist/manager/events/cron/daily/blog-auto-publisher.js +287 -0
  108. package/dist/manager/events/cron/daily/data-requests.js +57 -0
  109. package/dist/manager/events/cron/daily/expire-paypal-cancellations.js +191 -0
  110. package/dist/manager/events/cron/daily/marketing-prune.js +486 -0
  111. package/dist/manager/events/cron/daily/reset-usage.js +188 -0
  112. package/dist/manager/events/cron/daily/trial-lapse-sweep.js +355 -0
  113. package/dist/manager/events/cron/daily.js +3 -0
  114. package/dist/manager/events/cron/frequent/abandoned-carts.js +204 -0
  115. package/dist/manager/events/cron/frequent/email-queue.js +71 -0
  116. package/dist/manager/events/cron/frequent/marketing-campaigns.js +463 -0
  117. package/dist/manager/events/cron/frequent/retry-failed-webhooks.js +70 -0
  118. package/dist/manager/events/cron/frequent.js +3 -0
  119. package/dist/manager/events/cron/runner.js +64 -0
  120. package/dist/manager/events/firestore/notifications/on-write.js +123 -0
  121. package/dist/manager/events/firestore/payments-disputes/on-write.js +256 -0
  122. package/dist/manager/events/firestore/payments-disputes/providers/stripe.js +218 -0
  123. package/dist/manager/events/firestore/payments-disputes/providers/test.js +231 -0
  124. package/dist/manager/events/firestore/payments-webhooks/analytics.js +687 -0
  125. package/dist/manager/events/firestore/payments-webhooks/on-write.js +1224 -0
  126. package/dist/manager/events/firestore/payments-webhooks/transitions/index.js +395 -0
  127. package/dist/manager/events/firestore/payments-webhooks/transitions/one-time/purchase-completed.js +58 -0
  128. package/dist/manager/events/firestore/payments-webhooks/transitions/one-time/purchase-failed.js +28 -0
  129. package/dist/manager/events/firestore/payments-webhooks/transitions/one-time/purchase-refunded.js +30 -0
  130. package/dist/manager/events/firestore/payments-webhooks/transitions/send-email.js +74 -0
  131. package/dist/manager/events/firestore/payments-webhooks/transitions/subscription/cancellation-removed.js +14 -0
  132. package/dist/manager/events/firestore/payments-webhooks/transitions/subscription/cancellation-requested.js +28 -0
  133. package/dist/manager/events/firestore/payments-webhooks/transitions/subscription/checkout-declined.js +18 -0
  134. package/dist/manager/events/firestore/payments-webhooks/transitions/subscription/new-subscription.js +67 -0
  135. package/dist/manager/events/firestore/payments-webhooks/transitions/subscription/payment-failed.js +25 -0
  136. package/dist/manager/events/firestore/payments-webhooks/transitions/subscription/payment-recovered.js +26 -0
  137. package/dist/manager/events/firestore/payments-webhooks/transitions/subscription/payment-refunded.js +34 -0
  138. package/dist/manager/events/firestore/payments-webhooks/transitions/subscription/plan-changed.js +42 -0
  139. package/dist/manager/events/firestore/payments-webhooks/transitions/subscription/subscription-cancelled.js +33 -0
  140. package/dist/manager/events/firestore/payments-webhooks/transitions/subscription/subscription-winback.js +17 -0
  141. package/dist/manager/functions/_legacy/actions/create-post-handler.js +188 -0
  142. package/dist/manager/functions/_legacy/actions/generate-uuid.js +63 -0
  143. package/dist/manager/functions/_legacy/actions/sign-up-handler.js +205 -0
  144. package/dist/manager/functions/_legacy/admin/create-post.js +207 -0
  145. package/dist/manager/functions/_legacy/admin/firestore-write.js +72 -0
  146. package/dist/manager/functions/_legacy/admin/get-stats.js +218 -0
  147. package/dist/manager/functions/_legacy/admin/query.js +198 -0
  148. package/dist/manager/functions/_legacy/admin/send-notification.js +206 -0
  149. package/dist/manager/functions/_legacy/template.js +33 -0
  150. package/dist/manager/functions/_legacy/test/authenticate.js +40 -0
  151. package/dist/manager/functions/_legacy/test/webhook.js +37 -0
  152. package/dist/manager/functions/wrappers/mailchimp/addToList.js +25 -0
  153. package/dist/manager/helpers/analytics.js +498 -0
  154. package/dist/manager/helpers/api-manager.js +313 -0
  155. package/dist/manager/helpers/backend-router.js +37 -0
  156. package/dist/manager/helpers/context/authenticate.js +215 -0
  157. package/dist/manager/helpers/context/client-info.js +91 -0
  158. package/dist/manager/helpers/context/index.js +228 -0
  159. package/dist/manager/helpers/context/logging.js +150 -0
  160. package/dist/manager/helpers/context/parse.js +160 -0
  161. package/dist/manager/helpers/context/respond.js +247 -0
  162. package/dist/manager/helpers/event-middleware.js +109 -0
  163. package/dist/manager/helpers/metadata.js +32 -0
  164. package/dist/manager/helpers/middleware.js +541 -0
  165. package/dist/manager/helpers/redact-secret.js +25 -0
  166. package/dist/manager/helpers/resolved-config.js +34 -0
  167. package/dist/manager/helpers/roles.js +69 -0
  168. package/dist/manager/helpers/safe-compare.js +31 -0
  169. package/dist/manager/helpers/schema-engine.js +314 -0
  170. package/dist/manager/helpers/schema-zod.js +203 -0
  171. package/dist/manager/helpers/settings.js +215 -0
  172. package/dist/manager/helpers/usage.js +541 -0
  173. package/dist/manager/helpers/user.js +57 -0
  174. package/dist/manager/helpers/utilities.js +565 -0
  175. package/dist/manager/index.js +1404 -0
  176. package/dist/manager/libraries/abandoned-cart-config.js +12 -0
  177. package/dist/manager/libraries/ai/index.js +321 -0
  178. package/dist/manager/libraries/ai/prompt.js +85 -0
  179. package/dist/manager/libraries/ai/providers/anthropic-format.js +297 -0
  180. package/dist/manager/libraries/ai/providers/anthropic.js +169 -0
  181. package/dist/manager/libraries/ai/providers/claude-code.js +183 -0
  182. package/dist/manager/libraries/ai/providers/openai.js +1272 -0
  183. package/dist/manager/libraries/ai/providers/test.js +257 -0
  184. package/dist/manager/libraries/ai/tokens.js +54 -0
  185. package/dist/manager/libraries/analytics/conversions.js +478 -0
  186. package/dist/manager/libraries/analytics/match-data.js +573 -0
  187. package/dist/manager/libraries/analytics/signup.js +120 -0
  188. package/dist/manager/libraries/auth-user.js +46 -0
  189. package/dist/manager/libraries/content/feed-parser.js +198 -0
  190. package/dist/manager/libraries/content/ghostii.js +191 -0
  191. package/dist/manager/libraries/content/source-resolver.js +629 -0
  192. package/dist/manager/libraries/email/constants.js +532 -0
  193. package/dist/manager/libraries/email/data/blocked-local-parts.json +55 -0
  194. package/dist/manager/libraries/email/data/blocked-local-patterns.js +14 -0
  195. package/dist/manager/libraries/email/data/corporate-domains.json +23 -0
  196. package/dist/manager/libraries/email/data/custom-disposable-domains.json +58 -0
  197. package/dist/manager/libraries/email/data/disposable-domains.json +8184 -0
  198. package/dist/manager/libraries/email/data/typo-domains.js +83 -0
  199. package/dist/manager/libraries/email/disposable-domains.js +92 -0
  200. package/dist/manager/libraries/email/generators/lib/filter.js +179 -0
  201. package/dist/manager/libraries/email/generators/lib/image-host.js +344 -0
  202. package/dist/manager/libraries/email/generators/lib/image-illustrator.js +154 -0
  203. package/dist/manager/libraries/email/generators/lib/markdown-renderer.js +294 -0
  204. package/dist/manager/libraries/email/generators/lib/mjml-template.js +120 -0
  205. package/dist/manager/libraries/email/generators/lib/structure.js +299 -0
  206. package/dist/manager/libraries/email/generators/lib/svg-illustrator.js +197 -0
  207. package/dist/manager/libraries/email/generators/lib/templates/base.js +229 -0
  208. package/dist/manager/libraries/email/generators/lib/templates/card.js +33 -0
  209. package/dist/manager/libraries/email/generators/lib/templates/classic-schema.js +59 -0
  210. package/dist/manager/libraries/email/generators/lib/templates/clean.js +82 -0
  211. package/dist/manager/libraries/email/generators/lib/templates/editorial/helpers.js +100 -0
  212. package/dist/manager/libraries/email/generators/lib/templates/editorial/index.js +318 -0
  213. package/dist/manager/libraries/email/generators/lib/templates/feedback.js +101 -0
  214. package/dist/manager/libraries/email/generators/lib/templates/field-report/helpers.js +138 -0
  215. package/dist/manager/libraries/email/generators/lib/templates/field-report/index.js +494 -0
  216. package/dist/manager/libraries/email/generators/lib/templates/index.js +47 -0
  217. package/dist/manager/libraries/email/generators/lib/templates/newsletter-shared.js +610 -0
  218. package/dist/manager/libraries/email/generators/lib/templates/order.js +461 -0
  219. package/dist/manager/libraries/email/generators/lib/templates/plain.js +83 -0
  220. package/dist/manager/libraries/email/generators/lib/templates/shared-campaign.js +64 -0
  221. package/dist/manager/libraries/email/generators/newsletter.js +899 -0
  222. package/dist/manager/libraries/email/index.js +146 -0
  223. package/dist/manager/libraries/email/marketing/index.js +754 -0
  224. package/dist/manager/libraries/email/prepare.js +365 -0
  225. package/dist/manager/libraries/email/providers/beehiiv.js +589 -0
  226. package/dist/manager/libraries/email/providers/sendgrid.js +845 -0
  227. package/dist/manager/libraries/email/transactional/index.js +510 -0
  228. package/dist/manager/libraries/email/utm.js +86 -0
  229. package/dist/manager/libraries/email/validation-provider-neverbounce.js +70 -0
  230. package/dist/manager/libraries/email/validation-provider-zerobounce.js +42 -0
  231. package/dist/manager/libraries/email/validation.js +255 -0
  232. package/dist/manager/libraries/env.js +198 -0
  233. package/dist/manager/libraries/infer-contact.js +101 -0
  234. package/dist/manager/libraries/load-provider.js +65 -0
  235. package/dist/manager/libraries/notification.js +256 -0
  236. package/dist/manager/libraries/openai.js +13 -0
  237. package/dist/manager/libraries/payment/discount-codes.js +204 -0
  238. package/dist/manager/libraries/payment/fetch-failure.js +56 -0
  239. package/dist/manager/libraries/payment/license.js +44 -0
  240. package/dist/manager/libraries/payment/order-id.js +57 -0
  241. package/dist/manager/libraries/payment/provider-errors.js +71 -0
  242. package/dist/manager/libraries/payment/providers/chargebee.js +817 -0
  243. package/dist/manager/libraries/payment/providers/coinbase.js +330 -0
  244. package/dist/manager/libraries/payment/providers/paypal.js +987 -0
  245. package/dist/manager/libraries/payment/providers/stripe.js +755 -0
  246. package/dist/manager/libraries/payment/providers/test.js +250 -0
  247. package/dist/manager/libraries/payment/refund-linkage.js +78 -0
  248. package/dist/manager/libraries/payment/refund-policy.js +113 -0
  249. package/dist/manager/libraries/payment/winback.js +55 -0
  250. package/dist/manager/libraries/prompts/infer-contact.md +78 -0
  251. package/dist/manager/libraries/rate-limits.js +17 -0
  252. package/dist/manager/libraries/recaptcha.js +58 -0
  253. package/dist/manager/libraries/user-doc.js +234 -0
  254. package/dist/manager/routes/admin/backup/post.js +106 -0
  255. package/dist/manager/routes/admin/cron/post.js +37 -0
  256. package/dist/manager/routes/admin/database/get.js +35 -0
  257. package/dist/manager/routes/admin/database/post.js +34 -0
  258. package/dist/manager/routes/admin/email/post.js +74 -0
  259. package/dist/manager/routes/admin/firestore/get.js +35 -0
  260. package/dist/manager/routes/admin/firestore/post.js +56 -0
  261. package/dist/manager/routes/admin/firestore/query/post.js +128 -0
  262. package/dist/manager/routes/admin/hook/post.js +104 -0
  263. package/dist/manager/routes/admin/infer-contact/post.js +35 -0
  264. package/dist/manager/routes/admin/notification/post.js +37 -0
  265. package/dist/manager/routes/admin/payment/post.js +56 -0
  266. package/dist/manager/routes/admin/post/deduplicate-image-alts.js +52 -0
  267. package/dist/manager/routes/admin/post/dispatch-deploy.js +36 -0
  268. package/dist/manager/routes/admin/post/post.js +487 -0
  269. package/dist/manager/routes/admin/post/put.js +146 -0
  270. package/dist/manager/routes/admin/post/templates/post.html +14 -0
  271. package/dist/manager/routes/admin/repo/content/post.js +106 -0
  272. package/dist/manager/routes/admin/stats/get.js +222 -0
  273. package/dist/manager/routes/admin/users/disable/post.js +50 -0
  274. package/dist/manager/routes/admin/users/list/get.js +110 -0
  275. package/dist/manager/routes/admin/users/sync/post.js +119 -0
  276. package/dist/manager/routes/brand/get.js +26 -0
  277. package/dist/manager/routes/content/post/get.js +110 -0
  278. package/dist/manager/routes/general/email/post.js +89 -0
  279. package/dist/manager/routes/general/email/templates/general/download-app-link.js +42 -0
  280. package/dist/manager/routes/general/uuid/post.js +31 -0
  281. package/dist/manager/routes/handler/post/post.js +142 -0
  282. package/dist/manager/routes/health/get.js +43 -0
  283. package/dist/manager/routes/index.js +11 -0
  284. package/dist/manager/routes/marketing/campaign/delete.js +45 -0
  285. package/dist/manager/routes/marketing/campaign/get.js +69 -0
  286. package/dist/manager/routes/marketing/campaign/post.js +124 -0
  287. package/dist/manager/routes/marketing/campaign/put.js +86 -0
  288. package/dist/manager/routes/marketing/campaign/utils.js +59 -0
  289. package/dist/manager/routes/marketing/contact/delete.js +100 -0
  290. package/dist/manager/routes/marketing/contact/post.js +149 -0
  291. package/dist/manager/routes/marketing/contact/put.js +37 -0
  292. package/dist/manager/routes/marketing/email-preferences/post.js +275 -0
  293. package/dist/manager/routes/marketing/webhook/forward/post.js +170 -0
  294. package/dist/manager/routes/marketing/webhook/post.js +123 -0
  295. package/dist/manager/routes/marketing/webhook/providers/beehiiv.js +197 -0
  296. package/dist/manager/routes/marketing/webhook/providers/sendgrid.js +194 -0
  297. package/dist/manager/routes/payments/cancel/_is-trialing.js +40 -0
  298. package/dist/manager/routes/payments/cancel/post.js +149 -0
  299. package/dist/manager/routes/payments/cancel/providers/chargebee.js +41 -0
  300. package/dist/manager/routes/payments/cancel/providers/paypal.js +56 -0
  301. package/dist/manager/routes/payments/cancel/providers/stripe.js +33 -0
  302. package/dist/manager/routes/payments/cancel/providers/test.js +118 -0
  303. package/dist/manager/routes/payments/discount/get.js +25 -0
  304. package/dist/manager/routes/payments/dispute-alert/post.js +117 -0
  305. package/dist/manager/routes/payments/dispute-alert/providers/chargeblast.js +55 -0
  306. package/dist/manager/routes/payments/intent/post.js +341 -0
  307. package/dist/manager/routes/payments/intent/providers/chargebee.js +197 -0
  308. package/dist/manager/routes/payments/intent/providers/coinbase.js +94 -0
  309. package/dist/manager/routes/payments/intent/providers/paypal.js +244 -0
  310. package/dist/manager/routes/payments/intent/providers/stripe.js +141 -0
  311. package/dist/manager/routes/payments/intent/providers/test.js +341 -0
  312. package/dist/manager/routes/payments/plan/post.js +147 -0
  313. package/dist/manager/routes/payments/plan/providers/chargebee.js +62 -0
  314. package/dist/manager/routes/payments/plan/providers/paypal.js +62 -0
  315. package/dist/manager/routes/payments/plan/providers/stripe.js +59 -0
  316. package/dist/manager/routes/payments/plan/providers/test.js +113 -0
  317. package/dist/manager/routes/payments/portal/post.js +113 -0
  318. package/dist/manager/routes/payments/portal/providers/chargebee.js +62 -0
  319. package/dist/manager/routes/payments/portal/providers/paypal.js +25 -0
  320. package/dist/manager/routes/payments/portal/providers/stripe.js +62 -0
  321. package/dist/manager/routes/payments/portal/providers/test.js +18 -0
  322. package/dist/manager/routes/payments/refund/post.js +207 -0
  323. package/dist/manager/routes/payments/refund/providers/chargebee.js +147 -0
  324. package/dist/manager/routes/payments/refund/providers/coinbase.js +40 -0
  325. package/dist/manager/routes/payments/refund/providers/paypal.js +239 -0
  326. package/dist/manager/routes/payments/refund/providers/stripe.js +160 -0
  327. package/dist/manager/routes/payments/refund/providers/test.js +204 -0
  328. package/dist/manager/routes/payments/trial-eligibility/get.js +29 -0
  329. package/dist/manager/routes/payments/uncancel/post.js +106 -0
  330. package/dist/manager/routes/payments/uncancel/providers/chargebee.js +30 -0
  331. package/dist/manager/routes/payments/uncancel/providers/paypal.js +25 -0
  332. package/dist/manager/routes/payments/uncancel/providers/stripe.js +27 -0
  333. package/dist/manager/routes/payments/uncancel/providers/test.js +114 -0
  334. package/dist/manager/routes/payments/webhook/post.js +157 -0
  335. package/dist/manager/routes/payments/webhook/providers/chargebee.js +218 -0
  336. package/dist/manager/routes/payments/webhook/providers/coinbase.js +91 -0
  337. package/dist/manager/routes/payments/webhook/providers/paypal.js +214 -0
  338. package/dist/manager/routes/payments/webhook/providers/stripe.js +182 -0
  339. package/dist/manager/routes/payments/webhook/providers/test.js +18 -0
  340. package/dist/manager/routes/payments/winback/post.js +276 -0
  341. package/dist/manager/routes/payments/winback/providers/chargebee.js +24 -0
  342. package/dist/manager/routes/payments/winback/providers/paypal.js +22 -0
  343. package/dist/manager/routes/payments/winback/providers/stripe.js +41 -0
  344. package/dist/manager/routes/payments/winback/providers/test.js +42 -0
  345. package/dist/manager/routes/restart/index.js +37 -0
  346. package/dist/manager/routes/special/electron-client/post.js +59 -0
  347. package/dist/manager/routes/test/authenticate/get.js +11 -0
  348. package/dist/manager/routes/test/health/get.js +8 -0
  349. package/dist/manager/routes/test/index.js +16 -0
  350. package/dist/manager/routes/test/lab/post.js +17 -0
  351. package/dist/manager/routes/test/redirect/get.js +27 -0
  352. package/dist/manager/routes/test/reset-account/post.js +79 -0
  353. package/dist/manager/routes/test/roster/get.js +40 -0
  354. package/dist/manager/routes/test/schema/post.js +20 -0
  355. package/dist/manager/routes/test/usage/post.js +44 -0
  356. package/dist/manager/routes/test/webhook/post.js +21 -0
  357. package/dist/manager/routes/user/api-keys/post.js +51 -0
  358. package/dist/manager/routes/user/connections/_context.js +194 -0
  359. package/dist/manager/routes/user/connections/_grant.js +247 -0
  360. package/dist/manager/routes/user/connections/_lease.js +184 -0
  361. package/dist/manager/routes/user/connections/_providers.js +191 -0
  362. package/dist/manager/routes/user/connections/_state.js +117 -0
  363. package/dist/manager/routes/user/connections/delete.js +55 -0
  364. package/dist/manager/routes/user/connections/get.js +167 -0
  365. package/dist/manager/routes/user/connections/post.js +370 -0
  366. package/dist/manager/routes/user/connections/providers/discord.js +41 -0
  367. package/dist/manager/routes/user/connections/providers/google.js +55 -0
  368. package/dist/manager/routes/user/connections/providers/kick.js +68 -0
  369. package/dist/manager/routes/user/connections/providers/spotify.js +40 -0
  370. package/dist/manager/routes/user/connections/providers/twitch.js +52 -0
  371. package/dist/manager/routes/user/data-request/delete.js +84 -0
  372. package/dist/manager/routes/user/data-request/get.js +229 -0
  373. package/dist/manager/routes/user/data-request/post.js +136 -0
  374. package/dist/manager/routes/user/delete.js +149 -0
  375. package/dist/manager/routes/user/feedback/post.js +81 -0
  376. package/dist/manager/routes/user/get.js +14 -0
  377. package/dist/manager/routes/user/orders/get.js +95 -0
  378. package/dist/manager/routes/user/sessions/delete.js +95 -0
  379. package/dist/manager/routes/user/sessions/get.js +40 -0
  380. package/dist/manager/routes/user/settings/validate/post.js +86 -0
  381. package/dist/manager/routes/user/signup/post.js +662 -0
  382. package/dist/manager/routes/user/subscription/get.js +77 -0
  383. package/dist/manager/routes/user/token/post.js +30 -0
  384. package/dist/manager/routes/verts/delete.js +43 -0
  385. package/dist/manager/routes/verts/get.js +49 -0
  386. package/dist/manager/routes/verts/post.js +61 -0
  387. package/dist/manager/routes/verts/put.js +75 -0
  388. package/dist/manager/routes/verts/redirect/get.js +36 -0
  389. package/dist/manager/routes/verts/serve/get.js +67 -0
  390. package/dist/manager/routes/verts/utils.js +436 -0
  391. package/dist/manager/schemas/admin/backup/post.js +8 -0
  392. package/dist/manager/schemas/admin/cron/post.js +8 -0
  393. package/dist/manager/schemas/admin/database/get.js +5 -0
  394. package/dist/manager/schemas/admin/database/post.js +6 -0
  395. package/dist/manager/schemas/admin/email/post.js +31 -0
  396. package/dist/manager/schemas/admin/firestore/get.js +5 -0
  397. package/dist/manager/schemas/admin/firestore/post.js +8 -0
  398. package/dist/manager/schemas/admin/firestore/query/post.js +5 -0
  399. package/dist/manager/schemas/admin/hook/post.js +8 -0
  400. package/dist/manager/schemas/admin/infer-contact/post.js +6 -0
  401. package/dist/manager/schemas/admin/notification/post.js +23 -0
  402. package/dist/manager/schemas/admin/payment/post.js +8 -0
  403. package/dist/manager/schemas/admin/post/post.js +23 -0
  404. package/dist/manager/schemas/admin/post/put.js +13 -0
  405. package/dist/manager/schemas/admin/repo/content/post.js +10 -0
  406. package/dist/manager/schemas/admin/stats/get.js +5 -0
  407. package/dist/manager/schemas/admin/users/disable/post.js +9 -0
  408. package/dist/manager/schemas/admin/users/list/get.js +10 -0
  409. package/dist/manager/schemas/admin/users/sync/post.js +7 -0
  410. package/dist/manager/schemas/brand/get.js +3 -0
  411. package/dist/manager/schemas/content/post/get.js +8 -0
  412. package/dist/manager/schemas/general/email/post.js +10 -0
  413. package/dist/manager/schemas/general/uuid/post.js +9 -0
  414. package/dist/manager/schemas/handler/post/post.js +13 -0
  415. package/dist/manager/schemas/health/get.js +3 -0
  416. package/dist/manager/schemas/marketing/campaign/delete.js +8 -0
  417. package/dist/manager/schemas/marketing/campaign/get.js +13 -0
  418. package/dist/manager/schemas/marketing/campaign/post.js +43 -0
  419. package/dist/manager/schemas/marketing/campaign/put.js +37 -0
  420. package/dist/manager/schemas/marketing/contact/delete.js +8 -0
  421. package/dist/manager/schemas/marketing/contact/post.js +14 -0
  422. package/dist/manager/schemas/marketing/contact/put.js +8 -0
  423. package/dist/manager/schemas/marketing/email-preferences/post.js +15 -0
  424. package/dist/manager/schemas/marketing/webhook/forward/post.js +8 -0
  425. package/dist/manager/schemas/marketing/webhook/post.js +7 -0
  426. package/dist/manager/schemas/payments/cancel/post.js +15 -0
  427. package/dist/manager/schemas/payments/discount/get.js +8 -0
  428. package/dist/manager/schemas/payments/dispute-alert/post.js +6 -0
  429. package/dist/manager/schemas/payments/intent/post.js +28 -0
  430. package/dist/manager/schemas/payments/plan/post.js +11 -0
  431. package/dist/manager/schemas/payments/portal/post.js +12 -0
  432. package/dist/manager/schemas/payments/refund/post.js +14 -0
  433. package/dist/manager/schemas/payments/trial-eligibility/get.js +7 -0
  434. package/dist/manager/schemas/payments/uncancel/post.js +9 -0
  435. package/dist/manager/schemas/payments/webhook/post.js +6 -0
  436. package/dist/manager/schemas/payments/winback/post.js +12 -0
  437. package/dist/manager/schemas/restart/index.js +5 -0
  438. package/dist/manager/schemas/special/electron-client/post.js +11 -0
  439. package/dist/manager/schemas/test/authenticate/get.js +3 -0
  440. package/dist/manager/schemas/test/health/get.js +3 -0
  441. package/dist/manager/schemas/test/index.js +5 -0
  442. package/dist/manager/schemas/test/lab/post.js +3 -0
  443. package/dist/manager/schemas/test/redirect/get.js +7 -0
  444. package/dist/manager/schemas/test/reset-account/post.js +3 -0
  445. package/dist/manager/schemas/test/roster/get.js +3 -0
  446. package/dist/manager/schemas/test/schema/post.js +70 -0
  447. package/dist/manager/schemas/test/usage/post.js +8 -0
  448. package/dist/manager/schemas/test/webhook/post.js +7 -0
  449. package/dist/manager/schemas/user/api-keys/post.js +6 -0
  450. package/dist/manager/schemas/user/connections/delete.js +8 -0
  451. package/dist/manager/schemas/user/connections/get.js +21 -0
  452. package/dist/manager/schemas/user/connections/post.js +12 -0
  453. package/dist/manager/schemas/user/data-request/delete.js +3 -0
  454. package/dist/manager/schemas/user/data-request/get.js +5 -0
  455. package/dist/manager/schemas/user/data-request/post.js +6 -0
  456. package/dist/manager/schemas/user/delete.js +6 -0
  457. package/dist/manager/schemas/user/feedback/post.js +8 -0
  458. package/dist/manager/schemas/user/get.js +3 -0
  459. package/dist/manager/schemas/user/orders/get.js +6 -0
  460. package/dist/manager/schemas/user/sessions/delete.js +6 -0
  461. package/dist/manager/schemas/user/sessions/get.js +6 -0
  462. package/dist/manager/schemas/user/settings/validate/post.js +8 -0
  463. package/dist/manager/schemas/user/signup/post.js +27 -0
  464. package/dist/manager/schemas/user/subscription/get.js +5 -0
  465. package/dist/manager/schemas/user/token/post.js +5 -0
  466. package/dist/manager/schemas/verts/delete.js +8 -0
  467. package/dist/manager/schemas/verts/get.js +9 -0
  468. package/dist/manager/schemas/verts/post.js +23 -0
  469. package/dist/manager/schemas/verts/put.js +20 -0
  470. package/dist/manager/schemas/verts/redirect/get.js +10 -0
  471. package/dist/manager/schemas/verts/serve/get.js +14 -0
  472. package/dist/manager/server-manager.js +69 -0
  473. package/dist/mcp/client.js +98 -0
  474. package/dist/mcp/handler.js +521 -0
  475. package/dist/mcp/index.js +157 -0
  476. package/dist/mcp/tools.js +555 -0
  477. package/dist/mcp/utils.js +108 -0
  478. package/dist/omega-bin.js +6 -0
  479. package/dist/require.js +3 -0
  480. package/dist/test/fixtures/firebase-project/.firebaserc +5 -0
  481. package/dist/test/fixtures/firebase-project/config/omega.json5 +131 -0
  482. package/dist/test/fixtures/firebase-project/database.rules.json +6 -0
  483. package/dist/test/fixtures/firebase-project/firebase.json +49 -0
  484. package/dist/test/fixtures/firebase-project/firestore.indexes.json +4 -0
  485. package/dist/test/fixtures/firebase-project/package.json +14 -0
  486. package/dist/test/fixtures/firebase-project/src/index.js +11 -0
  487. package/dist/test/fixtures/firebase-project/storage.rules +8 -0
  488. package/dist/test/parse-audit.js +25 -0
  489. package/dist/test/run-tests.js +90 -0
  490. package/dist/test/runner.js +982 -0
  491. package/dist/test/seed.js +242 -0
  492. package/dist/test/test-accounts.js +2660 -0
  493. package/dist/test/utils/assertions.js +189 -0
  494. package/dist/test/utils/email-capture.js +252 -0
  495. package/dist/test/utils/extended-mode-warning.js +11 -0
  496. package/dist/test/utils/firestore-rules-client.js +277 -0
  497. package/dist/test/utils/http-client.js +228 -0
  498. package/dist/test/utils/test-mode-file.js +192 -0
  499. package/dist/utils/merge-line-files.js +6 -0
  500. package/dist/utils/scaffold-defaults.js +71 -0
  501. package/dist/utils/test-lanes.js +62 -0
  502. package/dist/vendor/account/engine.js +182 -0
  503. package/dist/vendor/account/features.js +220 -0
  504. package/dist/vendor/account/index.js +53 -0
  505. package/dist/vendor/account/schema.js +272 -0
  506. package/dist/vendor/account/subscription.js +38 -0
  507. package/dist/vendor/analytics/adapters/ga4.js +26 -0
  508. package/dist/vendor/analytics/adapters/meta.js +26 -0
  509. package/dist/vendor/analytics/adapters/resolve.js +130 -0
  510. package/dist/vendor/analytics/adapters/tiktok.js +27 -0
  511. package/dist/vendor/analytics/catalog.js +908 -0
  512. package/dist/vendor/analytics/identity.js +136 -0
  513. package/dist/vendor/config/company.js +31 -0
  514. package/dist/vendor/config/defaults.js +173 -0
  515. package/dist/vendor/config/demo.js +18 -0
  516. package/dist/vendor/config/desktop-artifacts.js +110 -0
  517. package/dist/vendor/config/edit.js +769 -0
  518. package/dist/vendor/config/env-delivery.js +145 -0
  519. package/dist/vendor/config/env-rules.js +93 -0
  520. package/dist/vendor/config/env-schema.js +1078 -0
  521. package/dist/vendor/config/env.js +445 -0
  522. package/dist/vendor/config/hooks.js +97 -0
  523. package/dist/vendor/config/index.js +237 -0
  524. package/dist/vendor/config/instances.js +208 -0
  525. package/dist/vendor/config/load.js +490 -0
  526. package/dist/vendor/config/merge.js +68 -0
  527. package/dist/vendor/config/order.js +139 -0
  528. package/dist/vendor/config/ports.js +374 -0
  529. package/dist/vendor/config/providers.js +32 -0
  530. package/dist/vendor/config/repo.js +142 -0
  531. package/dist/vendor/config/retired-keys.js +430 -0
  532. package/dist/vendor/config/schema.js +1610 -0
  533. package/dist/vendor/config/secrets.js +50 -0
  534. package/dist/vendor/config/seed.js +34 -0
  535. package/dist/vendor/config/site-global.js +205 -0
  536. package/dist/vendor/config/validate.js +554 -0
  537. package/dist/vendor/config/winback.js +61 -0
  538. package/dist/vendor/devkit/attach-log-file.js +262 -0
  539. package/dist/vendor/devkit/bare-requires.js +153 -0
  540. package/dist/vendor/devkit/command-path.js +46 -0
  541. package/dist/vendor/devkit/defaults-engine.js +372 -0
  542. package/dist/vendor/devkit/deploy-record.js +180 -0
  543. package/dist/vendor/devkit/deploy.js +286 -0
  544. package/dist/vendor/devkit/license.js +155 -0
  545. package/dist/vendor/devkit/local-https.js +360 -0
  546. package/dist/vendor/devkit/local.js +1905 -0
  547. package/dist/vendor/devkit/logger.js +128 -0
  548. package/dist/vendor/devkit/merge-line-files.js +296 -0
  549. package/dist/vendor/devkit/npm-registry.js +52 -0
  550. package/dist/vendor/devkit/omega-bin.js +345 -0
  551. package/dist/vendor/devkit/parse-audit.js +74 -0
  552. package/dist/vendor/devkit/safe-install.js +18 -0
  553. package/dist/vendor/devkit/scaffold-guard.js +96 -0
  554. package/dist/vendor/devkit/stop-signals.js +28 -0
  555. package/dist/vendor/devkit/test/assert.js +120 -0
  556. package/dist/vendor/devkit/test/define-cases.js +104 -0
  557. package/dist/vendor/devkit/test/runner-core.js +554 -0
  558. package/dist/vendor/devkit/test/scope.js +162 -0
  559. package/dist/vendor/devkit/update.js +569 -0
  560. package/dist/vendor/monitoring/core.js +180 -0
  561. package/dist/vendor/monitoring/env.js +49 -0
  562. package/dist/vendor/monitoring/logger.js +39 -0
  563. package/dist/vendor/monitoring/node.js +72 -0
  564. package/docs/admin-post-route.md +57 -0
  565. package/docs/ai-library.md +171 -0
  566. package/docs/architecture.md +62 -0
  567. package/docs/audit.md +70 -0
  568. package/docs/auth-hooks.md +74 -0
  569. package/docs/build-system.md +65 -0
  570. package/docs/cdp-debugging.md +29 -0
  571. package/docs/cli-firestore-auth.md +85 -0
  572. package/docs/cli-logs.md +67 -0
  573. package/docs/cli-output.md +146 -0
  574. package/docs/code-patterns.md +77 -0
  575. package/docs/common-mistakes.md +12 -0
  576. package/docs/common-operations.md +60 -0
  577. package/docs/connections.md +212 -0
  578. package/docs/consent.md +362 -0
  579. package/docs/directory-structure.md +150 -0
  580. package/docs/email-system.md +459 -0
  581. package/docs/environment-detection.md +93 -0
  582. package/docs/file-naming.md +10 -0
  583. package/docs/firestore.md +134 -0
  584. package/docs/ghostii.md +240 -0
  585. package/docs/index.md +299 -0
  586. package/docs/key-files.md +37 -0
  587. package/docs/logging.md +60 -0
  588. package/docs/marketing-campaigns.md +407 -0
  589. package/docs/marketing-fields.md +25 -0
  590. package/docs/mcp.md +222 -0
  591. package/docs/migration.md +129 -0
  592. package/docs/payment-system.md +856 -0
  593. package/docs/paypal-sandbox-qa.md +105 -0
  594. package/docs/response-headers.md +9 -0
  595. package/docs/routes.md +211 -0
  596. package/docs/sanitization.md +71 -0
  597. package/docs/schemas.md +163 -0
  598. package/docs/shared/agent-docs.md +89 -0
  599. package/docs/shared/analytics.md +612 -0
  600. package/docs/shared/brands.md +51 -0
  601. package/docs/shared/breaking-changes.md +497 -0
  602. package/docs/shared/config.md +1387 -0
  603. package/docs/shared/deploys.md +215 -0
  604. package/docs/shared/icons.md +201 -0
  605. package/docs/shared/local-dev.md +147 -0
  606. package/docs/shared/logging.md +202 -0
  607. package/docs/shared/monitoring.md +153 -0
  608. package/docs/shared/publishing.md +183 -0
  609. package/docs/shared/rulings.md +34 -0
  610. package/docs/shared/testing.md +147 -0
  611. package/docs/shared/theming.md +604 -0
  612. package/docs/shared/translation.md +291 -0
  613. package/docs/shared/updates.md +61 -0
  614. package/docs/stripe-webhook-forwarding.md +20 -0
  615. package/docs/test-boot-layer.md +67 -0
  616. package/docs/test-framework.md +583 -0
  617. package/docs/usage-rate-limiting.md +121 -0
  618. package/docs/verts.md +29 -0
  619. package/package.json +143 -0
  620. package/templates/config/omega.json5 +322 -0
  621. package/templates/database.rules.json +82 -0
  622. package/templates/firebase.json +67 -0
  623. package/templates/firestore.framework.rules +191 -0
  624. package/templates/firestore.indexes.json +4 -0
  625. package/templates/firestore.rules +59 -0
  626. package/templates/index.js +12 -0
  627. package/templates/public/404.html +26 -0
  628. package/templates/public/index.html +24 -0
  629. package/templates/remoteconfig.template.json +1 -0
  630. package/templates/storage-lifecycle-config-1-day.json +9 -0
  631. package/templates/storage-lifecycle-config-30-days.json +9 -0
  632. package/templates/storage.rules +11 -0
  633. package/test/_init/accounts-validation.js +58 -0
  634. package/test/ai/tools-live.test.js +171 -0
  635. package/test/analytics/conversion-delivery.test.js +1013 -0
  636. package/test/analytics/match-normalization.test.js +238 -0
  637. package/test/analytics/signup-conversion.test.js +135 -0
  638. package/test/boot/cli-dispatch.test.js +142 -0
  639. package/test/boot/defaults-scaffold.test.js +248 -0
  640. package/test/boot/deploy-staging.test.js +446 -0
  641. package/test/boot/disposable-domains.test.js +154 -0
  642. package/test/boot/emulator-boots.test.js +39 -0
  643. package/test/boot/emulator-port-preflight.test.js +126 -0
  644. package/test/boot/emulator-ready-timeout.test.js +46 -0
  645. package/test/boot/project-id-refresh.test.js +73 -0
  646. package/test/boot/suite-portability.test.js +278 -0
  647. package/test/boot/update-command.test.js +63 -0
  648. package/test/cli/cross-platform.test.js +168 -0
  649. package/test/cli/custom-project-type.test.js +426 -0
  650. package/test/cli/deploy-license-env.test.js +100 -0
  651. package/test/cli/emulator-adoption.test.js +254 -0
  652. package/test/cli/emulator-orphans.test.js +658 -0
  653. package/test/cli/emulator-ownership.test.js +177 -0
  654. package/test/cli/emulator-port-retry.test.js +395 -0
  655. package/test/cli/emulator-shutdown.test.js +788 -0
  656. package/test/cli/emulator-stale-reap.test.js +574 -0
  657. package/test/cli/ensure-target.test.js +325 -0
  658. package/test/cli/flags.test.js +64 -0
  659. package/test/cli/https-trust.test.js +38 -0
  660. package/test/cli/install-update-dispatch.test.js +47 -0
  661. package/test/cli/lane-environments.test.js +159 -0
  662. package/test/cli/marketing-campaigns-seeded.test.js +194 -0
  663. package/test/cli/migrate-bare-requires.test.js +128 -0
  664. package/test/cli/migrate-markers.test.js +530 -0
  665. package/test/cli/required-indexes.test.js +64 -0
  666. package/test/cli/rules-compile.test.js +622 -0
  667. package/test/cli/rules-migration-deferral.test.js +259 -0
  668. package/test/cli/rules-version.test.js +104 -0
  669. package/test/cli/setup-load-files.test.js +66 -0
  670. package/test/cli/setup-offline-mode.test.js +276 -0
  671. package/test/cli/setup-retired.test.js +64 -0
  672. package/test/cli/setup-shared-project-indexes.test.js +262 -0
  673. package/test/cli/setup-tests-requires.test.js +45 -0
  674. package/test/cli/stage-env-compose.test.js +316 -0
  675. package/test/cli/stripe-live-lane.test.js +303 -0
  676. package/test/cli/target.test.js +182 -0
  677. package/test/cli/templates.test.js +66 -0
  678. package/test/cli/test-runner-env.test.js +115 -0
  679. package/test/cli/test-stack-shutdown.test.js +275 -0
  680. package/test/cli/test-target-no-match.test.js +128 -0
  681. package/test/cli/verb-logs.test.js +118 -0
  682. package/test/cli/version-dispatch.test.js +39 -0
  683. package/test/content/blog-generate.test.js +164 -0
  684. package/test/email/campaign-config-fault.test.js +376 -0
  685. package/test/email/campaign-cron-pipeline.test.js +536 -0
  686. package/test/email/campaign-send.test.js +47 -0
  687. package/test/email/consent-lifecycle.test.js +258 -0
  688. package/test/email/content-html-policy.test.js +270 -0
  689. package/test/email/feedback-and-plain-send.test.js +54 -0
  690. package/test/email/fixtures/clean.json +30 -0
  691. package/test/email/fixtures/editorial.json +30 -0
  692. package/test/email/fixtures/field-report.json +53 -0
  693. package/test/email/identity.test.js +321 -0
  694. package/test/email/marketing/consent-gate.test.js +265 -0
  695. package/test/email/marketing/custom-fields-catalog.test.js +259 -0
  696. package/test/email/marketing/prune-per-provider.test.js +762 -0
  697. package/test/email/marketing/remove-log-privacy.test.js +225 -0
  698. package/test/email/marketing-lifecycle.test.js +139 -0
  699. package/test/email/newsletter-generate.test.js +853 -0
  700. package/test/email/newsletter-svg-tokens.test.js +51 -0
  701. package/test/email/newsletter-templates.test.js +492 -0
  702. package/test/email/order-one-time-cta.test.js +97 -0
  703. package/test/email/render-content.test.js +248 -0
  704. package/test/email/safe-url.test.js +0 -0
  705. package/test/email/sanitize-images.test.js +66 -0
  706. package/test/email/send-log-privacy.test.js +107 -0
  707. package/test/email/templates.test.js +288 -0
  708. package/test/email/testing-capture.test.js +260 -0
  709. package/test/email/transactional-send.test.js +36 -0
  710. package/test/email/transactional.test.js +562 -0
  711. package/test/email/unsubscribe-groups.test.js +155 -0
  712. package/test/email/unsubscribe-key.test.js +91 -0
  713. package/test/email/validation-cases.test.js +152 -0
  714. package/test/email/validation.test.js +746 -0
  715. package/test/events/auth-delete-conversion.test.js +138 -0
  716. package/test/events/auth-delete-race.test.js +211 -0
  717. package/test/events/auth-on-create-log.test.js +164 -0
  718. package/test/events/auth-signup-conversion.test.js +141 -0
  719. package/test/events/auth-signup-limit.test.js +142 -0
  720. package/test/events/auth-trigger-log-privacy.test.js +256 -0
  721. package/test/events/cron-job-doc-shape.test.js +101 -0
  722. package/test/events/cron-reset-usage.test.js +116 -0
  723. package/test/events/notification-conversion.test.js +182 -0
  724. package/test/events/payments/_webhook-harness.js +307 -0
  725. package/test/events/payments/abandoned-cart-activity.test.js +135 -0
  726. package/test/events/payments/analytics-payment-events.test.js +945 -0
  727. package/test/events/payments/dispute-email-status.test.js +55 -0
  728. package/test/events/payments/journey-payments-abandoned.test.js +126 -0
  729. package/test/events/payments/journey-payments-cancel-endpoint.test.js +102 -0
  730. package/test/events/payments/journey-payments-cancel-no-order.test.js +76 -0
  731. package/test/events/payments/journey-payments-cancel.test.js +184 -0
  732. package/test/events/payments/journey-payments-decline.test.js +225 -0
  733. package/test/events/payments/journey-payments-discount.test.js +91 -0
  734. package/test/events/payments/journey-payments-dispute.test.js +190 -0
  735. package/test/events/payments/journey-payments-failure.test.js +148 -0
  736. package/test/events/payments/journey-payments-legacy-product.test.js +151 -0
  737. package/test/events/payments/journey-payments-one-time-decline.test.js +127 -0
  738. package/test/events/payments/journey-payments-one-time-failure.test.js +113 -0
  739. package/test/events/payments/journey-payments-one-time-refund.test.js +186 -0
  740. package/test/events/payments/journey-payments-one-time.test.js +175 -0
  741. package/test/events/payments/journey-payments-plan-change.test.js +146 -0
  742. package/test/events/payments/journey-payments-plan-switch-trial.test.js +161 -0
  743. package/test/events/payments/journey-payments-plan-switch.test.js +182 -0
  744. package/test/events/payments/journey-payments-refund-no-order.test.js +76 -0
  745. package/test/events/payments/journey-payments-refund-webhook.test.js +225 -0
  746. package/test/events/payments/journey-payments-suspend.test.js +183 -0
  747. package/test/events/payments/journey-payments-trial-cancel.test.js +132 -0
  748. package/test/events/payments/journey-payments-trial.test.js +173 -0
  749. package/test/events/payments/journey-payments-uid-resolution.test.js +134 -0
  750. package/test/events/payments/journey-payments-uncancel.test.js +157 -0
  751. package/test/events/payments/journey-payments-upgrade.test.js +137 -0
  752. package/test/events/payments/journey-payments-winback-decline.test.js +171 -0
  753. package/test/events/payments/journey-payments-winback.test.js +195 -0
  754. package/test/events/payments/paypal-expiry-cron.test.js +166 -0
  755. package/test/events/payments/purchase-failed-handler.test.js +80 -0
  756. package/test/events/payments/purchase-refunded-handler.test.js +108 -0
  757. package/test/events/payments/test-processor-doc-shape.test.js +162 -0
  758. package/test/events/payments/transition-order-emails.test.js +185 -0
  759. package/test/events/payments/transition-promo-lines.test.js +192 -0
  760. package/test/events/payments/transitions-detect.test.js +767 -0
  761. package/test/events/payments/trial-lapse-sweep-staleness.test.js +173 -0
  762. package/test/events/payments/trial-lapse-sweep.test.js +359 -0
  763. package/test/events/payments/webhook-atomic-writes.test.js +69 -0
  764. package/test/events/payments/webhook-chargebee-unreachable.test.js +106 -0
  765. package/test/events/payments/webhook-discount-clear.test.js +189 -0
  766. package/test/events/payments/webhook-failure-intent.test.js +93 -0
  767. package/test/events/payments/webhook-hosted-page-uid-trust.test.js +212 -0
  768. package/test/events/payments/webhook-ordering.test.js +326 -0
  769. package/test/events/payments/webhook-provider-lookup-trust.test.js +206 -0
  770. package/test/events/payments/webhook-refund-amount-trust.test.js +223 -0
  771. package/test/events/payments/webhook-refund-envelope-shape.test.js +148 -0
  772. package/test/events/payments/webhook-refund-linkage-trust.test.js +404 -0
  773. package/test/events/payments/webhook-refund-transaction-fallback.test.js +184 -0
  774. package/test/events/payments/webhook-refund-without-order.test.js +170 -0
  775. package/test/events/payments/webhook-refusal-reporting.test.js +194 -0
  776. package/test/events/payments/webhook-refused-intent.test.js +142 -0
  777. package/test/events/payments/webhook-retry-sweep.test.js +252 -0
  778. package/test/events/payments/webhook-transition-claim.test.js +389 -0
  779. package/test/events/payments/webhook-uid-trust.test.js +203 -0
  780. package/test/events/payments/webhook-user-without-auth.test.js +161 -0
  781. package/test/fixtures/chargebee/invoice-one-time.json +27 -0
  782. package/test/fixtures/chargebee/subscription-active.json +44 -0
  783. package/test/fixtures/chargebee/subscription-cancelled.json +42 -0
  784. package/test/fixtures/chargebee/subscription-in-trial.json +41 -0
  785. package/test/fixtures/chargebee/subscription-legacy-plan.json +41 -0
  786. package/test/fixtures/chargebee/subscription-non-renewing.json +41 -0
  787. package/test/fixtures/chargebee/subscription-paused.json +42 -0
  788. package/test/fixtures/chargebee/webhook-payment-failed.json +51 -0
  789. package/test/fixtures/chargebee/webhook-subscription-created.json +47 -0
  790. package/test/fixtures/coinbase/charge-confirmed.json +50 -0
  791. package/test/fixtures/coinbase/charge-failed.json +34 -0
  792. package/test/fixtures/coinbase/charge-pending.json +34 -0
  793. package/test/fixtures/migrate/ported-route.js.txt +11 -0
  794. package/test/fixtures/paypal/capture-completed.json +51 -0
  795. package/test/fixtures/paypal/capture-refunded.json +43 -0
  796. package/test/fixtures/paypal/order-approved.json +62 -0
  797. package/test/fixtures/paypal/order-completed.json +110 -0
  798. package/test/fixtures/paypal/sale-refunded.json +38 -0
  799. package/test/fixtures/paypal/subscription-active.json +76 -0
  800. package/test/fixtures/paypal/subscription-cancelled.json +50 -0
  801. package/test/fixtures/paypal/subscription-suspended.json +65 -0
  802. package/test/fixtures/stripe/checkout-session-completed.json +130 -0
  803. package/test/fixtures/stripe/invoice-payment-failed.json +148 -0
  804. package/test/fixtures/stripe/invoice-subscription-payment-failed.json +28 -0
  805. package/test/fixtures/stripe/invoice-subscription-payment-succeeded.json +28 -0
  806. package/test/fixtures/stripe/subscription-active.json +161 -0
  807. package/test/fixtures/stripe/subscription-canceled.json +161 -0
  808. package/test/fixtures/stripe/subscription-trialing.json +161 -0
  809. package/test/helpers/_shared-config.js +15 -0
  810. package/test/helpers/ai-request-payload.test.js +619 -0
  811. package/test/helpers/ai-schema-resolve.test.js +125 -0
  812. package/test/helpers/ai-test-provider.test.js +227 -0
  813. package/test/helpers/ai-token-accounting.test.js +150 -0
  814. package/test/helpers/ai-tools-format.test.js +384 -0
  815. package/test/helpers/analytics-no-id-notice.test.js +146 -0
  816. package/test/helpers/analytics-user-data.test.js +194 -0
  817. package/test/helpers/api-manager.test.js +311 -0
  818. package/test/helpers/backend-router.test.js +136 -0
  819. package/test/helpers/content/blog-auto-publisher.test.js +482 -0
  820. package/test/helpers/content/feed-parser.test.js +529 -0
  821. package/test/helpers/content/ghostii-blocks.test.js +135 -0
  822. package/test/helpers/content/ghostii-feed-integration.test.js +405 -0
  823. package/test/helpers/content/ghostii-write-article.test.js +244 -0
  824. package/test/helpers/dev-only-routes.test.js +225 -0
  825. package/test/helpers/env-reader.test.js +362 -0
  826. package/test/helpers/environment.test.js +263 -0
  827. package/test/helpers/event-middleware.test.js +407 -0
  828. package/test/helpers/infer-contact.test.js +157 -0
  829. package/test/helpers/lane-url.test.js +90 -0
  830. package/test/helpers/merge-line-files.test.js +272 -0
  831. package/test/helpers/metadata.test.js +122 -0
  832. package/test/helpers/middleware-request-log.test.js +134 -0
  833. package/test/helpers/middleware-user-log.test.js +124 -0
  834. package/test/helpers/payment/chargebee/parse-webhook.test.js +490 -0
  835. package/test/helpers/payment/chargebee/refund-details.test.js +198 -0
  836. package/test/helpers/payment/chargebee/to-unified-one-time.test.js +148 -0
  837. package/test/helpers/payment/chargebee/to-unified-subscription.test.js +649 -0
  838. package/test/helpers/payment/coinbase/create-intent.test.js +247 -0
  839. package/test/helpers/payment/coinbase/parse-webhook.test.js +195 -0
  840. package/test/helpers/payment/coinbase/refund-unsupported.test.js +141 -0
  841. package/test/helpers/payment/coinbase/to-unified-one-time.test.js +201 -0
  842. package/test/helpers/payment/discount-codes.test.js +141 -0
  843. package/test/helpers/payment/extract-resource.test.js +113 -0
  844. package/test/helpers/payment/fetch-failure.test.js +215 -0
  845. package/test/helpers/payment/license-gate.test.js +108 -0
  846. package/test/helpers/payment/order-id.test.js +99 -0
  847. package/test/helpers/payment/paypal/create-intent.test.js +382 -0
  848. package/test/helpers/payment/paypal/fetch-capture.test.js +123 -0
  849. package/test/helpers/payment/paypal/fetch-sale.test.js +183 -0
  850. package/test/helpers/payment/paypal/parse-webhook.test.js +678 -0
  851. package/test/helpers/payment/paypal/refund-details.test.js +202 -0
  852. package/test/helpers/payment/paypal/resolve-plan-id.test.js +108 -0
  853. package/test/helpers/payment/paypal/switch-plan.test.js +92 -0
  854. package/test/helpers/payment/paypal/to-unified-one-time.test.js +383 -0
  855. package/test/helpers/payment/paypal/to-unified-subscription.test.js +884 -0
  856. package/test/helpers/payment/stripe/fetch-charge.test.js +147 -0
  857. package/test/helpers/payment/stripe/parse-webhook.test.js +448 -0
  858. package/test/helpers/payment/stripe/refund-details.test.js +147 -0
  859. package/test/helpers/payment/stripe/to-unified-one-time.test.js +307 -0
  860. package/test/helpers/payment/stripe/to-unified-subscription.test.js +709 -0
  861. package/test/helpers/persona-domain.test.js +87 -0
  862. package/test/helpers/recaptcha.test.js +166 -0
  863. package/test/helpers/resolved-config.test.js +106 -0
  864. package/test/helpers/response-log-redaction.test.js +262 -0
  865. package/test/helpers/roles.test.js +155 -0
  866. package/test/helpers/route-context-debug-gate.test.js +118 -0
  867. package/test/helpers/route-context-logging.test.js +214 -0
  868. package/test/helpers/route-context.test.js +129 -0
  869. package/test/helpers/safe-compare.test.js +114 -0
  870. package/test/helpers/sanitize.test.js +223 -0
  871. package/test/helpers/schema-engine.test.js +537 -0
  872. package/test/helpers/schema-zod.test.js +554 -0
  873. package/test/helpers/seed-accounts-load.test.js +163 -0
  874. package/test/helpers/seed-google-personas.test.js +114 -0
  875. package/test/helpers/seeded-personas.test.js +823 -0
  876. package/test/helpers/settings.test.js +292 -0
  877. package/test/helpers/setup-engines-pin.test.js +68 -0
  878. package/test/helpers/setup-manifest-sync.test.js +116 -0
  879. package/test/helpers/slugify.test.js +395 -0
  880. package/test/helpers/storage.test.js +195 -0
  881. package/test/helpers/test-banner-latch.test.js +139 -0
  882. package/test/helpers/usage-consume.test.js +460 -0
  883. package/test/helpers/usage-log-privacy.test.js +121 -0
  884. package/test/helpers/user-doc-heal.test.js +540 -0
  885. package/test/helpers/user.test.js +771 -0
  886. package/test/helpers/webhook-forward.test.js +419 -0
  887. package/test/helpers/wipe-auth-project.test.js +143 -0
  888. package/test/mcp/discovery.test.js +52 -0
  889. package/test/mcp/oauth.test.js +160 -0
  890. package/test/mcp/protocol.test.js +278 -0
  891. package/test/mcp/roles.test.js +203 -0
  892. package/test/mcp/utils.test.js +245 -0
  893. package/test/notification/identity.test.js +155 -0
  894. package/test/routes/admin/create-post.test.js +362 -0
  895. package/test/routes/admin/database.test.js +133 -0
  896. package/test/routes/admin/deduplicate-image-alts.test.js +191 -0
  897. package/test/routes/admin/email-content-html.test.js +58 -0
  898. package/test/routes/admin/email-request-log.test.js +86 -0
  899. package/test/routes/admin/email.test.js +116 -0
  900. package/test/routes/admin/firestore-query.test.js +206 -0
  901. package/test/routes/admin/firestore.test.js +129 -0
  902. package/test/routes/admin/infer-contact.test.js +220 -0
  903. package/test/routes/admin/notification.test.js +199 -0
  904. package/test/routes/admin/post-convert-image.test.js +159 -0
  905. package/test/routes/admin/post-deploy-flag.test.js +81 -0
  906. package/test/routes/admin/post-download-error.test.js +90 -0
  907. package/test/routes/admin/post-resize-image.test.js +185 -0
  908. package/test/routes/admin/post.test.js +369 -0
  909. package/test/routes/admin/repo-content.test.js +223 -0
  910. package/test/routes/admin/stats.test.js +114 -0
  911. package/test/routes/admin/users-disable.test.js +63 -0
  912. package/test/routes/admin/users-list.test.js +71 -0
  913. package/test/routes/content/post.test.js +60 -0
  914. package/test/routes/general/uuid.test.js +133 -0
  915. package/test/routes/health.test.js +110 -0
  916. package/test/routes/marketing/campaign.test.js +184 -0
  917. package/test/routes/marketing/contact.test.js +416 -0
  918. package/test/routes/marketing/email-preferences.test.js +293 -0
  919. package/test/routes/marketing/push-send.test.js +34 -0
  920. package/test/routes/marketing/webhook-forward.test.js +63 -0
  921. package/test/routes/marketing/webhook.test.js +641 -0
  922. package/test/routes/payments/_route-harness.js +145 -0
  923. package/test/routes/payments/cancel-provider-errors.test.js +227 -0
  924. package/test/routes/payments/cancel-skip-guards.test.js +126 -0
  925. package/test/routes/payments/cancel-trialing.test.js +428 -0
  926. package/test/routes/payments/cancel.test.js +165 -0
  927. package/test/routes/payments/dedup-race.test.js +186 -0
  928. package/test/routes/payments/discount.test.js +82 -0
  929. package/test/routes/payments/dispute-alert.test.js +324 -0
  930. package/test/routes/payments/intent-discount-amounts.test.js +550 -0
  931. package/test/routes/payments/intent-discount-coupons.test.js +293 -0
  932. package/test/routes/payments/intent-one-time-metadata.test.js +122 -0
  933. package/test/routes/payments/intent-purchaser-guard.test.js +139 -0
  934. package/test/routes/payments/intent-zero-total.test.js +260 -0
  935. package/test/routes/payments/intent.test.js +413 -0
  936. package/test/routes/payments/plan.test.js +367 -0
  937. package/test/routes/payments/portal-return-url.test.js +107 -0
  938. package/test/routes/payments/portal.test.js +94 -0
  939. package/test/routes/payments/refund-one-time.test.js +254 -0
  940. package/test/routes/payments/refund-paypal-proration.test.js +190 -0
  941. package/test/routes/payments/refund.test.js +181 -0
  942. package/test/routes/payments/trial-eligibility.test.js +73 -0
  943. package/test/routes/payments/uncancel.test.js +270 -0
  944. package/test/routes/payments/webhook-stripe-invoice.test.js +129 -0
  945. package/test/routes/payments/webhook-stripe-refund-one-time.test.js +130 -0
  946. package/test/routes/payments/webhook-test-provider.test.js +156 -0
  947. package/test/routes/payments/webhook.test.js +115 -0
  948. package/test/routes/payments/winback-stripe-coupon.test.js +126 -0
  949. package/test/routes/payments/winback.test.js +597 -0
  950. package/test/routes/test/authenticate.test.js +79 -0
  951. package/test/routes/test/redirect.test.js +66 -0
  952. package/test/routes/test/reset-account.test.js +126 -0
  953. package/test/routes/test/roster.test.js +101 -0
  954. package/test/routes/test/schema.test.js +556 -0
  955. package/test/routes/test/usage.test.js +374 -0
  956. package/test/routes/user/api-keys.test.js +158 -0
  957. package/test/routes/user/connections-grant.test.js +759 -0
  958. package/test/routes/user/connections-identity.test.js +260 -0
  959. package/test/routes/user/connections-log-privacy.test.js +206 -0
  960. package/test/routes/user/connections-refresh-lease.test.js +696 -0
  961. package/test/routes/user/connections-return.test.js +261 -0
  962. package/test/routes/user/connections-uid.test.js +516 -0
  963. package/test/routes/user/delete.test.js +138 -0
  964. package/test/routes/user/feedback.test.js +106 -0
  965. package/test/routes/user/orders.test.js +233 -0
  966. package/test/routes/user/sessions.test.js +231 -0
  967. package/test/routes/user/settings-validate.test.js +84 -0
  968. package/test/routes/user/signup-emails.test.js +113 -0
  969. package/test/routes/user/signup-location.test.js +84 -0
  970. package/test/routes/user/signup-log-privacy.test.js +112 -0
  971. package/test/routes/user/signup.test.js +579 -0
  972. package/test/routes/user/subscription.test.js +101 -0
  973. package/test/routes/user/token.test.js +111 -0
  974. package/test/routes/user/user.test.js +158 -0
  975. package/test/routes/verts/cache.test.js +78 -0
  976. package/test/routes/verts/click-destination.test.js +76 -0
  977. package/test/routes/verts/crud.test.js +194 -0
  978. package/test/routes/verts/redirect.test.js +147 -0
  979. package/test/routes/verts/selection.test.js +237 -0
  980. package/test/routes/verts/serve.test.js +185 -0
  981. package/test/routes/verts/unit-document.test.js +117 -0
  982. package/test/rules/_environment.js +66 -0
  983. package/test/rules/brand-merge.test.js +195 -0
  984. package/test/rules/field-helpers.test.js +309 -0
  985. package/test/rules/notifications.test.js +577 -0
  986. package/test/rules/payments-carts.test.js +406 -0
  987. package/test/rules/sessions.test.js +170 -0
  988. package/test/rules/user.test.js +517 -0
  989. package/test/rules/verts.test.js +101 -0
  990. package/test/security/fetch-log-secrets.test.js +124 -0
  991. package/test/security/primitives.test.js +105 -0
  992. package/test/security/repo-pinning.test.js +77 -0
  993. package/test/stripe-live/subscription-lifecycle.test.js +141 -0
@@ -0,0 +1,908 @@
1
+ /**
2
+ * The event catalog — the SSOT for every analytics event OMEGA fires
3
+ * ([#328](https://github.com/Omega-JS-Stack/omega/issues/328) §Architecture,
4
+ * built by [#382](https://github.com/Omega-JS-Stack/omega/issues/382)).
5
+ *
6
+ * ONE entry per canonical event. Callers only ever speak canonical names and
7
+ * canonical params; each adapter translates into its provider's own dialect,
8
+ * because there is no unified cross-provider signature (Ian's constraint).
9
+ *
10
+ * MANDATORY BEFORE ANY EDIT BELOW (Ian 2026-08-27): every provider `name`,
11
+ * `kind` and param shape in this file is checked LIVE against the platform's
12
+ * own specification, never from memory. Open all six, read the event you are
13
+ * touching, and confirm the name is spelled as the platform spells it, that
14
+ * `kind: 'standard'` only claims an event the platform lists, and that the
15
+ * shaper sends the parameters the platform documents for that event:
16
+ * GA4 https://support.google.com/analytics/answer/9267735
17
+ * Meta https://www.facebook.com/business/help/402791146561655
18
+ * Meta pixel https://developers.facebook.com/docs/meta-pixel/reference
19
+ * TikTok https://ads.tiktok.com/help/article/standard-events-parameters
20
+ * TikTok 2.0 https://business-api.tiktok.com/portal/docs?id=1771100865818625
21
+ * GA4 dedupe https://support.google.com/analytics/answer/12313109
22
+ * A platform renames and retires events (TikTok retired CompletePayment for
23
+ * Purchase); a mapping that was right when written can be wrong today. The
24
+ * last link is the one that binds a PARAM rather than a name: GA4
25
+ * deduplicates `purchase` on `transaction_id`, so a money event's id is one
26
+ * CHARGE's ([#656](https://github.com/Omega-JS-Stack/omega/issues/656)).
27
+ *
28
+ * Entry shape:
29
+ * params — the canonical param contract, documentation for callers.
30
+ * Drawn from the EXISTING call sites so a rewired site sends
31
+ * what it sends today.
32
+ * placement — 'client' | 'server' | 'both'. Money and account truth fire
33
+ * server-side, UI actions client-side, signup both.
34
+ * providers — per-provider mapping. A provider ABSENT from this object has
35
+ * no mapping: the adapter returns null and the facade logs the
36
+ * dev skip. Each mapping carries:
37
+ * name — the provider's NATIVE event name
38
+ * kind — 'standard' (the platform defines this event) or
39
+ * 'custom' (a deliberate custom event; the provider
40
+ * fires its custom-event mechanism)
41
+ * map — OPTIONAL (params, context) => payload, only where
42
+ * the provider's shape genuinely differs. Default is
43
+ * pass-through.
44
+ * method — OPTIONAL, browser only: the provider's own PIXEL
45
+ * METHOD to call instead of its tracked-event command,
46
+ * for the one signal a platform manages itself rather
47
+ * than exposing as a trackable name (TikTok's
48
+ * `ttq.page()`). The name and kind stay declared for the
49
+ * catalog and the fire log; the transport calls the
50
+ * method, with no name and no payload.
51
+ * actionSource — OPTIONAL, Meta only: the `action_source` this
52
+ * event's SERVER fire carries instead of the sender's
53
+ * default `website`. Meta requires the field and makes
54
+ * its accuracy a term of use, and its enum names the
55
+ * case itself: `system_generated`, "for example, a
56
+ * subscription renewal that's set to auto-pay each
57
+ * month". A charge a card takes on its own had nobody
58
+ * on a website to claim
59
+ * ([#498](https://github.com/Omega-JS-Stack/omega/issues/498)).
60
+ *
61
+ * The canonical param vocabulary is GA4-flavoured (flat params plus an `items`
62
+ * array), because that is what the live call sites and the backend's payment
63
+ * webhook already build — so GA4 is pass-through and the maps live where the
64
+ * other two platforms genuinely disagree: their commerce vocabulary (both spell
65
+ * a cart as `content_ids` + `contents`, but the contents OBJECT is each
66
+ * platform's own) and Search's `search_string`.
67
+ */
68
+
69
+ // Drop keys a caller did not supply — a provider payload carrying
70
+ // `content_name: undefined` is noise, not data.
71
+ function compact(payload) {
72
+ const out = {};
73
+ for (const [key, value] of Object.entries(payload)) {
74
+ if (value !== undefined) {
75
+ out[key] = value;
76
+ }
77
+ }
78
+ return out;
79
+ }
80
+
81
+ // ─── Shared provider shapers ────────────────────────────────────────────────
82
+
83
+ // Meta's commerce vocabulary: content_ids + contents + num_items instead of
84
+ // GA4's items[]. BOTH id carriers ride, because Meta accepts either and its
85
+ // pixel reference asks for "contents or content_ids" on Purchase and Search
86
+ // (plain `contents` on AddToCart) for Advantage+ catalog ads: the priced
87
+ // objects are what a catalog campaign can match on
88
+ // ([#498](https://github.com/Omega-JS-Stack/omega/issues/498)). The object's
89
+ // field names are Meta's own (`id`, `quantity`, `item_price`), never GA4's;
90
+ // `delivery_category` is the fourth and belongs to physical fulfilment, which a
91
+ // subscription has none of.
92
+ function metaCommerce(params) {
93
+ const items = Array.isArray(params.items) ? params.items : [];
94
+
95
+ return compact({
96
+ content_ids: items.length ? items.map((item) => item.item_id) : undefined,
97
+ contents: items.length ? items.map((item) => compact({
98
+ id: item.item_id,
99
+ // Meta's object requires id + quantity; a line naming none is one of it,
100
+ // the same answer num_items gives below
101
+ quantity: item.quantity ?? 1,
102
+ item_price: item.price,
103
+ })) : undefined,
104
+ // "Name of the page/product", SINGULAR. This named items[0] for a whole
105
+ // cart, which labels a two-product order with one of them; `content_ids` and
106
+ // `contents` are the members that carry every product [#498].
107
+ content_name: items.length === 1 ? items[0].item_name : undefined,
108
+ content_type: items.length ? 'product' : undefined,
109
+ currency: params.currency,
110
+ value: params.value,
111
+ // "The number of items that a user tries to buy", so two seats on one line
112
+ // are two items, and a line naming no quantity is one of that thing [#498].
113
+ num_items: items.length ? items.reduce((total, item) => total + (item.quantity ?? 1), 0) : undefined,
114
+ // The transaction's own id, in Meta's vocabulary. The dedupe `event_id` is
115
+ // not this: Meta reads that as the pair-key for one browser/server fire and
116
+ // never as the order [#498].
117
+ order_id: params.transaction_id,
118
+ });
119
+ }
120
+
121
+ // TikTok's commerce vocabulary: a `contents` ARRAY of product objects, plus the
122
+ // order's own content_type/value/currency. The pixel reference documents exactly
123
+ // this shape — `ttq.track('AddToCart', { contents: [{ content_id, content_name,
124
+ // quantity, price }], content_type: 'product', value, currency })`, with
125
+ // `contents` "a list of content objects that represent relevant products in a
126
+ // web event with product information" — and the flat single-item
127
+ // `content_id`/`price`/`quantity` this sent before appears nowhere in it
128
+ // ([#652](https://github.com/Omega-JS-Stack/omega/issues/652)).
129
+ //
130
+ // Events API 2.0 documents `content_ids` BESIDE `contents` in the same
131
+ // `properties` object, and TikTok's standard-events page recommends `content_ids`
132
+ // on every commerce event it lists, so both ride, as they do on Meta's half
133
+ // ([#498](https://github.com/Omega-JS-Stack/omega/issues/498)). `content_type`
134
+ // stays where 2.0 documents it, at the properties level: the per-item
135
+ // `content_type` of the older Pixel SDK model is not in 2.0's contents object,
136
+ // whose fields are price, content_id, content_name, content_category and brand.
137
+ function tiktokCommerce(params) {
138
+ const items = Array.isArray(params.items) ? params.items : [];
139
+
140
+ return compact({
141
+ content_ids: items.length ? items.map((item) => item.item_id) : undefined,
142
+ contents: items.length ? items.map((item) => compact({
143
+ content_id: item.item_id,
144
+ content_name: item.item_name,
145
+ price: item.price,
146
+ quantity: item.quantity,
147
+ })) : undefined,
148
+ content_type: items.length ? 'product' : undefined,
149
+ currency: params.currency,
150
+ value: params.value,
151
+ // 2.0's `properties.order_id`, Meta's `order_id` twin [#498].
152
+ order_id: params.transaction_id,
153
+ });
154
+ }
155
+
156
+ // A churn moment's ad-platform half: an EXCLUSION-AUDIENCE signal, never money
157
+ // ([#415](https://github.com/Omega-JS-Stack/omega/issues/415)). Neither platform
158
+ // can subtract revenue, so a cancellation or a refund carrying its amount would
159
+ // ADD to the return their ads manager reports — the exact opposite of the truth.
160
+ // `value: 0` is the honest number on that side; GA4 keeps the real one, where a
161
+ // refund is a standard event the revenue report knows how to net.
162
+ function metaAudienceSignal(params) {
163
+ // `contents` comes off whole: its `item_price` IS the amount, and Meta's
164
+ // object requires `id` + `quantity`, so a stripped one would be a malformed
165
+ // object rather than a quieter signal. `content_ids` already names the plan,
166
+ // which is the entire content of an exclusion audience
167
+ // ([#498](https://github.com/Omega-JS-Stack/omega/issues/498)).
168
+ const { contents, ...signal } = metaCommerce(params);
169
+
170
+ return { ...signal, value: 0 };
171
+ }
172
+
173
+ function tiktokAudienceSignal(params) {
174
+ // TikTok's per-item `price` and `quantity` come off with the value: zeroing
175
+ // one field while the amount rides inside `contents` is not a zero-value
176
+ // signal. Meta's signal drops its own `contents` outright for the same reason,
177
+ // and TikTok's array stays because it is that platform's only id carrier
178
+ // besides `content_ids`. What is left is who and which plan, which is the
179
+ // whole point of the audience.
180
+ const signal = tiktokCommerce(params);
181
+
182
+ return compact({
183
+ ...signal,
184
+ contents: signal.contents
185
+ ? signal.contents.map(({ price, quantity, ...content }) => content)
186
+ : undefined,
187
+ value: 0,
188
+ });
189
+ }
190
+
191
+ // Both ad platforms call the query `search_string`; GA4 calls it `search_term`.
192
+ function metaSearch(params) {
193
+ return compact({
194
+ search_string: params.search_term,
195
+ content_category: params.content_category,
196
+ });
197
+ }
198
+
199
+ function tiktokSearch(params) {
200
+ return compact({
201
+ search_string: params.search_term,
202
+ });
203
+ }
204
+
205
+ // The recurring-revenue events ride GA4's standard `purchase` under their own
206
+ // canonical name, so the flag that tells them apart in GA4 is set here.
207
+ function ga4Recurring(params) {
208
+ return { ...params, is_recurring: true };
209
+ }
210
+
211
+ // The canonical commerce param contract, shared by every money event.
212
+ const COMMERCE_PARAMS = ['transaction_id', 'value', 'currency', 'items', 'is_trial', 'is_recurring', 'payment_provider', 'payment_frequency'];
213
+
214
+ // A plan change is the one money event with a BEFORE: `items` is the plan the
215
+ // subscriber moved to, and these carry the one they came from, so the direction
216
+ // of the switch is readable without a second event
217
+ // ([#407](https://github.com/Omega-JS-Stack/omega/issues/407)).
218
+ const PLAN_CHANGE_PARAMS = [...COMMERCE_PARAMS, 'previous_item_id', 'previous_item_name', 'previous_value'];
219
+
220
+ // ─── The catalog ────────────────────────────────────────────────────────────
221
+
222
+ const CATALOG = {
223
+ // ─── Auth ───
224
+
225
+ // The funnel entry, fired when the signup form is submitted. No provider
226
+ // mapping: the signup FUNNEL is ours to read, not an ad platform's.
227
+ sign_up_started: {
228
+ params: ['method'],
229
+ placement: 'client',
230
+ providers: {},
231
+ },
232
+
233
+ sign_up: {
234
+ params: ['method', 'user_id'],
235
+ placement: 'both',
236
+ providers: {
237
+ ga4: { name: 'sign_up', kind: 'standard' },
238
+ meta: { name: 'CompleteRegistration', kind: 'standard' },
239
+ tiktok: { name: 'CompleteRegistration', kind: 'standard' },
240
+ },
241
+ },
242
+
243
+ login: {
244
+ params: ['method', 'user_id'],
245
+ placement: 'client',
246
+ providers: {
247
+ ga4: { name: 'login', kind: 'standard' },
248
+ // Neither ad platform defines a Login event — today's call sites already
249
+ // fire it as a custom one, and the catalog says so out loud.
250
+ meta: { name: 'Login', kind: 'custom' },
251
+ tiktok: { name: 'Login', kind: 'custom' },
252
+ },
253
+ },
254
+
255
+ // Deliberately unmapped everywhere: a logout is not an ad signal, and GA4
256
+ // reads the session end on its own.
257
+ logout: {
258
+ params: [],
259
+ placement: 'client',
260
+ providers: {},
261
+ },
262
+
263
+ password_reset: {
264
+ params: ['method', 'status'],
265
+ placement: 'client',
266
+ providers: {
267
+ ga4: { name: 'password_reset', kind: 'custom' },
268
+ meta: { name: 'PasswordReset', kind: 'custom' },
269
+ tiktok: { name: 'SubmitForm', kind: 'standard' },
270
+ },
271
+ },
272
+
273
+ // Every platform hears the page view through THIS entry
274
+ // ([#409](https://github.com/Omega-JS-Stack/omega/issues/409)): the web
275
+ // loader's raw `fbq('track', 'PageView')` and `ttq.page()` at pixel init are
276
+ // retired, so a page view walks the same consent gate and the same catalog as
277
+ // every other event. Pass-through: a page's own params are all any of them
278
+ // wants, and each pixel reads the URL itself when a fire carries none.
279
+ page_view: {
280
+ params: ['page_path', 'page_title', 'page_location'],
281
+ placement: 'client',
282
+ providers: {
283
+ ga4: { name: 'page_view', kind: 'standard' },
284
+ meta: { name: 'PageView', kind: 'standard' },
285
+ // TikTok's page view is a pixel METHOD it manages itself (`ttq.page()`),
286
+ // not a name in its trackable set — `ttq.track('Pageview')` appears
287
+ // nowhere in TikTok's documented surface, and sending it would risk a
288
+ // Pageview metric that silently reads zero. So the mapping names the
289
+ // METHOD and the browser transport calls exactly that; the name and the
290
+ // honest `custom` kind stay for the catalog and the fire log.
291
+ tiktok: { name: 'Pageview', kind: 'custom', method: 'page' },
292
+ },
293
+ },
294
+
295
+ // The page_view twin for the runtimes that have screens, not pages —
296
+ // desktop's renderers fire it through the main-process singleton.
297
+ screen_view: {
298
+ params: ['screen_name'],
299
+ placement: 'client',
300
+ providers: {
301
+ ga4: { name: 'screen_view', kind: 'standard' },
302
+ },
303
+ },
304
+
305
+ // ─── Commerce (client funnel) ───
306
+
307
+ view_item: {
308
+ params: ['currency', 'value', 'items'],
309
+ placement: 'client',
310
+ providers: {
311
+ ga4: { name: 'view_item', kind: 'standard' },
312
+ meta: { name: 'ViewContent', kind: 'standard', map: metaCommerce },
313
+ tiktok: { name: 'ViewContent', kind: 'standard', map: tiktokCommerce },
314
+ },
315
+ },
316
+
317
+ // The pricing page's monthly/yearly switch. Both platforms define ViewContent
318
+ // as a PAGE or product view (Meta: "a visit to a web page you care about";
319
+ // TikTok: "when a visitor views a specific page") and a toggle is neither, so
320
+ // all three read it as the custom event it is
321
+ // ([#652](https://github.com/Omega-JS-Stack/omega/issues/652)).
322
+ pricing_toggle: {
323
+ params: ['billing_type'],
324
+ placement: 'client',
325
+ providers: {
326
+ ga4: { name: 'pricing_toggle', kind: 'custom' },
327
+ meta: { name: 'PricingToggle', kind: 'custom' },
328
+ tiktok: { name: 'PricingToggle', kind: 'custom' },
329
+ },
330
+ },
331
+
332
+ add_to_cart: {
333
+ params: ['currency', 'value', 'items'],
334
+ placement: 'client',
335
+ providers: {
336
+ ga4: { name: 'add_to_cart', kind: 'standard' },
337
+ meta: { name: 'AddToCart', kind: 'standard', map: metaCommerce },
338
+ tiktok: { name: 'AddToCart', kind: 'standard', map: tiktokCommerce },
339
+ },
340
+ },
341
+
342
+ begin_checkout: {
343
+ params: ['currency', 'value', 'items'],
344
+ placement: 'client',
345
+ providers: {
346
+ ga4: { name: 'begin_checkout', kind: 'standard' },
347
+ meta: { name: 'InitiateCheckout', kind: 'standard', map: metaCommerce },
348
+ tiktok: { name: 'InitiateCheckout', kind: 'standard', map: tiktokCommerce },
349
+ },
350
+ },
351
+
352
+ add_payment_info: {
353
+ params: ['currency', 'value', 'payment_type', 'items'],
354
+ placement: 'client',
355
+ providers: {
356
+ ga4: { name: 'add_payment_info', kind: 'standard' },
357
+ meta: { name: 'AddPaymentInfo', kind: 'standard', map: metaCommerce },
358
+ tiktok: { name: 'AddPaymentInfo', kind: 'standard', map: tiktokCommerce },
359
+ },
360
+ },
361
+
362
+ // ─── Commerce (server truth) ───
363
+
364
+ // Server is the truth: the backend's payment webhook owns the revenue. The
365
+ // BROWSER half is the retargeting signal the ad platforms need
366
+ // ([#386](https://github.com/Omega-JS-Stack/omega/issues/386)) — and GA4's
367
+ // too, since GA4 deduplicates `purchase` on `transaction_id`: both halves
368
+ // name the ORDER, so the browser adds the session, the campaign and the
369
+ // client id, and GA4 still counts one purchase
370
+ // ([#656](https://github.com/Omega-JS-Stack/omega/issues/656)). All three
371
+ // carry the same `<canonical>.<order id>` dedupe id for the two platforms
372
+ // that key on one.
373
+ purchase: {
374
+ params: COMMERCE_PARAMS,
375
+ placement: 'both',
376
+ providers: {
377
+ ga4: { name: 'purchase', kind: 'standard' },
378
+ meta: { name: 'Purchase', kind: 'standard', map: metaCommerce },
379
+ // TikTok RETIRED CompletePayment: `Purchase` — "when a visitor makes a
380
+ // purchase" — is the standard event its live list names, and the only one
381
+ // it documents `value`/`currency` for ([#652]).
382
+ tiktok: { name: 'Purchase', kind: 'standard', map: tiktokCommerce },
383
+ },
384
+ },
385
+
386
+ // A trial checkout's own conversion, and the SECOND event with a browser half
387
+ // ([#654](https://github.com/Omega-JS-Stack/omega/issues/654)): the
388
+ // confirmation page fired `purchase` for every checkout, so a $0 trial sent a
389
+ // browser Purchase beside this trial_start. The names, not the amounts, were
390
+ // the defect — two different event names never deduplicate, so each platform
391
+ // counted the pair as two conversions. The browser half is meta + tiktok —
392
+ // GA4's trial_start is a custom event the server owns outright, and there is
393
+ // no revenue for GA4 to deduplicate here.
394
+ //
395
+ // Value 0 on both platforms: a trial charges nothing, and both spell that out
396
+ // (Meta `fbq('track', 'StartTrial', { value: '0.00', currency: 'USD' })`).
397
+ trial_start: {
398
+ params: COMMERCE_PARAMS,
399
+ placement: 'both',
400
+ providers: {
401
+ // GA4 has no trial_start in its standard set — an explicit custom event.
402
+ ga4: { name: 'trial_start', kind: 'custom' },
403
+ meta: { name: 'StartTrial', kind: 'standard', map: metaCommerce },
404
+ // TikTok's own StartTrial — "when a customer begins a free trial for your
405
+ // product or service" — replaces the Subscribe this claimed, which TikTok
406
+ // defines as subscribing, paid subscriptions included ([#652]).
407
+ tiktok: { name: 'StartTrial', kind: 'standard', map: tiktokCommerce },
408
+ },
409
+ },
410
+
411
+ // The FIRST real charge after a trial — the funnel step the generic renewal
412
+ // branch used to swallow, which made a conversion indistinguishable from a
413
+ // routine renewal ([#407](https://github.com/Omega-JS-Stack/omega/issues/407)).
414
+ //
415
+ // GA4 hears its standard `purchase`, because this is where the money finally
416
+ // moves and revenue belongs in the revenue report; the pair `is_trial: true` +
417
+ // `is_recurring: false` is what marks it inside that stream, so the conversion
418
+ // is still countable on its own. The ad platforms already heard `StartTrial`
419
+ // at trial start, and every REAL CHARGE is a Purchase to both of them — the
420
+ // one event each documents `value` + `currency` for (Ian's money-event table,
421
+ // [#652](https://github.com/Omega-JS-Stack/omega/issues/652)).
422
+ trial_convert: {
423
+ params: COMMERCE_PARAMS,
424
+ placement: 'server',
425
+ providers: {
426
+ ga4: { name: 'purchase', kind: 'standard' },
427
+ meta: { name: 'Purchase', kind: 'standard', map: metaCommerce, actionSource: 'system_generated' },
428
+ tiktok: { name: 'Purchase', kind: 'standard', map: tiktokCommerce },
429
+ },
430
+ },
431
+
432
+ // The other end of the same funnel: a trial that ended without ever paying.
433
+ // GA4-only, and DELIBERATELY out of the exclusion lane the two entries below
434
+ // joined ([#415](https://github.com/Omega-JS-Stack/omega/issues/415)): a
435
+ // lapsed trialist is a win-back audience worth RETARGETING, not somebody to
436
+ // stop showing ads to. An ad platform optimizes toward conversions, so the
437
+ // failure itself buys nothing either.
438
+ trial_lapse: {
439
+ params: COMMERCE_PARAMS,
440
+ placement: 'server',
441
+ providers: {
442
+ ga4: { name: 'trial_lapse', kind: 'custom' },
443
+ },
444
+ },
445
+
446
+ // GA4's own refund event, fired by the payment webhook's refund transitions.
447
+ // The ad platforms hear a zero-value custom `Refund` — an audience to stop
448
+ // paying to reach, and the one thing they can do with a churn moment.
449
+ refund: {
450
+ params: ['transaction_id', 'value', 'currency', 'items'],
451
+ placement: 'server',
452
+ providers: {
453
+ ga4: { name: 'refund', kind: 'standard' },
454
+ meta: { name: 'Refund', kind: 'custom', map: metaAudienceSignal },
455
+ tiktok: { name: 'Refund', kind: 'custom', map: tiktokAudienceSignal },
456
+ },
457
+ },
458
+
459
+ // The cancellation that TOOK EFFECT. Cancellation-REQUESTED stays event-less by
460
+ // design: a schedule changed, nothing ended, no money moved, and the
461
+ // subscription may never cancel at all.
462
+ subscription_cancel: {
463
+ params: COMMERCE_PARAMS,
464
+ placement: 'server',
465
+ providers: {
466
+ ga4: { name: 'subscription_cancel', kind: 'custom' },
467
+ meta: { name: 'SubscriptionCancel', kind: 'custom', map: metaAudienceSignal },
468
+ tiktok: { name: 'SubscriptionCancel', kind: 'custom', map: tiktokAudienceSignal },
469
+ },
470
+ },
471
+
472
+ // The uncancel — a scheduled cancellation withdrawn. The request had no event
473
+ // to be the pair of, which is the point: a retention win is an outcome, and it
474
+ // was completely dark before [#407].
475
+ subscription_uncancel: {
476
+ params: COMMERCE_PARAMS,
477
+ placement: 'server',
478
+ providers: {
479
+ ga4: { name: 'subscription_uncancel', kind: 'custom' },
480
+ },
481
+ },
482
+
483
+ // An upgrade or downgrade between two paid plans. GA4-only: no money moves at
484
+ // the switch itself, and firing a platform's Subscribe here would count a
485
+ // second subscription for a customer who already has one.
486
+ subscription_plan_change: {
487
+ params: PLAN_CHANGE_PARAMS,
488
+ placement: 'server',
489
+ providers: {
490
+ ga4: { name: 'subscription_plan_change', kind: 'custom' },
491
+ },
492
+ },
493
+
494
+ // A renewal and a recovered payment are CHARGES, so both ad platforms hear
495
+ // Purchase for the real amount. Neither is a Subscribe: Meta defines that as
496
+ // "the START of a paid subscription", and month two starts nothing — the
497
+ // mapping counted a new subscriber every month
498
+ // ([#652](https://github.com/Omega-JS-Stack/omega/issues/652)). GA4 keeps its
499
+ // standard `purchase` with `is_recurring`, and its `transaction_id` is THIS
500
+ // charge's, never the subscription's, or GA4 dedupes every renewal after the
501
+ // first away ([#656](https://github.com/Omega-JS-Stack/omega/issues/656)).
502
+ subscription_renew: {
503
+ params: COMMERCE_PARAMS,
504
+ placement: 'server',
505
+ providers: {
506
+ ga4: { name: 'purchase', kind: 'standard', map: ga4Recurring },
507
+ meta: { name: 'Purchase', kind: 'standard', map: metaCommerce, actionSource: 'system_generated' },
508
+ tiktok: { name: 'Purchase', kind: 'standard', map: tiktokCommerce },
509
+ },
510
+ },
511
+
512
+ payment_recovered: {
513
+ params: COMMERCE_PARAMS,
514
+ placement: 'server',
515
+ providers: {
516
+ ga4: { name: 'purchase', kind: 'standard', map: ga4Recurring },
517
+ meta: { name: 'Purchase', kind: 'standard', map: metaCommerce, actionSource: 'system_generated' },
518
+ tiktok: { name: 'Purchase', kind: 'standard', map: tiktokCommerce },
519
+ },
520
+ },
521
+
522
+ // ─── Engagement ───
523
+
524
+ // Meta's Lead is exactly this ("a submission of information by a customer with
525
+ // the understanding that they may be contacted at a later date"), and TikTok's
526
+ // SubmitForm is the standard event for a form; its Contact means "when a
527
+ // visitor contacts you", which a lead form is not
528
+ // ([#652](https://github.com/Omega-JS-Stack/omega/issues/652)).
529
+ generate_lead: {
530
+ params: ['lead_source', 'subject'],
531
+ placement: 'client',
532
+ providers: {
533
+ ga4: { name: 'generate_lead', kind: 'standard' },
534
+ meta: { name: 'Lead', kind: 'standard' },
535
+ tiktok: { name: 'SubmitForm', kind: 'standard' },
536
+ },
537
+ },
538
+
539
+ // The enterprise "talk to us" path off the pricing page.
540
+ contact_enterprise: {
541
+ params: ['from_page'],
542
+ placement: 'client',
543
+ providers: {
544
+ ga4: { name: 'contact_enterprise', kind: 'custom' },
545
+ meta: { name: 'Contact', kind: 'standard' },
546
+ tiktok: { name: 'Contact', kind: 'standard' },
547
+ },
548
+ },
549
+
550
+ // The contact form's honeypot catch. GA4 only: a spam signal is ours to
551
+ // read, and feeding it to an ad platform would poison the audience.
552
+ contact_form_spam: {
553
+ params: ['content_type'],
554
+ placement: 'client',
555
+ providers: {
556
+ ga4: { name: 'contact_form_spam', kind: 'custom' },
557
+ },
558
+ },
559
+
560
+ // GA4's standard name, replacing the literal `download` today's page sends.
561
+ file_download: {
562
+ params: ['platform', 'download_name', 'download_url'],
563
+ placement: 'client',
564
+ providers: {
565
+ ga4: { name: 'file_download', kind: 'standard' },
566
+ meta: { name: 'Download', kind: 'custom' },
567
+ tiktok: { name: 'Download', kind: 'standard' },
568
+ },
569
+ },
570
+
571
+ // Meta's SubmitApplication is "an application for a product, service or
572
+ // program you offer... a credit card, educational program or job" — feedback
573
+ // applies for nothing, so Meta hears a custom event. TikTok's SubmitForm
574
+ // ("when a visitor submits a form") fits as it stands
575
+ // ([#652](https://github.com/Omega-JS-Stack/omega/issues/652)).
576
+ feedback_submit: {
577
+ params: ['feedback_rating'],
578
+ placement: 'client',
579
+ providers: {
580
+ ga4: { name: 'feedback_submit', kind: 'custom' },
581
+ meta: { name: 'FeedbackSubmit', kind: 'custom' },
582
+ tiktok: { name: 'SubmitForm', kind: 'standard' },
583
+ },
584
+ },
585
+
586
+ // A click through to a review page is neither Meta's Lead (a submission of
587
+ // information) nor TikTok's Contact (a visitor contacting you), so both hear
588
+ // the canonical event as a custom one
589
+ // ([#652](https://github.com/Omega-JS-Stack/omega/issues/652)).
590
+ review_click: {
591
+ params: ['review_url'],
592
+ placement: 'client',
593
+ providers: {
594
+ ga4: { name: 'review_click', kind: 'custom' },
595
+ meta: { name: 'ReviewClick', kind: 'custom' },
596
+ tiktok: { name: 'ReviewClick', kind: 'custom' },
597
+ },
598
+ },
599
+
600
+ // The prompt half of the review pair — ours to read, no ad signal in it.
601
+ review_prompt_show: {
602
+ params: ['review_url'],
603
+ placement: 'client',
604
+ providers: {
605
+ ga4: { name: 'review_prompt_show', kind: 'custom' },
606
+ },
607
+ },
608
+
609
+ search: {
610
+ params: ['search_term', 'content_category'],
611
+ placement: 'client',
612
+ providers: {
613
+ ga4: { name: 'search', kind: 'standard' },
614
+ meta: { name: 'Search', kind: 'standard', map: metaSearch },
615
+ tiktok: { name: 'Search', kind: 'standard', map: tiktokSearch },
616
+ },
617
+ },
618
+
619
+ share: {
620
+ params: ['method', 'content_type', 'item_id'],
621
+ placement: 'client',
622
+ providers: {
623
+ ga4: { name: 'share', kind: 'standard' },
624
+ // Neither platform defines Share — today's sites claim it as standard.
625
+ meta: { name: 'Share', kind: 'custom' },
626
+ tiktok: { name: 'Share', kind: 'custom' },
627
+ },
628
+ },
629
+
630
+ // The share panel's copy-to-clipboard half. ClickButton is on NEITHER
631
+ // platform's standard list — TikTok's own set runs AddPaymentInfo … ViewContent
632
+ // and never names it — so this is a custom event on both, under the canonical
633
+ // name ([#652](https://github.com/Omega-JS-Stack/omega/issues/652)).
634
+ copy_link: {
635
+ params: ['content_type', 'item_id'],
636
+ placement: 'client',
637
+ providers: {
638
+ ga4: { name: 'copy_link', kind: 'custom' },
639
+ meta: { name: 'CopyLink', kind: 'custom' },
640
+ tiktok: { name: 'CopyLink', kind: 'custom' },
641
+ },
642
+ },
643
+
644
+ marketing_newsletter_subscribe: {
645
+ params: ['method'],
646
+ placement: 'client',
647
+ providers: {
648
+ ga4: { name: 'marketing_newsletter_subscribe', kind: 'custom' },
649
+ meta: { name: 'Lead', kind: 'standard' },
650
+ tiktok: { name: 'Subscribe', kind: 'standard' },
651
+ },
652
+ },
653
+
654
+ // The status page's incident-updates opt-in — its own event, keeping its
655
+ // live provider dialect (TikTok reads it as a form submit, not a Subscribe).
656
+ status_subscribe: {
657
+ params: ['method'],
658
+ placement: 'client',
659
+ providers: {
660
+ ga4: { name: 'status_subscribe', kind: 'custom' },
661
+ meta: { name: 'Lead', kind: 'standard' },
662
+ tiktok: { name: 'SubmitForm', kind: 'standard' },
663
+ },
664
+ },
665
+
666
+ // ─── Exit popup ───
667
+
668
+ // The popup trio, all custom on both ad platforms
669
+ // ([#652](https://github.com/Omega-JS-Stack/omega/issues/652)): a popup is not
670
+ // a page view (TikTok's ViewContent is "when a visitor views a specific
671
+ // page"), a click is not Meta's Lead ("a submission of information"), and
672
+ // ClickButton is not on TikTok's standard list at all.
673
+ exit_popup_show: {
674
+ params: ['event_category', 'event_label', 'page_path'],
675
+ placement: 'client',
676
+ providers: {
677
+ ga4: { name: 'exit_popup_show', kind: 'custom' },
678
+ meta: { name: 'ExitPopupShow', kind: 'custom' },
679
+ tiktok: { name: 'ExitPopupShow', kind: 'custom' },
680
+ },
681
+ },
682
+
683
+ exit_popup_click: {
684
+ params: ['event_category', 'event_label', 'destination_url'],
685
+ placement: 'client',
686
+ providers: {
687
+ ga4: { name: 'exit_popup_click', kind: 'custom' },
688
+ meta: { name: 'ExitPopupClick', kind: 'custom' },
689
+ tiktok: { name: 'ExitPopupClick', kind: 'custom' },
690
+ },
691
+ },
692
+
693
+ exit_popup_dismiss: {
694
+ params: ['event_category', 'event_label'],
695
+ placement: 'client',
696
+ providers: {
697
+ ga4: { name: 'exit_popup_dismiss', kind: 'custom' },
698
+ meta: { name: 'ExitPopupDismiss', kind: 'custom' },
699
+ tiktok: { name: 'ExitPopupDismiss', kind: 'custom' },
700
+ },
701
+ },
702
+
703
+ // ─── Cookie consent ───
704
+ // TikTok is deliberately unmapped: consent bookkeeping is not an ad signal.
705
+ // (`cookie_consent_auto_accept` is DROPPED — the new consent system has no
706
+ // auto-accept-on-scroll.)
707
+
708
+ cookie_banner_show: {
709
+ params: ['event_category'],
710
+ placement: 'client',
711
+ providers: {
712
+ ga4: { name: 'cookie_banner_show', kind: 'custom' },
713
+ meta: { name: 'CookieBannerShow', kind: 'custom' },
714
+ },
715
+ },
716
+
717
+ cookie_consent_accept: {
718
+ params: ['event_category', 'consent_type'],
719
+ placement: 'client',
720
+ providers: {
721
+ ga4: { name: 'cookie_consent_accept', kind: 'custom' },
722
+ meta: { name: 'CookieConsentAccept', kind: 'custom' },
723
+ },
724
+ },
725
+
726
+ cookie_consent_deny: {
727
+ params: ['event_category', 'consent_type'],
728
+ placement: 'client',
729
+ providers: {
730
+ ga4: { name: 'cookie_consent_deny', kind: 'custom' },
731
+ meta: { name: 'CookieConsentDeny', kind: 'custom' },
732
+ },
733
+ },
734
+
735
+ cookie_policy_reopen: {
736
+ params: ['event_category'],
737
+ placement: 'client',
738
+ providers: {
739
+ ga4: { name: 'cookie_policy_reopen', kind: 'custom' },
740
+ meta: { name: 'CookiePolicyReopen', kind: 'custom' },
741
+ },
742
+ },
743
+
744
+ // ─── Account & portal ───
745
+ // Action buckets: one event with an `action`/`section_name` param, never a
746
+ // per-action event sprawl (the inventory ruling).
747
+
748
+ user_section_view: {
749
+ params: ['section_name'],
750
+ placement: 'client',
751
+ providers: {
752
+ ga4: { name: 'user_section_view', kind: 'custom' },
753
+ },
754
+ },
755
+
756
+ user_billing_action: {
757
+ params: ['action'],
758
+ placement: 'client',
759
+ providers: {
760
+ ga4: { name: 'user_billing_action', kind: 'custom' },
761
+ },
762
+ },
763
+
764
+ user_refund_request: {
765
+ params: ['action'],
766
+ placement: 'client',
767
+ providers: {
768
+ ga4: { name: 'user_refund_request', kind: 'custom' },
769
+ },
770
+ },
771
+
772
+ user_data_request: {
773
+ params: ['action'],
774
+ placement: 'client',
775
+ providers: {
776
+ ga4: { name: 'user_data_request', kind: 'custom' },
777
+ },
778
+ },
779
+
780
+ marketing_email_subscribe: {
781
+ params: ['content_type'],
782
+ placement: 'client',
783
+ providers: {
784
+ ga4: { name: 'marketing_email_subscribe', kind: 'custom' },
785
+ meta: { name: 'EmailSubscribe', kind: 'custom' },
786
+ },
787
+ },
788
+
789
+ marketing_email_unsubscribe: {
790
+ params: ['content_type'],
791
+ placement: 'client',
792
+ providers: {
793
+ ga4: { name: 'marketing_email_unsubscribe', kind: 'custom' },
794
+ meta: { name: 'EmailUnsubscribe', kind: 'custom' },
795
+ },
796
+ },
797
+
798
+ // ─── Notifications ───
799
+
800
+ notification_permission_request: {
801
+ params: [],
802
+ placement: 'client',
803
+ providers: {
804
+ ga4: { name: 'notification_permission_request', kind: 'custom' },
805
+ },
806
+ },
807
+
808
+ notification_permission_grant: {
809
+ params: [],
810
+ placement: 'client',
811
+ providers: {
812
+ ga4: { name: 'notification_permission_grant', kind: 'custom' },
813
+ },
814
+ },
815
+
816
+ notification_permission_deny: {
817
+ params: [],
818
+ placement: 'client',
819
+ providers: {
820
+ ga4: { name: 'notification_permission_deny', kind: 'custom' },
821
+ },
822
+ },
823
+
824
+ notification_subscribe: {
825
+ params: [],
826
+ placement: 'server',
827
+ providers: {
828
+ ga4: { name: 'notification_subscribe', kind: 'custom' },
829
+ },
830
+ },
831
+
832
+ notification_unsubscribe: {
833
+ params: [],
834
+ placement: 'server',
835
+ providers: {
836
+ ga4: { name: 'notification_unsubscribe', kind: 'custom' },
837
+ },
838
+ },
839
+
840
+ // ─── Surfaces ───
841
+
842
+ vert_click: {
843
+ params: ['vert_id', 'vert_lane', 'vert_campaign', 'vert_slot', 'vert_source'],
844
+ placement: 'client',
845
+ providers: {
846
+ ga4: { name: 'vert_click', kind: 'custom' },
847
+ },
848
+ },
849
+
850
+ extension_install: {
851
+ params: ['browser', 'install_url'],
852
+ placement: 'client',
853
+ providers: {
854
+ ga4: { name: 'extension_install', kind: 'custom' },
855
+ meta: { name: 'ExtensionInstall', kind: 'custom' },
856
+ tiktok: { name: 'Download', kind: 'standard' },
857
+ },
858
+ },
859
+
860
+ app_launch: {
861
+ params: [],
862
+ placement: 'client',
863
+ providers: {
864
+ ga4: { name: 'app_launch', kind: 'custom' },
865
+ },
866
+ },
867
+
868
+ // The 404 page's own event, carrying the path that missed. GA4 only: a broken
869
+ // link is ours to fix, never an ad signal.
870
+ page_not_found: {
871
+ params: ['path'],
872
+ placement: 'client',
873
+ providers: {
874
+ ga4: { name: 'page_not_found', kind: 'custom' },
875
+ },
876
+ },
877
+
878
+ user_delete: {
879
+ params: [],
880
+ placement: 'server',
881
+ providers: {
882
+ ga4: { name: 'user_delete', kind: 'custom' },
883
+ },
884
+ },
885
+ };
886
+
887
+ // The placements an entry may declare.
888
+ const PLACEMENTS = ['client', 'server', 'both'];
889
+
890
+ // The provider kinds a mapping may declare.
891
+ const KINDS = ['standard', 'custom'];
892
+
893
+ /**
894
+ * The catalog entry for a canonical event name, or null when it has none.
895
+ * @param {string} name - The canonical event name.
896
+ * @returns {object|null}
897
+ */
898
+ function entryFor(name) {
899
+ return Object.prototype.hasOwnProperty.call(CATALOG, name) ? CATALOG[name] : null;
900
+ }
901
+
902
+ module.exports = {
903
+ CATALOG,
904
+ PLACEMENTS,
905
+ KINDS,
906
+ entryFor,
907
+ compact,
908
+ };