@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,201 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Test: Coinbase Commerce toUnifiedOneTime()
|
|
3
|
+
* Unit tests for the Coinbase library's charge → unified one-time transformation
|
|
4
|
+
* ([#642](https://github.com/Omega-JS-Stack/omega/issues/642)).
|
|
5
|
+
*
|
|
6
|
+
* Tests the pure function directly — no emulator, no Firestore, no HTTP.
|
|
7
|
+
* Mirrors paypal/to-unified-one-time.js for consistent coverage.
|
|
8
|
+
*
|
|
9
|
+
* A Coinbase charge has no status FIELD: its timeline is the record, appended to
|
|
10
|
+
* as the payment is detected, confirmed or expires, so the status is the last
|
|
11
|
+
* entry of that list and nothing else.
|
|
12
|
+
*
|
|
13
|
+
* Run: npx omega test backend:helpers/payment/coinbase/to-unified-one-time
|
|
14
|
+
*/
|
|
15
|
+
const Coinbase = require('../../../../dist/manager/libraries/payment/providers/coinbase.js');
|
|
16
|
+
|
|
17
|
+
const FIXTURE_CONFIRMED = require('../../../fixtures/coinbase/charge-confirmed.json');
|
|
18
|
+
const FIXTURE_PENDING = require('../../../fixtures/coinbase/charge-pending.json');
|
|
19
|
+
const FIXTURE_FAILED = require('../../../fixtures/coinbase/charge-failed.json');
|
|
20
|
+
const defineCases = require('../../../../dist/vendor/devkit/test/define-cases.js');
|
|
21
|
+
|
|
22
|
+
const MOCK_CONFIG = {
|
|
23
|
+
payment: {
|
|
24
|
+
products: [
|
|
25
|
+
{ id: 'basic', name: 'Basic', type: 'subscription', limits: { requests: 100 } },
|
|
26
|
+
{ id: 'launch-kit', name: 'Starter Library', type: 'one-time', prices: { once: 49.99 } },
|
|
27
|
+
],
|
|
28
|
+
},
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
const CHARGE_CONFIRMED = FIXTURE_CONFIRMED.event.data;
|
|
32
|
+
const CHARGE_PENDING = FIXTURE_PENDING.event.data;
|
|
33
|
+
const CHARGE_FAILED = FIXTURE_FAILED.event.data;
|
|
34
|
+
|
|
35
|
+
function toUnifiedOneTime(charge, options) {
|
|
36
|
+
return Coinbase.toUnifiedOneTime(charge, { config: MOCK_CONFIG, ...options });
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/** A charge whose timeline ends on `status` */
|
|
40
|
+
function chargeEndingOn(status) {
|
|
41
|
+
return { id: 'ch_status_probe', timeline: [{ status: 'NEW' }, { status: status }] };
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
module.exports = defineCases({
|
|
45
|
+
description: 'Coinbase Commerce toUnifiedOneTime() transformation',
|
|
46
|
+
type: 'group',
|
|
47
|
+
|
|
48
|
+
tests: [
|
|
49
|
+
// ─── Status mapping (the timeline's LAST entry) ───
|
|
50
|
+
|
|
51
|
+
{
|
|
52
|
+
name: 'status-completed',
|
|
53
|
+
async run({ assert }) {
|
|
54
|
+
assert.equal(toUnifiedOneTime(CHARGE_CONFIRMED).status, 'completed', 'COMPLETED → completed');
|
|
55
|
+
},
|
|
56
|
+
},
|
|
57
|
+
|
|
58
|
+
{
|
|
59
|
+
name: 'status-pending',
|
|
60
|
+
async run({ assert }) {
|
|
61
|
+
assert.equal(toUnifiedOneTime(CHARGE_PENDING).status, 'pending', 'PENDING → pending — money detected, not settled');
|
|
62
|
+
},
|
|
63
|
+
},
|
|
64
|
+
|
|
65
|
+
{
|
|
66
|
+
name: 'status-expired-is-failed',
|
|
67
|
+
async run({ assert }) {
|
|
68
|
+
assert.equal(toUnifiedOneTime(CHARGE_FAILED).status, 'failed', 'EXPIRED → failed');
|
|
69
|
+
},
|
|
70
|
+
},
|
|
71
|
+
|
|
72
|
+
{
|
|
73
|
+
name: 'status-resolved-is-completed',
|
|
74
|
+
async run({ assert }) {
|
|
75
|
+
// An under/overpaid charge the merchant RESOLVED is money accepted — it
|
|
76
|
+
// books the way a clean COMPLETED does
|
|
77
|
+
assert.equal(toUnifiedOneTime(chargeEndingOn('RESOLVED')).status, 'completed');
|
|
78
|
+
},
|
|
79
|
+
},
|
|
80
|
+
|
|
81
|
+
{
|
|
82
|
+
name: 'status-canceled-is-failed',
|
|
83
|
+
async run({ assert }) {
|
|
84
|
+
assert.equal(toUnifiedOneTime(chargeEndingOn('CANCELED')).status, 'failed');
|
|
85
|
+
},
|
|
86
|
+
},
|
|
87
|
+
|
|
88
|
+
{
|
|
89
|
+
name: 'status-new-is-pending',
|
|
90
|
+
async run({ assert }) {
|
|
91
|
+
assert.equal(toUnifiedOneTime(chargeEndingOn('NEW')).status, 'pending', 'A charge nobody has paid yet is pending, never failed');
|
|
92
|
+
},
|
|
93
|
+
},
|
|
94
|
+
|
|
95
|
+
{
|
|
96
|
+
name: 'an-unmapped-status-passes-through-lowercased',
|
|
97
|
+
async run({ assert }) {
|
|
98
|
+
// Inventing `failed` for a word we do not know would revoke a purchase
|
|
99
|
+
// that may be perfectly fine — the siblings pass their own words through
|
|
100
|
+
assert.equal(toUnifiedOneTime(chargeEndingOn('UNRESOLVED')).status, 'unresolved');
|
|
101
|
+
},
|
|
102
|
+
},
|
|
103
|
+
|
|
104
|
+
{
|
|
105
|
+
name: 'a-charge-with-no-timeline-is-unknown',
|
|
106
|
+
async run({ assert }) {
|
|
107
|
+
assert.equal(toUnifiedOneTime({ id: 'ch_bare' }).status, 'unknown', 'Absent data never claims an outcome');
|
|
108
|
+
},
|
|
109
|
+
},
|
|
110
|
+
|
|
111
|
+
// ─── Identifiers and product resolution ───
|
|
112
|
+
|
|
113
|
+
{
|
|
114
|
+
name: 'resolves-the-product-from-charge-metadata',
|
|
115
|
+
async run({ assert }) {
|
|
116
|
+
const result = toUnifiedOneTime(CHARGE_CONFIRMED);
|
|
117
|
+
|
|
118
|
+
assert.equal(result.product.id, 'launch-kit');
|
|
119
|
+
assert.equal(result.product.name, 'Starter Library');
|
|
120
|
+
},
|
|
121
|
+
},
|
|
122
|
+
|
|
123
|
+
{
|
|
124
|
+
name: 'prices-from-config-not-from-the-charge',
|
|
125
|
+
async run({ assert }) {
|
|
126
|
+
// The catalog is the price of record, the way every sibling reads it —
|
|
127
|
+
// a charge's local amount can carry a discount off it
|
|
128
|
+
const result = toUnifiedOneTime(CHARGE_CONFIRMED);
|
|
129
|
+
|
|
130
|
+
assert.equal(result.payment.price, 49.99);
|
|
131
|
+
},
|
|
132
|
+
},
|
|
133
|
+
|
|
134
|
+
{
|
|
135
|
+
name: 'unknown-product-degrades-without-throwing',
|
|
136
|
+
async run({ assert }) {
|
|
137
|
+
const result = toUnifiedOneTime({ id: 'ch_x', metadata: { productId: 'not-in-catalog' }, timeline: [{ status: 'COMPLETED' }] });
|
|
138
|
+
|
|
139
|
+
assert.equal(result.product.id, 'not-in-catalog');
|
|
140
|
+
assert.equal(result.payment.price, 0);
|
|
141
|
+
},
|
|
142
|
+
},
|
|
143
|
+
|
|
144
|
+
{
|
|
145
|
+
name: 'carries-the-order-and-the-resource',
|
|
146
|
+
async run({ assert }) {
|
|
147
|
+
const result = toUnifiedOneTime(CHARGE_CONFIRMED, { eventName: 'charge:confirmed', eventId: '_test-evt-charge-confirmed' });
|
|
148
|
+
|
|
149
|
+
assert.equal(result.payment.provider, 'coinbase');
|
|
150
|
+
assert.equal(result.payment.orderId, '_test-order-coinbase-1');
|
|
151
|
+
assert.equal(result.payment.resourceId, '8f783fa6-eaa3-4460-af64-cac26b183ed1');
|
|
152
|
+
assert.equal(result.payment.updatedBy.event.name, 'charge:confirmed');
|
|
153
|
+
assert.equal(result.payment.updatedBy.event.id, '_test-evt-charge-confirmed');
|
|
154
|
+
assert.ok(result.payment.updatedBy.date.timestampUNIX > 0, 'The write stamps when it happened');
|
|
155
|
+
},
|
|
156
|
+
},
|
|
157
|
+
|
|
158
|
+
{
|
|
159
|
+
name: 'getUid-and-getOrderId-read-the-charge-record',
|
|
160
|
+
async run({ assert }) {
|
|
161
|
+
assert.equal(Coinbase.getUid(CHARGE_CONFIRMED), '_test-coinbase-buyer');
|
|
162
|
+
assert.equal(Coinbase.getOrderId(CHARGE_CONFIRMED), '_test-order-coinbase-1');
|
|
163
|
+
|
|
164
|
+
// A charge carrying nothing answers nothing, never undefined
|
|
165
|
+
assert.equal(Coinbase.getUid({}), null);
|
|
166
|
+
assert.equal(Coinbase.getOrderId({}), null);
|
|
167
|
+
},
|
|
168
|
+
},
|
|
169
|
+
|
|
170
|
+
{
|
|
171
|
+
name: 'buildMetadata-is-the-one-shape-the-readers-expect',
|
|
172
|
+
async run({ assert }) {
|
|
173
|
+
const metadata = Coinbase.buildMetadata('u1', 'ord-1', 'launch-kit');
|
|
174
|
+
|
|
175
|
+
assert.deepEqual(metadata, { uid: 'u1', orderId: 'ord-1', productId: 'launch-kit' });
|
|
176
|
+
assert.equal(Coinbase.getUid({ metadata }), 'u1', 'What the intent writes is what the pipeline reads');
|
|
177
|
+
assert.equal(Coinbase.getOrderId({ metadata }), 'ord-1');
|
|
178
|
+
},
|
|
179
|
+
},
|
|
180
|
+
|
|
181
|
+
// ─── There is no subscription half ───
|
|
182
|
+
|
|
183
|
+
{
|
|
184
|
+
name: 'a-charge-is-never-a-subscription',
|
|
185
|
+
async run({ assert }) {
|
|
186
|
+
// Fabricating one would grant recurring access off a single crypto
|
|
187
|
+
// payment, so the bug stops here instead
|
|
188
|
+
let threw = false;
|
|
189
|
+
|
|
190
|
+
try {
|
|
191
|
+
Coinbase.toUnifiedSubscription(CHARGE_CONFIRMED, { config: MOCK_CONFIG });
|
|
192
|
+
} catch (e) {
|
|
193
|
+
threw = true;
|
|
194
|
+
assert.match(e.message, /no subscriptions/i, 'The refusal says why');
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
assert.ok(threw, 'toUnifiedSubscription() must refuse');
|
|
198
|
+
},
|
|
199
|
+
},
|
|
200
|
+
],
|
|
201
|
+
});
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Test: what validate() hands the rest of the system
|
|
3
|
+
* ([#239](https://github.com/Omega-JS-Stack/omega/issues/239)).
|
|
4
|
+
*
|
|
5
|
+
* A validate() result is not just read — `POST /payments/intent` WRITES it into
|
|
6
|
+
* `payments-intents/{orderId}` (`intent/post.js`, the `discount:` field). Firestore
|
|
7
|
+
* refuses a document containing an `undefined` value and firebase-admin throws
|
|
8
|
+
* SYNCHRONOUSLY when it validates the data, with no `ignoreUndefinedProperties`
|
|
9
|
+
* set anywhere in this framework. That throw lands AFTER the provider has already
|
|
10
|
+
* created the real checkout session, so a single undefined-valued key on the result
|
|
11
|
+
* turns every discounted checkout into a 500 with a live session stranded behind it.
|
|
12
|
+
*
|
|
13
|
+
* The rule this pins: a code carries the ONE shape it has (percent or amount) and
|
|
14
|
+
* the result never carries a key whose value is undefined — for every entry in the
|
|
15
|
+
* table, so a code added tomorrow is covered without touching this file.
|
|
16
|
+
*
|
|
17
|
+
* Run: npx omega test framework:helpers/payment/discount-codes
|
|
18
|
+
*
|
|
19
|
+
* firebase-admin's document validation is the real thing here, not a stand-in: it
|
|
20
|
+
* runs synchronously inside set(), before any I/O, so the check needs no live
|
|
21
|
+
* Firestore. The returned promise is deliberately never awaited (the write itself
|
|
22
|
+
* is not the subject) and its rejection is swallowed.
|
|
23
|
+
*/
|
|
24
|
+
const admin = require('firebase-admin');
|
|
25
|
+
const discountCodes = require('../../../dist/manager/libraries/payment/discount-codes.js');
|
|
26
|
+
const defineCases = require('../../../dist/vendor/devkit/test/define-cases.js');
|
|
27
|
+
|
|
28
|
+
const { DISCOUNT_CODES, validate } = discountCodes;
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* The runner has already initialized the admin app; outside it a demo project
|
|
32
|
+
* needs no credentials for the synchronous validation this exercises.
|
|
33
|
+
*/
|
|
34
|
+
function firestore() {
|
|
35
|
+
if (!admin.apps.length) {
|
|
36
|
+
admin.initializeApp({ projectId: 'demo-discount-codes' });
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
return admin.firestore();
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Ask firebase-admin to accept the document `POST /payments/intent` writes.
|
|
44
|
+
* Returns the synchronous error it refused with, or null.
|
|
45
|
+
*/
|
|
46
|
+
function refusedBy(discount) {
|
|
47
|
+
const ref = firestore().doc('payments-intents/_test-discount-writable');
|
|
48
|
+
|
|
49
|
+
try {
|
|
50
|
+
const write = ref.set({ discount: discount }, { merge: true });
|
|
51
|
+
|
|
52
|
+
if (write && typeof write.catch === 'function') {
|
|
53
|
+
write.catch(() => {});
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
return null;
|
|
57
|
+
} catch (e) {
|
|
58
|
+
return e;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
module.exports = defineCases({
|
|
63
|
+
description: 'Discount codes: the validate() contract',
|
|
64
|
+
type: 'group',
|
|
65
|
+
timeout: 15000,
|
|
66
|
+
|
|
67
|
+
tests: [
|
|
68
|
+
{
|
|
69
|
+
name: 'the-table-is-not-empty-so-this-suite-covers-something',
|
|
70
|
+
async run({ assert }) {
|
|
71
|
+
assert.ok(Object.keys(DISCOUNT_CODES).length > 1, 'Several codes should be seeded');
|
|
72
|
+
},
|
|
73
|
+
},
|
|
74
|
+
|
|
75
|
+
{
|
|
76
|
+
name: 'every-code-validates-into-a-firestore-writable-object',
|
|
77
|
+
async run({ assert }) {
|
|
78
|
+
for (const code of Object.keys(DISCOUNT_CODES)) {
|
|
79
|
+
const result = validate(code);
|
|
80
|
+
|
|
81
|
+
assert.equal(result.valid, true, `${code} should validate (eligibility is skipped with no user)`);
|
|
82
|
+
|
|
83
|
+
const refusal = refusedBy(result);
|
|
84
|
+
|
|
85
|
+
assert.equal(
|
|
86
|
+
refusal,
|
|
87
|
+
null,
|
|
88
|
+
`${code}: the intent route writes this object — Firestore refused it: ${refusal?.message?.split('\n')[0]}`
|
|
89
|
+
);
|
|
90
|
+
}
|
|
91
|
+
},
|
|
92
|
+
},
|
|
93
|
+
|
|
94
|
+
{
|
|
95
|
+
name: 'a-validated-code-carries-only-the-shape-it-has',
|
|
96
|
+
async run({ assert }) {
|
|
97
|
+
for (const [code, entry] of Object.entries(DISCOUNT_CODES)) {
|
|
98
|
+
const result = validate(code);
|
|
99
|
+
|
|
100
|
+
if (entry.percent !== undefined) {
|
|
101
|
+
assert.equal(result.percent, entry.percent, `${code} should report its percent`);
|
|
102
|
+
assert.equal('amount' in result, false, `${code} is percent-based — it must not carry an amount key at all`);
|
|
103
|
+
} else {
|
|
104
|
+
assert.equal(result.amount, entry.amount, `${code} should report its amount`);
|
|
105
|
+
assert.equal('percent' in result, false, `${code} is amount-based — it must not carry a percent key at all`);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
for (const [key, value] of Object.entries(result)) {
|
|
109
|
+
assert.notEqual(value, undefined, `${code}.${key} is undefined — Firestore refuses the whole document`);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
},
|
|
113
|
+
},
|
|
114
|
+
|
|
115
|
+
{
|
|
116
|
+
name: 'every-table-entry-declares-exactly-one-shape',
|
|
117
|
+
async run({ assert }) {
|
|
118
|
+
// The readers downstream branch on the shape (the providers' coupon
|
|
119
|
+
// params, the order email's promo line) — a code carrying both, or
|
|
120
|
+
// neither, has no defined meaning at any of them.
|
|
121
|
+
for (const [code, entry] of Object.entries(DISCOUNT_CODES)) {
|
|
122
|
+
const shapes = [entry.percent, entry.amount].filter((v) => v !== undefined);
|
|
123
|
+
|
|
124
|
+
assert.equal(shapes.length, 1, `${code} should declare exactly one of percent/amount, found ${shapes.length}`);
|
|
125
|
+
assert.ok(shapes[0] > 0, `${code}'s discount should be a positive number`);
|
|
126
|
+
}
|
|
127
|
+
},
|
|
128
|
+
},
|
|
129
|
+
|
|
130
|
+
{
|
|
131
|
+
name: 'a-refused-code-is-writable-too',
|
|
132
|
+
async run({ assert }) {
|
|
133
|
+
// The route only persists a VALID result today, but the invalid shape is
|
|
134
|
+
// one object away from the same write path
|
|
135
|
+
const refusal = refusedBy(validate('NOT-A-REAL-CODE'));
|
|
136
|
+
|
|
137
|
+
assert.equal(refusal, null, `An invalid result should be writable too: ${refusal?.message?.split('\n')[0]}`);
|
|
138
|
+
},
|
|
139
|
+
},
|
|
140
|
+
],
|
|
141
|
+
});
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Test: provider extractResource() — each library names its own webhook envelope
|
|
3
|
+
*
|
|
4
|
+
* The webhook trigger reads the resource out of the event it received to name what
|
|
5
|
+
* the event is ABOUT — the orderId a failed event belongs to, and the body the test
|
|
6
|
+
* provider answers its own lookups from. It used to read Stripe's envelope for every
|
|
7
|
+
* provider — `raw.data.object` — so a Chargebee event (`content.<type>`) or a PayPal
|
|
8
|
+
* event (`resource`) resolved to nothing at all ([#222]).
|
|
9
|
+
*
|
|
10
|
+
* Each library now names its own shape, and these assert the shape against the
|
|
11
|
+
* real fixtures each provider's route parser already reads.
|
|
12
|
+
*
|
|
13
|
+
* What the envelope must NEVER do is drive state: that comes from the provider's own
|
|
14
|
+
* lookup ([#506](https://github.com/Omega-JS-Stack/omega/issues/506)).
|
|
15
|
+
*/
|
|
16
|
+
const assert = require('node:assert');
|
|
17
|
+
const Stripe = require('../../../dist/manager/libraries/payment/providers/stripe.js');
|
|
18
|
+
const PayPal = require('../../../dist/manager/libraries/payment/providers/paypal.js');
|
|
19
|
+
const Chargebee = require('../../../dist/manager/libraries/payment/providers/chargebee.js');
|
|
20
|
+
const Coinbase = require('../../../dist/manager/libraries/payment/providers/coinbase.js');
|
|
21
|
+
const Test = require('../../../dist/manager/libraries/payment/providers/test.js');
|
|
22
|
+
|
|
23
|
+
const chargebeeSubscriptionCreated = require('../../fixtures/chargebee/webhook-subscription-created.json');
|
|
24
|
+
const chargebeeInvoiceOneTime = require('../../fixtures/chargebee/invoice-one-time.json');
|
|
25
|
+
const stripeCheckoutSession = require('../../fixtures/stripe/checkout-session-completed.json');
|
|
26
|
+
const coinbaseChargeConfirmed = require('../../fixtures/coinbase/charge-confirmed.json');
|
|
27
|
+
const defineCases = require('../../../dist/vendor/devkit/test/define-cases.js');
|
|
28
|
+
|
|
29
|
+
// Stripe's fixtures are bare resources — a webhook wraps one in the event envelope
|
|
30
|
+
const stripeEvent = { id: 'evt_test_session', type: 'checkout.session.completed', data: { object: stripeCheckoutSession } };
|
|
31
|
+
|
|
32
|
+
module.exports = defineCases({
|
|
33
|
+
description: 'Provider extractResource() envelope shapes',
|
|
34
|
+
type: 'group',
|
|
35
|
+
|
|
36
|
+
tests: [
|
|
37
|
+
{
|
|
38
|
+
name: 'stripe-reads-data-object',
|
|
39
|
+
async run() {
|
|
40
|
+
const resource = Stripe.extractResource(stripeEvent);
|
|
41
|
+
|
|
42
|
+
assert.equal(resource.id, stripeCheckoutSession.id, 'Stripe nests its resource at data.object');
|
|
43
|
+
},
|
|
44
|
+
},
|
|
45
|
+
|
|
46
|
+
{
|
|
47
|
+
name: 'test-provider-reads-stripes-envelope',
|
|
48
|
+
async run() {
|
|
49
|
+
// The test provider BUILDS Stripe-shaped payloads, so it reads the Stripe
|
|
50
|
+
// envelope. Without its own extractResource it fell to the empty fallback —
|
|
51
|
+
// which is the whole journey lane, since every journey runs on this provider
|
|
52
|
+
const resource = Test.extractResource(stripeEvent);
|
|
53
|
+
|
|
54
|
+
assert.equal(resource.id, stripeCheckoutSession.id, 'The test provider speaks Stripe, envelope included');
|
|
55
|
+
assert.equal(Test.extractResource({ id: 'evt_empty' }), null, 'And answers nothing the same way Stripe does');
|
|
56
|
+
},
|
|
57
|
+
},
|
|
58
|
+
|
|
59
|
+
{
|
|
60
|
+
name: 'paypal-reads-resource',
|
|
61
|
+
async run() {
|
|
62
|
+
const raw = { id: 'WH-TEST', event_type: 'BILLING.SUBSCRIPTION.ACTIVATED', resource: { id: 'I-TEST', status: 'ACTIVE' } };
|
|
63
|
+
const resource = PayPal.extractResource(raw);
|
|
64
|
+
|
|
65
|
+
assert.equal(resource.id, 'I-TEST', 'PayPal carries its resource at the top-level resource key');
|
|
66
|
+
},
|
|
67
|
+
},
|
|
68
|
+
|
|
69
|
+
{
|
|
70
|
+
name: 'coinbase-reads-the-data-inside-its-event-key',
|
|
71
|
+
async run() {
|
|
72
|
+
// Coinbase Commerce nests its charge two deep — the delivery envelope
|
|
73
|
+
// wraps an EVENT, and the charge is that event's data
|
|
74
|
+
// ([#642](https://github.com/Omega-JS-Stack/omega/issues/642))
|
|
75
|
+
const charge = Coinbase.extractResource(coinbaseChargeConfirmed);
|
|
76
|
+
|
|
77
|
+
assert.equal(charge.id, coinbaseChargeConfirmed.event.data.id, 'Coinbase carries its charge at event.data');
|
|
78
|
+
assert.equal(Coinbase.extractResource({ id: 'delivery_only' }), null, 'And answers nothing the same way its siblings do');
|
|
79
|
+
},
|
|
80
|
+
},
|
|
81
|
+
|
|
82
|
+
{
|
|
83
|
+
name: 'chargebee-reads-the-content-key-of-the-event',
|
|
84
|
+
async run() {
|
|
85
|
+
const subscription = Chargebee.extractResource(chargebeeSubscriptionCreated);
|
|
86
|
+
|
|
87
|
+
assert.equal(subscription.id, chargebeeSubscriptionCreated.content.subscription.id, 'A subscription event resolves content.subscription');
|
|
88
|
+
assert.equal(subscription.object, 'subscription', 'The resolved resource is the subscription, not the invoice beside it');
|
|
89
|
+
},
|
|
90
|
+
},
|
|
91
|
+
|
|
92
|
+
{
|
|
93
|
+
name: 'chargebee-falls-to-the-invoice-when-there-is-no-subscription',
|
|
94
|
+
async run() {
|
|
95
|
+
// The one-time lane: invoice_generated for a non-recurring invoice carries no
|
|
96
|
+
// subscription at all — the same precedence parseWebhook categorizes on
|
|
97
|
+
const raw = { id: 'ev_cb_invoice_001', event_type: 'invoice_generated', content: { invoice: chargebeeInvoiceOneTime, customer: { id: 'cb_cust_001' } } };
|
|
98
|
+
const resource = Chargebee.extractResource(raw);
|
|
99
|
+
|
|
100
|
+
assert.equal(resource.id, chargebeeInvoiceOneTime.id, 'An invoice-only event resolves content.invoice');
|
|
101
|
+
},
|
|
102
|
+
},
|
|
103
|
+
|
|
104
|
+
{
|
|
105
|
+
name: 'an-envelope-with-no-resource-extracts-nothing',
|
|
106
|
+
async run() {
|
|
107
|
+
assert.equal(Chargebee.extractResource({ id: 'ev_empty', content: {} }), null, 'Chargebee: no content key, nothing to fall back to');
|
|
108
|
+
assert.equal(Stripe.extractResource({ id: 'evt_empty' }), null, 'Stripe: no data.object, nothing to fall back to');
|
|
109
|
+
assert.equal(PayPal.extractResource({ id: 'WH-empty' }), null, 'PayPal: no resource, nothing to fall back to');
|
|
110
|
+
},
|
|
111
|
+
},
|
|
112
|
+
],
|
|
113
|
+
});
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Test: provider fetchResource() failure classification
|
|
3
|
+
*
|
|
4
|
+
* Every provider library used to swallow a failed lookup and hand back the payload
|
|
5
|
+
* the WEBHOOK carried, flagged stale — so the object whoever posted the event
|
|
6
|
+
* supplied drove real subscription state ([#506](https://github.com/Omega-JS-Stack/omega/issues/506)).
|
|
7
|
+
* No library falls back any more: a lookup that fails throws, and the throw carries
|
|
8
|
+
* the one thing the pipeline branches on — whether the provider said the resource
|
|
9
|
+
* DOES NOT EXIST (refuse and acknowledge) or simply could not be reached (defer for
|
|
10
|
+
* retry).
|
|
11
|
+
*
|
|
12
|
+
* Each provider's real fetchResource() runs here. The transport is the only thing
|
|
13
|
+
* stubbed (an HTTP client, an SDK) — reading a resource back needs live credentials;
|
|
14
|
+
* everything inward, including the classification, runs for real.
|
|
15
|
+
*
|
|
16
|
+
* Run: npx omega test backend:helpers/payment/fetch-failure
|
|
17
|
+
*/
|
|
18
|
+
const assert = require('node:assert');
|
|
19
|
+
const Stripe = require('../../../dist/manager/libraries/payment/providers/stripe.js');
|
|
20
|
+
const PayPal = require('../../../dist/manager/libraries/payment/providers/paypal.js');
|
|
21
|
+
const Chargebee = require('../../../dist/manager/libraries/payment/providers/chargebee.js');
|
|
22
|
+
const Coinbase = require('../../../dist/manager/libraries/payment/providers/coinbase.js');
|
|
23
|
+
const defineCases = require('../../../dist/vendor/devkit/test/define-cases.js');
|
|
24
|
+
|
|
25
|
+
const RESOURCE_ID = '_test-res-lookup';
|
|
26
|
+
|
|
27
|
+
/** Run fn with a library's transport replaced by a stand-in, restored afterwards */
|
|
28
|
+
async function withTransport(library, key, stub, fn) {
|
|
29
|
+
const real = library[key];
|
|
30
|
+
|
|
31
|
+
library[key] = stub;
|
|
32
|
+
|
|
33
|
+
try {
|
|
34
|
+
return await fn();
|
|
35
|
+
} finally {
|
|
36
|
+
library[key] = real;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/** The error a call is expected to throw, or a failure saying it did not throw */
|
|
41
|
+
async function throwsFrom(fn) {
|
|
42
|
+
try {
|
|
43
|
+
await fn();
|
|
44
|
+
} catch (e) {
|
|
45
|
+
return e;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
assert.fail('A failed lookup must throw — there is nothing to fall back to');
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
module.exports = defineCases({
|
|
52
|
+
description: 'Provider fetchResource() failure classification',
|
|
53
|
+
type: 'group',
|
|
54
|
+
|
|
55
|
+
tests: [
|
|
56
|
+
{
|
|
57
|
+
name: 'chargebee-classifies-a-404-as-not-found',
|
|
58
|
+
async run() {
|
|
59
|
+
// The shape libraries/payment/providers/chargebee.js throws for a 404
|
|
60
|
+
const notThere = new Error('Chargebee API 404: Sorry, we couldn\'t find that resource');
|
|
61
|
+
notThere.statusCode = 404;
|
|
62
|
+
|
|
63
|
+
const error = await throwsFrom(() => withTransport(Chargebee, 'request', async () => {
|
|
64
|
+
throw notThere;
|
|
65
|
+
}, () => Chargebee.fetchResource('subscription', RESOURCE_ID, {})));
|
|
66
|
+
|
|
67
|
+
assert.equal(error.notFound, true, 'Chargebee answering 404 means the resource is gone');
|
|
68
|
+
assert.equal(error.provider, 'chargebee', 'the failure names the provider that was asked');
|
|
69
|
+
assert.equal(error.resourceId, RESOURCE_ID, 'and the resource it was asked about');
|
|
70
|
+
assert.match(error.message, /chargebee does not have subscription/, 'the message says the provider does not have it');
|
|
71
|
+
},
|
|
72
|
+
},
|
|
73
|
+
|
|
74
|
+
{
|
|
75
|
+
name: 'chargebee-classifies-an-unreachable-api-as-transient',
|
|
76
|
+
async run() {
|
|
77
|
+
const error = await throwsFrom(() => withTransport(Chargebee, 'request', async () => {
|
|
78
|
+
throw new Error('fetch failed');
|
|
79
|
+
}, () => Chargebee.fetchResource('subscription', RESOURCE_ID, {})));
|
|
80
|
+
|
|
81
|
+
assert.equal(error.notFound, false, 'an unreachable API is not a provider saying the resource is gone');
|
|
82
|
+
assert.match(error.message, /could not be reached/, 'the message says the lookup never got an answer');
|
|
83
|
+
},
|
|
84
|
+
},
|
|
85
|
+
|
|
86
|
+
{
|
|
87
|
+
name: 'coinbase-classifies-a-404-as-not-found',
|
|
88
|
+
async run() {
|
|
89
|
+
// Coinbase Commerce carries the status on the error the way Chargebee
|
|
90
|
+
// does, so the ONE classifier answers for it with no new rule
|
|
91
|
+
// ([#642](https://github.com/Omega-JS-Stack/omega/issues/642))
|
|
92
|
+
const notThere = new Error('Coinbase Commerce API 404: Not found');
|
|
93
|
+
notThere.statusCode = 404;
|
|
94
|
+
|
|
95
|
+
const error = await throwsFrom(() => withTransport(Coinbase, 'request', async () => {
|
|
96
|
+
throw notThere;
|
|
97
|
+
}, () => Coinbase.fetchResource('charge', RESOURCE_ID, {})));
|
|
98
|
+
|
|
99
|
+
assert.equal(error.notFound, true, 'Coinbase answering 404 means the charge is gone');
|
|
100
|
+
assert.equal(error.provider, 'coinbase', 'the failure names the provider that was asked');
|
|
101
|
+
assert.equal(error.resourceId, RESOURCE_ID, 'and the resource it was asked about');
|
|
102
|
+
assert.match(error.message, /coinbase does not have charge/, 'the message says the provider does not have it');
|
|
103
|
+
},
|
|
104
|
+
},
|
|
105
|
+
|
|
106
|
+
{
|
|
107
|
+
name: 'coinbase-classifies-an-unreachable-api-as-transient',
|
|
108
|
+
async run() {
|
|
109
|
+
const error = await throwsFrom(() => withTransport(Coinbase, 'request', async () => {
|
|
110
|
+
throw new Error('fetch failed');
|
|
111
|
+
}, () => Coinbase.fetchResource('charge', RESOURCE_ID, {})));
|
|
112
|
+
|
|
113
|
+
assert.equal(error.notFound, false, 'an unreachable API is not a provider saying the charge is gone');
|
|
114
|
+
assert.match(error.message, /could not be reached/, 'the message says the lookup never got an answer');
|
|
115
|
+
},
|
|
116
|
+
},
|
|
117
|
+
|
|
118
|
+
{
|
|
119
|
+
name: 'paypal-classifies-a-404-as-not-found',
|
|
120
|
+
async run() {
|
|
121
|
+
// PayPal carries the status in the message only — the shape its client throws
|
|
122
|
+
const error = await throwsFrom(() => withTransport(PayPal, 'request', async () => {
|
|
123
|
+
throw new Error('PayPal API 404: The specified resource does not exist.');
|
|
124
|
+
}, () => PayPal.fetchResource('subscription', RESOURCE_ID, {})));
|
|
125
|
+
|
|
126
|
+
assert.equal(error.notFound, true, 'PayPal answering 404 means the resource is gone');
|
|
127
|
+
assert.equal(error.provider, 'paypal', 'the failure names the provider that was asked');
|
|
128
|
+
},
|
|
129
|
+
},
|
|
130
|
+
|
|
131
|
+
{
|
|
132
|
+
name: 'paypal-says-an-uncaptured-order-never-moved-the-funds',
|
|
133
|
+
async run() {
|
|
134
|
+
// An order fetch IS the capture, so the caller has to be told the money
|
|
135
|
+
// did not move — the payload it used to fall back to described a captured
|
|
136
|
+
// order that never was
|
|
137
|
+
const error = await throwsFrom(() => withTransport(PayPal, 'request', async () => {
|
|
138
|
+
throw new Error('PayPal API 503: Service unavailable');
|
|
139
|
+
}, () => PayPal.fetchResource('order', RESOURCE_ID, {})));
|
|
140
|
+
|
|
141
|
+
assert.equal(error.notFound, false, 'a 503 is transient');
|
|
142
|
+
assert.match(error.message, /NOT captured/, 'the consequence of the failed capture rides on the failure');
|
|
143
|
+
},
|
|
144
|
+
},
|
|
145
|
+
|
|
146
|
+
{
|
|
147
|
+
name: 'stripe-classifies-a-missing-resource-as-not-found',
|
|
148
|
+
async run() {
|
|
149
|
+
const missing = new Error(`No such subscription: '${RESOURCE_ID}'`);
|
|
150
|
+
missing.code = 'resource_missing';
|
|
151
|
+
missing.statusCode = 404;
|
|
152
|
+
|
|
153
|
+
const sdk = {
|
|
154
|
+
subscriptions: {
|
|
155
|
+
retrieve: async () => {
|
|
156
|
+
throw missing;
|
|
157
|
+
},
|
|
158
|
+
},
|
|
159
|
+
};
|
|
160
|
+
|
|
161
|
+
const error = await throwsFrom(() => withTransport(Stripe, 'init', () => sdk,
|
|
162
|
+
() => Stripe.fetchResource('subscription', RESOURCE_ID, {})));
|
|
163
|
+
|
|
164
|
+
assert.equal(error.notFound, true, 'Stripe resource_missing means the resource is gone');
|
|
165
|
+
assert.equal(error.cause, missing, 'the provider\'s own error rides along for the logs');
|
|
166
|
+
},
|
|
167
|
+
},
|
|
168
|
+
|
|
169
|
+
{
|
|
170
|
+
name: 'stripe-classifies-an-outage-as-transient',
|
|
171
|
+
async run() {
|
|
172
|
+
const sdk = {
|
|
173
|
+
subscriptions: {
|
|
174
|
+
retrieve: async () => {
|
|
175
|
+
throw new Error('An error occurred with our connection to Stripe.');
|
|
176
|
+
},
|
|
177
|
+
},
|
|
178
|
+
};
|
|
179
|
+
|
|
180
|
+
const error = await throwsFrom(() => withTransport(Stripe, 'init', () => sdk,
|
|
181
|
+
() => Stripe.fetchResource('subscription', RESOURCE_ID, {})));
|
|
182
|
+
|
|
183
|
+
assert.equal(error.notFound, false, 'an outage is not a provider saying the resource is gone');
|
|
184
|
+
},
|
|
185
|
+
},
|
|
186
|
+
|
|
187
|
+
{
|
|
188
|
+
name: 'a-refund-miss-names-the-call-that-missed',
|
|
189
|
+
async run() {
|
|
190
|
+
// The failure names its own call site: a refund lookup thrown from
|
|
191
|
+
// getRefundDetails() used to read `fetchResource(refund/…)`, pointing
|
|
192
|
+
// whoever reads the log at a function that never ran.
|
|
193
|
+
const error = await throwsFrom(() => withTransport(PayPal, 'request', async () => {
|
|
194
|
+
throw new Error('PayPal API 404: The specified resource does not exist.');
|
|
195
|
+
}, () => PayPal.getRefundDetails({ id: 'SALE-1' }, { refundId: RESOURCE_ID, eventType: 'PAYMENT.SALE.REFUNDED' })));
|
|
196
|
+
|
|
197
|
+
assert.match(error.message, /getRefundDetails\(refund\//, 'the refund lookup names getRefundDetails, not fetchResource');
|
|
198
|
+
assert.equal(error.notFound, true, 'and still classifies — a 404 refund is gone');
|
|
199
|
+
},
|
|
200
|
+
},
|
|
201
|
+
|
|
202
|
+
{
|
|
203
|
+
name: 'an-unknown-resource-type-is-never-read-as-not-found',
|
|
204
|
+
async run() {
|
|
205
|
+
// A resource type the library does not know is a fault on THIS side. It must
|
|
206
|
+
// not masquerade as the provider affirmatively answering "no such resource",
|
|
207
|
+
// which would acknowledge the event and drop it forever.
|
|
208
|
+
const error = await throwsFrom(() => Chargebee.fetchResource('unknown-type', RESOURCE_ID, {}));
|
|
209
|
+
|
|
210
|
+
assert.equal(error.notFound, false, 'nothing was asked, so nothing was answered');
|
|
211
|
+
assert.match(error.message, /Unknown resource type/, 'the original error still surfaces');
|
|
212
|
+
},
|
|
213
|
+
},
|
|
214
|
+
],
|
|
215
|
+
});
|