@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
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Email validation — single entry point for all email quality checks
|
|
3
|
+
*
|
|
4
|
+
* Available checks (run in this order):
|
|
5
|
+
* - format — basic email regex
|
|
6
|
+
* - disposable — checks against known disposable domain list (~7k domains)
|
|
7
|
+
* - corporate — blocks corporate/social-media domains (meta.com, instagram.com, soundcloud.com, etc.)
|
|
8
|
+
* - localPart — blocks spam/junk local parts (test, noreply, all-numeric, etc.)
|
|
9
|
+
* - typo — catches common domain misspellings (gamil., gmai., aol.con, etc.)
|
|
10
|
+
* - dns — verifies domain has MX records (no MX = can't receive email, guaranteed fail)
|
|
11
|
+
* - mailbox — verifies mailbox exists via API (costs money, requires NEVERBOUNCE_API_KEY or ZEROBOUNCE_API_KEY)
|
|
12
|
+
*
|
|
13
|
+
* Usage:
|
|
14
|
+
* validate(email) // All free checks (format + disposable + corporate + localPart + typo)
|
|
15
|
+
* validate(email, { checks: ['format', 'disposable'] }) // Only format + disposable
|
|
16
|
+
* validate(email, { checks: ALL_CHECKS }) // Everything including dns + mailbox
|
|
17
|
+
*
|
|
18
|
+
* Used by:
|
|
19
|
+
* - routes/marketing/contact/post.js
|
|
20
|
+
* - routes/user/signup/post.js (ALL_CHECKS before marketing sync; isDisposable() for affiliate fraud prevention)
|
|
21
|
+
* - libraries/email/marketing/index.js (safety net before Beehiiv/SendGrid add/sync)
|
|
22
|
+
*/
|
|
23
|
+
const path = require('path');
|
|
24
|
+
const dns = require('dns');
|
|
25
|
+
const { promisify } = require('util');
|
|
26
|
+
const neverbounceProvider = require('./validation-provider-neverbounce');
|
|
27
|
+
const zerobounceProvider = require('./validation-provider-zerobounce');
|
|
28
|
+
|
|
29
|
+
const resolveMx = promisify(dns.resolveMx);
|
|
30
|
+
|
|
31
|
+
// All data lives in ./data/ — domains and local-part blocklists are co-located JSON files.
|
|
32
|
+
const DATA_DIR = path.join(__dirname, 'data');
|
|
33
|
+
|
|
34
|
+
// Load disposable domains: curated vendor list + custom additions.
|
|
35
|
+
// The vendor list comes through ./disposable-domains.js — gitignored refresh
|
|
36
|
+
// cache if present, committed seed otherwise (see that module for the contract).
|
|
37
|
+
const DISPOSABLE_DOMAINS = require('./disposable-domains').load();
|
|
38
|
+
const CUSTOM_DISPOSABLE_DOMAINS = require(path.join(DATA_DIR, 'custom-disposable-domains.json'));
|
|
39
|
+
const DISPOSABLE_SET = new Set([
|
|
40
|
+
...DISPOSABLE_DOMAINS.map(d => d.toLowerCase()),
|
|
41
|
+
...CUSTOM_DISPOSABLE_DOMAINS.map(d => d.toLowerCase()),
|
|
42
|
+
]);
|
|
43
|
+
|
|
44
|
+
// Load corporate/social-media domains — real mailboxes we never want on marketing lists
|
|
45
|
+
const CORPORATE_DOMAINS = require(path.join(DATA_DIR, 'corporate-domains.json'));
|
|
46
|
+
const CORPORATE_SET = new Set(CORPORATE_DOMAINS.map(d => d.toLowerCase()));
|
|
47
|
+
|
|
48
|
+
// Load local-part blocklists from ./data/ (JSON for strings, JS for regex patterns)
|
|
49
|
+
const BLOCKED_LOCAL_PARTS_DATA = require(path.join(DATA_DIR, 'blocked-local-parts.json'));
|
|
50
|
+
const BLOCKED_LOCAL_PARTS = new Set(
|
|
51
|
+
Object.values(BLOCKED_LOCAL_PARTS_DATA).flat().map(p => p.toLowerCase())
|
|
52
|
+
);
|
|
53
|
+
const BLOCKED_LOCAL_PATTERNS = require(path.join(DATA_DIR, 'blocked-local-patterns.js'));
|
|
54
|
+
|
|
55
|
+
// Load typo-domain prefixes — common misspellings of major providers
|
|
56
|
+
const TYPO_DOMAIN_PREFIXES = require(path.join(DATA_DIR, 'typo-domains.js'));
|
|
57
|
+
const env = require('../env.js');
|
|
58
|
+
|
|
59
|
+
// Format regex
|
|
60
|
+
const EMAIL_FORMAT = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
61
|
+
|
|
62
|
+
// Default checks (all free checks — mailbox excluded because it costs money)
|
|
63
|
+
const DEFAULT_CHECKS = ['format', 'disposable', 'corporate', 'localPart', 'typo'];
|
|
64
|
+
|
|
65
|
+
// All available checks (dns is free but async/slow — opt-in for bulk validation)
|
|
66
|
+
const ALL_CHECKS = ['format', 'disposable', 'corporate', 'localPart', 'typo', 'dns', 'mailbox'];
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Validate an email address through selected checks.
|
|
70
|
+
*
|
|
71
|
+
* Returns valid: true on mailbox API errors so emails are never silently dropped.
|
|
72
|
+
*
|
|
73
|
+
* @param {string} email
|
|
74
|
+
* @param {object} [options]
|
|
75
|
+
* @param {Array<string>} [options.checks] - Which checks to run (default: DEFAULT_CHECKS)
|
|
76
|
+
* @returns {{ valid: boolean, checks: { format?: object, disposable?: object, corporate?: object, localPart?: object, mailbox?: object } }}
|
|
77
|
+
*/
|
|
78
|
+
async function validate(email, options = {}) {
|
|
79
|
+
const checks = new Set(options.checks || DEFAULT_CHECKS);
|
|
80
|
+
const result = { valid: true, checks: {} };
|
|
81
|
+
|
|
82
|
+
// 1. Format
|
|
83
|
+
if (checks.has('format')) {
|
|
84
|
+
if (!email || !EMAIL_FORMAT.test(email)) {
|
|
85
|
+
result.valid = false;
|
|
86
|
+
result.checks.format = { valid: false, reason: 'Invalid email format' };
|
|
87
|
+
return result;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
result.checks.format = { valid: true };
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
const [rawLocalPart, domain] = (email || '').toLowerCase().split('@');
|
|
94
|
+
|
|
95
|
+
// 2. Disposable domain
|
|
96
|
+
if (checks.has('disposable') && domain) {
|
|
97
|
+
if (DISPOSABLE_SET.has(domain)) {
|
|
98
|
+
result.valid = false;
|
|
99
|
+
result.checks.disposable = { valid: false, blocked: true, domain };
|
|
100
|
+
return result;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
result.checks.disposable = { valid: true, blocked: false };
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// 3. Corporate / social-media domain (real mailbox, but never wanted on marketing lists)
|
|
107
|
+
if (checks.has('corporate') && domain) {
|
|
108
|
+
if (CORPORATE_SET.has(domain)) {
|
|
109
|
+
result.valid = false;
|
|
110
|
+
result.checks.corporate = { valid: false, blocked: true, domain, reason: 'Corporate/social-media domain' };
|
|
111
|
+
return result;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
result.checks.corporate = { valid: true, blocked: false };
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// 4. Local part — strip +suffix before checking
|
|
118
|
+
if (checks.has('localPart') && rawLocalPart) {
|
|
119
|
+
const localPart = rawLocalPart.split('+')[0];
|
|
120
|
+
|
|
121
|
+
if (BLOCKED_LOCAL_PARTS.has(localPart)) {
|
|
122
|
+
result.valid = false;
|
|
123
|
+
result.checks.localPart = { valid: false, blocked: true, localPart, reason: 'Blocked local part' };
|
|
124
|
+
return result;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
const blockedPattern = BLOCKED_LOCAL_PATTERNS.find((p) => p.test(localPart));
|
|
128
|
+
|
|
129
|
+
if (blockedPattern) {
|
|
130
|
+
result.valid = false;
|
|
131
|
+
result.checks.localPart = { valid: false, blocked: true, localPart, reason: 'Matches junk pattern' };
|
|
132
|
+
return result;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
result.checks.localPart = { valid: true };
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// 5. Typo domain — common misspellings of major providers
|
|
139
|
+
if (checks.has('typo') && domain) {
|
|
140
|
+
const matchedPrefix = TYPO_DOMAIN_PREFIXES.find((prefix) => domain.startsWith(prefix));
|
|
141
|
+
|
|
142
|
+
if (matchedPrefix) {
|
|
143
|
+
result.valid = false;
|
|
144
|
+
result.checks.typo = { valid: false, domain, matchedPrefix, reason: 'Likely misspelled domain' };
|
|
145
|
+
return result;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
result.checks.typo = { valid: true };
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
// 6. DNS — guaranteed-fail checks (no MX, null MX, loopback MX, domain not found)
|
|
152
|
+
if (checks.has('dns') && domain) {
|
|
153
|
+
try {
|
|
154
|
+
const records = await resolveMx(domain);
|
|
155
|
+
|
|
156
|
+
if (!records || records.length === 0) {
|
|
157
|
+
result.valid = false;
|
|
158
|
+
result.checks.dns = { valid: false, domain, reason: 'No MX records' };
|
|
159
|
+
return result;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// Null MX (RFC 7505): exchange is empty or "." — domain explicitly rejects email
|
|
163
|
+
const hasNullMx = records.some((r) => !r.exchange || r.exchange === '.');
|
|
164
|
+
if (hasNullMx) {
|
|
165
|
+
result.valid = false;
|
|
166
|
+
result.checks.dns = { valid: false, domain, reason: 'Null MX (domain rejects email)' };
|
|
167
|
+
return result;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
// Loopback MX: points to localhost or 0.0.0.0 — can't receive external mail
|
|
171
|
+
const hasLoopbackMx = records.some((r) =>
|
|
172
|
+
r.exchange === 'localhost'
|
|
173
|
+
|| r.exchange === '0.0.0.0'
|
|
174
|
+
|| r.exchange.startsWith('127.')
|
|
175
|
+
|| r.exchange.endsWith('.invalid'),
|
|
176
|
+
);
|
|
177
|
+
if (hasLoopbackMx) {
|
|
178
|
+
result.valid = false;
|
|
179
|
+
result.checks.dns = { valid: false, domain, reason: 'Loopback MX (localhost/invalid)' };
|
|
180
|
+
return result;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
result.checks.dns = { valid: true, mxCount: records.length };
|
|
184
|
+
} catch (e) {
|
|
185
|
+
if (e.code === 'ENOTFOUND' || e.code === 'ENODATA' || e.code === 'ESERVFAIL') {
|
|
186
|
+
result.valid = false;
|
|
187
|
+
result.checks.dns = { valid: false, domain, reason: `DNS lookup failed: ${e.code}` };
|
|
188
|
+
return result;
|
|
189
|
+
}
|
|
190
|
+
// Network error or timeout — don't block the email
|
|
191
|
+
result.checks.dns = { valid: true, skipped: true, reason: `DNS error: ${e.code}` };
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// 7. Mailbox verification (NeverBounce preferred, ZeroBounce fallback)
|
|
196
|
+
if (checks.has('mailbox')) {
|
|
197
|
+
const provider = env.get('NEVERBOUNCE_API_KEY')
|
|
198
|
+
? neverbounceProvider
|
|
199
|
+
: (env.get('ZEROBOUNCE_API_KEY') ? zerobounceProvider : null);
|
|
200
|
+
|
|
201
|
+
if (!provider) {
|
|
202
|
+
result.checks.mailbox = { valid: true, skipped: true, reason: 'No API key', provider: null };
|
|
203
|
+
return result;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
const mailboxResult = await provider.verify(email);
|
|
207
|
+
result.checks.mailbox = mailboxResult;
|
|
208
|
+
|
|
209
|
+
if (!mailboxResult.valid) {
|
|
210
|
+
result.valid = false;
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
return result;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
/**
|
|
218
|
+
* Quick check: is this email from a disposable domain?
|
|
219
|
+
* Works with a full email address or just a domain.
|
|
220
|
+
*
|
|
221
|
+
* @param {string} emailOrDomain
|
|
222
|
+
* @returns {boolean}
|
|
223
|
+
*/
|
|
224
|
+
function isDisposable(emailOrDomain) {
|
|
225
|
+
if (!emailOrDomain) {
|
|
226
|
+
return false;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
const domain = emailOrDomain.includes('@')
|
|
230
|
+
? emailOrDomain.split('@')[1]
|
|
231
|
+
: emailOrDomain;
|
|
232
|
+
|
|
233
|
+
return DISPOSABLE_SET.has(domain.toLowerCase());
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* Quick check: is this email from a blocked corporate/social-media domain?
|
|
238
|
+
* Works with a full email address or just a domain.
|
|
239
|
+
*
|
|
240
|
+
* @param {string} emailOrDomain
|
|
241
|
+
* @returns {boolean}
|
|
242
|
+
*/
|
|
243
|
+
function isCorporate(emailOrDomain) {
|
|
244
|
+
if (!emailOrDomain) {
|
|
245
|
+
return false;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
const domain = emailOrDomain.includes('@')
|
|
249
|
+
? emailOrDomain.split('@')[1]
|
|
250
|
+
: emailOrDomain;
|
|
251
|
+
|
|
252
|
+
return CORPORATE_SET.has(domain.toLowerCase());
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
module.exports = { validate, isDisposable, isCorporate, DEFAULT_CHECKS, ALL_CHECKS };
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The ONE env reader ([#581](https://github.com/Omega-JS-Stack/omega/issues/581)).
|
|
3
|
+
*
|
|
4
|
+
* Every framework read of a brand-supplied key goes through here instead of
|
|
5
|
+
* touching `process.env` directly, so three things stop being possible: a
|
|
6
|
+
* key nobody declared (`get()` refuses a name the env schema does not know —
|
|
7
|
+
* a typo used to resolve to `undefined` forever), a required key discovered
|
|
8
|
+
* at a customer's first action instead of at boot (`assertRequired()`), and
|
|
9
|
+
* two readers of one secret drifting apart (#569's raw read beside its own
|
|
10
|
+
* helper).
|
|
11
|
+
*
|
|
12
|
+
* The schema is @omega.js/config's `ENV_SCHEMA` — the same list the manager
|
|
13
|
+
* mints from, groups a brand .env by, and composes `targets/backend/.env`
|
|
14
|
+
* from — so "what the backend needs" has one home shared with the thing that
|
|
15
|
+
* provides it. Runtime/platform vars are NOT in it and never come through
|
|
16
|
+
* here: `FIREBASE_CONFIG`, `FUNCTIONS_EMULATOR`, `GCLOUD_PROJECT`, the
|
|
17
|
+
* `OMEGA_*_PORT` map, the test-mode switches — those are the runtime's own
|
|
18
|
+
* facts about itself, not a brand's credentials.
|
|
19
|
+
*
|
|
20
|
+
* A key whose value must differ between a local run and a deployed one is NOT
|
|
21
|
+
* this reader's business ([#586](https://github.com/Omega-JS-Stack/omega/issues/586)):
|
|
22
|
+
* the brand's `.env.<environment>` overlay supplies the other value and the
|
|
23
|
+
* cascade resolves it before anything reaches here, so `env.get()` reads ONE
|
|
24
|
+
* name in every environment.
|
|
25
|
+
*
|
|
26
|
+
* Values are never printed. Errors name the KEY and the fix.
|
|
27
|
+
*/
|
|
28
|
+
const { envSchemaEntry, requiredEnvKeys, envEnvironment } = require('../../vendor/config/index.js');
|
|
29
|
+
const { checkEnvRules } = require('../../vendor/config/env-rules.js');
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* The runtime environment — what the Manager's `getEnvironment()` and the three
|
|
33
|
+
* `is*()` checks return. It is @omega.js/config's `envEnvironment()`, the ONE
|
|
34
|
+
* home of the vocabulary: the same three names the `.env.<environment>` overlay
|
|
35
|
+
* files are spelled with (#586), so a `.env.development` and a
|
|
36
|
+
* `Manager.isDevelopment()` can never mean different things.
|
|
37
|
+
*
|
|
38
|
+
* Re-exported here because the provider libraries below already read the
|
|
39
|
+
* environment through this reader and hold no Manager handle.
|
|
40
|
+
*
|
|
41
|
+
* @returns {'testing'|'production'|'development'} The environment.
|
|
42
|
+
*/
|
|
43
|
+
const environment = envEnvironment;
|
|
44
|
+
|
|
45
|
+
/** How a missing key gets fixed, by who is supposed to provide it. */
|
|
46
|
+
function remedy(entry) {
|
|
47
|
+
return entry && typeof entry.generated === 'function'
|
|
48
|
+
? 'Run `npx omega manage` at the brand root (it mints the key), then redeploy the backend.'
|
|
49
|
+
: 'Add it to the brand .env, then redeploy: every backend verb composes dist/.env from the cascade.';
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* The resolved value of a declared env key: the cascade's value, else the
|
|
54
|
+
* schema's static default, else undefined. An empty string reads as absent — a
|
|
55
|
+
* key set to nothing is not set.
|
|
56
|
+
*
|
|
57
|
+
* @param {string} name - The env var name.
|
|
58
|
+
* @returns {string|undefined} The value.
|
|
59
|
+
* @throws {Error} UnknownEnvKeyError when the schema does not declare `name`.
|
|
60
|
+
*/
|
|
61
|
+
function get(name) {
|
|
62
|
+
const entry = envSchemaEntry(name);
|
|
63
|
+
|
|
64
|
+
if (!entry) {
|
|
65
|
+
// Programmer error, not configuration: reading an undeclared key can only
|
|
66
|
+
// ever return undefined, so it fails at the read instead of at the symptom
|
|
67
|
+
const error = new Error(`${name} is not declared in the env schema (@omega.js/config's env-schema.js) — declare it there, or read a runtime var directly.`);
|
|
68
|
+
error.name = 'UnknownEnvKeyError';
|
|
69
|
+
throw error;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
return process.env[name] || entry.default;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Whether a declared env key resolves to a value — the switch every optional
|
|
77
|
+
* provider gates on (`env.has('SENDGRID_API_KEY')`).
|
|
78
|
+
*
|
|
79
|
+
* @param {string} name - The env var name.
|
|
80
|
+
* @returns {boolean} True when the key resolves to a non-empty value.
|
|
81
|
+
*/
|
|
82
|
+
function has(name) {
|
|
83
|
+
return !!get(name);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* The value of a key the caller cannot proceed without.
|
|
88
|
+
*
|
|
89
|
+
* @param {string} name - The env var name.
|
|
90
|
+
* @returns {string} The value.
|
|
91
|
+
* @throws {Error} MissingEnvKeyError (code 500) naming the key and the fix.
|
|
92
|
+
*/
|
|
93
|
+
function require_(name) {
|
|
94
|
+
const value = get(name);
|
|
95
|
+
if (value) { return value; }
|
|
96
|
+
|
|
97
|
+
const entry = envSchemaEntry(name);
|
|
98
|
+
// code 500 like the libraries' other faults (errorWithCode): a missing key
|
|
99
|
+
// is the server's misconfiguration, never the caller's input
|
|
100
|
+
const error = new Error(`${name} is missing from the .env cascade — ${entry.description} ${remedy(entry)}`);
|
|
101
|
+
error.name = 'MissingEnvKeyError';
|
|
102
|
+
error.code = 500;
|
|
103
|
+
throw error;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Validate every key this target refuses to run without, in ONE pass — the
|
|
108
|
+
* boot guard. Missing keys are reported together: a brand fixes its .env
|
|
109
|
+
* once, not once per restart.
|
|
110
|
+
*
|
|
111
|
+
* @param {string} [target] - The target whose required keys to check.
|
|
112
|
+
* @throws {Error} MissingEnvKeysError (code 500) listing every missing key.
|
|
113
|
+
*/
|
|
114
|
+
function assertRequired(target = 'backend') {
|
|
115
|
+
const missing = requiredEnvKeys(target).filter((name) => !get(name));
|
|
116
|
+
if (missing.length === 0) { return; }
|
|
117
|
+
|
|
118
|
+
const lines = missing.map((name) => ` - ${name}: ${envSchemaEntry(name).description}`);
|
|
119
|
+
const error = new Error(
|
|
120
|
+
`${missing.length} required env ${missing.length === 1 ? 'key is' : 'keys are'} missing from the .env cascade:\n${lines.join('\n')}\n`
|
|
121
|
+
+ `${remedy(envSchemaEntry(missing[0]))}`,
|
|
122
|
+
);
|
|
123
|
+
error.name = 'MissingEnvKeysError';
|
|
124
|
+
error.code = 500;
|
|
125
|
+
error.keys = missing;
|
|
126
|
+
throw error;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Validate every key this brand's OWN config made mandatory — the schema's
|
|
131
|
+
* `requiredWhen` rules ([#626](https://github.com/Omega-JS-Stack/omega/issues/626)).
|
|
132
|
+
*
|
|
133
|
+
* `assertRequired` above covers the keys OMEGA needs no matter what a brand
|
|
134
|
+
* configures. This is the other half: a config path that is set makes its key
|
|
135
|
+
* mandatory (a GA4 Measurement ID with no Measurement Protocol secret sends no
|
|
136
|
+
* events; a reCAPTCHA site key with no secret half 403s every protected POST).
|
|
137
|
+
* The rule is declared once in the env schema and evaluated by ONE checker
|
|
138
|
+
* shared with the manager's manage-time pass — this reader only decides what a
|
|
139
|
+
* violation costs, which the caller in index.js resolves: production refuses,
|
|
140
|
+
* everything else warns and continues.
|
|
141
|
+
*
|
|
142
|
+
* Violations name the BRAND-LEVEL key (GOOGLE_ANALYTICS_SECRET_BACKEND, not
|
|
143
|
+
* the GOOGLE_ANALYTICS_SECRET it is delivered as), because that is the name a
|
|
144
|
+
* human puts in the brand .env.
|
|
145
|
+
*
|
|
146
|
+
* @param {object} config - The resolved omega.json5 config.
|
|
147
|
+
* @param {string} [target] - The target whose rules to check.
|
|
148
|
+
* @throws {Error} MissingConditionalEnvKeysError (code 500) naming every key
|
|
149
|
+
* and the config path that made it mandatory.
|
|
150
|
+
*/
|
|
151
|
+
function assertRules(config, target = 'backend') {
|
|
152
|
+
// The checker answers for BOTH schema rules; the unconditional `required`
|
|
153
|
+
// half is assertRequired's above, and reporting a key twice in one boot
|
|
154
|
+
// would just be noise.
|
|
155
|
+
const violations = checkEnvRules(config, process.env, { target })
|
|
156
|
+
.filter((violation) => violation.rule === 'requiredWhen');
|
|
157
|
+
if (violations.length === 0) { return; }
|
|
158
|
+
|
|
159
|
+
const named = violations.map(({ key, path }) => (path ? `${key} (required by ${path})` : key)).join(', ');
|
|
160
|
+
const error = new Error(
|
|
161
|
+
`${violations.length} env ${violations.length === 1 ? 'key this brand\'s config requires is' : 'keys this brand\'s config requires are'} missing from the .env cascade: ${named}. `
|
|
162
|
+
+ `${remedy(envSchemaEntry(violations[0].key))}`,
|
|
163
|
+
);
|
|
164
|
+
error.name = 'MissingConditionalEnvKeysError';
|
|
165
|
+
error.code = 500;
|
|
166
|
+
error.keys = violations.map((violation) => violation.key);
|
|
167
|
+
throw error;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Whether a boot that FAILED assertRequired() may warn and continue instead
|
|
172
|
+
* of refusing. Exactly one lane qualifies: a process with no consumer
|
|
173
|
+
* omega.json5 is not a brand's backend at all — it is the framework booting
|
|
174
|
+
* itself (its offline unit lanes, a bare require of the package), where there
|
|
175
|
+
* is no brand for a manage run to have minted keys into. Anything shaped like
|
|
176
|
+
* a brand refuses in EVERY environment, development included (#569's
|
|
177
|
+
* production-only branch is gone): the key is one `npx omega manage` away,
|
|
178
|
+
* and a dev loop that boots without it just moves the crash to a customer.
|
|
179
|
+
* The self-test fixture IS brand-shaped, so it gets its required keys seeded
|
|
180
|
+
* the same way a real brand does — see ensureFixtureEnv in cli/commands/test.js.
|
|
181
|
+
*
|
|
182
|
+
* @param {object} context
|
|
183
|
+
* @param {boolean} context.hasConsumerConfig - Whether a consumer omega.json5 resolved.
|
|
184
|
+
* @returns {boolean} True when the fault is advisory.
|
|
185
|
+
*/
|
|
186
|
+
function guardIsAdvisory({ hasConsumerConfig }) {
|
|
187
|
+
return !hasConsumerConfig;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
module.exports = {
|
|
191
|
+
environment,
|
|
192
|
+
get,
|
|
193
|
+
has,
|
|
194
|
+
require: require_,
|
|
195
|
+
assertRequired,
|
|
196
|
+
assertRules,
|
|
197
|
+
guardIsAdvisory,
|
|
198
|
+
};
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared contact inference library
|
|
3
|
+
*
|
|
4
|
+
* Infers first/last name and company from an email address using AI.
|
|
5
|
+
* Requires OPENAI_API_KEY to be set.
|
|
6
|
+
*
|
|
7
|
+
* Usage:
|
|
8
|
+
* const { inferContact } = require('./libraries/infer-contact.js');
|
|
9
|
+
* const result = await inferContact(email, ctx);
|
|
10
|
+
* // { firstName, lastName, company, confidence, method }
|
|
11
|
+
*/
|
|
12
|
+
const path = require('path');
|
|
13
|
+
const env = require('./env.js');
|
|
14
|
+
|
|
15
|
+
const PROMPT_PATH = path.join(__dirname, 'prompts', 'infer-contact.md');
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Infer contact info from email address using AI
|
|
19
|
+
*
|
|
20
|
+
* @param {string} email - Email address
|
|
21
|
+
* @param {object} ctx - Assistant instance (for AI access)
|
|
22
|
+
* @returns {{ firstName: string, lastName: string, company: string, confidence: number, method: string }}
|
|
23
|
+
*/
|
|
24
|
+
async function inferContact(email, ctx) {
|
|
25
|
+
if (env.get('OPENAI_API_KEY')) {
|
|
26
|
+
const aiResult = await inferContactWithAI(email, ctx);
|
|
27
|
+
if (aiResult) {
|
|
28
|
+
return aiResult;
|
|
29
|
+
}
|
|
30
|
+
ctx?.log(`inferContact: AI returned null for ${email} — falling back to empty result`);
|
|
31
|
+
} else {
|
|
32
|
+
ctx?.log(`inferContact: OPENAI_API_KEY not set — skipping AI inference for ${email}`);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return { firstName: '', lastName: '', company: '', confidence: 0, method: 'none' };
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Use AI to infer contact info from email
|
|
40
|
+
*
|
|
41
|
+
* @param {string} email - Email address
|
|
42
|
+
* @param {object} ctx - Assistant instance
|
|
43
|
+
* @returns {object|null} Inferred contact or null on failure
|
|
44
|
+
*/
|
|
45
|
+
async function inferContactWithAI(email, ctx) {
|
|
46
|
+
try {
|
|
47
|
+
const ai = ctx.Manager.AI(ctx, env.get('OPENAI_API_KEY'));
|
|
48
|
+
const result = await ai.request({
|
|
49
|
+
model: 'gpt-5.4-mini',
|
|
50
|
+
timeout: 60000,
|
|
51
|
+
maxTokens: 1024 * 2,
|
|
52
|
+
moderate: false,
|
|
53
|
+
response: 'json',
|
|
54
|
+
prompt: {
|
|
55
|
+
path: PROMPT_PATH,
|
|
56
|
+
},
|
|
57
|
+
message: {
|
|
58
|
+
content: `Email: ${email}`,
|
|
59
|
+
},
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
const parsed = result?.content;
|
|
63
|
+
if (parsed?.firstName !== undefined) {
|
|
64
|
+
const inferred = {
|
|
65
|
+
firstName: capitalize(parsed.firstName || ''),
|
|
66
|
+
lastName: capitalize(parsed.lastName || ''),
|
|
67
|
+
company: capitalize(parsed.company || ''),
|
|
68
|
+
confidence: typeof parsed.confidence === 'number' ? parsed.confidence : 0.5,
|
|
69
|
+
method: 'ai',
|
|
70
|
+
};
|
|
71
|
+
if (!inferred.firstName && !inferred.lastName && !inferred.company) {
|
|
72
|
+
ctx?.log(`inferContactWithAI: AI parsed response had ALL fields empty for ${email}. Raw:`, parsed);
|
|
73
|
+
}
|
|
74
|
+
return inferred;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
ctx?.log(`inferContactWithAI: AI response missing firstName for ${email}. Raw result:`, result);
|
|
78
|
+
} catch (e) {
|
|
79
|
+
ctx?.error('inferContactWithAI: Failed:', e);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
return null;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Capitalize first letter of each word
|
|
87
|
+
*
|
|
88
|
+
* @param {string} str - String to capitalize
|
|
89
|
+
* @returns {string} Capitalized string
|
|
90
|
+
*/
|
|
91
|
+
function capitalize(str) {
|
|
92
|
+
if (!str) {
|
|
93
|
+
return '';
|
|
94
|
+
}
|
|
95
|
+
return str
|
|
96
|
+
.split(' ')
|
|
97
|
+
.map(word => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())
|
|
98
|
+
.join(' ');
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
module.exports = { inferContact, capitalize };
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Safe dynamic provider loader — the ONE way to require a provider module by name.
|
|
3
|
+
*
|
|
4
|
+
* Confines the require() to the given providers directory: names are strictly
|
|
5
|
+
* lowercase [a-z0-9-], so a caller-controlled value can never traverse out
|
|
6
|
+
* (`../`, absolute paths, or dots are rejected before any path math happens).
|
|
7
|
+
*/
|
|
8
|
+
const path = require('path');
|
|
9
|
+
|
|
10
|
+
const NAME_PATTERN = /^[a-z0-9-]+$/;
|
|
11
|
+
const ID_PATTERN = /^[a-z0-9_-]+(?::[a-z0-9_-]+)*$/;
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* The file `${dir}/${name}.js` resolves to, rejecting any name that could
|
|
15
|
+
* escape the directory. Split out of loadProvider so a caller that searches
|
|
16
|
+
* SEVERAL directories (the connections lane: the brand's dir, then the package's)
|
|
17
|
+
* can ask whether a file is there without owning a second copy of the name
|
|
18
|
+
* rule ([#771](https://github.com/Omega-JS-Stack/omega/issues/771)).
|
|
19
|
+
*
|
|
20
|
+
* @param {string} dir - Absolute path of the providers directory
|
|
21
|
+
* @param {string} name - Provider name (strictly [a-z0-9-])
|
|
22
|
+
* @returns {string} Absolute path of the provider file
|
|
23
|
+
* @throws {Error} When the name is not a valid provider name
|
|
24
|
+
*/
|
|
25
|
+
function providerPath(dir, name) {
|
|
26
|
+
if (typeof name !== 'string' || !NAME_PATTERN.test(name)) {
|
|
27
|
+
throw new Error(`Invalid provider name: ${name}`);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
return path.join(dir, `${name}.js`);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Load `${dir}/${name}.js`, rejecting any name that could escape the directory.
|
|
35
|
+
*
|
|
36
|
+
* @param {string} dir - Absolute path of the providers directory
|
|
37
|
+
* @param {string} name - Provider name (strictly [a-z0-9-])
|
|
38
|
+
* @returns {*} The required module
|
|
39
|
+
* @throws {Error} When the name is not a valid provider name
|
|
40
|
+
*/
|
|
41
|
+
function loadProvider(dir, name) {
|
|
42
|
+
return require(providerPath(dir, name));
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Load a module by colon-joined id (e.g. "general:download-app-link" →
|
|
47
|
+
* `${dir}/general/download-app-link.js`), rejecting any id that could escape
|
|
48
|
+
* the directory: every segment is strictly [a-z0-9_-].
|
|
49
|
+
*
|
|
50
|
+
* @param {string} dir - Absolute path of the modules directory
|
|
51
|
+
* @param {string} id - Colon-joined module id
|
|
52
|
+
* @returns {*} The required module
|
|
53
|
+
* @throws {Error} When the id is not a valid module id
|
|
54
|
+
*/
|
|
55
|
+
function loadTemplate(dir, id) {
|
|
56
|
+
if (typeof id !== 'string' || !ID_PATTERN.test(id)) {
|
|
57
|
+
throw new Error(`Invalid template id: ${id}`);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return require(path.join(dir, `${id.split(':').join('/')}.js`));
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
module.exports = loadProvider;
|
|
64
|
+
module.exports.providerPath = providerPath;
|
|
65
|
+
module.exports.loadTemplate = loadTemplate;
|