@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.
- package/LICENSE +98 -0
- package/README.md +1053 -0
- package/bin/omega +2 -0
- package/bin/omega-backend +2 -0
- package/bin/omg +2 -0
- package/cli.js +3 -0
- package/dist/cli/command-table.js +268 -0
- package/dist/cli/commands/auth.js +259 -0
- package/dist/cli/commands/base-command.js +451 -0
- package/dist/cli/commands/build.js +27 -0
- package/dist/cli/commands/clean.js +13 -0
- package/dist/cli/commands/clear.js +11 -0
- package/dist/cli/commands/cwd.js +9 -0
- package/dist/cli/commands/deploy.js +205 -0
- package/dist/cli/commands/emulator-orphans.js +440 -0
- package/dist/cli/commands/emulator.js +1829 -0
- package/dist/cli/commands/firebase-init.js +101 -0
- package/dist/cli/commands/firestore.js +261 -0
- package/dist/cli/commands/indexes.js +51 -0
- package/dist/cli/commands/install.js +151 -0
- package/dist/cli/commands/logs.js +358 -0
- package/dist/cli/commands/mcp.js +41 -0
- package/dist/cli/commands/migrate-markers.js +176 -0
- package/dist/cli/commands/migrate-rules.js +90 -0
- package/dist/cli/commands/migrate.js +59 -0
- package/dist/cli/commands/serve.js +208 -0
- package/dist/cli/commands/setup-tests/base-test.js +174 -0
- package/dist/cli/commands/setup-tests/emulator-config.js +109 -0
- package/dist/cli/commands/setup-tests/env-runtime-config-deprecated.js +47 -0
- package/dist/cli/commands/setup-tests/firebase-admin.js +49 -0
- package/dist/cli/commands/setup-tests/firebase-auth.js +26 -0
- package/dist/cli/commands/setup-tests/firebase-cli.js +26 -0
- package/dist/cli/commands/setup-tests/firebase-functions.js +49 -0
- package/dist/cli/commands/setup-tests/firestore-indexes-file.js +72 -0
- package/dist/cli/commands/setup-tests/firestore-indexes-in-json.js +20 -0
- package/dist/cli/commands/setup-tests/firestore-indexes-required.js +108 -0
- package/dist/cli/commands/setup-tests/firestore-indexes-synced.js +236 -0
- package/dist/cli/commands/setup-tests/firestore-rules-file.js +115 -0
- package/dist/cli/commands/setup-tests/firestore-rules-in-json.js +49 -0
- package/dist/cli/commands/setup-tests/functions-package.js +44 -0
- package/dist/cli/commands/setup-tests/gcloud-cli.js +26 -0
- package/dist/cli/commands/setup-tests/gitignore.js +122 -0
- package/dist/cli/commands/setup-tests/helpers/merge-line-files.js +28 -0
- package/dist/cli/commands/setup-tests/helpers/required-indexes.js +109 -0
- package/dist/cli/commands/setup-tests/helpers/seed-campaigns.js +246 -0
- package/dist/cli/commands/setup-tests/helpers.js +72 -0
- package/dist/cli/commands/setup-tests/hosting-folder.js +23 -0
- package/dist/cli/commands/setup-tests/hosting-rewrites.js +52 -0
- package/dist/cli/commands/setup-tests/index.js +111 -0
- package/dist/cli/commands/setup-tests/is-firebase-project.js +21 -0
- package/dist/cli/commands/setup-tests/java-installed.js +27 -0
- package/dist/cli/commands/setup-tests/legacy-tests-cleanup.js +43 -0
- package/dist/cli/commands/setup-tests/marketing-campaigns-seeded.js +230 -0
- package/dist/cli/commands/setup-tests/node-version.js +60 -0
- package/dist/cli/commands/setup-tests/npm-project-scripts.js +42 -0
- package/dist/cli/commands/setup-tests/nvmrc-version.js +36 -0
- package/dist/cli/commands/setup-tests/omega-backend.js +42 -0
- package/dist/cli/commands/setup-tests/omega-config.js +84 -0
- package/dist/cli/commands/setup-tests/project-directories.js +34 -0
- package/dist/cli/commands/setup-tests/project-id-consistency.js +201 -0
- package/dist/cli/commands/setup-tests/public-html-files.js +22 -0
- package/dist/cli/commands/setup-tests/realtime-rules-file.js +69 -0
- package/dist/cli/commands/setup-tests/realtime-rules-in-json.js +20 -0
- package/dist/cli/commands/setup-tests/remoteconfig-template-file.js +32 -0
- package/dist/cli/commands/setup-tests/remoteconfig-template-in-json.js +31 -0
- package/dist/cli/commands/setup-tests/service-account.js +86 -0
- package/dist/cli/commands/setup-tests/storage-lifecycle-policy.js +81 -0
- package/dist/cli/commands/setup-tests/storage-rules-file.js +32 -0
- package/dist/cli/commands/setup-tests/storage-rules-in-json.js +20 -0
- package/dist/cli/commands/stripe.js +14 -0
- package/dist/cli/commands/test-lanes/stripe-live.js +440 -0
- package/dist/cli/commands/test.js +976 -0
- package/dist/cli/commands/update.js +27 -0
- package/dist/cli/commands/version.js +10 -0
- package/dist/cli/commands/watch.js +196 -0
- package/dist/cli/flags.js +13 -0
- package/dist/cli/index.js +173 -0
- package/dist/cli/run.js +33 -0
- package/dist/cli/utils/attach-log-file.js +4 -0
- package/dist/cli/utils/compile-rules.js +1155 -0
- package/dist/cli/utils/ensure-target.js +314 -0
- package/dist/cli/utils/project-type.js +140 -0
- package/dist/cli/utils/public-files.js +49 -0
- package/dist/cli/utils/safe-install.js +4 -0
- package/dist/cli/utils/spawn-shell.js +94 -0
- package/dist/cli/utils/stage-functions.js +338 -0
- package/dist/cli/utils/stage-local-packages.js +210 -0
- package/dist/cli/utils/target-checks.js +161 -0
- package/dist/cli/utils/target.js +24 -0
- package/dist/cli/utils/ui.js +292 -0
- package/dist/defaults/AGENTS.md +125 -0
- package/dist/defaults/CHANGELOG.md +15 -0
- package/dist/defaults/CLAUDE.md +1 -0
- package/dist/defaults/_.gitignore +65 -0
- package/dist/defaults/docs/README.md +17 -0
- package/dist/defaults/test/README.md +65 -0
- package/dist/defaults/test/_init.js +14 -0
- package/dist/defaults/test/helpers/connect-trap.js +72 -0
- package/dist/defaults/test/unit/registration.test.js +143 -0
- package/dist/defaults/test/unit/rules-posture.test.js +101 -0
- package/dist/defaults/test/unit/socket-free.test.js +43 -0
- package/dist/manager/events/auth/before-create.js +89 -0
- package/dist/manager/events/auth/before-signin.js +76 -0
- package/dist/manager/events/auth/on-create.js +112 -0
- package/dist/manager/events/auth/on-delete.js +141 -0
- package/dist/manager/events/auth/utils.js +93 -0
- package/dist/manager/events/cron/daily/blog-auto-publisher.js +287 -0
- package/dist/manager/events/cron/daily/data-requests.js +57 -0
- package/dist/manager/events/cron/daily/expire-paypal-cancellations.js +191 -0
- package/dist/manager/events/cron/daily/marketing-prune.js +486 -0
- package/dist/manager/events/cron/daily/reset-usage.js +188 -0
- package/dist/manager/events/cron/daily/trial-lapse-sweep.js +355 -0
- package/dist/manager/events/cron/daily.js +3 -0
- package/dist/manager/events/cron/frequent/abandoned-carts.js +204 -0
- package/dist/manager/events/cron/frequent/email-queue.js +71 -0
- package/dist/manager/events/cron/frequent/marketing-campaigns.js +463 -0
- package/dist/manager/events/cron/frequent/retry-failed-webhooks.js +70 -0
- package/dist/manager/events/cron/frequent.js +3 -0
- package/dist/manager/events/cron/runner.js +64 -0
- package/dist/manager/events/firestore/notifications/on-write.js +123 -0
- package/dist/manager/events/firestore/payments-disputes/on-write.js +256 -0
- package/dist/manager/events/firestore/payments-disputes/providers/stripe.js +218 -0
- package/dist/manager/events/firestore/payments-disputes/providers/test.js +231 -0
- package/dist/manager/events/firestore/payments-webhooks/analytics.js +687 -0
- package/dist/manager/events/firestore/payments-webhooks/on-write.js +1224 -0
- package/dist/manager/events/firestore/payments-webhooks/transitions/index.js +395 -0
- package/dist/manager/events/firestore/payments-webhooks/transitions/one-time/purchase-completed.js +58 -0
- package/dist/manager/events/firestore/payments-webhooks/transitions/one-time/purchase-failed.js +28 -0
- package/dist/manager/events/firestore/payments-webhooks/transitions/one-time/purchase-refunded.js +30 -0
- package/dist/manager/events/firestore/payments-webhooks/transitions/send-email.js +74 -0
- package/dist/manager/events/firestore/payments-webhooks/transitions/subscription/cancellation-removed.js +14 -0
- package/dist/manager/events/firestore/payments-webhooks/transitions/subscription/cancellation-requested.js +28 -0
- package/dist/manager/events/firestore/payments-webhooks/transitions/subscription/checkout-declined.js +18 -0
- package/dist/manager/events/firestore/payments-webhooks/transitions/subscription/new-subscription.js +67 -0
- package/dist/manager/events/firestore/payments-webhooks/transitions/subscription/payment-failed.js +25 -0
- package/dist/manager/events/firestore/payments-webhooks/transitions/subscription/payment-recovered.js +26 -0
- package/dist/manager/events/firestore/payments-webhooks/transitions/subscription/payment-refunded.js +34 -0
- package/dist/manager/events/firestore/payments-webhooks/transitions/subscription/plan-changed.js +42 -0
- package/dist/manager/events/firestore/payments-webhooks/transitions/subscription/subscription-cancelled.js +33 -0
- package/dist/manager/events/firestore/payments-webhooks/transitions/subscription/subscription-winback.js +17 -0
- package/dist/manager/functions/_legacy/actions/create-post-handler.js +188 -0
- package/dist/manager/functions/_legacy/actions/generate-uuid.js +63 -0
- package/dist/manager/functions/_legacy/actions/sign-up-handler.js +205 -0
- package/dist/manager/functions/_legacy/admin/create-post.js +207 -0
- package/dist/manager/functions/_legacy/admin/firestore-write.js +72 -0
- package/dist/manager/functions/_legacy/admin/get-stats.js +218 -0
- package/dist/manager/functions/_legacy/admin/query.js +198 -0
- package/dist/manager/functions/_legacy/admin/send-notification.js +206 -0
- package/dist/manager/functions/_legacy/template.js +33 -0
- package/dist/manager/functions/_legacy/test/authenticate.js +40 -0
- package/dist/manager/functions/_legacy/test/webhook.js +37 -0
- package/dist/manager/functions/wrappers/mailchimp/addToList.js +25 -0
- package/dist/manager/helpers/analytics.js +498 -0
- package/dist/manager/helpers/api-manager.js +313 -0
- package/dist/manager/helpers/backend-router.js +37 -0
- package/dist/manager/helpers/context/authenticate.js +215 -0
- package/dist/manager/helpers/context/client-info.js +91 -0
- package/dist/manager/helpers/context/index.js +228 -0
- package/dist/manager/helpers/context/logging.js +150 -0
- package/dist/manager/helpers/context/parse.js +160 -0
- package/dist/manager/helpers/context/respond.js +247 -0
- package/dist/manager/helpers/event-middleware.js +109 -0
- package/dist/manager/helpers/metadata.js +32 -0
- package/dist/manager/helpers/middleware.js +541 -0
- package/dist/manager/helpers/redact-secret.js +25 -0
- package/dist/manager/helpers/resolved-config.js +34 -0
- package/dist/manager/helpers/roles.js +69 -0
- package/dist/manager/helpers/safe-compare.js +31 -0
- package/dist/manager/helpers/schema-engine.js +314 -0
- package/dist/manager/helpers/schema-zod.js +203 -0
- package/dist/manager/helpers/settings.js +215 -0
- package/dist/manager/helpers/usage.js +541 -0
- package/dist/manager/helpers/user.js +57 -0
- package/dist/manager/helpers/utilities.js +565 -0
- package/dist/manager/index.js +1404 -0
- package/dist/manager/libraries/abandoned-cart-config.js +12 -0
- package/dist/manager/libraries/ai/index.js +321 -0
- package/dist/manager/libraries/ai/prompt.js +85 -0
- package/dist/manager/libraries/ai/providers/anthropic-format.js +297 -0
- package/dist/manager/libraries/ai/providers/anthropic.js +169 -0
- package/dist/manager/libraries/ai/providers/claude-code.js +183 -0
- package/dist/manager/libraries/ai/providers/openai.js +1272 -0
- package/dist/manager/libraries/ai/providers/test.js +257 -0
- package/dist/manager/libraries/ai/tokens.js +54 -0
- package/dist/manager/libraries/analytics/conversions.js +478 -0
- package/dist/manager/libraries/analytics/match-data.js +573 -0
- package/dist/manager/libraries/analytics/signup.js +120 -0
- package/dist/manager/libraries/auth-user.js +46 -0
- package/dist/manager/libraries/content/feed-parser.js +198 -0
- package/dist/manager/libraries/content/ghostii.js +191 -0
- package/dist/manager/libraries/content/source-resolver.js +629 -0
- package/dist/manager/libraries/email/constants.js +532 -0
- package/dist/manager/libraries/email/data/blocked-local-parts.json +55 -0
- package/dist/manager/libraries/email/data/blocked-local-patterns.js +14 -0
- package/dist/manager/libraries/email/data/corporate-domains.json +23 -0
- package/dist/manager/libraries/email/data/custom-disposable-domains.json +58 -0
- package/dist/manager/libraries/email/data/disposable-domains.json +8184 -0
- package/dist/manager/libraries/email/data/typo-domains.js +83 -0
- package/dist/manager/libraries/email/disposable-domains.js +92 -0
- package/dist/manager/libraries/email/generators/lib/filter.js +179 -0
- package/dist/manager/libraries/email/generators/lib/image-host.js +344 -0
- package/dist/manager/libraries/email/generators/lib/image-illustrator.js +154 -0
- package/dist/manager/libraries/email/generators/lib/markdown-renderer.js +294 -0
- package/dist/manager/libraries/email/generators/lib/mjml-template.js +120 -0
- package/dist/manager/libraries/email/generators/lib/structure.js +299 -0
- package/dist/manager/libraries/email/generators/lib/svg-illustrator.js +197 -0
- package/dist/manager/libraries/email/generators/lib/templates/base.js +229 -0
- package/dist/manager/libraries/email/generators/lib/templates/card.js +33 -0
- package/dist/manager/libraries/email/generators/lib/templates/classic-schema.js +59 -0
- package/dist/manager/libraries/email/generators/lib/templates/clean.js +82 -0
- package/dist/manager/libraries/email/generators/lib/templates/editorial/helpers.js +100 -0
- package/dist/manager/libraries/email/generators/lib/templates/editorial/index.js +318 -0
- package/dist/manager/libraries/email/generators/lib/templates/feedback.js +101 -0
- package/dist/manager/libraries/email/generators/lib/templates/field-report/helpers.js +138 -0
- package/dist/manager/libraries/email/generators/lib/templates/field-report/index.js +494 -0
- package/dist/manager/libraries/email/generators/lib/templates/index.js +47 -0
- package/dist/manager/libraries/email/generators/lib/templates/newsletter-shared.js +610 -0
- package/dist/manager/libraries/email/generators/lib/templates/order.js +461 -0
- package/dist/manager/libraries/email/generators/lib/templates/plain.js +83 -0
- package/dist/manager/libraries/email/generators/lib/templates/shared-campaign.js +64 -0
- package/dist/manager/libraries/email/generators/newsletter.js +899 -0
- package/dist/manager/libraries/email/index.js +146 -0
- package/dist/manager/libraries/email/marketing/index.js +754 -0
- package/dist/manager/libraries/email/prepare.js +365 -0
- package/dist/manager/libraries/email/providers/beehiiv.js +589 -0
- package/dist/manager/libraries/email/providers/sendgrid.js +845 -0
- package/dist/manager/libraries/email/transactional/index.js +510 -0
- package/dist/manager/libraries/email/utm.js +86 -0
- package/dist/manager/libraries/email/validation-provider-neverbounce.js +70 -0
- package/dist/manager/libraries/email/validation-provider-zerobounce.js +42 -0
- package/dist/manager/libraries/email/validation.js +255 -0
- package/dist/manager/libraries/env.js +198 -0
- package/dist/manager/libraries/infer-contact.js +101 -0
- package/dist/manager/libraries/load-provider.js +65 -0
- package/dist/manager/libraries/notification.js +256 -0
- package/dist/manager/libraries/openai.js +13 -0
- package/dist/manager/libraries/payment/discount-codes.js +204 -0
- package/dist/manager/libraries/payment/fetch-failure.js +56 -0
- package/dist/manager/libraries/payment/license.js +44 -0
- package/dist/manager/libraries/payment/order-id.js +57 -0
- package/dist/manager/libraries/payment/provider-errors.js +71 -0
- package/dist/manager/libraries/payment/providers/chargebee.js +817 -0
- package/dist/manager/libraries/payment/providers/coinbase.js +330 -0
- package/dist/manager/libraries/payment/providers/paypal.js +987 -0
- package/dist/manager/libraries/payment/providers/stripe.js +755 -0
- package/dist/manager/libraries/payment/providers/test.js +250 -0
- package/dist/manager/libraries/payment/refund-linkage.js +78 -0
- package/dist/manager/libraries/payment/refund-policy.js +113 -0
- package/dist/manager/libraries/payment/winback.js +55 -0
- package/dist/manager/libraries/prompts/infer-contact.md +78 -0
- package/dist/manager/libraries/rate-limits.js +17 -0
- package/dist/manager/libraries/recaptcha.js +58 -0
- package/dist/manager/libraries/user-doc.js +234 -0
- package/dist/manager/routes/admin/backup/post.js +106 -0
- package/dist/manager/routes/admin/cron/post.js +37 -0
- package/dist/manager/routes/admin/database/get.js +35 -0
- package/dist/manager/routes/admin/database/post.js +34 -0
- package/dist/manager/routes/admin/email/post.js +74 -0
- package/dist/manager/routes/admin/firestore/get.js +35 -0
- package/dist/manager/routes/admin/firestore/post.js +56 -0
- package/dist/manager/routes/admin/firestore/query/post.js +128 -0
- package/dist/manager/routes/admin/hook/post.js +104 -0
- package/dist/manager/routes/admin/infer-contact/post.js +35 -0
- package/dist/manager/routes/admin/notification/post.js +37 -0
- package/dist/manager/routes/admin/payment/post.js +56 -0
- package/dist/manager/routes/admin/post/deduplicate-image-alts.js +52 -0
- package/dist/manager/routes/admin/post/dispatch-deploy.js +36 -0
- package/dist/manager/routes/admin/post/post.js +487 -0
- package/dist/manager/routes/admin/post/put.js +146 -0
- package/dist/manager/routes/admin/post/templates/post.html +14 -0
- package/dist/manager/routes/admin/repo/content/post.js +106 -0
- package/dist/manager/routes/admin/stats/get.js +222 -0
- package/dist/manager/routes/admin/users/disable/post.js +50 -0
- package/dist/manager/routes/admin/users/list/get.js +110 -0
- package/dist/manager/routes/admin/users/sync/post.js +119 -0
- package/dist/manager/routes/brand/get.js +26 -0
- package/dist/manager/routes/content/post/get.js +110 -0
- package/dist/manager/routes/general/email/post.js +89 -0
- package/dist/manager/routes/general/email/templates/general/download-app-link.js +42 -0
- package/dist/manager/routes/general/uuid/post.js +31 -0
- package/dist/manager/routes/handler/post/post.js +142 -0
- package/dist/manager/routes/health/get.js +43 -0
- package/dist/manager/routes/index.js +11 -0
- package/dist/manager/routes/marketing/campaign/delete.js +45 -0
- package/dist/manager/routes/marketing/campaign/get.js +69 -0
- package/dist/manager/routes/marketing/campaign/post.js +124 -0
- package/dist/manager/routes/marketing/campaign/put.js +86 -0
- package/dist/manager/routes/marketing/campaign/utils.js +59 -0
- package/dist/manager/routes/marketing/contact/delete.js +100 -0
- package/dist/manager/routes/marketing/contact/post.js +149 -0
- package/dist/manager/routes/marketing/contact/put.js +37 -0
- package/dist/manager/routes/marketing/email-preferences/post.js +275 -0
- package/dist/manager/routes/marketing/webhook/forward/post.js +170 -0
- package/dist/manager/routes/marketing/webhook/post.js +123 -0
- package/dist/manager/routes/marketing/webhook/providers/beehiiv.js +197 -0
- package/dist/manager/routes/marketing/webhook/providers/sendgrid.js +194 -0
- package/dist/manager/routes/payments/cancel/_is-trialing.js +40 -0
- package/dist/manager/routes/payments/cancel/post.js +149 -0
- package/dist/manager/routes/payments/cancel/providers/chargebee.js +41 -0
- package/dist/manager/routes/payments/cancel/providers/paypal.js +56 -0
- package/dist/manager/routes/payments/cancel/providers/stripe.js +33 -0
- package/dist/manager/routes/payments/cancel/providers/test.js +118 -0
- package/dist/manager/routes/payments/discount/get.js +25 -0
- package/dist/manager/routes/payments/dispute-alert/post.js +117 -0
- package/dist/manager/routes/payments/dispute-alert/providers/chargeblast.js +55 -0
- package/dist/manager/routes/payments/intent/post.js +341 -0
- package/dist/manager/routes/payments/intent/providers/chargebee.js +197 -0
- package/dist/manager/routes/payments/intent/providers/coinbase.js +94 -0
- package/dist/manager/routes/payments/intent/providers/paypal.js +244 -0
- package/dist/manager/routes/payments/intent/providers/stripe.js +141 -0
- package/dist/manager/routes/payments/intent/providers/test.js +341 -0
- package/dist/manager/routes/payments/plan/post.js +147 -0
- package/dist/manager/routes/payments/plan/providers/chargebee.js +62 -0
- package/dist/manager/routes/payments/plan/providers/paypal.js +62 -0
- package/dist/manager/routes/payments/plan/providers/stripe.js +59 -0
- package/dist/manager/routes/payments/plan/providers/test.js +113 -0
- package/dist/manager/routes/payments/portal/post.js +113 -0
- package/dist/manager/routes/payments/portal/providers/chargebee.js +62 -0
- package/dist/manager/routes/payments/portal/providers/paypal.js +25 -0
- package/dist/manager/routes/payments/portal/providers/stripe.js +62 -0
- package/dist/manager/routes/payments/portal/providers/test.js +18 -0
- package/dist/manager/routes/payments/refund/post.js +207 -0
- package/dist/manager/routes/payments/refund/providers/chargebee.js +147 -0
- package/dist/manager/routes/payments/refund/providers/coinbase.js +40 -0
- package/dist/manager/routes/payments/refund/providers/paypal.js +239 -0
- package/dist/manager/routes/payments/refund/providers/stripe.js +160 -0
- package/dist/manager/routes/payments/refund/providers/test.js +204 -0
- package/dist/manager/routes/payments/trial-eligibility/get.js +29 -0
- package/dist/manager/routes/payments/uncancel/post.js +106 -0
- package/dist/manager/routes/payments/uncancel/providers/chargebee.js +30 -0
- package/dist/manager/routes/payments/uncancel/providers/paypal.js +25 -0
- package/dist/manager/routes/payments/uncancel/providers/stripe.js +27 -0
- package/dist/manager/routes/payments/uncancel/providers/test.js +114 -0
- package/dist/manager/routes/payments/webhook/post.js +157 -0
- package/dist/manager/routes/payments/webhook/providers/chargebee.js +218 -0
- package/dist/manager/routes/payments/webhook/providers/coinbase.js +91 -0
- package/dist/manager/routes/payments/webhook/providers/paypal.js +214 -0
- package/dist/manager/routes/payments/webhook/providers/stripe.js +182 -0
- package/dist/manager/routes/payments/webhook/providers/test.js +18 -0
- package/dist/manager/routes/payments/winback/post.js +276 -0
- package/dist/manager/routes/payments/winback/providers/chargebee.js +24 -0
- package/dist/manager/routes/payments/winback/providers/paypal.js +22 -0
- package/dist/manager/routes/payments/winback/providers/stripe.js +41 -0
- package/dist/manager/routes/payments/winback/providers/test.js +42 -0
- package/dist/manager/routes/restart/index.js +37 -0
- package/dist/manager/routes/special/electron-client/post.js +59 -0
- package/dist/manager/routes/test/authenticate/get.js +11 -0
- package/dist/manager/routes/test/health/get.js +8 -0
- package/dist/manager/routes/test/index.js +16 -0
- package/dist/manager/routes/test/lab/post.js +17 -0
- package/dist/manager/routes/test/redirect/get.js +27 -0
- package/dist/manager/routes/test/reset-account/post.js +79 -0
- package/dist/manager/routes/test/roster/get.js +40 -0
- package/dist/manager/routes/test/schema/post.js +20 -0
- package/dist/manager/routes/test/usage/post.js +44 -0
- package/dist/manager/routes/test/webhook/post.js +21 -0
- package/dist/manager/routes/user/api-keys/post.js +51 -0
- package/dist/manager/routes/user/connections/_context.js +194 -0
- package/dist/manager/routes/user/connections/_grant.js +247 -0
- package/dist/manager/routes/user/connections/_lease.js +184 -0
- package/dist/manager/routes/user/connections/_providers.js +191 -0
- package/dist/manager/routes/user/connections/_state.js +117 -0
- package/dist/manager/routes/user/connections/delete.js +55 -0
- package/dist/manager/routes/user/connections/get.js +167 -0
- package/dist/manager/routes/user/connections/post.js +370 -0
- package/dist/manager/routes/user/connections/providers/discord.js +41 -0
- package/dist/manager/routes/user/connections/providers/google.js +55 -0
- package/dist/manager/routes/user/connections/providers/kick.js +68 -0
- package/dist/manager/routes/user/connections/providers/spotify.js +40 -0
- package/dist/manager/routes/user/connections/providers/twitch.js +52 -0
- package/dist/manager/routes/user/data-request/delete.js +84 -0
- package/dist/manager/routes/user/data-request/get.js +229 -0
- package/dist/manager/routes/user/data-request/post.js +136 -0
- package/dist/manager/routes/user/delete.js +149 -0
- package/dist/manager/routes/user/feedback/post.js +81 -0
- package/dist/manager/routes/user/get.js +14 -0
- package/dist/manager/routes/user/orders/get.js +95 -0
- package/dist/manager/routes/user/sessions/delete.js +95 -0
- package/dist/manager/routes/user/sessions/get.js +40 -0
- package/dist/manager/routes/user/settings/validate/post.js +86 -0
- package/dist/manager/routes/user/signup/post.js +662 -0
- package/dist/manager/routes/user/subscription/get.js +77 -0
- package/dist/manager/routes/user/token/post.js +30 -0
- package/dist/manager/routes/verts/delete.js +43 -0
- package/dist/manager/routes/verts/get.js +49 -0
- package/dist/manager/routes/verts/post.js +61 -0
- package/dist/manager/routes/verts/put.js +75 -0
- package/dist/manager/routes/verts/redirect/get.js +36 -0
- package/dist/manager/routes/verts/serve/get.js +67 -0
- package/dist/manager/routes/verts/utils.js +436 -0
- package/dist/manager/schemas/admin/backup/post.js +8 -0
- package/dist/manager/schemas/admin/cron/post.js +8 -0
- package/dist/manager/schemas/admin/database/get.js +5 -0
- package/dist/manager/schemas/admin/database/post.js +6 -0
- package/dist/manager/schemas/admin/email/post.js +31 -0
- package/dist/manager/schemas/admin/firestore/get.js +5 -0
- package/dist/manager/schemas/admin/firestore/post.js +8 -0
- package/dist/manager/schemas/admin/firestore/query/post.js +5 -0
- package/dist/manager/schemas/admin/hook/post.js +8 -0
- package/dist/manager/schemas/admin/infer-contact/post.js +6 -0
- package/dist/manager/schemas/admin/notification/post.js +23 -0
- package/dist/manager/schemas/admin/payment/post.js +8 -0
- package/dist/manager/schemas/admin/post/post.js +23 -0
- package/dist/manager/schemas/admin/post/put.js +13 -0
- package/dist/manager/schemas/admin/repo/content/post.js +10 -0
- package/dist/manager/schemas/admin/stats/get.js +5 -0
- package/dist/manager/schemas/admin/users/disable/post.js +9 -0
- package/dist/manager/schemas/admin/users/list/get.js +10 -0
- package/dist/manager/schemas/admin/users/sync/post.js +7 -0
- package/dist/manager/schemas/brand/get.js +3 -0
- package/dist/manager/schemas/content/post/get.js +8 -0
- package/dist/manager/schemas/general/email/post.js +10 -0
- package/dist/manager/schemas/general/uuid/post.js +9 -0
- package/dist/manager/schemas/handler/post/post.js +13 -0
- package/dist/manager/schemas/health/get.js +3 -0
- package/dist/manager/schemas/marketing/campaign/delete.js +8 -0
- package/dist/manager/schemas/marketing/campaign/get.js +13 -0
- package/dist/manager/schemas/marketing/campaign/post.js +43 -0
- package/dist/manager/schemas/marketing/campaign/put.js +37 -0
- package/dist/manager/schemas/marketing/contact/delete.js +8 -0
- package/dist/manager/schemas/marketing/contact/post.js +14 -0
- package/dist/manager/schemas/marketing/contact/put.js +8 -0
- package/dist/manager/schemas/marketing/email-preferences/post.js +15 -0
- package/dist/manager/schemas/marketing/webhook/forward/post.js +8 -0
- package/dist/manager/schemas/marketing/webhook/post.js +7 -0
- package/dist/manager/schemas/payments/cancel/post.js +15 -0
- package/dist/manager/schemas/payments/discount/get.js +8 -0
- package/dist/manager/schemas/payments/dispute-alert/post.js +6 -0
- package/dist/manager/schemas/payments/intent/post.js +28 -0
- package/dist/manager/schemas/payments/plan/post.js +11 -0
- package/dist/manager/schemas/payments/portal/post.js +12 -0
- package/dist/manager/schemas/payments/refund/post.js +14 -0
- package/dist/manager/schemas/payments/trial-eligibility/get.js +7 -0
- package/dist/manager/schemas/payments/uncancel/post.js +9 -0
- package/dist/manager/schemas/payments/webhook/post.js +6 -0
- package/dist/manager/schemas/payments/winback/post.js +12 -0
- package/dist/manager/schemas/restart/index.js +5 -0
- package/dist/manager/schemas/special/electron-client/post.js +11 -0
- package/dist/manager/schemas/test/authenticate/get.js +3 -0
- package/dist/manager/schemas/test/health/get.js +3 -0
- package/dist/manager/schemas/test/index.js +5 -0
- package/dist/manager/schemas/test/lab/post.js +3 -0
- package/dist/manager/schemas/test/redirect/get.js +7 -0
- package/dist/manager/schemas/test/reset-account/post.js +3 -0
- package/dist/manager/schemas/test/roster/get.js +3 -0
- package/dist/manager/schemas/test/schema/post.js +70 -0
- package/dist/manager/schemas/test/usage/post.js +8 -0
- package/dist/manager/schemas/test/webhook/post.js +7 -0
- package/dist/manager/schemas/user/api-keys/post.js +6 -0
- package/dist/manager/schemas/user/connections/delete.js +8 -0
- package/dist/manager/schemas/user/connections/get.js +21 -0
- package/dist/manager/schemas/user/connections/post.js +12 -0
- package/dist/manager/schemas/user/data-request/delete.js +3 -0
- package/dist/manager/schemas/user/data-request/get.js +5 -0
- package/dist/manager/schemas/user/data-request/post.js +6 -0
- package/dist/manager/schemas/user/delete.js +6 -0
- package/dist/manager/schemas/user/feedback/post.js +8 -0
- package/dist/manager/schemas/user/get.js +3 -0
- package/dist/manager/schemas/user/orders/get.js +6 -0
- package/dist/manager/schemas/user/sessions/delete.js +6 -0
- package/dist/manager/schemas/user/sessions/get.js +6 -0
- package/dist/manager/schemas/user/settings/validate/post.js +8 -0
- package/dist/manager/schemas/user/signup/post.js +27 -0
- package/dist/manager/schemas/user/subscription/get.js +5 -0
- package/dist/manager/schemas/user/token/post.js +5 -0
- package/dist/manager/schemas/verts/delete.js +8 -0
- package/dist/manager/schemas/verts/get.js +9 -0
- package/dist/manager/schemas/verts/post.js +23 -0
- package/dist/manager/schemas/verts/put.js +20 -0
- package/dist/manager/schemas/verts/redirect/get.js +10 -0
- package/dist/manager/schemas/verts/serve/get.js +14 -0
- package/dist/manager/server-manager.js +69 -0
- package/dist/mcp/client.js +98 -0
- package/dist/mcp/handler.js +521 -0
- package/dist/mcp/index.js +157 -0
- package/dist/mcp/tools.js +555 -0
- package/dist/mcp/utils.js +108 -0
- package/dist/omega-bin.js +6 -0
- package/dist/require.js +3 -0
- package/dist/test/fixtures/firebase-project/.firebaserc +5 -0
- package/dist/test/fixtures/firebase-project/config/omega.json5 +131 -0
- package/dist/test/fixtures/firebase-project/database.rules.json +6 -0
- package/dist/test/fixtures/firebase-project/firebase.json +49 -0
- package/dist/test/fixtures/firebase-project/firestore.indexes.json +4 -0
- package/dist/test/fixtures/firebase-project/package.json +14 -0
- package/dist/test/fixtures/firebase-project/src/index.js +11 -0
- package/dist/test/fixtures/firebase-project/storage.rules +8 -0
- package/dist/test/parse-audit.js +25 -0
- package/dist/test/run-tests.js +90 -0
- package/dist/test/runner.js +982 -0
- package/dist/test/seed.js +242 -0
- package/dist/test/test-accounts.js +2660 -0
- package/dist/test/utils/assertions.js +189 -0
- package/dist/test/utils/email-capture.js +252 -0
- package/dist/test/utils/extended-mode-warning.js +11 -0
- package/dist/test/utils/firestore-rules-client.js +277 -0
- package/dist/test/utils/http-client.js +228 -0
- package/dist/test/utils/test-mode-file.js +192 -0
- package/dist/utils/merge-line-files.js +6 -0
- package/dist/utils/scaffold-defaults.js +71 -0
- package/dist/utils/test-lanes.js +62 -0
- package/dist/vendor/account/engine.js +182 -0
- package/dist/vendor/account/features.js +220 -0
- package/dist/vendor/account/index.js +53 -0
- package/dist/vendor/account/schema.js +272 -0
- package/dist/vendor/account/subscription.js +38 -0
- package/dist/vendor/analytics/adapters/ga4.js +26 -0
- package/dist/vendor/analytics/adapters/meta.js +26 -0
- package/dist/vendor/analytics/adapters/resolve.js +130 -0
- package/dist/vendor/analytics/adapters/tiktok.js +27 -0
- package/dist/vendor/analytics/catalog.js +908 -0
- package/dist/vendor/analytics/identity.js +136 -0
- package/dist/vendor/config/company.js +31 -0
- package/dist/vendor/config/defaults.js +173 -0
- package/dist/vendor/config/demo.js +18 -0
- package/dist/vendor/config/desktop-artifacts.js +110 -0
- package/dist/vendor/config/edit.js +769 -0
- package/dist/vendor/config/env-delivery.js +145 -0
- package/dist/vendor/config/env-rules.js +93 -0
- package/dist/vendor/config/env-schema.js +1078 -0
- package/dist/vendor/config/env.js +445 -0
- package/dist/vendor/config/hooks.js +97 -0
- package/dist/vendor/config/index.js +237 -0
- package/dist/vendor/config/instances.js +208 -0
- package/dist/vendor/config/load.js +490 -0
- package/dist/vendor/config/merge.js +68 -0
- package/dist/vendor/config/order.js +139 -0
- package/dist/vendor/config/ports.js +374 -0
- package/dist/vendor/config/providers.js +32 -0
- package/dist/vendor/config/repo.js +142 -0
- package/dist/vendor/config/retired-keys.js +430 -0
- package/dist/vendor/config/schema.js +1610 -0
- package/dist/vendor/config/secrets.js +50 -0
- package/dist/vendor/config/seed.js +34 -0
- package/dist/vendor/config/site-global.js +205 -0
- package/dist/vendor/config/validate.js +554 -0
- package/dist/vendor/config/winback.js +61 -0
- package/dist/vendor/devkit/attach-log-file.js +262 -0
- package/dist/vendor/devkit/bare-requires.js +153 -0
- package/dist/vendor/devkit/command-path.js +46 -0
- package/dist/vendor/devkit/defaults-engine.js +372 -0
- package/dist/vendor/devkit/deploy-record.js +180 -0
- package/dist/vendor/devkit/deploy.js +286 -0
- package/dist/vendor/devkit/license.js +155 -0
- package/dist/vendor/devkit/local-https.js +360 -0
- package/dist/vendor/devkit/local.js +1905 -0
- package/dist/vendor/devkit/logger.js +128 -0
- package/dist/vendor/devkit/merge-line-files.js +296 -0
- package/dist/vendor/devkit/npm-registry.js +52 -0
- package/dist/vendor/devkit/omega-bin.js +345 -0
- package/dist/vendor/devkit/parse-audit.js +74 -0
- package/dist/vendor/devkit/safe-install.js +18 -0
- package/dist/vendor/devkit/scaffold-guard.js +96 -0
- package/dist/vendor/devkit/stop-signals.js +28 -0
- package/dist/vendor/devkit/test/assert.js +120 -0
- package/dist/vendor/devkit/test/define-cases.js +104 -0
- package/dist/vendor/devkit/test/runner-core.js +554 -0
- package/dist/vendor/devkit/test/scope.js +162 -0
- package/dist/vendor/devkit/update.js +569 -0
- package/dist/vendor/monitoring/core.js +180 -0
- package/dist/vendor/monitoring/env.js +49 -0
- package/dist/vendor/monitoring/logger.js +39 -0
- package/dist/vendor/monitoring/node.js +72 -0
- package/docs/admin-post-route.md +57 -0
- package/docs/ai-library.md +171 -0
- package/docs/architecture.md +62 -0
- package/docs/audit.md +70 -0
- package/docs/auth-hooks.md +74 -0
- package/docs/build-system.md +65 -0
- package/docs/cdp-debugging.md +29 -0
- package/docs/cli-firestore-auth.md +85 -0
- package/docs/cli-logs.md +67 -0
- package/docs/cli-output.md +146 -0
- package/docs/code-patterns.md +77 -0
- package/docs/common-mistakes.md +12 -0
- package/docs/common-operations.md +60 -0
- package/docs/connections.md +212 -0
- package/docs/consent.md +362 -0
- package/docs/directory-structure.md +150 -0
- package/docs/email-system.md +459 -0
- package/docs/environment-detection.md +93 -0
- package/docs/file-naming.md +10 -0
- package/docs/firestore.md +134 -0
- package/docs/ghostii.md +240 -0
- package/docs/index.md +299 -0
- package/docs/key-files.md +37 -0
- package/docs/logging.md +60 -0
- package/docs/marketing-campaigns.md +407 -0
- package/docs/marketing-fields.md +25 -0
- package/docs/mcp.md +222 -0
- package/docs/migration.md +129 -0
- package/docs/payment-system.md +856 -0
- package/docs/paypal-sandbox-qa.md +105 -0
- package/docs/response-headers.md +9 -0
- package/docs/routes.md +211 -0
- package/docs/sanitization.md +71 -0
- package/docs/schemas.md +163 -0
- package/docs/shared/agent-docs.md +89 -0
- package/docs/shared/analytics.md +612 -0
- package/docs/shared/brands.md +51 -0
- package/docs/shared/breaking-changes.md +497 -0
- package/docs/shared/config.md +1387 -0
- package/docs/shared/deploys.md +215 -0
- package/docs/shared/icons.md +201 -0
- package/docs/shared/local-dev.md +147 -0
- package/docs/shared/logging.md +202 -0
- package/docs/shared/monitoring.md +153 -0
- package/docs/shared/publishing.md +183 -0
- package/docs/shared/rulings.md +34 -0
- package/docs/shared/testing.md +147 -0
- package/docs/shared/theming.md +604 -0
- package/docs/shared/translation.md +291 -0
- package/docs/shared/updates.md +61 -0
- package/docs/stripe-webhook-forwarding.md +20 -0
- package/docs/test-boot-layer.md +67 -0
- package/docs/test-framework.md +583 -0
- package/docs/usage-rate-limiting.md +121 -0
- package/docs/verts.md +29 -0
- package/package.json +143 -0
- package/templates/config/omega.json5 +322 -0
- package/templates/database.rules.json +82 -0
- package/templates/firebase.json +67 -0
- package/templates/firestore.framework.rules +191 -0
- package/templates/firestore.indexes.json +4 -0
- package/templates/firestore.rules +59 -0
- package/templates/index.js +12 -0
- package/templates/public/404.html +26 -0
- package/templates/public/index.html +24 -0
- package/templates/remoteconfig.template.json +1 -0
- package/templates/storage-lifecycle-config-1-day.json +9 -0
- package/templates/storage-lifecycle-config-30-days.json +9 -0
- package/templates/storage.rules +11 -0
- package/test/_init/accounts-validation.js +58 -0
- package/test/ai/tools-live.test.js +171 -0
- package/test/analytics/conversion-delivery.test.js +1013 -0
- package/test/analytics/match-normalization.test.js +238 -0
- package/test/analytics/signup-conversion.test.js +135 -0
- package/test/boot/cli-dispatch.test.js +142 -0
- package/test/boot/defaults-scaffold.test.js +248 -0
- package/test/boot/deploy-staging.test.js +446 -0
- package/test/boot/disposable-domains.test.js +154 -0
- package/test/boot/emulator-boots.test.js +39 -0
- package/test/boot/emulator-port-preflight.test.js +126 -0
- package/test/boot/emulator-ready-timeout.test.js +46 -0
- package/test/boot/project-id-refresh.test.js +73 -0
- package/test/boot/suite-portability.test.js +278 -0
- package/test/boot/update-command.test.js +63 -0
- package/test/cli/cross-platform.test.js +168 -0
- package/test/cli/custom-project-type.test.js +426 -0
- package/test/cli/deploy-license-env.test.js +100 -0
- package/test/cli/emulator-adoption.test.js +254 -0
- package/test/cli/emulator-orphans.test.js +658 -0
- package/test/cli/emulator-ownership.test.js +177 -0
- package/test/cli/emulator-port-retry.test.js +395 -0
- package/test/cli/emulator-shutdown.test.js +788 -0
- package/test/cli/emulator-stale-reap.test.js +574 -0
- package/test/cli/ensure-target.test.js +325 -0
- package/test/cli/flags.test.js +64 -0
- package/test/cli/https-trust.test.js +38 -0
- package/test/cli/install-update-dispatch.test.js +47 -0
- package/test/cli/lane-environments.test.js +159 -0
- package/test/cli/marketing-campaigns-seeded.test.js +194 -0
- package/test/cli/migrate-bare-requires.test.js +128 -0
- package/test/cli/migrate-markers.test.js +530 -0
- package/test/cli/required-indexes.test.js +64 -0
- package/test/cli/rules-compile.test.js +622 -0
- package/test/cli/rules-migration-deferral.test.js +259 -0
- package/test/cli/rules-version.test.js +104 -0
- package/test/cli/setup-load-files.test.js +66 -0
- package/test/cli/setup-offline-mode.test.js +276 -0
- package/test/cli/setup-retired.test.js +64 -0
- package/test/cli/setup-shared-project-indexes.test.js +262 -0
- package/test/cli/setup-tests-requires.test.js +45 -0
- package/test/cli/stage-env-compose.test.js +316 -0
- package/test/cli/stripe-live-lane.test.js +303 -0
- package/test/cli/target.test.js +182 -0
- package/test/cli/templates.test.js +66 -0
- package/test/cli/test-runner-env.test.js +115 -0
- package/test/cli/test-stack-shutdown.test.js +275 -0
- package/test/cli/test-target-no-match.test.js +128 -0
- package/test/cli/verb-logs.test.js +118 -0
- package/test/cli/version-dispatch.test.js +39 -0
- package/test/content/blog-generate.test.js +164 -0
- package/test/email/campaign-config-fault.test.js +376 -0
- package/test/email/campaign-cron-pipeline.test.js +536 -0
- package/test/email/campaign-send.test.js +47 -0
- package/test/email/consent-lifecycle.test.js +258 -0
- package/test/email/content-html-policy.test.js +270 -0
- package/test/email/feedback-and-plain-send.test.js +54 -0
- package/test/email/fixtures/clean.json +30 -0
- package/test/email/fixtures/editorial.json +30 -0
- package/test/email/fixtures/field-report.json +53 -0
- package/test/email/identity.test.js +321 -0
- package/test/email/marketing/consent-gate.test.js +265 -0
- package/test/email/marketing/custom-fields-catalog.test.js +259 -0
- package/test/email/marketing/prune-per-provider.test.js +762 -0
- package/test/email/marketing/remove-log-privacy.test.js +225 -0
- package/test/email/marketing-lifecycle.test.js +139 -0
- package/test/email/newsletter-generate.test.js +853 -0
- package/test/email/newsletter-svg-tokens.test.js +51 -0
- package/test/email/newsletter-templates.test.js +492 -0
- package/test/email/order-one-time-cta.test.js +97 -0
- package/test/email/render-content.test.js +248 -0
- package/test/email/safe-url.test.js +0 -0
- package/test/email/sanitize-images.test.js +66 -0
- package/test/email/send-log-privacy.test.js +107 -0
- package/test/email/templates.test.js +288 -0
- package/test/email/testing-capture.test.js +260 -0
- package/test/email/transactional-send.test.js +36 -0
- package/test/email/transactional.test.js +562 -0
- package/test/email/unsubscribe-groups.test.js +155 -0
- package/test/email/unsubscribe-key.test.js +91 -0
- package/test/email/validation-cases.test.js +152 -0
- package/test/email/validation.test.js +746 -0
- package/test/events/auth-delete-conversion.test.js +138 -0
- package/test/events/auth-delete-race.test.js +211 -0
- package/test/events/auth-on-create-log.test.js +164 -0
- package/test/events/auth-signup-conversion.test.js +141 -0
- package/test/events/auth-signup-limit.test.js +142 -0
- package/test/events/auth-trigger-log-privacy.test.js +256 -0
- package/test/events/cron-job-doc-shape.test.js +101 -0
- package/test/events/cron-reset-usage.test.js +116 -0
- package/test/events/notification-conversion.test.js +182 -0
- package/test/events/payments/_webhook-harness.js +307 -0
- package/test/events/payments/abandoned-cart-activity.test.js +135 -0
- package/test/events/payments/analytics-payment-events.test.js +945 -0
- package/test/events/payments/dispute-email-status.test.js +55 -0
- package/test/events/payments/journey-payments-abandoned.test.js +126 -0
- package/test/events/payments/journey-payments-cancel-endpoint.test.js +102 -0
- package/test/events/payments/journey-payments-cancel-no-order.test.js +76 -0
- package/test/events/payments/journey-payments-cancel.test.js +184 -0
- package/test/events/payments/journey-payments-decline.test.js +225 -0
- package/test/events/payments/journey-payments-discount.test.js +91 -0
- package/test/events/payments/journey-payments-dispute.test.js +190 -0
- package/test/events/payments/journey-payments-failure.test.js +148 -0
- package/test/events/payments/journey-payments-legacy-product.test.js +151 -0
- package/test/events/payments/journey-payments-one-time-decline.test.js +127 -0
- package/test/events/payments/journey-payments-one-time-failure.test.js +113 -0
- package/test/events/payments/journey-payments-one-time-refund.test.js +186 -0
- package/test/events/payments/journey-payments-one-time.test.js +175 -0
- package/test/events/payments/journey-payments-plan-change.test.js +146 -0
- package/test/events/payments/journey-payments-plan-switch-trial.test.js +161 -0
- package/test/events/payments/journey-payments-plan-switch.test.js +182 -0
- package/test/events/payments/journey-payments-refund-no-order.test.js +76 -0
- package/test/events/payments/journey-payments-refund-webhook.test.js +225 -0
- package/test/events/payments/journey-payments-suspend.test.js +183 -0
- package/test/events/payments/journey-payments-trial-cancel.test.js +132 -0
- package/test/events/payments/journey-payments-trial.test.js +173 -0
- package/test/events/payments/journey-payments-uid-resolution.test.js +134 -0
- package/test/events/payments/journey-payments-uncancel.test.js +157 -0
- package/test/events/payments/journey-payments-upgrade.test.js +137 -0
- package/test/events/payments/journey-payments-winback-decline.test.js +171 -0
- package/test/events/payments/journey-payments-winback.test.js +195 -0
- package/test/events/payments/paypal-expiry-cron.test.js +166 -0
- package/test/events/payments/purchase-failed-handler.test.js +80 -0
- package/test/events/payments/purchase-refunded-handler.test.js +108 -0
- package/test/events/payments/test-processor-doc-shape.test.js +162 -0
- package/test/events/payments/transition-order-emails.test.js +185 -0
- package/test/events/payments/transition-promo-lines.test.js +192 -0
- package/test/events/payments/transitions-detect.test.js +767 -0
- package/test/events/payments/trial-lapse-sweep-staleness.test.js +173 -0
- package/test/events/payments/trial-lapse-sweep.test.js +359 -0
- package/test/events/payments/webhook-atomic-writes.test.js +69 -0
- package/test/events/payments/webhook-chargebee-unreachable.test.js +106 -0
- package/test/events/payments/webhook-discount-clear.test.js +189 -0
- package/test/events/payments/webhook-failure-intent.test.js +93 -0
- package/test/events/payments/webhook-hosted-page-uid-trust.test.js +212 -0
- package/test/events/payments/webhook-ordering.test.js +326 -0
- package/test/events/payments/webhook-provider-lookup-trust.test.js +206 -0
- package/test/events/payments/webhook-refund-amount-trust.test.js +223 -0
- package/test/events/payments/webhook-refund-envelope-shape.test.js +148 -0
- package/test/events/payments/webhook-refund-linkage-trust.test.js +404 -0
- package/test/events/payments/webhook-refund-transaction-fallback.test.js +184 -0
- package/test/events/payments/webhook-refund-without-order.test.js +170 -0
- package/test/events/payments/webhook-refusal-reporting.test.js +194 -0
- package/test/events/payments/webhook-refused-intent.test.js +142 -0
- package/test/events/payments/webhook-retry-sweep.test.js +252 -0
- package/test/events/payments/webhook-transition-claim.test.js +389 -0
- package/test/events/payments/webhook-uid-trust.test.js +203 -0
- package/test/events/payments/webhook-user-without-auth.test.js +161 -0
- package/test/fixtures/chargebee/invoice-one-time.json +27 -0
- package/test/fixtures/chargebee/subscription-active.json +44 -0
- package/test/fixtures/chargebee/subscription-cancelled.json +42 -0
- package/test/fixtures/chargebee/subscription-in-trial.json +41 -0
- package/test/fixtures/chargebee/subscription-legacy-plan.json +41 -0
- package/test/fixtures/chargebee/subscription-non-renewing.json +41 -0
- package/test/fixtures/chargebee/subscription-paused.json +42 -0
- package/test/fixtures/chargebee/webhook-payment-failed.json +51 -0
- package/test/fixtures/chargebee/webhook-subscription-created.json +47 -0
- package/test/fixtures/coinbase/charge-confirmed.json +50 -0
- package/test/fixtures/coinbase/charge-failed.json +34 -0
- package/test/fixtures/coinbase/charge-pending.json +34 -0
- package/test/fixtures/migrate/ported-route.js.txt +11 -0
- package/test/fixtures/paypal/capture-completed.json +51 -0
- package/test/fixtures/paypal/capture-refunded.json +43 -0
- package/test/fixtures/paypal/order-approved.json +62 -0
- package/test/fixtures/paypal/order-completed.json +110 -0
- package/test/fixtures/paypal/sale-refunded.json +38 -0
- package/test/fixtures/paypal/subscription-active.json +76 -0
- package/test/fixtures/paypal/subscription-cancelled.json +50 -0
- package/test/fixtures/paypal/subscription-suspended.json +65 -0
- package/test/fixtures/stripe/checkout-session-completed.json +130 -0
- package/test/fixtures/stripe/invoice-payment-failed.json +148 -0
- package/test/fixtures/stripe/invoice-subscription-payment-failed.json +28 -0
- package/test/fixtures/stripe/invoice-subscription-payment-succeeded.json +28 -0
- package/test/fixtures/stripe/subscription-active.json +161 -0
- package/test/fixtures/stripe/subscription-canceled.json +161 -0
- package/test/fixtures/stripe/subscription-trialing.json +161 -0
- package/test/helpers/_shared-config.js +15 -0
- package/test/helpers/ai-request-payload.test.js +619 -0
- package/test/helpers/ai-schema-resolve.test.js +125 -0
- package/test/helpers/ai-test-provider.test.js +227 -0
- package/test/helpers/ai-token-accounting.test.js +150 -0
- package/test/helpers/ai-tools-format.test.js +384 -0
- package/test/helpers/analytics-no-id-notice.test.js +146 -0
- package/test/helpers/analytics-user-data.test.js +194 -0
- package/test/helpers/api-manager.test.js +311 -0
- package/test/helpers/backend-router.test.js +136 -0
- package/test/helpers/content/blog-auto-publisher.test.js +482 -0
- package/test/helpers/content/feed-parser.test.js +529 -0
- package/test/helpers/content/ghostii-blocks.test.js +135 -0
- package/test/helpers/content/ghostii-feed-integration.test.js +405 -0
- package/test/helpers/content/ghostii-write-article.test.js +244 -0
- package/test/helpers/dev-only-routes.test.js +225 -0
- package/test/helpers/env-reader.test.js +362 -0
- package/test/helpers/environment.test.js +263 -0
- package/test/helpers/event-middleware.test.js +407 -0
- package/test/helpers/infer-contact.test.js +157 -0
- package/test/helpers/lane-url.test.js +90 -0
- package/test/helpers/merge-line-files.test.js +272 -0
- package/test/helpers/metadata.test.js +122 -0
- package/test/helpers/middleware-request-log.test.js +134 -0
- package/test/helpers/middleware-user-log.test.js +124 -0
- package/test/helpers/payment/chargebee/parse-webhook.test.js +490 -0
- package/test/helpers/payment/chargebee/refund-details.test.js +198 -0
- package/test/helpers/payment/chargebee/to-unified-one-time.test.js +148 -0
- package/test/helpers/payment/chargebee/to-unified-subscription.test.js +649 -0
- package/test/helpers/payment/coinbase/create-intent.test.js +247 -0
- package/test/helpers/payment/coinbase/parse-webhook.test.js +195 -0
- package/test/helpers/payment/coinbase/refund-unsupported.test.js +141 -0
- package/test/helpers/payment/coinbase/to-unified-one-time.test.js +201 -0
- package/test/helpers/payment/discount-codes.test.js +141 -0
- package/test/helpers/payment/extract-resource.test.js +113 -0
- package/test/helpers/payment/fetch-failure.test.js +215 -0
- package/test/helpers/payment/license-gate.test.js +108 -0
- package/test/helpers/payment/order-id.test.js +99 -0
- package/test/helpers/payment/paypal/create-intent.test.js +382 -0
- package/test/helpers/payment/paypal/fetch-capture.test.js +123 -0
- package/test/helpers/payment/paypal/fetch-sale.test.js +183 -0
- package/test/helpers/payment/paypal/parse-webhook.test.js +678 -0
- package/test/helpers/payment/paypal/refund-details.test.js +202 -0
- package/test/helpers/payment/paypal/resolve-plan-id.test.js +108 -0
- package/test/helpers/payment/paypal/switch-plan.test.js +92 -0
- package/test/helpers/payment/paypal/to-unified-one-time.test.js +383 -0
- package/test/helpers/payment/paypal/to-unified-subscription.test.js +884 -0
- package/test/helpers/payment/stripe/fetch-charge.test.js +147 -0
- package/test/helpers/payment/stripe/parse-webhook.test.js +448 -0
- package/test/helpers/payment/stripe/refund-details.test.js +147 -0
- package/test/helpers/payment/stripe/to-unified-one-time.test.js +307 -0
- package/test/helpers/payment/stripe/to-unified-subscription.test.js +709 -0
- package/test/helpers/persona-domain.test.js +87 -0
- package/test/helpers/recaptcha.test.js +166 -0
- package/test/helpers/resolved-config.test.js +106 -0
- package/test/helpers/response-log-redaction.test.js +262 -0
- package/test/helpers/roles.test.js +155 -0
- package/test/helpers/route-context-debug-gate.test.js +118 -0
- package/test/helpers/route-context-logging.test.js +214 -0
- package/test/helpers/route-context.test.js +129 -0
- package/test/helpers/safe-compare.test.js +114 -0
- package/test/helpers/sanitize.test.js +223 -0
- package/test/helpers/schema-engine.test.js +537 -0
- package/test/helpers/schema-zod.test.js +554 -0
- package/test/helpers/seed-accounts-load.test.js +163 -0
- package/test/helpers/seed-google-personas.test.js +114 -0
- package/test/helpers/seeded-personas.test.js +823 -0
- package/test/helpers/settings.test.js +292 -0
- package/test/helpers/setup-engines-pin.test.js +68 -0
- package/test/helpers/setup-manifest-sync.test.js +116 -0
- package/test/helpers/slugify.test.js +395 -0
- package/test/helpers/storage.test.js +195 -0
- package/test/helpers/test-banner-latch.test.js +139 -0
- package/test/helpers/usage-consume.test.js +460 -0
- package/test/helpers/usage-log-privacy.test.js +121 -0
- package/test/helpers/user-doc-heal.test.js +540 -0
- package/test/helpers/user.test.js +771 -0
- package/test/helpers/webhook-forward.test.js +419 -0
- package/test/helpers/wipe-auth-project.test.js +143 -0
- package/test/mcp/discovery.test.js +52 -0
- package/test/mcp/oauth.test.js +160 -0
- package/test/mcp/protocol.test.js +278 -0
- package/test/mcp/roles.test.js +203 -0
- package/test/mcp/utils.test.js +245 -0
- package/test/notification/identity.test.js +155 -0
- package/test/routes/admin/create-post.test.js +362 -0
- package/test/routes/admin/database.test.js +133 -0
- package/test/routes/admin/deduplicate-image-alts.test.js +191 -0
- package/test/routes/admin/email-content-html.test.js +58 -0
- package/test/routes/admin/email-request-log.test.js +86 -0
- package/test/routes/admin/email.test.js +116 -0
- package/test/routes/admin/firestore-query.test.js +206 -0
- package/test/routes/admin/firestore.test.js +129 -0
- package/test/routes/admin/infer-contact.test.js +220 -0
- package/test/routes/admin/notification.test.js +199 -0
- package/test/routes/admin/post-convert-image.test.js +159 -0
- package/test/routes/admin/post-deploy-flag.test.js +81 -0
- package/test/routes/admin/post-download-error.test.js +90 -0
- package/test/routes/admin/post-resize-image.test.js +185 -0
- package/test/routes/admin/post.test.js +369 -0
- package/test/routes/admin/repo-content.test.js +223 -0
- package/test/routes/admin/stats.test.js +114 -0
- package/test/routes/admin/users-disable.test.js +63 -0
- package/test/routes/admin/users-list.test.js +71 -0
- package/test/routes/content/post.test.js +60 -0
- package/test/routes/general/uuid.test.js +133 -0
- package/test/routes/health.test.js +110 -0
- package/test/routes/marketing/campaign.test.js +184 -0
- package/test/routes/marketing/contact.test.js +416 -0
- package/test/routes/marketing/email-preferences.test.js +293 -0
- package/test/routes/marketing/push-send.test.js +34 -0
- package/test/routes/marketing/webhook-forward.test.js +63 -0
- package/test/routes/marketing/webhook.test.js +641 -0
- package/test/routes/payments/_route-harness.js +145 -0
- package/test/routes/payments/cancel-provider-errors.test.js +227 -0
- package/test/routes/payments/cancel-skip-guards.test.js +126 -0
- package/test/routes/payments/cancel-trialing.test.js +428 -0
- package/test/routes/payments/cancel.test.js +165 -0
- package/test/routes/payments/dedup-race.test.js +186 -0
- package/test/routes/payments/discount.test.js +82 -0
- package/test/routes/payments/dispute-alert.test.js +324 -0
- package/test/routes/payments/intent-discount-amounts.test.js +550 -0
- package/test/routes/payments/intent-discount-coupons.test.js +293 -0
- package/test/routes/payments/intent-one-time-metadata.test.js +122 -0
- package/test/routes/payments/intent-purchaser-guard.test.js +139 -0
- package/test/routes/payments/intent-zero-total.test.js +260 -0
- package/test/routes/payments/intent.test.js +413 -0
- package/test/routes/payments/plan.test.js +367 -0
- package/test/routes/payments/portal-return-url.test.js +107 -0
- package/test/routes/payments/portal.test.js +94 -0
- package/test/routes/payments/refund-one-time.test.js +254 -0
- package/test/routes/payments/refund-paypal-proration.test.js +190 -0
- package/test/routes/payments/refund.test.js +181 -0
- package/test/routes/payments/trial-eligibility.test.js +73 -0
- package/test/routes/payments/uncancel.test.js +270 -0
- package/test/routes/payments/webhook-stripe-invoice.test.js +129 -0
- package/test/routes/payments/webhook-stripe-refund-one-time.test.js +130 -0
- package/test/routes/payments/webhook-test-provider.test.js +156 -0
- package/test/routes/payments/webhook.test.js +115 -0
- package/test/routes/payments/winback-stripe-coupon.test.js +126 -0
- package/test/routes/payments/winback.test.js +597 -0
- package/test/routes/test/authenticate.test.js +79 -0
- package/test/routes/test/redirect.test.js +66 -0
- package/test/routes/test/reset-account.test.js +126 -0
- package/test/routes/test/roster.test.js +101 -0
- package/test/routes/test/schema.test.js +556 -0
- package/test/routes/test/usage.test.js +374 -0
- package/test/routes/user/api-keys.test.js +158 -0
- package/test/routes/user/connections-grant.test.js +759 -0
- package/test/routes/user/connections-identity.test.js +260 -0
- package/test/routes/user/connections-log-privacy.test.js +206 -0
- package/test/routes/user/connections-refresh-lease.test.js +696 -0
- package/test/routes/user/connections-return.test.js +261 -0
- package/test/routes/user/connections-uid.test.js +516 -0
- package/test/routes/user/delete.test.js +138 -0
- package/test/routes/user/feedback.test.js +106 -0
- package/test/routes/user/orders.test.js +233 -0
- package/test/routes/user/sessions.test.js +231 -0
- package/test/routes/user/settings-validate.test.js +84 -0
- package/test/routes/user/signup-emails.test.js +113 -0
- package/test/routes/user/signup-location.test.js +84 -0
- package/test/routes/user/signup-log-privacy.test.js +112 -0
- package/test/routes/user/signup.test.js +579 -0
- package/test/routes/user/subscription.test.js +101 -0
- package/test/routes/user/token.test.js +111 -0
- package/test/routes/user/user.test.js +158 -0
- package/test/routes/verts/cache.test.js +78 -0
- package/test/routes/verts/click-destination.test.js +76 -0
- package/test/routes/verts/crud.test.js +194 -0
- package/test/routes/verts/redirect.test.js +147 -0
- package/test/routes/verts/selection.test.js +237 -0
- package/test/routes/verts/serve.test.js +185 -0
- package/test/routes/verts/unit-document.test.js +117 -0
- package/test/rules/_environment.js +66 -0
- package/test/rules/brand-merge.test.js +195 -0
- package/test/rules/field-helpers.test.js +309 -0
- package/test/rules/notifications.test.js +577 -0
- package/test/rules/payments-carts.test.js +406 -0
- package/test/rules/sessions.test.js +170 -0
- package/test/rules/user.test.js +517 -0
- package/test/rules/verts.test.js +101 -0
- package/test/security/fetch-log-secrets.test.js +124 -0
- package/test/security/primitives.test.js +105 -0
- package/test/security/repo-pinning.test.js +77 -0
- package/test/stripe-live/subscription-lifecycle.test.js +141 -0
package/docs/index.md
ADDED
|
@@ -0,0 +1,299 @@
|
|
|
1
|
+
# OMEGA Backend (@omega.js/backend)
|
|
2
|
+
|
|
3
|
+
> **Note for contributors and Claude:** This file is the guide for `@omega.js/backend` — identity, top-level conventions, and a map to the deep references. It lives in the monorepo's `docs/` tree and is loaded on demand (the omega Claude plugin's hooks inject it by context; the repo-root AGENTS.md map is the one agent entry — packages carry no agent docs). The **meat** (per-subsystem APIs, behavior tables, recipes) lives in the package's own [`docs/<topic>.md`](../docs) files. When extending or adding content, write it in the matching `docs/*.md` file and cross-link from here — do NOT inline it. If a topic doesn't have a doc yet, create one.
|
|
4
|
+
|
|
5
|
+
> **Mirrored structure:** the four framework guides — `docs/web/index.md`, `docs/backend/index.md`, `docs/extension/index.md`, and `docs/desktop/index.md` — mirror each other (the legacy UJM/BEM/BXM/EM lineage): shared sections (Supply-Chain Security, Development Workflow, File Conventions, Doc-update parity, etc.) appear in the **same order at the same position** across all four. When adding a section that applies to multiple frameworks, insert it in the same spot in all of them.
|
|
6
|
+
|
|
7
|
+
## Identity
|
|
8
|
+
|
|
9
|
+
OMEGA Backend (@omega.js/backend) is a comprehensive framework for building modern Firebase Cloud Functions backends. Sister project to Electron Manager (EM), Browser Extension Manager (BXM), and Ultimate Jekyll Manager (UJM). Provides a single `Manager.init(exports, {...})` bootstrap that wires built-in functions (`omega_api`, auth events, cron jobs), helper classes (RouteContext, User, Analytics, Usage, Middleware, Settings, Utilities, Metadata), payment provider integrations (Stripe / PayPal / Chargebee / Coinbase Commerce), Firestore-trigger pipelines, marketing campaign automation, an MCP server, and a CLI for emulator/deploy/logs/auth/Firestore operations.
|
|
10
|
+
|
|
11
|
+
**This repository** is the @omega.js/backend library itself. **Consumer projects** are src-first Firebase apps: `require('@omega.js/backend')` in `src/index.js`, with optional `src/routes/`, `src/schemas/`, and `src/hooks/` for custom endpoints; `omega build` stages everything into `dist/` (the tree `firebase.json` points at). Config is loaded via `@omega.js/config` (shared sections top-level, backend settings under `targets.backend`; brand-monorepo hierarchy supported — brand targets carry NO config file of their own).
|
|
12
|
+
|
|
13
|
+
## Recommended skills
|
|
14
|
+
|
|
15
|
+
- **`omega:backend`** — the router skill from the omega Claude plugin. The inject hook loads it automatically in any project with `@omega.js/backend` (root or `functions/`, and inside `packages/backend` here); it points back to this guide + `docs/` (the SSOT).
|
|
16
|
+
- **`js:patterns`** — JavaScript/Node.js conventions: file structure, JSDoc, defensive coding (`?.` usage), template literals, `package.json` conventions. Auto-loads when creating new `.js` files or touching JS module structure.
|
|
17
|
+
|
|
18
|
+
## Quick Start
|
|
19
|
+
|
|
20
|
+
### For Consuming Projects
|
|
21
|
+
|
|
22
|
+
1. `npm install @omega.js/backend` (at the target root — it's a runtime dependency; the staged `dist/package.json` derives from the target manifest)
|
|
23
|
+
2. Run any verb — there is no bootstrap command ([#675](https://github.com/Omega-JS-Stack/omega/issues/675)). Every verb calls `ensureTarget()` first (`src/cli/utils/ensure-target.js`), which scaffolds `.firebaserc`, `firebase.json`, `src/index.js`, `engines.node`, `firestore.rules`, `database.rules.json`, syncs the standard `package.json` scripts to the framework's `projectScripts` defaults (framework-owned keys, rewritten on every run — customize through hook points, not by editing them, [#689](https://github.com/Omega-JS-Stack/omega/issues/689); each spells the verb BARE — `omega serve`, never `npx omega`, since npm already puts `node_modules/.bin` on the path inside a script, [#748](https://github.com/Omega-JS-Stack/omega/issues/748)), plus the defaults tree via the shared devkit engine: AGENTS.md + its one-line `@AGENTS.md` CLAUDE.md pointer, CHANGELOG.md, docs/, test/, `.gitignore` (AGENTS.md and `.gitignore` live-sync their `Default Values` section). It is idempotent and silent when nothing changes, and it writes no `.env` — that file is yours (see [The env cascade](#the-env-cascade--678)). `npx omega test` adds the target CHECKS on top (config validation, Firestore index provisioning)
|
|
24
|
+
3. `npx omega emulator` — start Firebase emulators (auth/firestore/functions/database/storage). Every boot first reaps the machine's orphaned emulator-family processes left by earlier runs — parent gone, this user, a strict command match (hub, functions worker, functions discovery server, emulator jar, puppeteer chrome) — whatever project they named, and logs one line naming what it removed ([#781](https://github.com/Omega-JS-Stack/omega/issues/781)). This is also a **prerequisite of the brand's frontend targets**: `omega dev` in the website target auto-connects Auth/Firestore to these emulators with no live-Firebase opt-out, so start them here first ([docs/web/index.md](../web/index.md))
|
|
25
|
+
4. `npx omega serve` — local serve with Stripe webhook forwarding (if `STRIPE_SECRET_KEY` is set)
|
|
26
|
+
5. `npx omega test` — runs the project's test suites against an emulator (bare consumer runs never include the framework corpus; the framework self-test context flips the default). Positional target(s) select which test FILES run, by source + path (multiple space-separated targets compose):
|
|
27
|
+
- `npx omega test` — the project's suites
|
|
28
|
+
- `npx omega test email/transactional` — bare path (no prefix): project tests matched by path (relative to `test/`)
|
|
29
|
+
- `npx omega test full:` / `npx omega test full:email` — BOTH sources, the explicit way to include the framework suite
|
|
30
|
+
- `npx omega test mgr:` / `npx omega test backend:` — ONLY framework tests (`mgr:` is the universal cross-framework alias for the manager's own tests; `backend:` is the equivalent @omega.js/backend-specific alias)
|
|
31
|
+
- `npx omega test mgr:email/templates` / `npx omega test backend:email/templates` — only framework tests matching a path
|
|
32
|
+
- `npx omega test project:` — ONLY project tests (all of them)
|
|
33
|
+
- `npx omega test project:routes/custom` — only consumer project tests matching a path
|
|
34
|
+
- `npx omega test backend:rules project:routes` — multiple targets compose (runs both selections)
|
|
35
|
+
- Pass `--extended` (or prefix `TEST_EXTENDED_MODE=true`) for tests that hit real external APIs (SendGrid, OpenAI, etc.). `--extended` is the CLI shorthand for the shared, unprefixed `TEST_EXTENDED_MODE` env var standardized across @omega.js/backend/BXM/UJM/EM; @omega.js/backend propagates it to BOTH the runner subprocess and the live emulator. See [docs/test-framework.md](../docs/test-framework.md#extended-mode-test_extended_mode).
|
|
36
|
+
- Pass `--lane=<name>` for an OPT-IN lane: suites that exist only for a real external service, unreachable by any other run, each behind a gate that prints one skip line rather than failing. Today: `--lane=stripe-live`, which creates test-mode fixtures, forwards REAL Stripe webhooks into the emulator with `stripe listen`, and opens only for an `sk_test_` secret resolved through the ONE env reader (put it in the brand's `.env.testing` overlay). See [docs/test-framework.md](../docs/test-framework.md#opt-in-lanes---lane).
|
|
37
|
+
6. `npx omega deploy` — deploy Cloud Functions to Firebase
|
|
38
|
+
7. `npx omega logs:read` / `npx omega logs:tail` — Cloud Function logs from Google Cloud Logging
|
|
39
|
+
|
|
40
|
+
`npx omega-backend <cmd>` works as an alias for `npx omega <cmd>`.
|
|
41
|
+
|
|
42
|
+
> **Important:** All `npx omega ...` commands run from the consumer project's **target root** (the directory with `package.json` + `src/`). `dist/` is staged output — never edit it. The CLI also accepts a `functions/` cwd for muscle memory (it normalizes up).
|
|
43
|
+
|
|
44
|
+
### For Framework Development (This Repository)
|
|
45
|
+
|
|
46
|
+
> **🚫 NEVER use `npx omega ...` from the framework repo.** `npx omega` is for CONSUMER projects (where the bin is linked in the target's `node_modules/.bin/`). From the framework repo, use `npm test`, `npm run prepare`, etc. — the `scripts` in `package.json` call the local `bin/` directly.
|
|
47
|
+
|
|
48
|
+
1. `npm install` — install @omega.js/backend's own deps
|
|
49
|
+
2. `npm run prepare` — build once: copies `src/` → `dist/` via prepare-package
|
|
50
|
+
3. `npm run prepare:watch` — watch mode
|
|
51
|
+
4. `npm test` — run framework tests via the bundled fixture project (equivalent to `node bin/omega-backend test`). Accepts the same target syntax: `npm test -- mgr:helpers/content/blog-auto-publisher`. Bare = the fast `boot/` smoke; the FULL framework suite passes against the fixture too — `npm test -- backend:` (the fixture carries corpus-parity payment config and boot-syncs the canonical rules; see [docs/test-boot-layer.md](../docs/test-boot-layer.md))
|
|
52
|
+
5. Test in the **designated test consumer** — `../../ITW-Creative-Works/ultimate-jekyll-backend` is @omega.js/backend's consumer for validating framework changes end-to-end (exercise any consumer-level flow there freely: emulator, tests, deploy paths). From inside it, run `npx omega install dev` to swap @omega.js/backend to this local repo — required whenever you edit the framework source and want the consumer to pick up the changes (the consumer otherwise keeps its installed `node_modules/@omega.js/backend`). Reverse with `npx omega install live`. If `npx omega` then errors with "could not determine executable to run", the local install skipped bin-linking — re-run `npm install` to relink, or call `node node_modules/@omega.js/backend/bin/omega-backend <cmd>` directly.
|
|
53
|
+
|
|
54
|
+
## Architecture
|
|
55
|
+
|
|
56
|
+
@omega.js/backend exposes a single `Manager` class that orchestrates everything: it initializes Firebase Admin, wires built-in functions (`omega_api`, auth events, cron), and hands out helper instances via factory methods. Supports **two deployment modes** — Firebase Functions (`projectType: 'firebase'`) or Custom Server (`projectType: 'custom'`). See [docs/architecture.md](../docs/architecture.md) for the full overview of the Manager class, dual-mode support, the derived `config.resolved.*` values consumer code reads (`config.resolved.github.repo` — the brand repo slug), and helper factory pattern.
|
|
57
|
+
|
|
58
|
+
For the directory layout of both the @omega.js/backend library and consumer projects, see [docs/directory-structure.md](../docs/directory-structure.md).
|
|
59
|
+
|
|
60
|
+
### The wakeup short-circuit
|
|
61
|
+
|
|
62
|
+
Any request carrying `wakeup` in its data (query or body) is answered `{ wakeup: true }` by the middleware and goes no further ([helpers/middleware.js](../src/manager/helpers/middleware.js)). The check runs BEFORE the route module is loaded and before the caller is authenticated, so the request costs one cold start and nothing else. There is no dedicated ping route and none is needed: every route is the same warm-up at the same price.
|
|
63
|
+
|
|
64
|
+
The frontend half is `omega.request(WAKEUP_ROUTE, { wakeup: true })` ([docs/client/index.md](../client/index.md), which lists every page and surface that fires it) — web, desktop and extension all warm the function ahead of the first user action that needs it ([#637](https://github.com/Omega-JS-Stack/omega/issues/637), [#644](https://github.com/Omega-JS-Stack/omega/issues/644)).
|
|
65
|
+
|
|
66
|
+
### Custom-server mode — `projectType: 'custom'` ([#584](https://github.com/Omega-JS-Stack/omega/issues/584))
|
|
67
|
+
|
|
68
|
+
**The brand's config is the switch**, not an init flag: `targets.backend.projectType` in `config/omega.json5` (`'firebase'` — the default — or `'custom'`), resolved by `Manager.init()` off the loaded config, so a consumer's `src/index.js` stays the same two lines in both modes. An explicit `init(exports, { projectType })` still wins for a caller that means to override it.
|
|
69
|
+
|
|
70
|
+
Custom mode is the SAME backend: the same routes, the same schemas, the same auth middleware, the same helper factories, the same `.env` — served by the Express app on `process.env.PORT` (`setupCustomServer`) for a container host (Render & co) instead of exported as Cloud Functions. `firebase-functions` is not even loaded (`Manager.libraries.functions` is `null`); `firebase-admin` still is, so Firestore, Auth and the rest of the Admin SDK work exactly as before.
|
|
71
|
+
|
|
72
|
+
What it takes away is the **Firebase lane**, and `src/cli/utils/project-type.js` is the ONE home of that list. Each verb refuses loudly, names the mode, names the lane that replaces it, and exits 1 — a refusal that read green would look like a deploy that happened:
|
|
73
|
+
|
|
74
|
+
| Verb | In custom mode |
|
|
75
|
+
|---|---|
|
|
76
|
+
| `omega deploy` | REFUSED — a custom backend publishes through its host; put that command in this target's `deploy` script, which the brand-root `omega deploy` runs |
|
|
77
|
+
| `omega serve` | REFUSED — `npm start` boots the server on `PORT` |
|
|
78
|
+
| `omega emulator` | REFUSED — there are no Cloud Functions to emulate |
|
|
79
|
+
| `omega test` | REFUSED — the emulator lane needs Cloud Functions; `npm test` runs the target's static suite ([#567](https://github.com/Omega-JS-Stack/omega/issues/567)) |
|
|
80
|
+
| the verbs' scaffold | Runs, minus the Firebase-only half ([#614](https://github.com/Omega-JS-Stack/omega/issues/614)) and minus the brand-owned scripts ([#689](https://github.com/Omega-JS-Stack/omega/issues/689)) — see below |
|
|
81
|
+
| `omega build`, everything else | Unchanged — a custom backend stages `src/` → `dist/` like any other |
|
|
82
|
+
|
|
83
|
+
**The scaffold writes no Firebase-only artifact** in custom mode ([#614](https://github.com/Omega-JS-Stack/omega/issues/614)): no `firebase.json` (deploy targets + emulator config), no `firestore.rules`, no `database.rules.json`, no `storage.rules`, no `firestore.indexes.json` — and no compiled `dist/firestore.rules`, which nothing in this mode deploys. The checks that maintain those files (every firebase.json check, the rules and index seeds, the live index sync) come off the run with them; the same `project-type.js` table names both lists. Everything else is the identical scaffold — the config, `.firebaserc`, the service account, the project directories, the defaults. Skipping is not deleting: a custom project that authored a `firebase.json` (or rules) of its own keeps it exactly as written, migrations included.
|
|
84
|
+
|
|
85
|
+
**The script sync turns per KEY** ([#689](https://github.com/Omega-JS-Stack/omega/issues/689)): the scripts running a verb this mode refuses — `start`, `deploy`, `emulator`, `test:emulator` — are the BRAND's, never written and never scaffolded (no placeholder to delete), while `test` and `test:static` stay framework-owned like anywhere else. The manifest's `projectScriptsCustomOwned` is the one home of that list, derived from the verb table above and read by both writers: this framework's scaffold and the manager's workspace walk.
|
|
86
|
+
|
|
87
|
+
The brand-root side of it — how the manager deploys, tests and boots a custom backend — is in [deploys.md](shared/deploys.md) and [manager/index.md](../manager/index.md).
|
|
88
|
+
|
|
89
|
+
### The env reader (`libraries/env.js`) — #581
|
|
90
|
+
|
|
91
|
+
Every framework read of a brand-supplied env key goes through ONE reader; nothing under `src/manager/` touches `process.env.<KEY>` directly except the runtime's own vars (`FIREBASE_CONFIG`, `FUNCTIONS_EMULATOR`, `GCLOUD_PROJECT`, the `OMEGA_*_PORT` map, the test-mode switches).
|
|
92
|
+
|
|
93
|
+
- `env.get('KEY')` — the resolved value, empty reading as absent. A key the env schema does not declare **throws** (`UnknownEnvKeyError`): a typo used to resolve to `undefined` forever.
|
|
94
|
+
- `env.has('KEY')` — the switch every optional provider gates on.
|
|
95
|
+
- `env.require('KEY')` — value or `MissingEnvKeyError` (code 500) naming the key and the fix.
|
|
96
|
+
- `env.assertRequired('backend')` — the **boot guard**, run by `Manager.init()`: every required key of the schema, validated in ONE pass, with ONE error listing everything missing. A brand's backend refuses to boot in **every environment**, development included — the keys are one `npx omega manage` away, and booting without them only moves the crash to a customer's first order email ([#569](https://github.com/Omega-JS-Stack/omega/issues/569)). The single advisory lane is a process with no consumer `config/omega.json5` — the framework booting itself, where there is no brand for a manage run to have minted keys into; it warns and continues. The self-test fixture is brand-shaped, so `omega test` seeds its required keys from the fixture's own config values (`ensureFixtureEnv`), the same way manage mints a real brand's.
|
|
97
|
+
|
|
98
|
+
- `env.environment()` — the runtime environment (`testing` › `production` › `development`), and the SSOT `Manager.getEnvironment()` returns. It is `@omega.js/config`'s `envEnvironment()` re-exported ([#586](https://github.com/Omega-JS-Stack/omega/issues/586)), so the three names the `.env.<environment>` overlay files are spelled with and the three the runtime answers are ONE vocabulary. It is reachable here because the provider libraries below hold no Manager handle. "No signal" resolves to **production**: a deployed Cloud Function has no `FUNCTIONS_EMULATOR` and often no `ENVIRONMENT`.
|
|
99
|
+
|
|
100
|
+
**One key, every environment** ([#586](https://github.com/Omega-JS-Stack/omega/issues/586)) — the reader never decides WHICH name to read. A key whose value must differ between a local run and a deployed one is supplied by the brand's `.env.<environment>` overlay under the SAME name, and the cascade has already resolved it before anything reaches `env.get()`. So a brand puts its `sk_test_…` in `.env.development` and its live key in `.env`, and `Stripe.init()` still calls `env.get('STRIPE_SECRET_KEY')`. There is no `<KEY>_DEV` twin and no live-shape guard: every key is equal and its value is trusted.
|
|
101
|
+
|
|
102
|
+
**Which key the emulator charges is the BRAND's answer, not a guard's** ([#586](https://github.com/Omega-JS-Stack/omega/issues/586)). The backend uses whatever key the env chain resolves for the running environment, whatever that key turns out to be, and it never inspects a value to decide. Putting the TEST key in `.env.development` is what keeps a live key out of the local emulator, and it is the brand's own opt-in: onboarding writes only the base `.env`, so a brand with no overlay runs its local emulator on whatever `.env` holds. Since the `_DEV` twins were removed nothing else stands between a live key and a local run, so a brand that puts a live key in `.env` and writes no overlay CAN charge a real card from the emulator. Write the overlay.
|
|
103
|
+
|
|
104
|
+
The key inventory (owner, targets, generated-or-third-party, required, description) lives in `@omega.js/config`'s env schema — the same list the manager mints from and the composer below delivers from: [docs/shared/config.md](shared/config.md).
|
|
105
|
+
|
|
106
|
+
### The env cascade — #678
|
|
107
|
+
|
|
108
|
+
`dist/.env` is **generated output**, composed on every verb that stages ([#678](https://github.com/Omega-JS-Stack/omega/issues/678)). Nobody has to run a manage first for a brand-root key to reach the artifact.
|
|
109
|
+
|
|
110
|
+
- **Two human files, one machine file.** The brand root's `.env` is the one file humans and the manager edit. A target's own `.env` is OPTIONAL — a per-key override you write by hand. No machine writes either target `.env` or brand `.env` values into a target. `dist/.env` is the machine's, regenerated from scratch on every stage.
|
|
111
|
+
- **The layers, weakest first**: company `.env` ← brand `.env` ← target `.env`, resolved through `@omega.js/config`'s `resolveEnvChain` (the same walk the runtime cascade uses), each layer overlaid by its own `.env.<environment>` file (#586). Files only — never the shell, so a build produces the same artifact under any terminal. An empty value never claims a key.
|
|
112
|
+
- **The schema is the only filter.** A key rides down from the company/brand layers when an `ENV_SCHEMA` entry claims it (by name OR by pattern — the `CONNECTIONS_<PROVIDER>_CLIENT_ID`/`_SECRET` family composes), names `backend` in its `targets`, and sits in a file group. A desktop signing key stays out of the functions upload. The target layer passes through UNFILTERED: placing a key in the target's own `.env` is the targeting.
|
|
113
|
+
- **`deliverAs` renames on delivery**: the brand's `GOOGLE_ANALYTICS_SECRET_BACKEND` arrives as `GOOGLE_ANALYTICS_SECRET`, the one name the runtime reads.
|
|
114
|
+
- **The dev server restages** on a change to the target, brand-root, or company `.env` — the watcher resolves all three through the chain (`envWatchInputs`), never a hard-coded path.
|
|
115
|
+
- **Each lane stages for ONE environment** (#586): `omega deploy` composes base + `.env.production`, the emulator base + `.env.development`, `omega test` base + `.env.testing` — `stageFunctions({ environment })`, and the stage WATCH keeps the boot's own environment, so a hot reload can never swap the artifact's overlay mid-run. No other environment's file ever rides the upload.
|
|
116
|
+
- Delivered key NAMES and the layer each came from are logged; a value never is.
|
|
117
|
+
|
|
118
|
+
### Test framework
|
|
119
|
+
|
|
120
|
+
A consumer project has **two test lanes**, and the verbs' scaffold seeds both.
|
|
121
|
+
|
|
122
|
+
- **Emulator lane** — `npm run test:emulator` (`npx omega test`) runs the project's suites (scope `framework:` or `full:` to include the framework's own) against a **real Firebase emulator** (real Firestore/Auth — never mocked). Suites are organized by concern (`test/routes/`, `test/events/`, `test/rules/`, …) rather than runtime layers. See [docs/test-framework.md](../docs/test-framework.md).
|
|
123
|
+
- **Static lane** — `npm test` (`npm run test:static`) is plain `node --test` over `test/_unit/**/*.test.js`, with `test/_helpers/connect-trap.js` **preloaded into every test process**: it replaces `net.Socket.prototype.connect` and `dns.lookup` with a throw, so a suite that requires the framework tree can never reach live Firebase with whatever `.env` and `.omega/secrets/` carry. No emulator, no network, no credentials ([#567](https://github.com/Omega-JS-Stack/omega/issues/567)).
|
|
124
|
+
|
|
125
|
+
**The framework suite runs from a consumer too** ([#720](https://github.com/Omega-JS-Stack/omega/issues/720)) — `npx omega test mgr:` from a backend target works on a locally linked brand AND on a plain npm install, because the package ships `test/` as raw source (a `files` entry beside `dist/`). That is why every case file requires the framework through `../../dist/…` rather than `../../src/…`, and `@omega.js/devkit` / `@omega.js/config` / `@omega.js/account` through `../../dist/vendor/…`: `src/` never ships and those packages never publish, so the shipped copies are the only ones an install can reach. In the monorepo `dist/` is the prepare output the root watch keeps fresh — edit `src/`, and the suite reads it once the watch has copied it. `test/boot/suite-portability.test.js` audits every require and package-relative path literal in `test/` against the published `files` list, so a case file that reaches back into `src/` fails at home instead of in a consumer.
|
|
126
|
+
|
|
127
|
+
The static lane ships as skeletons the brand OWNS and edits — `registration.test.js` (index.js boots the installed framework; every dispatched route resolves and its imports load), `rules-posture.test.js` (every Firestore/Storage path the brand opens is declared in the suite, so adding a rule is deliberate), `socket-free.test.js` (the trap is loaded, and refuses). They pass on a freshly scaffolded target. Both lanes live under `test/`: the `_`-prefixed dirs are invisible to the framework's discovery, so the static suites never run inside the emulator lane.
|
|
128
|
+
|
|
129
|
+
### Test coverage
|
|
130
|
+
|
|
131
|
+
Every feature ships with tests at EVERY surface it exposes — logic (`test/routes/`/`test/events/` handler suites against the real emulator), wiring (route round-trips over `http.as(...)` — registration, auth gates, schema validation; this IS @omega.js/backend's end-to-end), and rules (Firestore security-rules suites when rules change). @omega.js/backend has no UI layer — a feature's UI coverage lives in the consuming frontend (UJM/BXM/EM). Skip a surface ONLY when the feature genuinely doesn't have one; "the handler test already covers it" is NOT a reason to skip the route round-trip. See [docs/test-framework.md](../docs/test-framework.md).
|
|
132
|
+
|
|
133
|
+
## CLI
|
|
134
|
+
|
|
135
|
+
`npx omega <command>` (alias `omega-backend`):
|
|
136
|
+
|
|
137
|
+
| Command | Description |
|
|
138
|
+
|---|---|
|
|
139
|
+
| `emulator` | Start Firebase emulators (auth/firestore/functions/database/storage); fronts the public hosting port with the mkcert HTTPS proxy (`--no-https` for plain http). A stop takes the whole family: firebase-tools puts each java emulator in its OWN process group, so the stop path signals the pids it recorded at boot, sweeps whatever orphaned outside that record, and only then verifies the ports came back free. A boot that never comes up takes the same path before it reports ([#304](https://github.com/Omega-JS-Stack/omega/issues/304)). EVERY stop path runs it: Ctrl+C (SIGINT), `omega dev`'s stop (SIGTERM), and a closed terminal (SIGHUP) share one handler, registered off the ONE list every OMEGA supervisor imports (`STOP_SIGNALS` in [@omega.js/devkit's src/stop-signals.js](../../packages/devkit/src/stop-signals.js), which the manager's `omega dev`, the web dev server and both log tails register too, so no supervisor can carry a subset again). So no way of stopping the dev loop leaves an emulator, a java jar, or the reload watcher behind ([#629](https://github.com/Omega-JS-Stack/omega/issues/629)). A boot also reaps the leftovers of a previous run BY PID, from that run's own record, before overwriting it — the port sweep cannot see a watcher that binds nothing — and it signals only a recorded pid whose LIVE command line still reads as this project's emulator machinery, so a recycled number that reads as anything else is left alone. A record that names no root pid of its own is not a kill order at all — staleness is proved BY the root, and an unprovable root over a live stack would read as pure leftovers ([#721](https://github.com/Omega-JS-Stack/omega/issues/721)). The allocator's probe and firebase-tools' bind are two moments, so a boot that dies on `EADDRINUSE` re-allocates around the port it could not bind, republishes the map, and boots ONE more time; a second failure names the port and, where lsof can identify it, the pid holding it, and never signals it. The record reap waits for the pids it took to actually be gone before anything probes a port, so a shutdown still unwinding can never answer "free" for a port it is about to keep ([#778](https://github.com/Omega-JS-Stack/omega/issues/778)) |
|
|
140
|
+
| `serve` | Local Firebase serve (with auto Stripe webhook forwarding if keys set) |
|
|
141
|
+
| `watch` | Auto-reload functions on file change |
|
|
142
|
+
| `deploy` | Deploy Cloud Functions to Firebase. REFUSED on a `projectType: 'custom'` target — see [Custom-server mode](#custom-server-mode--projecttype-custom-584) |
|
|
143
|
+
| `test` | Run the TARGET CHECKS (config validation, doc/script defaults, Firestore index provisioning — the audit half of the retired `setup`, [#675](https://github.com/Omega-JS-Stack/omega/issues/675)), then the project's test suites against an emulator (`framework:` / `full:` reach the framework suite). `--offline` blocks every live mutation the checks would make (deploys, bucket policy, seeding) and downgrades them to reported warnings — reads still run ([#284](https://github.com/Omega-JS-Stack/omega/issues/284)). On a `cloud.shared: true` project the live index sync is skipped whole (one dim line, no read, no merge): a shared project's deployed indexes carry every tenant brand's collections, and pulling them down rewrote the consumer's authored `firestore.indexes.json` with the other brands' definitions ([#716](https://github.com/Omega-JS-Stack/omega/issues/716)). REFUSED in custom mode — `npm test` is the lane. A run that starts its OWN emulator tears the whole stack down — the emulator AND the test-runner child, which a directed signal never reaches on its own — on the same three signals `emulator` does, once per run however many arrive ([#722](https://github.com/Omega-JS-Stack/omega/issues/722)) |
|
|
144
|
+
| `install <local\|live>` | Switch the installed framework copy: `local` links this monorepo's @omega.js/backend, `live` restores the published package. Aliases: `-i`, `i`, `--install` (the same short flag every sibling framework spells, [#81](https://github.com/Omega-JS-Stack/omega/issues/81)) |
|
|
145
|
+
| `update` | Dependency freshness report (installed/wanted/latest + patch/minor/major, < 7-day releases QUARANTINED); `--apply` installs the safe set via npu, `--major` explicit. Aliases: `-u`, `--update`, `outdated`, `out` (the same short flags every sibling framework spells, [#81](https://github.com/Omega-JS-Stack/omega/issues/81)). See docs/shared/updates.md in the Omega repo |
|
|
146
|
+
| `migrate` | The ported-project REPORT, and it changes nothing ([#600](https://github.com/Omega-JS-Stack/omega/issues/600)): every bare `require()` under `src/` of a package this target's own package.json does not declare, named file:line with the fix. BEM's FLAT install answered such a require and OMEGA's resolves it only by HOISTING, and the ones that carry it are LAZY (inside the handler), so the module loads fine and the route 500s on the first real request. REPORT ONLY, never an install: which version a brand wants is the brand's call. The scan is devkit's `src/bare-requires.js`, the same one @omega.js/web's `omega migrate` runs, so the two frameworks cannot answer differently; a backend has no bundler, so it excludes no aliases. The one-time CONVERSIONS are separate run-alone verbs (`migrate:rules`, `migrate:markers`) |
|
|
147
|
+
| `mcp` | Start the stdio MCP server (for Claude Code / Claude Desktop). Supports `--token <key>` for user-level connections |
|
|
148
|
+
| `firestore:get/set/query/delete` | Direct Firestore reads/writes from the terminal (emulator unless `--production`) |
|
|
149
|
+
| `auth:get/list/delete/set-claims` | Manage Auth users from the terminal (emulator unless `--production`) |
|
|
150
|
+
| `auth:token` | Mint a custom token + one-click sign-in URL (QA "log in as anyone"; emulator by default, `--production` explicit) |
|
|
151
|
+
| `logs:read` / `logs:tail` | Cloud Function logs from Google Cloud Logging |
|
|
152
|
+
| `stripe` | Standalone Stripe CLI webhook forwarding |
|
|
153
|
+
| `indexes` | Sync deployed Firestore indexes into `firestore.indexes.json` (aliases `indexes:get`, `firestore:indexes:get`) |
|
|
154
|
+
| `migrate:rules` | The one-time move of a legacy `firestore.rules` onto the compiled model — run ALONE and deliberately, because it changes what the live project enforces. The target checks defer to it instead of healing the tree on the way to a deploy ([#522](https://github.com/Omega-JS-Stack/omega/issues/522)). Alias `migrate:firestore-rules` |
|
|
155
|
+
| `migrate:markers` | The one-time conversion of the PRE-FAMILY marker formats a tree carried over from BEM still holds — the `{{ backend-manager }}` placeholder, the `# BEM>>>` `.gitignore` block, the `///---backend-manager---///` rules block, and the cp72-74 `///---omega---///` interim flavor — onto the family grammar. Run ALONE: every evergreen verb speaks only the family, so they detect those shapes and point here rather than converting ([#40](https://github.com/Omega-JS-Stack/omega/issues/40)) |
|
|
156
|
+
| `clean` | Remove node_modules + lockfile and reinstall (alias `clean:npm`) |
|
|
157
|
+
| `version` | Print @omega.js/backend version |
|
|
158
|
+
| `help` | Print the command listing (also `-h`/`--help`); bare `omega` prints it too (nothing claims the default slot since `setup` was retired), unknown commands print the listing and exit 1. The listing is GENERATED from the same command table the dispatcher reads (`src/cli/command-table.js`) — it cannot drift from what actually dispatches |
|
|
159
|
+
|
|
160
|
+
Backend has no separate deploy PRECHECK: its network steps are inside the verb itself ([#675](https://github.com/Omega-JS-Stack/omega/issues/675)). `omega deploy` sets the Cloud Functions artifact cleanup policy and grants the public `allUsers` invoker on every HTTP function before it uploads — both idempotent, both skipped without a fuss when the project has nothing to set yet. There is nothing to opt out of, so the `--no-secrets` flag the other three frameworks honor is accepted and IGNORED here (parity of spelling, not of behavior).
|
|
161
|
+
|
|
162
|
+
The target checks also regenerate the OMEGA-managed block in `database.rules.json` and seed (or migrate) the brand's `firestore.rules` source — except on a brand that has DEFERRED the compiled-rules migration, where it reports and changes nothing (see [Firestore rules: compiled, not managed](#firestore-rules-compiled-not-managed)); the `(vX.Y.Z)` stamp in the marker header — and in the compiled firestore artifact's header — is `RULES_VERSION`, a rules SCHEMA version that bumps only when generated rule semantics change (never the package version). Its one home is `src/cli/utils/compile-rules.js`.
|
|
163
|
+
|
|
164
|
+
## Firestore rules: compiled, not managed
|
|
165
|
+
|
|
166
|
+
A brand's `firestore.rules` is **source**, not a file the framework rewrites ([#255](https://github.com/Omega-JS-Stack/omega/issues/255)). Firestore ORs `allow` across sibling match blocks, so a brand's own `match /users/{uid}` can only ever WIDEN access — under the old managed-marker-block model a brand had no way to protect a field of its own, and hand-edits to the managed block were wiped on the next run.
|
|
167
|
+
|
|
168
|
+
```
|
|
169
|
+
firestore.rules ← the brand's, pure rules language
|
|
170
|
+
+ @omega.js/backend/templates/firestore.framework.rules ← ships inside the package
|
|
171
|
+
= dist/firestore.rules ← GENERATED, what firebase.json points at
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
- **Where it happens**: `stageFunctions()` (`src/cli/utils/stage-functions.js`) compiles on every stage, so `omega build`, emulator/serve boot, `omega test` and `omega deploy` all read a current artifact — and the stage watch treats `firestore.rules` as a stage input, so editing it hot-reloads the running emulator. The compiled artifact opens with a header naming BOTH sources and forbidding edits.
|
|
175
|
+
- **`firebase.json`** points `firestore.rules` at `dist/firestore.rules` for the emulator AND `firebase deploy`. A build that finds a stale target reports it loudly.
|
|
176
|
+
- **Merge-by-match is how a brand TIGHTENS** ([#353](https://github.com/Omega-JS-Stack/omega/issues/353)). Both halves land in one `match /databases/{database}/documents` scope, so functions resolve across the seam in both directions and brand rules call framework helpers (`isUser`, `isAdmin`, `getExistingData`, `isWritingAny`, …). A brand match block whose path CANONICALIZES to a framework block's (wildcard names normalized, the brand's variable renamed to the framework's inside the fold-in) is merged into it:
|
|
177
|
+
|
|
178
|
+
```
|
|
179
|
+
yours match /users/{userId} { allow create, update: if !isWritingAny(['xp']) && isEmailVerified(); }
|
|
180
|
+
framework match /users/{uid} { allow create, update: if isUser(uid) && !isWritingFrameworkField(); }
|
|
181
|
+
compiled match /users/{uid} { allow create, update: if isUser(uid) && !isWritingFrameworkField() && (!isWritingAny(['xp']) && isEmailVerified()); }
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
An op BOTH blocks declare gets the brand condition parenthesized and ANDed on (a framework statement listing several ops splits only as far as it must). An op only the BRAND declares appends verbatim — that op widens, exactly as a sibling block always did. Nested matches and functions inside the brand block splice in. A path the framework never declares passes through untouched.
|
|
185
|
+
- **The documented limit**: ops pair by NAME, so a brand `allow create` beside the framework's `allow write` does not tighten it — Firestore ORs the two. The compiler REPORTS that case rather than letting it look like a tightening. Widening a framework-declared op from the brand file is not expressible.
|
|
186
|
+
- **The hooks are gone.** `protectedFields()` and `canWriteUser()` (the 0.36.0 model) retired with rules v3: no lint, no re-seed, no injection. Setup strips a hook still carrying its shipped default body, KEEPS a customized one as an ordinary brand function (reported loudly — nothing calls it now), renames calls to the helpers v3 renamed, and refreshes the seed header.
|
|
187
|
+
- **The framework helpers** (`templates/firestore.framework.rules` is the SSOT). The naming convention is the API: **`is*` is a predicate** about the caller or about this write — `isAuthenticated()`, `isUser(identity)`, `isOwner()`, `isAdmin()`, `isEmailVerified()`, `isWritingAny(fields)`, `isWritingField(field)`, `isCreatingField(field)`, `isUpdatingField(field)`, `isWritingFrameworkField()` — and **`get*` hands back a value** to compare against: `getAuthUid()`, `getAuthEmail()`, `getRoles()`, `getExistingData()`, `getIncomingData()`. Four things to know: `getRoles()` bills ONE document read per call and is the only helper that costs anything (so every `isAdmin()` costs one too); `isEmailVerified()` reads the AUTH TOKEN (`request.auth.token.get('email_verified', false)`) and no stored field — unforgeable, unbilled, and true on the caller's very first request; `isUser()`'s EMAIL arm requires that verified token (anyone can sign up claiming any address, so an unproven claim never matches an email-keyed doc) while its uid arm does not; and `isOwner()` reads the STORED `owner` once the document exists and the INCOMING one on a create, so an update can never hand ownership to whoever is writing. `getExistingData()` reads an ABSENT document as the empty map — `resource` is null on a create and reading through it errors, which denies the whole rule, so this is what makes every field helper mean the same thing on create and on update. Field lists are TOP-LEVEL: protecting `xp.total` means listing `'xp'`.
|
|
188
|
+
- **The framework's `match /users/{uid}` declares `read` and `create, update`, never `write`.** `allow write` covers delete too, and a delete carries no incoming data for the field guard to read — so an owner deleting their own user document used to be denied by an evaluation ERROR. Naming the two ops the rule means leaves delete to the admin catch-all, denied by the rule. A brand tightening that block names the same ops (`allow write` beside it would widen, and the compiler says so).
|
|
189
|
+
- **Migration**: `npx omega migrate:rules` detects a legacy `// ========== OMEGA Rules (vX.Y.Z) ==========` block, extracts the non-managed region into the new source ONCE, and retargets `firebase.json`; a 0.36.0 hook-era file migrates the same way, once. It is a RUN-ALONE verb, never another verb's side effect ([#522](https://github.com/Omega-JS-Stack/omega/issues/522)): while `firebase.json` still names the brand's own rules file, that brand deploys the legacy posture deliberately, and adopting the compiled artifact changes what the live project enforces (the framework half joins, and a legacy `allow write` becomes `allow create, update` — a client deleting its own user doc flips allowed → denied). Both target checks DEFER there: they print the deferral plus this pointer, report deferred (not failed, not fixed), and continue. Once `firebase.json` points at `dist/firestore.rules`, the checks heal the source exactly as before.
|
|
190
|
+
- **`database.rules.json` keeps the marker model** and `storage.rules` stays a copy-if-missing deny-all scaffold — SETTLED ([#351](https://github.com/Omega-JS-Stack/omega/issues/351), 2026-08-18): neither has a framework half a brand needs to tighten, RTDB rules are a JSON tree with no function language to splice (the brand owns its sibling keys outright), and compiling either would add machinery with no merge semantics to buy. The three rules surfaces deliberately run three models.
|
|
191
|
+
|
|
192
|
+
See [docs/cli-firestore-auth.md](../docs/cli-firestore-auth.md) and [docs/cli-logs.md](../docs/cli-logs.md) for full flag references.
|
|
193
|
+
|
|
194
|
+
## Dependency Resolution
|
|
195
|
+
|
|
196
|
+
- **Consumer code can use `Manager.require(name)`** to load any @omega.js/backend dependency from @omega.js/backend's own module context (static + prototype). Consumer projects do NOT need to install @omega.js/backend's transitive deps directly.
|
|
197
|
+
- **No bundler hook is needed here (#87).** @omega.js/web gives consumers bare imports of framework-declared libraries through an esbuild resolve hook ([docs/devkit/index.md](../devkit/index.md) owns the declared-set reader behind it), and desktop and extension through the same hook. Backend functions are NOT bundled: they run under plain node resolution, and `Manager.require(name)` resolves from @omega.js/backend's own module context, which already delivers the same guarantee — the framework's copy, one copy, from the framework's installation. Bare `require('<framework dep>')` in consumer code is NOT part of the contract here; use `Manager.require`.
|
|
198
|
+
- **@omega.js/client owns Firebase on the client side.** Consumer frontend code (UJM pages, BXM popup/options, EM renderers) NEVER imports Firebase directly — `firebase.firestore()` → `omega.firestore()`, `firebase.auth()` → `omega.auth()`. @omega.js/backend backend code uses `firebase-admin` directly (server-side is different).
|
|
199
|
+
|
|
200
|
+
## Development Workflow
|
|
201
|
+
|
|
202
|
+
- **🚫 NEVER use `npx omega ...` from the framework repo** — `npx omega` is for CONSUMER projects only (where the bin lives in the target's `node_modules/.bin/`). From the framework repo, use `npm test`, `npm run prepare`, etc. — the `scripts` in `package.json` call `node bin/omega-backend` directly. This applies to ALL four OMEGA frameworks (@omega.js/backend/UJM/BXM/EM).
|
|
203
|
+
- **🚫 NEVER run `npx omega serve` / `npx omega emulator`** (consumer projects) — they're the user's long-running dev processes. Assume they're already running; if they aren't, **instruct the user to run them** rather than running them yourself (running them again kills theirs). To see output, **read the log files** — `logs/dev.log` for the CLI's own run, `dist/emulator.log` for the emulator's traffic — never tail/attach to the process. Running `npx omega test` is fine (it auto-starts its own emulator if needed).
|
|
204
|
+
- **Where the output logs live — two files per verb, one contains the other.** The CLI VERB tees its whole run to `<projectDir>/logs/`, the cross-framework lane every OMEGA target shares: `dev.log` (`npx omega serve` / `npx omega emulator`), `build.log` (`npx omega build`), `test.log` (`npx omega test`) — and since the verb mirrors every child chunk, this file is a superset holding the firebase children's output too. The child-only view lives in `<projectDir>/dist/` (@omega.js/backend's deliberate exception, co-located with firebase-tools' own `*-debug.log`): `emulator.log`, `dev.log`, `test.log`, plus `deploy.log` (`npx omega deploy`) and `production.log` (`npx omega logs`). Both truncate per launch; the sweep at every verb start clears ours and never touches firebase-tools'. Full table and mechanism: [docs/shared/logging.md](shared/logging.md); backend specifics: [docs/logging.md](../docs/logging.md).
|
|
205
|
+
- **A credential never rides a log line.** The request, headers and user lines redact the channels the authenticator reads ([#275](https://github.com/Omega-JS-Stack/omega/issues/275)), and the route logger's `Sending response` line gets the same treatment at any depth of the payload: keys are matched lower-cased with `-` and `_` stripped (so `accessToken` and `access_token` are one key), and every name ending in `token`, `secret`, `password`, `privatekey` or `apikey`, plus `sessionCookie`, logs as `***<last 4> (<n> chars)` when it holds a string and `***(redacted object)` when it holds anything else, while a null, a boolean or a number passes through ([#796](https://github.com/Omega-JS-Stack/omega/issues/796)).
|
|
206
|
+
- **If the user reports an error**, check the emulator/test output for the root cause before guessing.
|
|
207
|
+
- **Live-test UI changes via CDP.** When working on admin dashboards or browser-facing endpoints, use the `chrome-devtools` MCP tools (screenshots, click, evaluate JS, console logs) to verify the change works in the running browser — your session auto-launches its own private Chrome on the first tool call (no setup, no ports). See [docs/cdp-debugging.md](../docs/cdp-debugging.md) + `~/.claude/mcp-server/servers/chrome-devtools/CLAUDE.md`.
|
|
208
|
+
|
|
209
|
+
## Supply-Chain Security
|
|
210
|
+
|
|
211
|
+
All `npm install` calls in CLI commands (`npx omega i`, the target checks) route through the `safeInstall()` helper (`src/cli/utils/safe-install.js`). It prefixes `sfw` (Socket Firewall) when installed — blocking confirmed malware at the network level before packages reach disk. Falls back to plain npm if sfw isn't available. CI workflows install sfw globally and run `sfw npm install`/`sfw npm ci`. Installs will **fail if sfw detects confirmed malware** in any package in the dependency tree; non-critical CVEs and quality warnings pass through.
|
|
212
|
+
|
|
213
|
+
## File Conventions
|
|
214
|
+
|
|
215
|
+
- **CommonJS** throughout. `prepare-package` copies `src/` → `dist/` 1:1 (no transforms).
|
|
216
|
+
- **`fs-jetpack`** over `fs` / `fs-extra` for file operations.
|
|
217
|
+
- One `module.exports = ...` per file.
|
|
218
|
+
- **Short-circuit early returns** rather than nested ifs.
|
|
219
|
+
- **Logical operators at the start of continuation lines** (`|| condB` on a new line, not `condA ||` trailing).
|
|
220
|
+
- **Firestore shorthand**: `admin.firestore().doc('users/abc123')` (path string) rather than `.collection('users').doc('abc123')`.
|
|
221
|
+
- **Template strings for requires**: `` require(`${functionsDir}/node_modules/@omega.js/backend`) `` rather than string concat.
|
|
222
|
+
- **No backwards compatibility** unless explicitly requested.
|
|
223
|
+
- **Routes receive whitespace-trimmed data; HTML is preserved.** Sanitize at the HTML-insertion site via `utilities.sanitize()`. Opt into middleware-level HTML strip per-route with `{ sanitize: true }`. See [docs/sanitization.md](../docs/sanitization.md).
|
|
224
|
+
- **Match schema names to route names** — if route is `myEndpoint`, schema is `myEndpoint`.
|
|
225
|
+
- **Always use `ctx.respond()` for responses** — do NOT use `res.send()` directly.
|
|
226
|
+
- **Always use `Manager.getApiUrl()` for the API URL** — never read the cached `Manager.project.apiUrl` property. The getter is the SSOT and auto-resolves to the local emulator in dev AND test (and production otherwise), so it's safe everywhere without passing an env arg. See [docs/environment-detection.md](../docs/environment-detection.md).
|
|
227
|
+
- **Add Firestore composite indexes** for any compound query (`where` + `orderBy`, or multiple `where`s) to `src/cli/commands/setup-tests/helpers/required-indexes.js` (the SSOT). Without the index, queries crash with `FAILED_PRECONDITION` in production.
|
|
228
|
+
|
|
229
|
+
See [docs/code-patterns.md](../docs/code-patterns.md) for code-pattern detail, [docs/common-mistakes.md](../docs/common-mistakes.md) for the full anti-pattern checklist, and [docs/file-naming.md](../docs/file-naming.md) for the naming table (routes / schemas / API commands / events / cron jobs / hooks).
|
|
230
|
+
|
|
231
|
+
## Doc-update parity
|
|
232
|
+
|
|
233
|
+
Whenever you make a behavioral change (new command, new flag, new pattern, removed feature), update:
|
|
234
|
+
|
|
235
|
+
1. **`README.md`** — user-facing summary
|
|
236
|
+
2. **`docs/backend/index.md`** (this file) — architecture overview, one paragraph or cross-link
|
|
237
|
+
3. **`docs/<topic>.md`** — the meat. If a topic doesn't have a doc yet, create one.
|
|
238
|
+
4. **`CHANGELOG.md`** — if the project keeps one
|
|
239
|
+
|
|
240
|
+
Don't ship behavioral changes with stale docs. Validate first, then document — write docs that describe shipped reality, not intentions.
|
|
241
|
+
|
|
242
|
+
**The four framework guides are structurally MIRRORED.** [docs/web/index.md](../web/index.md), [docs/backend/index.md](../backend/index.md), [docs/desktop/index.md](../desktop/index.md), and [docs/extension/index.md](../extension/index.md) keep the same section skeleton in the same order, and each consumer template (`src/defaults/AGENTS.md`; web's lives at `scaffold/AGENTS.md`) mirrors its guide. Never add, rename, or reorder a section in one without making the SAME change in the others in the same pass.
|
|
243
|
+
|
|
244
|
+
## Documentation
|
|
245
|
+
|
|
246
|
+
Deep references live in `docs/`. **Whenever you make a behavioral change, update both this overview AND the relevant `docs/*.md` deep reference.**
|
|
247
|
+
|
|
248
|
+
### Architecture & Conventions
|
|
249
|
+
|
|
250
|
+
- [docs/architecture.md](../docs/architecture.md) — Manager class, dual-mode (firebase/custom), helper factory pattern
|
|
251
|
+
- [docs/directory-structure.md](../docs/directory-structure.md) — @omega.js/backend library + consumer project layouts
|
|
252
|
+
- [docs/build-system.md](../docs/build-system.md) — no consumer build (deliberate outlier), framework prepare-package, deploy pipeline
|
|
253
|
+
- [docs/code-patterns.md](../docs/code-patterns.md) — short-circuit returns, logical operators on new lines, Firestore shorthand, template-string requires, fs-jetpack preference
|
|
254
|
+
- [docs/file-naming.md](../docs/file-naming.md) — naming table for routes, schemas, API commands, events, cron jobs, hooks
|
|
255
|
+
- [docs/common-mistakes.md](../docs/common-mistakes.md) — anti-pattern checklist (don't modify Manager internals, always await, one `ctx.usage.consume()` call counts, etc.)
|
|
256
|
+
- [docs/audit.md](../docs/audit.md) — full-audit check catalog (U-xx universal / @omega.js/backend-xx / F-xx IDs with severity + scope), protocol + fix loop
|
|
257
|
+
- [docs/cdp-debugging.md](../docs/cdp-debugging.md) — launching a controllable Chrome (CDP) to verify the frontend against your routes (network payloads, auth'd flows via the persistent agent profile)
|
|
258
|
+
- [docs/key-files.md](../docs/key-files.md) — quick lookup for the most-touched files (Manager, helpers, auth events, cron, payment providers, CLI commands)
|
|
259
|
+
- [docs/cli-output.md](../docs/cli-output.md) — shared CLI styling module (`src/cli/utils/ui.js`): OMEGA-style banner/dividers/sections/status symbols + the `Summary` block (pass/warn/fail); setup check return types (`true`/`false`/`Error`/`'warn'`); used by the target checks, adoptable by other commands
|
|
260
|
+
- [docs/environment-detection.md](../docs/environment-detection.md) — `getEnvironment()` returns `'development' | 'testing' | 'production'` (mutually exclusive); gate side effects on the INTENTIONAL check (`isProduction()` for prod-only, `isDevelopment() || isTesting()` for local-or-test) — never `!isDevelopment()`. Plus the URL helper convention (always `Manager.getApiUrl()` — auto-resolves local in dev+test, never read `project.apiUrl`)
|
|
261
|
+
- [docs/response-headers.md](../docs/response-headers.md) — automatic `omega-properties` header
|
|
262
|
+
|
|
263
|
+
### Building Routes & Components
|
|
264
|
+
|
|
265
|
+
- [docs/routes.md](../docs/routes.md) — recipes for new API commands, routes (context-object handlers, CRUD method files, ownership checks, firebase.json rewrites + ordering, src/index.js entry), event handlers, cron jobs
|
|
266
|
+
- [docs/schemas.md](../docs/schemas.md) — schema contract (context object → flat schema, in-function plan branching), field properties, ID generation + path extraction, required-vs-default footgun
|
|
267
|
+
- [docs/firestore.md](../docs/firestore.md) — path style, NO subcollections, batch reads (~500 cursor pagination), `metadata.{created,updated}` timestamps, response format + redaction
|
|
268
|
+
- [docs/migration.md](../docs/migration.md) — legacy-project migration: runtime config → top-level env vars, `Manager.config.*` → `process.env.*`, constructor routes / tiered schemas → current format
|
|
269
|
+
- [docs/sanitization.md](../docs/sanitization.md) — middleware trim-only default; opt-in HTML strip (`{ sanitize: true }`) with per-field opt-out (`sanitize: false`); manual `utilities.sanitize()` for HTML-insertion sites
|
|
270
|
+
- [docs/auth-hooks.md](../docs/auth-hooks.md) — consumer hooks for `before-create`/`before-signin`/`on-create`/`on-delete` (blocking + non-blocking examples)
|
|
271
|
+
- [docs/common-operations.md](../docs/common-operations.md) — inside-the-handler patterns: authenticate, read/write Firestore, error handling, send response, `omega_api` hook
|
|
272
|
+
|
|
273
|
+
### Built-in Routes
|
|
274
|
+
|
|
275
|
+
- [docs/verts.md](../docs/verts.md) — house verts module (adblock-safe ad system): `verts` collection, public `GET /omega/verts/serve` (self-contained HTML unit, 204 no-fill) + fail-closed `GET /omega/verts/redirect`, admin CRUD, in-memory inventory cache (~5 min TTL), contextual targeting × weight selection
|
|
276
|
+
- [docs/connections.md](../docs/connections.md) — user connections (`/user/connections`): the stored record and its `type` ([#788](https://github.com/Omega-JS-Stack/omega/issues/788)), the two things a provider adds (a `src/connections/<name>.js` module the lane loads before its own, the two `CONNECTIONS_<PROVIDER>_*` env keys), `pkce: 'S256'` as a declaration, the ONE context every step takes and the `authorize`/`exchange`/`identity`/`refresh`/`revoke`/`status` table, the route-owned identity uniqueness and the config-defaults card rule ([#793](https://github.com/Omega-JS-Stack/omega/issues/793)), and how another target reads or refreshes the token ([#771](https://github.com/Omega-JS-Stack/omega/issues/771)) — plus the cross-instance refresh lease and the `{ success, token }` answer ([#783](https://github.com/Omega-JS-Stack/omega/issues/783)) and the public client that sends no `client_secret` ([#785](https://github.com/Omega-JS-Stack/omega/issues/785))
|
|
277
|
+
- [docs/admin-post-route.md](../docs/admin-post-route.md) — `POST/PUT /admin/post` blog creation via GitHub (image extraction + resize at ingest + `@post/` rewriting). Also the publish target for the Ghostii article engine (`libraries/content/ghostii.js`).
|
|
278
|
+
- [docs/payment-system.md](../docs/payment-system.md) — full payment pipeline: Intent → Webhook → On-Write → Transition; subscription model, statuses, `resolveSubscription()`, transition handlers, provider interface (Stripe, PayPal, Chargebee, Coinbase Commerce for crypto one-time purchases, test), webhook verification (the shared `?key=` param, the one check), product config, test provider
|
|
279
|
+
- [docs/paypal-sandbox-qa.md](../docs/paypal-sandbox-qa.md) — the live PayPal sandbox QA drive: standing fixtures (creds, webhook, the trial-free `proof-press` product — listed on /pricing on purpose, the hand-made sandbox buyer — PayPal has no account-creation API), the subscription sale → refund sequence, and the gotchas
|
|
280
|
+
- [docs/marketing-campaigns.md](../docs/marketing-campaigns.md) — campaign CRUD routes, recurring campaigns, generator pipeline (newsletter), newsletter-driven blog article (`content.article.enabled`), template-owned schemas, asset hosting, seed campaigns
|
|
281
|
+
- [docs/consent.md](../docs/consent.md) — marketing consent capture: canonical `consent.{legal,marketing}` user-doc shape, signup-form capture, account-page toggle, HMAC unsub link (cross-provider unsub + re-add on resubscribe), admin contact-DELETE revoke mirror, SendGrid+Beehiiv webhook receivers, parent forwarder (`/marketing/webhook/forward`), library-level consent gate in `email.add()`/`email.sync()` (revoked-only skip), migration script template
|
|
282
|
+
- [docs/mcp.md](../docs/mcp.md) — Model Context Protocol server: 28 tools with role-based scoping (24 admin / 2 user / 2 public), tool annotations (title, read/write hints), OAuth 2.1 with PKCE + dynamic client registration + consumer website sign-in, consumer MCP tools (`src/mcp.js`), HTTPS local dev (mkcert), Claude Desktop/Chat/Code configuration
|
|
283
|
+
|
|
284
|
+
### Subsystems & Libraries
|
|
285
|
+
|
|
286
|
+
- [docs/ghostii.md](../docs/ghostii.md) — Blog auto-publisher (Ghostii provider): source types (`$brand` / `$feed:` / `$parent` / URL / text), provider-based architecture, per-entry API overrides, RSS/Atom feed parser, unified `content-sources` Firestore tracking, `sourceContent` pass-through to Ghostii API
|
|
287
|
+
- [docs/email-system.md](../docs/email-system.md) — unified MJML email rendering pipeline: shared preparation (`prepare.js`), composable template system (`base.js` blocks), 4 email templates (card, plain, order, feedback), no SendGrid dynamic templates — everything rendered server-side
|
|
288
|
+
- [docs/usage-rate-limiting.md](../docs/usage-rate-limiting.md) — the counted-feature gate ([#647](https://github.com/Omega-JS-Stack/omega/issues/647)): ONE call, `await ctx.usage.consume('<feature>')`, checks both counters (month and the day's share of it), refuses with a 429 naming which one hit, else counts and writes. What a feature IS lives once in the top-level `features` catalog and each product names only its VALUE; per-user overrides on the user doc win over the plan's number; mirrors are declared in the catalog, not at the call site; anonymous counting is explicit (`usage.forKey(ip)`); init is lazy, so a route that never counts pays nothing
|
|
289
|
+
- [docs/ai-library.md](../docs/ai-library.md) — `Manager.AI()` unified entry for OpenAI + Anthropic (text via `.request()`, images via `.image()` → `gpt-image-2`)
|
|
290
|
+
- [docs/marketing-fields.md](../docs/marketing-fields.md) — adding custom fields to SendGrid + Beehiiv via the @omega.js/backend/OMEGA SSOT pair
|
|
291
|
+
- [docs/stripe-webhook-forwarding.md](../docs/stripe-webhook-forwarding.md) — auto-started Stripe CLI forwarding for local dev, and the shared key the forwarded deliveries carry
|
|
292
|
+
|
|
293
|
+
### Testing & CLI
|
|
294
|
+
|
|
295
|
+
- [docs/test-framework.md](../docs/test-framework.md) — running, filtering, log files, test types (standalone/suite/group), context object, assertions, auth levels. **NEVER mock — test against the real emulator.** No `mockManager`/`mockAdmin`/fake `firestore`/stubbed `ctx`; every `run()` gets the real `Manager`/`ctx`/`firestore`/`http`/`accounts` — use them. Pure functions (zero I/O) are the only thing you call directly; anything touching Firestore or an external API runs for real. Real external APIs (OpenAI/PayPal/GitHub/SendGrid/Stripe) are gated behind `TEST_EXTENDED_MODE` in-source (not mocked) — opt in with `--extended` or `TEST_EXTENDED_MODE=true` (shared, unprefixed across @omega.js/backend/BXM/UJM/EM; propagates to BOTH runner + emulator) — and anything an extended test creates externally must be cleaned up by the test. **Each test file `module.exports` a `{ description, type, tests }` object — NOT raw Mocha (`describe`/`it`/`beforeEach`); those globals are not injected and the file fails to load. The only lifecycle hook is `cleanup` — exported `before`/`after` properties are silently IGNORED (do setup inside the tests via an idempotent helper, or in `test/_init.js`). Split tests one-file-per-concern under `test/<area>/`, never one giant `test/test.js`.** **All cleanup runs at the START of every run, never at the end** — the runner flushes the ENTIRE emulator Firestore before every run, so there's nothing to register; seed any needed fixtures in `test/_init.js`'s `setup()`, and never add a trailing cleanup step. Marketing providers (SendGrid/Beehiiv) don't need a special exception — `_test.*` emails are blocked at the validation layer so test signups never reach providers. The `_test.allow_*` carve-out exists only for the live-provider lifecycle test (`test/marketing/consent-lifecycle.js`), which manages its own teardown.
|
|
296
|
+
- [docs/test-boot-layer.md](../docs/test-boot-layer.md) — the `boot/` smoke layer: framework self-test from the repo via the bundled fixture project + `OMEGA_TEST_BOOT_PROJECT` (@omega.js/backend's analog of BXM/UJM `*_TEST_BOOT_PROJECT`)
|
|
297
|
+
- [docs/cli-firestore-auth.md](../docs/cli-firestore-auth.md) — `npx omega firestore:*` and `auth:*` commands, shared flags, examples
|
|
298
|
+
- [docs/cli-logs.md](../docs/cli-logs.md) — `npx omega logs:read` / `logs:tail` with full flag reference and built-in Cloud Function names
|
|
299
|
+
- [docs/logging.md](../docs/logging.md) — `dist/*.log` file table (the `dist/` location exception — co-located with firebase-tools' debug logs), `production.log`
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# Key Files Reference
|
|
2
|
+
|
|
3
|
+
| Purpose | File |
|
|
4
|
+
|---------|------|
|
|
5
|
+
| Main Manager class | `src/manager/index.js` |
|
|
6
|
+
| Request/response handling | `src/manager/helpers/context/` |
|
|
7
|
+
| Middleware pipeline | `src/manager/helpers/middleware.js` |
|
|
8
|
+
| Schema validation | `src/manager/helpers/settings.js` |
|
|
9
|
+
| Rate limiting | `src/manager/helpers/usage.js` |
|
|
10
|
+
| User properties + schema | `src/manager/helpers/user.js` |
|
|
11
|
+
| Batch utilities | `src/manager/helpers/utilities.js` |
|
|
12
|
+
| Auth: before-create | `src/manager/events/auth/before-create.js` |
|
|
13
|
+
| Auth: before-signin | `src/manager/events/auth/before-signin.js` |
|
|
14
|
+
| Auth: on-create | `src/manager/events/auth/on-create.js` |
|
|
15
|
+
| Auth: on-delete | `src/manager/events/auth/on-delete.js` |
|
|
16
|
+
| Auth: shared utilities | `src/manager/events/auth/utils.js` |
|
|
17
|
+
| Cron runner | `src/manager/events/cron/runner.js` |
|
|
18
|
+
| Main API handler (middleware) | `src/manager/helpers/middleware.js` |
|
|
19
|
+
| Config template | `templates/config/omega.json5` |
|
|
20
|
+
| CLI entry | `src/cli/index.js` |
|
|
21
|
+
| CLI command table (dispatch order + generated help) | `src/cli/command-table.js` |
|
|
22
|
+
| Stripe webhook forwarding | `src/cli/commands/stripe.js` |
|
|
23
|
+
| Firebase init helper (CLI) | `src/cli/commands/firebase-init.js` |
|
|
24
|
+
| Firestore CLI commands | `src/cli/commands/firestore.js` |
|
|
25
|
+
| Auth CLI commands | `src/cli/commands/auth.js` |
|
|
26
|
+
| Logs CLI commands | `src/cli/commands/logs.js` |
|
|
27
|
+
| Intent creation | `src/manager/routes/payments/intent/post.js` |
|
|
28
|
+
| Webhook ingestion | `src/manager/routes/payments/webhook/post.js` |
|
|
29
|
+
| Webhook processing (on-write) | `src/manager/events/firestore/payments-webhooks/on-write.js` |
|
|
30
|
+
| Payment analytics | `src/manager/events/firestore/payments-webhooks/analytics.js` |
|
|
31
|
+
| Transition detection | `src/manager/events/firestore/payments-webhooks/transitions/index.js` |
|
|
32
|
+
| Payment provider libraries | `src/manager/libraries/payment/providers/` |
|
|
33
|
+
| Stripe library | `src/manager/libraries/payment/providers/stripe.js` |
|
|
34
|
+
| PayPal library | `src/manager/libraries/payment/providers/paypal.js` |
|
|
35
|
+
| Order ID generator | `src/manager/libraries/payment/order-id.js` |
|
|
36
|
+
| Required Firestore indexes (SSOT) | `src/cli/commands/setup-tests/helpers/required-indexes.js` |
|
|
37
|
+
| Test accounts | `src/test/test-accounts.js` |
|
package/docs/logging.md
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# Logging
|
|
2
|
+
|
|
3
|
+
@omega.js/backend CLI commands automatically save all output to log files while still streaming to the console — in two files per verb, one of which CONTAINS the other.
|
|
4
|
+
|
|
5
|
+
The **verb's whole run** lands in `<projectDir>/logs/<verb>.log`, the lane every OMEGA framework shares (contract: `docs/shared/logging.md` in the Omega repo). It is a SUPERSET: the verb mirrors every chunk its firebase child pipes over to its own stdout, so this file holds the full child stream plus the verb's own lines:
|
|
6
|
+
|
|
7
|
+
| File | Source | Lifetime |
|
|
8
|
+
|---|---|---|
|
|
9
|
+
| `logs/dev.log` | `npx omega serve` / `npx omega emulator` — port allocation, the TLS proxy, the stage watcher, **and** the firebase child's whole stream | Truncated each run |
|
|
10
|
+
| `logs/build.log` | `npx omega build` | Truncated each run |
|
|
11
|
+
| `logs/test.log` | `npx omega test` — setup lines, the port summary, the emulator boot, **and** the runner/emulator child's stream | Truncated each run |
|
|
12
|
+
|
|
13
|
+
The **firebase children's** output ALSO lands on its own in `<projectDir>/dist/`, not `logs/` — a deliberate exception so it sits inside the staged tree (which the stage step PRESERVES across re-stages) and can be grepped alongside the runtime it drove, beside firebase-tools' own `*-debug.log` files.
|
|
14
|
+
|
|
15
|
+
## Log files
|
|
16
|
+
|
|
17
|
+
The child-only files, all in `<projectDir>/dist/` — the same lines the verb log carries, with none of the verb's own around them (and the only ones that roll mid-run):
|
|
18
|
+
|
|
19
|
+
| File | Source | Lifetime |
|
|
20
|
+
|---|---|---|
|
|
21
|
+
| `dev.log` | `npx omega serve` — @omega.js/backend's local dev server (Firebase serve) | Overwritten each run |
|
|
22
|
+
| `deploy.log` | `npx omega deploy` — Firebase deployment output (function uploads, hosting deploys, errors) | Overwritten each run |
|
|
23
|
+
| `emulator.log` | `npx omega emulator` — full emulator output (Firebase emulator + Cloud Functions logs); also `npx omega test` when it starts its own emulator | Overwritten each run |
|
|
24
|
+
| `test.log` | `npx omega test` runner output when running against an already-running emulator | Overwritten each run |
|
|
25
|
+
| `production.log` | `npx omega logs:read` / `npx omega logs:tail` — production Cloud Function logs from Google Cloud Logging (raw JSON for `read`, streaming text for `tail`) | Overwritten each run |
|
|
26
|
+
|
|
27
|
+
The `dev`/`test` names match EM/BXM/UJM for cross-framework parity.
|
|
28
|
+
|
|
29
|
+
## attach-log-file utility
|
|
30
|
+
|
|
31
|
+
`src/cli/utils/attach-log-file.js` — shared DRY utility (same pattern as BXM/UJM/EM). Intercepts `process.stdout.write` / `process.stderr.write` to tee all output to a log file while preserving console display. ANSI codes stripped from file output for grep-friendliness.
|
|
32
|
+
|
|
33
|
+
```js
|
|
34
|
+
const attachLogFile = require('../utils/attach-log-file');
|
|
35
|
+
|
|
36
|
+
attachLogFile(this.getLogsPath('deploy.log'));
|
|
37
|
+
// ... run command — all stdout/stderr is now teed to the log file ...
|
|
38
|
+
attachLogFile.detach();
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
- **Singleton**: default export is a process-wide singleton (one file at a time)
|
|
42
|
+
- **Factory**: `attachLogFile.createTee()` returns an independent tee for stacking, with LIFO detach
|
|
43
|
+
- **Idempotent**: attaching the same path twice returns the existing handle
|
|
44
|
+
- **Crash-safe**: writes go to an open fd synchronously, so the lines describing a crash survive it
|
|
45
|
+
- **Synchronous detach**: `detach()` restores the writers and closes the fd — it returns nothing and there is no buffered tail to flush
|
|
46
|
+
- **Truncate on attach**: a new launch clears the previous run's file
|
|
47
|
+
- **CI no-op**: under `CI` / `GITHUB_ACTIONS` the tee declines — the runner captures its own output
|
|
48
|
+
|
|
49
|
+
Every verb attaches it through `BaseCommand#attachVerbLog(verb)` for the `logs/` lane; `deploy.js` attaches a `dist/` path directly. The `serve`/`emulator`/`test` commands additionally pipe their firebase CHILD into `createChildLog()` — the same sink plus the mid-run `roll()` that reset-sentinel polling and reload detection need.
|
|
50
|
+
|
|
51
|
+
## What gets captured
|
|
52
|
+
|
|
53
|
+
When `npx omega test` starts its own emulator, logs go to `emulator.log` (it delegates to the emulator command). When running against an already-running emulator, logs go to `test.log`.
|
|
54
|
+
|
|
55
|
+
All files are gitignored (`logs/` as a directory, `dist/` output via `*.log`). Reset sentinels (`*.log.reset`), the watch trigger file, and `test-mode.json` live separately in `<projectDir>/.temp/` — they're transient internal signals with no debugging value.
|
|
56
|
+
|
|
57
|
+
## See also
|
|
58
|
+
|
|
59
|
+
- [cli-logs.md](cli-logs.md) — `npx omega logs:read` / `logs:tail` flag reference (the commands that feed `production.log`)
|
|
60
|
+
- [test-framework.md](test-framework.md) — the test runner that feeds `test.log` / `emulator.log`
|