@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,113 @@
|
|
|
1
|
+
const powertools = require('node-powertools');
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Test plan-switch provider
|
|
5
|
+
* Simulates the Stripe webhook that results from a plan change by writing
|
|
6
|
+
* directly to payments-webhooks/{eventId} with status=pending. The on-write
|
|
7
|
+
* trigger picks it up and runs the full pipeline.
|
|
8
|
+
*
|
|
9
|
+
* The event is customer.subscription.updated carrying the NEW product and the NEW
|
|
10
|
+
* billing interval, so the existing plan-changed transition fires naturally — the
|
|
11
|
+
* route needs no pipeline work of its own.
|
|
12
|
+
*
|
|
13
|
+
* It also carries the EXISTING trial forward, exactly as Stripe keeps trial_start
|
|
14
|
+
* and trial_end on a subscription whose item was swapped. Fabricating them as null
|
|
15
|
+
* is what ended a live trial on switch ([#237]) — the unified transform reads
|
|
16
|
+
* `trial.claimed` straight off the event, and the user-doc write is a merge.
|
|
17
|
+
*
|
|
18
|
+
* Only available in non-production environments.
|
|
19
|
+
*/
|
|
20
|
+
module.exports = {
|
|
21
|
+
async switchPlan({ resourceId, uid, subscription, product, frequency, ctx }) {
|
|
22
|
+
if (ctx.isProduction()) {
|
|
23
|
+
throw new Error('Test provider is not available in production');
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const admin = ctx.Manager.libraries.admin;
|
|
27
|
+
|
|
28
|
+
const timestamp = Date.now();
|
|
29
|
+
const now = Math.floor(timestamp / 1000);
|
|
30
|
+
const periodEnd = now + (30 * 86400);
|
|
31
|
+
|
|
32
|
+
// The TARGET product's Stripe ID — this is what makes the pipeline resolve the
|
|
33
|
+
// new plan. Falls back to the "_test_<id>" sentinel when no real Stripe
|
|
34
|
+
// product is configured.
|
|
35
|
+
const stripeProductId = product.stripe?.productId || `_test_${product.id}`;
|
|
36
|
+
|
|
37
|
+
const FREQUENCY_TO_INTERVAL = { annually: 'year', monthly: 'month', weekly: 'week', daily: 'day' };
|
|
38
|
+
const interval = FREQUENCY_TO_INTERVAL[frequency] || 'month';
|
|
39
|
+
|
|
40
|
+
const eventType = 'customer.subscription.updated';
|
|
41
|
+
const eventId = `_test-evt-plan-${timestamp}`;
|
|
42
|
+
|
|
43
|
+
const startDate = subscription?.payment?.startDate?.timestampUNIX || (now - (30 * 86400));
|
|
44
|
+
|
|
45
|
+
// The trial rides along untouched: a claimed trial keeps its ORIGINAL end
|
|
46
|
+
// date on the new plan, and the subscription is still `trialing` while that
|
|
47
|
+
// date is ahead of us — the same two facts Stripe reports after an item swap.
|
|
48
|
+
const trialEnd = subscription?.trial?.claimed ? (subscription.trial.expires?.timestampUNIX || null) : null;
|
|
49
|
+
const trialStart = trialEnd ? startDate : null;
|
|
50
|
+
const trialing = !!trialEnd && trialEnd > now;
|
|
51
|
+
|
|
52
|
+
const subscriptionObj = {
|
|
53
|
+
id: resourceId,
|
|
54
|
+
object: 'subscription',
|
|
55
|
+
status: trialing ? 'trialing' : 'active',
|
|
56
|
+
metadata: { uid, orderId: subscription?.payment?.orderId || null },
|
|
57
|
+
cancel_at_period_end: false,
|
|
58
|
+
cancel_at: null,
|
|
59
|
+
canceled_at: null,
|
|
60
|
+
// While a subscription is trialing, Stripe's current period IS the trial
|
|
61
|
+
// period — and the cancel providers read that equality (`trial.expires`
|
|
62
|
+
// === `expires`) to decide a cancellation is immediate. Fabricating a
|
|
63
|
+
// 30-day period under a live trial would break cancel-immediacy after a
|
|
64
|
+
// switch and misreport the next billing date.
|
|
65
|
+
current_period_end: trialing ? trialEnd : periodEnd,
|
|
66
|
+
current_period_start: trialing ? trialStart : now,
|
|
67
|
+
start_date: startDate,
|
|
68
|
+
trial_start: trialStart,
|
|
69
|
+
trial_end: trialEnd,
|
|
70
|
+
plan: { product: stripeProductId, interval: interval },
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
const nowTs = powertools.timestamp(new Date(), { output: 'string' });
|
|
74
|
+
const nowUNIX = powertools.timestamp(nowTs, { output: 'unix' });
|
|
75
|
+
|
|
76
|
+
// Write directly to payments-webhooks — on-write trigger handles the rest
|
|
77
|
+
await admin.firestore().doc(`payments-webhooks/${eventId}`).set({
|
|
78
|
+
id: eventId,
|
|
79
|
+
provider: 'test',
|
|
80
|
+
status: 'pending',
|
|
81
|
+
owner: uid,
|
|
82
|
+
raw: {
|
|
83
|
+
id: eventId,
|
|
84
|
+
type: eventType,
|
|
85
|
+
data: { object: subscriptionObj },
|
|
86
|
+
},
|
|
87
|
+
event: {
|
|
88
|
+
type: eventType,
|
|
89
|
+
category: 'subscription',
|
|
90
|
+
resourceType: 'subscription',
|
|
91
|
+
resourceId: resourceId,
|
|
92
|
+
},
|
|
93
|
+
error: null,
|
|
94
|
+
// The SAME keys the webhook route writes ([../../webhook/post.js]) — the
|
|
95
|
+
// pipeline's staleness clock reads `metadata.created.timestampUNIX`, so a
|
|
96
|
+
// synthetic doc spelling it `received` handed the clock nothing and rode a
|
|
97
|
+
// now-fallback that made every test-processor event look freshly arrived
|
|
98
|
+
// ([#212](https://github.com/Omega-JS-Stack/omega/issues/212)).
|
|
99
|
+
metadata: {
|
|
100
|
+
created: {
|
|
101
|
+
timestamp: nowTs,
|
|
102
|
+
timestampUNIX: nowUNIX,
|
|
103
|
+
},
|
|
104
|
+
completed: {
|
|
105
|
+
timestamp: null,
|
|
106
|
+
timestampUNIX: null,
|
|
107
|
+
},
|
|
108
|
+
},
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
ctx.log(`Test plan provider: wrote payments-webhooks/${eventId} (${eventType}) for sub=${resourceId}, uid=${uid}, product=${product.id}, frequency=${frequency}, trialEnd=${trialEnd}`);
|
|
112
|
+
},
|
|
113
|
+
};
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
const path = require('path');
|
|
2
|
+
const loadProvider = require('../../../libraries/load-provider.js');
|
|
3
|
+
|
|
4
|
+
// Where a portal session returns to when the caller names no URL of its own, or
|
|
5
|
+
// names one that is not the brand's — the account page's billing section, the
|
|
6
|
+
// same destination the transactional emails link to.
|
|
7
|
+
const DEFAULT_RETURN_PATH = '/dashboard/account#billing';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* POST /payments/portal
|
|
11
|
+
* Creates a Stripe Billing Portal session for the authenticated user.
|
|
12
|
+
* The portal allows managing payment methods and viewing invoices,
|
|
13
|
+
* but does NOT allow cancellation (users must use POST /payments/cancel).
|
|
14
|
+
* Requires authentication.
|
|
15
|
+
*/
|
|
16
|
+
module.exports = async ({ ctx, Manager, user, settings }) => {
|
|
17
|
+
// Require authentication
|
|
18
|
+
if (!user.authenticated) {
|
|
19
|
+
return ctx.respond('Authentication required', { code: 401 });
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const uid = user.auth.uid;
|
|
23
|
+
const returnUrl = resolveReturnUrl(Manager, ctx, settings.returnUrl, uid);
|
|
24
|
+
const subscription = user.subscription;
|
|
25
|
+
|
|
26
|
+
// Require a paid subscription (any status — suspended users can still manage billing)
|
|
27
|
+
if (!subscription || subscription.product?.id === 'basic') {
|
|
28
|
+
ctx.log(`Portal rejected: uid=${uid}, product=${subscription?.product?.id}`);
|
|
29
|
+
return ctx.respond('No paid subscription found', { code: 400 });
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const provider = subscription.payment?.provider;
|
|
33
|
+
|
|
34
|
+
if (!provider) {
|
|
35
|
+
ctx.log(`Portal rejected: uid=${uid}, no provider set`);
|
|
36
|
+
return ctx.respond('Subscription payment provider not found', { code: 400 });
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// Load the provider module
|
|
40
|
+
let providerModule;
|
|
41
|
+
try {
|
|
42
|
+
providerModule = loadProvider(path.join(__dirname, 'providers'), provider);
|
|
43
|
+
} catch (e) {
|
|
44
|
+
return ctx.respond(`Unknown provider: ${provider}`, { code: 400 });
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// Create the portal session via the provider
|
|
48
|
+
const email = user.auth?.email || null;
|
|
49
|
+
let result;
|
|
50
|
+
try {
|
|
51
|
+
result = await providerModule.createPortalSession({ uid, email, returnUrl, ctx });
|
|
52
|
+
} catch (e) {
|
|
53
|
+
// The provider's own words stay in the logs — a client gets one neutral
|
|
54
|
+
// sentence, never an SDK message naming our internals ([#212]).
|
|
55
|
+
ctx.error(`Failed to create ${provider} portal session: uid=${uid}, error=${e.message}`);
|
|
56
|
+
return ctx.respond('We could not open your billing portal right now. Please try again shortly.', { code: 500 });
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
ctx.log(`Portal session created: uid=${uid}, provider=${provider}`);
|
|
60
|
+
|
|
61
|
+
return ctx.respond({ url: result.url });
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Resolve the URL the provider sends the user back to.
|
|
66
|
+
*
|
|
67
|
+
* `returnUrl` is client-settable and lands in the provider's hosted page, so an
|
|
68
|
+
* arbitrary host would make the brand's own billing portal a redirector to
|
|
69
|
+
* anywhere. Only the brand's OWN origins pass — the resolved website URL (which
|
|
70
|
+
* is localhost during a dev/test run) and the configured brand URL. Anything
|
|
71
|
+
* else, and anything unparseable, falls back to the brand's account page with a
|
|
72
|
+
* warning ([#212]).
|
|
73
|
+
*
|
|
74
|
+
* @param {object} Manager - The @omega.js/backend Manager
|
|
75
|
+
* @param {object} ctx - Assistant instance for logging
|
|
76
|
+
* @param {string|null} returnUrl - The caller's requested return URL
|
|
77
|
+
* @param {string} uid - User's UID (for logging)
|
|
78
|
+
* @returns {string} A URL on one of the brand's own origins
|
|
79
|
+
*/
|
|
80
|
+
function resolveReturnUrl(Manager, ctx, returnUrl, uid) {
|
|
81
|
+
const websiteUrl = Manager.project.websiteUrl;
|
|
82
|
+
const fallback = new URL(DEFAULT_RETURN_PATH, websiteUrl).toString();
|
|
83
|
+
|
|
84
|
+
if (!returnUrl) {
|
|
85
|
+
return fallback;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
const allowedOrigins = [websiteUrl, Manager.config.brand?.url]
|
|
89
|
+
.filter(Boolean)
|
|
90
|
+
.map((url) => safeOrigin(url))
|
|
91
|
+
.filter(Boolean);
|
|
92
|
+
|
|
93
|
+
const requestedOrigin = safeOrigin(returnUrl);
|
|
94
|
+
|
|
95
|
+
if (requestedOrigin && allowedOrigins.includes(requestedOrigin)) {
|
|
96
|
+
return returnUrl;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
ctx.warn(`Ignoring off-brand portal returnUrl "${returnUrl}" from uid=${uid} (allowed: ${allowedOrigins.join(', ') || 'none'}) — returning to ${fallback}`);
|
|
100
|
+
|
|
101
|
+
return fallback;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* The origin of a URL, or null when it does not parse as one.
|
|
106
|
+
*/
|
|
107
|
+
function safeOrigin(url) {
|
|
108
|
+
try {
|
|
109
|
+
return new URL(url).origin;
|
|
110
|
+
} catch (e) {
|
|
111
|
+
return null;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Chargebee portal provider
|
|
3
|
+
* Creates a Chargebee Self-Serve Portal session for the customer.
|
|
4
|
+
*
|
|
5
|
+
* The portal session provides an access_url that expires after 1 hour.
|
|
6
|
+
* Once accessed, the session remains valid until the user logs out.
|
|
7
|
+
*/
|
|
8
|
+
module.exports = {
|
|
9
|
+
/**
|
|
10
|
+
* Create a Chargebee Portal session
|
|
11
|
+
*
|
|
12
|
+
* @param {object} options
|
|
13
|
+
* @param {string} options.uid - User's UID
|
|
14
|
+
* @param {string} options.email - User's email
|
|
15
|
+
* @param {string|null} options.returnUrl - URL to redirect after logout
|
|
16
|
+
* @param {object} options.ctx - Assistant instance for logging
|
|
17
|
+
* @returns {object} { url }
|
|
18
|
+
*/
|
|
19
|
+
async createPortalSession({ uid, email, returnUrl, ctx }) {
|
|
20
|
+
const ChargebeeLib = require('../../../../libraries/payment/providers/chargebee.js');
|
|
21
|
+
ChargebeeLib.init();
|
|
22
|
+
|
|
23
|
+
// Chargebee portal sessions require a customer ID.
|
|
24
|
+
// The customer_id in Chargebee is set during subscription checkout.
|
|
25
|
+
// We look up the subscription to find the Chargebee customer_id.
|
|
26
|
+
const admin = ctx.Manager.libraries.admin;
|
|
27
|
+
const userDoc = await admin.firestore().doc(`users/${uid}`).get();
|
|
28
|
+
const subscription = userDoc.data()?.subscription;
|
|
29
|
+
|
|
30
|
+
if (!subscription?.payment?.resourceId) {
|
|
31
|
+
throw new Error('No active subscription found for portal access');
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// Fetch the subscription to get the customer_id
|
|
35
|
+
const subResult = await ChargebeeLib.request(`/subscriptions/${subscription.payment.resourceId}`);
|
|
36
|
+
const customerId = subResult.subscription?.customer_id;
|
|
37
|
+
|
|
38
|
+
if (!customerId) {
|
|
39
|
+
throw new Error('Could not resolve Chargebee customer ID');
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Create portal session
|
|
43
|
+
const params = {
|
|
44
|
+
customer: { id: customerId },
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
if (returnUrl) {
|
|
48
|
+
params.redirect_url = returnUrl;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const result = await ChargebeeLib.request('/portal_sessions', {
|
|
52
|
+
method: 'POST',
|
|
53
|
+
body: params,
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
const portalSession = result.portal_session;
|
|
57
|
+
|
|
58
|
+
ctx.log(`Chargebee portal session created: uid=${uid}, customerId=${customerId}, url=${portalSession.access_url}`);
|
|
59
|
+
|
|
60
|
+
return { url: portalSession.access_url };
|
|
61
|
+
},
|
|
62
|
+
};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PayPal portal provider
|
|
3
|
+
* PayPal does not have a hosted billing portal like Stripe.
|
|
4
|
+
* Returns a link to PayPal's subscription management page.
|
|
5
|
+
*/
|
|
6
|
+
module.exports = {
|
|
7
|
+
/**
|
|
8
|
+
* Get the PayPal subscription management URL
|
|
9
|
+
*
|
|
10
|
+
* @param {object} options
|
|
11
|
+
* @param {string} options.uid - User's UID
|
|
12
|
+
* @param {string} options.email - User's email (not used for PayPal)
|
|
13
|
+
* @param {string|null} options.returnUrl - Not used for PayPal
|
|
14
|
+
* @param {object} options.ctx - Assistant instance for logging
|
|
15
|
+
* @returns {object} { url }
|
|
16
|
+
*/
|
|
17
|
+
async createPortalSession({ uid, email, returnUrl, ctx }) {
|
|
18
|
+
// PayPal subscribers manage their subscription directly at PayPal
|
|
19
|
+
const url = 'https://www.paypal.com/myaccount/autopay/';
|
|
20
|
+
|
|
21
|
+
ctx.log(`PayPal portal redirect: uid=${uid}, url=${url}`);
|
|
22
|
+
|
|
23
|
+
return { url };
|
|
24
|
+
},
|
|
25
|
+
};
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stripe portal provider
|
|
3
|
+
* Creates a Stripe Billing Portal session with cancellation disabled.
|
|
4
|
+
* The portal config is lazily created and cached per cold start.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
// Cached portal configuration ID (no cancellation allowed)
|
|
8
|
+
let portalConfigId = null;
|
|
9
|
+
|
|
10
|
+
module.exports = {
|
|
11
|
+
/**
|
|
12
|
+
* Create a Stripe Billing Portal session
|
|
13
|
+
*
|
|
14
|
+
* @param {object} options
|
|
15
|
+
* @param {string} options.uid - User's UID
|
|
16
|
+
* @param {string} options.email - User's email (for customer resolution)
|
|
17
|
+
* @param {string|null} options.returnUrl - URL to return to after portal session
|
|
18
|
+
* @param {object} options.ctx - Assistant instance for logging
|
|
19
|
+
* @returns {object} { url }
|
|
20
|
+
*/
|
|
21
|
+
async createPortalSession({ uid, email, returnUrl, ctx }) {
|
|
22
|
+
const StripeLib = require('../../../../libraries/payment/providers/stripe.js');
|
|
23
|
+
const stripe = StripeLib.init();
|
|
24
|
+
|
|
25
|
+
// Resolve the Stripe customer for this user
|
|
26
|
+
const customer = await StripeLib.resolveCustomer(uid, email, ctx);
|
|
27
|
+
|
|
28
|
+
// Lazily create and cache a portal configuration with cancellation disabled
|
|
29
|
+
if (!portalConfigId) {
|
|
30
|
+
const config = await stripe.billingPortal.configurations.create({
|
|
31
|
+
business_profile: {
|
|
32
|
+
headline: 'Manage your subscription',
|
|
33
|
+
},
|
|
34
|
+
features: {
|
|
35
|
+
subscription_cancel: { enabled: false },
|
|
36
|
+
subscription_update: { enabled: false },
|
|
37
|
+
payment_method_update: { enabled: true },
|
|
38
|
+
invoice_history: { enabled: true },
|
|
39
|
+
},
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
portalConfigId = config.id;
|
|
43
|
+
ctx.log(`Created Stripe portal config: ${portalConfigId}`);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// Build session params
|
|
47
|
+
const sessionParams = {
|
|
48
|
+
customer: customer.id,
|
|
49
|
+
configuration: portalConfigId,
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
if (returnUrl) {
|
|
53
|
+
sessionParams.return_url = returnUrl;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const session = await stripe.billingPortal.sessions.create(sessionParams);
|
|
57
|
+
|
|
58
|
+
ctx.log(`Stripe portal session created: uid=${uid}, customerId=${customer.id}, url=${session.url}`);
|
|
59
|
+
|
|
60
|
+
return { url: session.url };
|
|
61
|
+
},
|
|
62
|
+
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Test portal provider
|
|
3
|
+
* Returns a fake portal URL — no external API calls.
|
|
4
|
+
* Only available in non-production environments.
|
|
5
|
+
*/
|
|
6
|
+
module.exports = {
|
|
7
|
+
async createPortalSession({ uid, returnUrl, ctx }) {
|
|
8
|
+
if (ctx.isProduction()) {
|
|
9
|
+
throw new Error('Test provider is not available in production');
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const url = returnUrl || 'https://example.com/account';
|
|
13
|
+
|
|
14
|
+
ctx.log(`Test portal session: uid=${uid}, url=${url}`);
|
|
15
|
+
|
|
16
|
+
return { url };
|
|
17
|
+
},
|
|
18
|
+
};
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
const path = require('path');
|
|
2
|
+
const loadProvider = require('../../../libraries/load-provider.js');
|
|
3
|
+
const powertools = require('node-powertools');
|
|
4
|
+
const { OUTSIDE_WINDOW_MESSAGE, isWithinRefundWindow, oneTimeRefundRefusal } = require('../../../libraries/payment/refund-policy.js');
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* POST /payments/refund
|
|
8
|
+
* Refunds a purchase. Two subjects, one endpoint:
|
|
9
|
+
*
|
|
10
|
+
* - No `orderId` — the authenticated user's SUBSCRIPTION. Refunds the latest
|
|
11
|
+
* payment and cancels immediately; requires the subscription to be cancelled or
|
|
12
|
+
* pending cancellation first.
|
|
13
|
+
* - With `orderId` — a ONE-TIME purchase, named by its payments-orders doc. A
|
|
14
|
+
* one-time purchase never touches the user doc, so the order IS the subject
|
|
15
|
+
* ([#212](https://github.com/Omega-JS-Stack/omega/issues/212)).
|
|
16
|
+
*
|
|
17
|
+
* Delegates to the provider (e.g., Stripe) to issue the refund. The resulting
|
|
18
|
+
* webhook triggers the Firestore pipeline, which fires the matching transition
|
|
19
|
+
* handler (subscription-cancelled / purchase-refunded).
|
|
20
|
+
* Stores the refund reason/feedback on payments-orders/{orderId}.requests.refund.
|
|
21
|
+
* Requires authentication.
|
|
22
|
+
*/
|
|
23
|
+
module.exports = async ({ ctx, user, settings }) => {
|
|
24
|
+
// Require authentication
|
|
25
|
+
if (!user.authenticated) {
|
|
26
|
+
return ctx.respond('Authentication required', { code: 401 });
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const uid = user.auth.uid;
|
|
30
|
+
const confirmed = settings.confirmed;
|
|
31
|
+
|
|
32
|
+
// Require explicit confirmation
|
|
33
|
+
if (!confirmed) {
|
|
34
|
+
return ctx.respond('Refund must be confirmed', { code: 400 });
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// A named order is a one-time purchase — its own subject, its own guards
|
|
38
|
+
if (settings.orderId) {
|
|
39
|
+
return refundOneTimePurchase({ ctx, uid, settings });
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const subscription = user.subscription;
|
|
43
|
+
|
|
44
|
+
// Require a paid subscription
|
|
45
|
+
if (!subscription || subscription.product?.id === 'basic') {
|
|
46
|
+
ctx.log(`Refund rejected: uid=${uid}, no paid subscription`);
|
|
47
|
+
return ctx.respond('No paid subscription found', { code: 400 });
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// Require cancelled or pending cancellation — cannot refund an active subscription
|
|
51
|
+
const isCancelled = subscription.status === 'cancelled';
|
|
52
|
+
const isPendingCancel = subscription.cancellation?.pending === true;
|
|
53
|
+
|
|
54
|
+
if (!isCancelled && !isPendingCancel) {
|
|
55
|
+
ctx.log(`Refund rejected: uid=${uid}, status=${subscription.status}, pending=${subscription.cancellation?.pending}`);
|
|
56
|
+
return ctx.respond('Subscription must be cancelled or pending cancellation before requesting a refund', { code: 400 });
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Reject if the most recent payment is older than 6 months
|
|
60
|
+
const startDateUNIX = subscription.payment?.startDate?.timestampUNIX
|
|
61
|
+
|| subscription.payment?.updatedBy?.date?.timestampUNIX;
|
|
62
|
+
|
|
63
|
+
if (!isWithinRefundWindow(startDateUNIX)) {
|
|
64
|
+
ctx.log(`Refund rejected: uid=${uid}, payment too old (startDate=${new Date(startDateUNIX * 1000).toISOString()})`);
|
|
65
|
+
return ctx.respond(OUTSIDE_WINDOW_MESSAGE, { code: 400 });
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const provider = subscription.payment?.provider;
|
|
69
|
+
const resourceId = subscription.payment?.resourceId;
|
|
70
|
+
|
|
71
|
+
if (!provider || !resourceId) {
|
|
72
|
+
ctx.log(`Refund rejected: uid=${uid}, missing provider=${provider} or resourceId=${resourceId}`);
|
|
73
|
+
return ctx.respond('Subscription payment details not found', { code: 400 });
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// Load the provider module
|
|
77
|
+
let providerModule;
|
|
78
|
+
try {
|
|
79
|
+
providerModule = loadProvider(path.join(__dirname, 'providers'), provider);
|
|
80
|
+
} catch (e) {
|
|
81
|
+
return ctx.respond(`Unknown provider: ${provider}`, { code: 400 });
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// Process the refund via the provider
|
|
85
|
+
let refund;
|
|
86
|
+
try {
|
|
87
|
+
refund = await providerModule.processRefund({ resourceId, uid, subscription, ctx });
|
|
88
|
+
} catch (e) {
|
|
89
|
+
// The provider's own words stay in the logs — a client gets one neutral
|
|
90
|
+
// sentence, never an SDK message naming our internals ([#212]).
|
|
91
|
+
ctx.error(`Failed to process refund via ${provider}: uid=${uid}, sub=${resourceId}, error=${e.message}`);
|
|
92
|
+
return ctx.respond('We could not process your refund right now. Please try again shortly.', { code: 500 });
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// Store refund reason/feedback on the order doc
|
|
96
|
+
const orderId = subscription.payment?.orderId;
|
|
97
|
+
|
|
98
|
+
if (orderId) {
|
|
99
|
+
await storeRefundRequest({ ctx, orderId, refund, settings });
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
ctx.log(`Refund processed: uid=${uid}, provider=${provider}, sub=${resourceId}, amount=${refund.amount}, full=${refund.full}, reason=${settings.reason}`);
|
|
103
|
+
|
|
104
|
+
return ctx.respond({ success: true, refund });
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Refund a ONE-TIME purchase, named by its payments-orders doc.
|
|
109
|
+
*
|
|
110
|
+
* The subject is the order, not the user doc: a one-time purchase writes nothing
|
|
111
|
+
* to users/{uid}.subscription, so there is no subscription state to check and
|
|
112
|
+
* nothing to cancel — the purchase is either refundable or it is not.
|
|
113
|
+
*
|
|
114
|
+
* @param {object} options
|
|
115
|
+
* @param {object} options.ctx - RouteContext
|
|
116
|
+
* @param {string} options.uid - The caller's UID
|
|
117
|
+
* @param {object} options.settings - Resolved request settings
|
|
118
|
+
*/
|
|
119
|
+
async function refundOneTimePurchase({ ctx, uid, settings }) {
|
|
120
|
+
const admin = ctx.Manager.libraries.admin;
|
|
121
|
+
const orderId = settings.orderId;
|
|
122
|
+
|
|
123
|
+
const orderSnap = await admin.firestore().doc(`payments-orders/${orderId}`).get();
|
|
124
|
+
const order = orderSnap.exists ? orderSnap.data() : null;
|
|
125
|
+
|
|
126
|
+
// Missing and not-yours answer identically: an order id must never be a probe
|
|
127
|
+
// for whether somebody else's purchase exists
|
|
128
|
+
if (!order || order.owner !== uid) {
|
|
129
|
+
ctx.log(`Refund rejected: uid=${uid}, orderId=${orderId}, exists=${orderSnap.exists}, owner=${order?.owner || 'null'}`);
|
|
130
|
+
return ctx.respond('Order not found', { code: 400 });
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// Type, already-refunded, age and payment details, in the ONE place that
|
|
134
|
+
// decides them: the account page's orders list offers its refund button off
|
|
135
|
+
// the same predicate, so a button it offers is a refund this route accepts
|
|
136
|
+
// ([#672](https://github.com/Omega-JS-Stack/omega/issues/672)).
|
|
137
|
+
const refusal = oneTimeRefundRefusal(order);
|
|
138
|
+
|
|
139
|
+
if (refusal) {
|
|
140
|
+
ctx.log(`Refund rejected: uid=${uid}, orderId=${orderId}, ${refusal.reason} (type=${order.type}, status=${order.unified?.status}, request=${!!order.requests?.refund})`);
|
|
141
|
+
return ctx.respond(refusal.message, { code: 400 });
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
const provider = order.provider || order.unified?.payment?.provider;
|
|
145
|
+
const resourceId = order.resourceId || order.unified?.payment?.resourceId;
|
|
146
|
+
|
|
147
|
+
// Load the provider module
|
|
148
|
+
let providerModule;
|
|
149
|
+
try {
|
|
150
|
+
providerModule = loadProvider(path.join(__dirname, 'providers'), provider);
|
|
151
|
+
} catch (e) {
|
|
152
|
+
return ctx.respond(`Unknown provider: ${provider}`, { code: 400 });
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// Process the refund via the provider
|
|
156
|
+
let refund;
|
|
157
|
+
try {
|
|
158
|
+
refund = await providerModule.processOneTimeRefund({ resourceId, uid, order, ctx });
|
|
159
|
+
} catch (e) {
|
|
160
|
+
// The provider's own words stay in the logs — a client gets one neutral
|
|
161
|
+
// sentence, never an SDK message naming our internals ([#212]).
|
|
162
|
+
ctx.error(`Failed to process one-time refund via ${provider}: uid=${uid}, orderId=${orderId}, resource=${resourceId}, error=${e.message}`);
|
|
163
|
+
return ctx.respond('We could not process your refund right now. Please try again shortly.', { code: 500 });
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
await storeRefundRequest({ ctx, orderId, refund, settings });
|
|
167
|
+
|
|
168
|
+
ctx.log(`One-time refund processed: uid=${uid}, provider=${provider}, orderId=${orderId}, resource=${resourceId}, amount=${refund.amount}, reason=${settings.reason}`);
|
|
169
|
+
|
|
170
|
+
return ctx.respond({ success: true, refund });
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* Store the refund reason/feedback on the order doc.
|
|
175
|
+
*
|
|
176
|
+
* ONE shape for both subjects — the refund record on an order must not differ
|
|
177
|
+
* depending on which branch wrote it.
|
|
178
|
+
*
|
|
179
|
+
* @param {object} options
|
|
180
|
+
* @param {object} options.ctx - RouteContext
|
|
181
|
+
* @param {string} options.orderId - The payments-orders id
|
|
182
|
+
* @param {object} options.refund - What the provider returned ({ amount, currency, full })
|
|
183
|
+
* @param {object} options.settings - Resolved request settings (reason, feedback)
|
|
184
|
+
*/
|
|
185
|
+
async function storeRefundRequest({ ctx, orderId, refund, settings }) {
|
|
186
|
+
const admin = ctx.Manager.libraries.admin;
|
|
187
|
+
const now = powertools.timestamp(new Date(), { output: 'string' });
|
|
188
|
+
const nowUNIX = powertools.timestamp(now, { output: 'unix' });
|
|
189
|
+
|
|
190
|
+
await admin.firestore().doc(`payments-orders/${orderId}`).set({
|
|
191
|
+
requests: {
|
|
192
|
+
refund: {
|
|
193
|
+
reason: settings.reason || null,
|
|
194
|
+
feedback: settings.feedback || null,
|
|
195
|
+
amount: refund.amount,
|
|
196
|
+
full: refund.full,
|
|
197
|
+
date: {
|
|
198
|
+
timestamp: now,
|
|
199
|
+
timestampUNIX: nowUNIX,
|
|
200
|
+
},
|
|
201
|
+
},
|
|
202
|
+
},
|
|
203
|
+
}, { merge: true });
|
|
204
|
+
|
|
205
|
+
ctx.log(`Stored refund request on payments-orders/${orderId}: reason=${settings.reason}, amount=${refund.amount}`);
|
|
206
|
+
}
|
|
207
|
+
|