@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,177 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Test: the orphan sweep only signals processes it can prove are ours
|
|
3
|
+
* ([#274](https://github.com/Omega-JS-Stack/omega/issues/274)).
|
|
4
|
+
*
|
|
5
|
+
* The post-shutdown sweep scanned its resolved port set plus the SHARED hub and
|
|
6
|
+
* storage ports and signaled whatever was listening. Port occupancy is not
|
|
7
|
+
* ownership: it terminated a live `mgr emulator` belonging to another project
|
|
8
|
+
* and another session. Ownership now needs proof — a pid this run recorded when
|
|
9
|
+
* it spawned the stack, or a command line that names an emulator AND this
|
|
10
|
+
* project id. Everything else is left alone, on every port.
|
|
11
|
+
*
|
|
12
|
+
* Run: npx omega test backend:cli/emulator-ownership
|
|
13
|
+
*
|
|
14
|
+
* The matcher is pure (a ps row in, a verdict out). The command lines below are
|
|
15
|
+
* REAL, copied from `ps -A -o pid=,ppid=,command=` against a booted sandbox
|
|
16
|
+
* emulator — the fixture is what the sweep actually reads, not an invention.
|
|
17
|
+
*/
|
|
18
|
+
const EmulatorCommand = require('../../dist/cli/commands/emulator.js');
|
|
19
|
+
const defineCases = require('../../dist/vendor/devkit/test/define-cases.js');
|
|
20
|
+
|
|
21
|
+
const { isOwnedEmulatorProcess, ownershipFromRecord } = EmulatorCommand;
|
|
22
|
+
|
|
23
|
+
const OURS = 'demo-sandbox-brand';
|
|
24
|
+
|
|
25
|
+
// Real rows from a booted sandbox emulator (paths shortened only where they
|
|
26
|
+
// carry no signal). The firestore jar is the ONE child whose command names the
|
|
27
|
+
// project; the firebase parent and the other emulators name nothing.
|
|
28
|
+
const FIREBASE_PARENT = 'node /Users/ian/.nvm/versions/node/v22.22.1/bin/firebase emulators:start --only functions,firestore,auth,database,hosting,pubsub --config firebase.resolved.json';
|
|
29
|
+
const FIRESTORE_JAR = 'java -Dgoogle.cloud_firestore.debug_log_level=FINE -Duser.language=en -jar /Users/ian/.cache/firebase/emulators/cloud-firestore-emulator-v1.21.0.jar --host 127.0.0.1 --port 8080 --websocket_port 9150 --database-edition standard --project_id demo-sandbox-brand --rules /Users/ian/Developer/Repositories/Omega/omega/brands/sandbox-brand/targets/backend/firestore.rules --single_project_mode true';
|
|
30
|
+
const PUBSUB_JAR = 'java -jar /Users/ian/.cache/firebase/emulators/pubsub-emulator-0.8.34/pubsub-emulator/lib/cloud-pubsub-emulator-0.8.34-all.jar --host=127.0.0.1 --port=8085';
|
|
31
|
+
|
|
32
|
+
// The processes the sweep must never touch.
|
|
33
|
+
const FOREIGN_EMULATOR_CLI = 'node /Users/ian/Developer/Repositories/Omega/omega/node_modules/.bin/omega emulator';
|
|
34
|
+
const FOREIGN_FIRESTORE_JAR = FIRESTORE_JAR.replace(OURS, 'demo-other-brand');
|
|
35
|
+
// The hot-reload watcher: its command line mentions both "firebase" paths and
|
|
36
|
+
// `emulator.log.reset`, so a name-only signature matches it — and it is
|
|
37
|
+
// reparented to PID 1, so an orphan-shaped check matches it too.
|
|
38
|
+
const RELOAD_WATCHER = 'node /Users/ian/.nvm/versions/node/v22.22.1/bin/nodemon --on-change-only --delay 1 --watch /Users/ian/Developer/Repositories/Omega/omega/packages/backend/src --ext js,json --exec node -e "fs.writeFileSync(\'/Users/ian/Developer/Repositories/Omega/omega/brands/sandbox-brand/targets/backend/.temp/emulator.log.reset\',\'\')"';
|
|
39
|
+
|
|
40
|
+
module.exports = defineCases({
|
|
41
|
+
description: 'emulator orphan sweep ownership matcher',
|
|
42
|
+
type: 'group',
|
|
43
|
+
|
|
44
|
+
tests: [
|
|
45
|
+
{
|
|
46
|
+
name: 'a-recorded-pid-is-ours-whatever-it-looks-like',
|
|
47
|
+
async run({ assert }) {
|
|
48
|
+
// The pid record written at spawn is the primary proof: the java
|
|
49
|
+
// emulators name no project, so nothing else can vouch for them.
|
|
50
|
+
const ownership = { pids: [37088, 37360, 38921], projectId: OURS };
|
|
51
|
+
|
|
52
|
+
assert.equal(isOwnedEmulatorProcess({ pid: 38921, command: PUBSUB_JAR }, ownership), true);
|
|
53
|
+
assert.equal(isOwnedEmulatorProcess({ pid: 37360, command: 'java -jar firebase-database-emulator-v4.11.2.jar --host 127.0.0.1 --port 9000' }, ownership), true);
|
|
54
|
+
},
|
|
55
|
+
},
|
|
56
|
+
|
|
57
|
+
{
|
|
58
|
+
name: 'an-emulator-command-naming-this-project-is-ours',
|
|
59
|
+
async run({ assert }) {
|
|
60
|
+
// The second proof route, for a child this run never recorded (a
|
|
61
|
+
// leftover from a previous run of the SAME project).
|
|
62
|
+
assert.equal(isOwnedEmulatorProcess({ pid: 37088, command: FIRESTORE_JAR }, { pids: [], projectId: OURS }), true);
|
|
63
|
+
},
|
|
64
|
+
},
|
|
65
|
+
|
|
66
|
+
{
|
|
67
|
+
name: 'another-projects-emulator-is-never-ours',
|
|
68
|
+
async run({ assert }) {
|
|
69
|
+
// The reported case, in both shapes: a sibling brand's stack.
|
|
70
|
+
assert.equal(isOwnedEmulatorProcess({ pid: 51001, command: FOREIGN_FIRESTORE_JAR }, { pids: [], projectId: OURS }), false);
|
|
71
|
+
assert.equal(isOwnedEmulatorProcess({ pid: 51002, command: FOREIGN_EMULATOR_CLI }, { pids: [], projectId: OURS }), false);
|
|
72
|
+
},
|
|
73
|
+
},
|
|
74
|
+
|
|
75
|
+
{
|
|
76
|
+
name: 'a-foreign-process-on-a-shared-port-is-never-ours',
|
|
77
|
+
async run({ assert }) {
|
|
78
|
+
// 4400 and 9199 are shared: whatever answers there is evidence of
|
|
79
|
+
// nothing. The matcher is the only gate, and it sees no ports at all.
|
|
80
|
+
assert.equal(isOwnedEmulatorProcess({ pid: 60001, command: RELOAD_WATCHER }, { pids: [], projectId: OURS }), false);
|
|
81
|
+
assert.equal(isOwnedEmulatorProcess({ pid: 60002, command: 'node /Users/ian/some-other-tool/server.js' }, { pids: [], projectId: OURS }), false);
|
|
82
|
+
},
|
|
83
|
+
},
|
|
84
|
+
|
|
85
|
+
{
|
|
86
|
+
name: 'an-emulator-that-names-no-project-is-not-proven-ours',
|
|
87
|
+
async run({ assert }) {
|
|
88
|
+
// The firebase parent names no project — unrecorded, it is a stranger.
|
|
89
|
+
// This is the row the old sweep signaled on port evidence alone.
|
|
90
|
+
assert.equal(isOwnedEmulatorProcess({ pid: 34965, command: FIREBASE_PARENT }, { pids: [], projectId: OURS }), false);
|
|
91
|
+
// ...and recorded, it is ours.
|
|
92
|
+
assert.equal(isOwnedEmulatorProcess({ pid: 34965, command: FIREBASE_PARENT }, { pids: [34965], projectId: OURS }), true);
|
|
93
|
+
},
|
|
94
|
+
},
|
|
95
|
+
|
|
96
|
+
{
|
|
97
|
+
name: 'missing-evidence-never-reads-as-ownership',
|
|
98
|
+
async run({ assert }) {
|
|
99
|
+
assert.equal(isOwnedEmulatorProcess({ pid: 37088, command: FIRESTORE_JAR }, { pids: [], projectId: null }), false, 'no project id of our own proves nothing');
|
|
100
|
+
assert.equal(isOwnedEmulatorProcess({ pid: 37088, command: FIRESTORE_JAR }, undefined), false, 'no evidence at all proves nothing');
|
|
101
|
+
assert.equal(isOwnedEmulatorProcess({ pid: 1, command: FIRESTORE_JAR }, { pids: [1], projectId: OURS }), false, 'init is never a candidate');
|
|
102
|
+
assert.equal(isOwnedEmulatorProcess({ pid: NaN, command: FIRESTORE_JAR }, { pids: [], projectId: OURS }), false);
|
|
103
|
+
},
|
|
104
|
+
},
|
|
105
|
+
|
|
106
|
+
{
|
|
107
|
+
name: 'a-project-id-that-only-appears-as-a-substring-does-not-count',
|
|
108
|
+
async run({ assert }) {
|
|
109
|
+
// `--project_id demo-sandbox-brand-staging` is a DIFFERENT project that
|
|
110
|
+
// happens to start with ours; a path containing the brand name is not
|
|
111
|
+
// a project id at all.
|
|
112
|
+
const staging = FIRESTORE_JAR.replace(`--project_id ${OURS}`, `--project_id ${OURS}-staging`);
|
|
113
|
+
|
|
114
|
+
assert.equal(isOwnedEmulatorProcess({ pid: 51003, command: staging }, { pids: [], projectId: OURS }), false);
|
|
115
|
+
assert.equal(isOwnedEmulatorProcess({ pid: 51004, command: `java -jar cloud-firestore-emulator.jar --rules /repos/${OURS}/firestore.rules` }, { pids: [], projectId: OURS }), false);
|
|
116
|
+
},
|
|
117
|
+
},
|
|
118
|
+
|
|
119
|
+
// ─── the pid record's shelf life ───
|
|
120
|
+
|
|
121
|
+
{
|
|
122
|
+
name: 'a-fresh-pid-record-is-evidence',
|
|
123
|
+
async run({ assert }) {
|
|
124
|
+
const record = { pids: [37088, 37360], projectId: OURS, rootPid: 34965, ports: { firestore: 8080 }, startedAt: new Date().toISOString() };
|
|
125
|
+
|
|
126
|
+
assert.deepEqual(ownershipFromRecord(record), { pids: [37088, 37360], projectId: OURS, rootPid: 34965, ports: { firestore: 8080 } });
|
|
127
|
+
},
|
|
128
|
+
},
|
|
129
|
+
|
|
130
|
+
{
|
|
131
|
+
name: 'a-stale-records-pids-are-not-evidence-anymore',
|
|
132
|
+
async run({ assert }) {
|
|
133
|
+
// The record is never deleted, so a run days later still read the last
|
|
134
|
+
// one. Pids get RECYCLED: those numbers now name whatever the OS
|
|
135
|
+
// handed them to, and the sweep SIGKILLs a recorded pid without
|
|
136
|
+
// looking at anything else. The project-id proof is not pid-based and
|
|
137
|
+
// survives.
|
|
138
|
+
const record = {
|
|
139
|
+
pids: [37088, 37360],
|
|
140
|
+
projectId: OURS,
|
|
141
|
+
rootPid: 34965,
|
|
142
|
+
startedAt: new Date(Date.now() - 13 * 60 * 60 * 1000).toISOString(),
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
assert.deepEqual(ownershipFromRecord(record), { pids: [], projectId: OURS, rootPid: 34965, ports: {} });
|
|
146
|
+
},
|
|
147
|
+
},
|
|
148
|
+
|
|
149
|
+
{
|
|
150
|
+
name: 'a-record-that-cannot-date-itself-is-not-evidence',
|
|
151
|
+
async run({ assert }) {
|
|
152
|
+
// A record written before startedAt existed, or a half-written one:
|
|
153
|
+
// unknown age is treated as expired, never as fresh.
|
|
154
|
+
assert.deepEqual(ownershipFromRecord({ pids: [37088], projectId: OURS }).pids, []);
|
|
155
|
+
assert.deepEqual(ownershipFromRecord({ pids: [37088], projectId: OURS, startedAt: 'whenever' }).pids, []);
|
|
156
|
+
assert.deepEqual(ownershipFromRecord(null), { pids: [], projectId: null, rootPid: null, ports: {} });
|
|
157
|
+
assert.deepEqual(ownershipFromRecord({ pids: 'nope', startedAt: new Date().toISOString() }).pids, []);
|
|
158
|
+
},
|
|
159
|
+
},
|
|
160
|
+
|
|
161
|
+
{
|
|
162
|
+
name: 'a-stale-record-still-spares-everything-it-cannot-prove',
|
|
163
|
+
async run({ assert }) {
|
|
164
|
+
// The whole point of expiring the pids: the recycled pid stops being a
|
|
165
|
+
// kill order and the process is judged on its command line alone.
|
|
166
|
+
const stale = ownershipFromRecord({
|
|
167
|
+
pids: [60001],
|
|
168
|
+
projectId: OURS,
|
|
169
|
+
startedAt: new Date(Date.now() - 13 * 60 * 60 * 1000).toISOString(),
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
assert.equal(isOwnedEmulatorProcess({ pid: 60001, command: RELOAD_WATCHER }, stale), false);
|
|
173
|
+
assert.equal(isOwnedEmulatorProcess({ pid: 37088, command: FIRESTORE_JAR }, stale), true, 'the command-line proof is untouched');
|
|
174
|
+
},
|
|
175
|
+
},
|
|
176
|
+
],
|
|
177
|
+
});
|
|
@@ -0,0 +1,395 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Test: a port taken between the probe and the bind bumps and retries once
|
|
3
|
+
* ([#778](https://github.com/Omega-JS-Stack/omega/issues/778)).
|
|
4
|
+
*
|
|
5
|
+
* The allocator probes, then firebase-tools binds: two moments, and on a
|
|
6
|
+
* machine running a second brand's stack a foreign listener fits between them.
|
|
7
|
+
* The boot then died on `listen EADDRINUSE 127.0.0.1:9099` and took every
|
|
8
|
+
* emulator-backed step of the lane with it. So a bind failure re-allocates
|
|
9
|
+
* around the port that failed, republishes the map, and boots ONE more time;
|
|
10
|
+
* a second failure is the report, naming the port and whoever holds it.
|
|
11
|
+
*
|
|
12
|
+
* Run: npx omega test backend:cli/emulator-port-retry
|
|
13
|
+
*
|
|
14
|
+
* Nothing here spawns an emulator or signals anything: `spawn` itself is a
|
|
15
|
+
* fixture for the duration of each boot, the ports are a throwaway map nowhere
|
|
16
|
+
* near the classic ones, and the reap case reads the world through the same
|
|
17
|
+
* injected `ps`/kill/probe seams the stale-reap suite uses.
|
|
18
|
+
*/
|
|
19
|
+
const os = require('os');
|
|
20
|
+
const path = require('path');
|
|
21
|
+
const childProcess = require('child_process');
|
|
22
|
+
const { EventEmitter } = require('events');
|
|
23
|
+
const jetpack = require('fs-jetpack');
|
|
24
|
+
|
|
25
|
+
const EmulatorCommand = require('../../dist/cli/commands/emulator.js');
|
|
26
|
+
const defineCases = require('../../dist/vendor/devkit/test/define-cases.js');
|
|
27
|
+
|
|
28
|
+
const OURS = 'demo-sandbox-brand';
|
|
29
|
+
|
|
30
|
+
// A real row from `ps -o command=` against a booted sandbox emulator.
|
|
31
|
+
const FIRESTORE_JAR = `java -jar cloud-firestore-emulator-v1.21.0.jar --host 127.0.0.1 --port 8080 --project_id ${OURS}`;
|
|
32
|
+
|
|
33
|
+
// Where a dead run's survivors are parented.
|
|
34
|
+
const ORPHANED = 1;
|
|
35
|
+
|
|
36
|
+
// Every emulator this project declares. All eight, because a name missing from
|
|
37
|
+
// firebase.json falls back to the CLASSIC port, and a fixture must never send
|
|
38
|
+
// the allocator at the ports a real stack on this machine is using.
|
|
39
|
+
const EMULATOR_NAMES = ['auth', 'functions', 'firestore', 'database', 'hosting', 'storage', 'pubsub', 'ui'];
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* A throwaway backend target whose emulator ports are nowhere near the classic
|
|
43
|
+
* map, spaced out so a bump of one name cannot collide with the next.
|
|
44
|
+
*/
|
|
45
|
+
function makeProject() {
|
|
46
|
+
const projectDir = path.join(os.tmpdir(), `omega-retry-${Date.now()}-${Math.random().toString(36).slice(2)}`);
|
|
47
|
+
const base = 49100 + Math.floor(Math.random() * 300) * 10;
|
|
48
|
+
|
|
49
|
+
jetpack.write(path.join(projectDir, 'firebase.json'), JSON.stringify({
|
|
50
|
+
emulators: Object.fromEntries(EMULATOR_NAMES.map((name, index) => [name, { port: base + index * 10 }])),
|
|
51
|
+
}, null, 2));
|
|
52
|
+
|
|
53
|
+
return { projectDir, cleanup: () => jetpack.remove(projectDir) };
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/** The `firebase emulators:start` child, as a fixture: no shell, no ports, no pid to signal. */
|
|
57
|
+
function fixtureChild() {
|
|
58
|
+
const child = new EventEmitter();
|
|
59
|
+
|
|
60
|
+
child.pid = -1;
|
|
61
|
+
child.stdout = new EventEmitter();
|
|
62
|
+
child.stderr = new EventEmitter();
|
|
63
|
+
child.exitCode = null;
|
|
64
|
+
child.signalCode = null;
|
|
65
|
+
|
|
66
|
+
return child;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* An emulator command over a throwaway project with every path that touches a
|
|
71
|
+
* REAL process stubbed out: the port-driven reaper, the preflight sweep, the
|
|
72
|
+
* pid record and the stop path's sweep all signal live pids on live ports.
|
|
73
|
+
* @param {string} projectDir - The throwaway project.
|
|
74
|
+
*/
|
|
75
|
+
function bootCommand(projectDir) {
|
|
76
|
+
const command = new EmulatorCommand({ firebaseProjectPath: projectDir, argv: { https: false, seed: false }, options: {} });
|
|
77
|
+
const lines = [];
|
|
78
|
+
|
|
79
|
+
command.log = (message) => lines.push(String(message));
|
|
80
|
+
command.logWarning = (message) => lines.push(String(message));
|
|
81
|
+
command.ensureStaged = () => {};
|
|
82
|
+
command.startStageWatch = () => ({ close: () => {} });
|
|
83
|
+
command.reapMachineOrphans = async () => {};
|
|
84
|
+
command.reapStaleRecordedProcesses = async () => {};
|
|
85
|
+
command.preflightEmulatorPorts = async () => [];
|
|
86
|
+
command.writeEmulatorPidRecord = () => [];
|
|
87
|
+
command.terminateRecordedEmulatorProcesses = async () => {};
|
|
88
|
+
|
|
89
|
+
return { command, lines };
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Run `fn` with the given fixture standing in for `child_process.spawn`.
|
|
94
|
+
*
|
|
95
|
+
* The boot reaches spawn through `cli/utils/spawn-shell.js`, which reads
|
|
96
|
+
* `childProcess.spawn` at CALL time
|
|
97
|
+
* ([#769](https://github.com/Omega-JS-Stack/omega/issues/769)), so the stand-in
|
|
98
|
+
* is installed for the DURATION of the boot and taken straight back out.
|
|
99
|
+
* @param {Function} spawn - Stands in for child_process.spawn.
|
|
100
|
+
* @param {Function} fn - What runs while it stands in.
|
|
101
|
+
*/
|
|
102
|
+
async function withSpawn(spawn, fn) {
|
|
103
|
+
const realSpawn = childProcess.spawn;
|
|
104
|
+
|
|
105
|
+
childProcess.spawn = spawn;
|
|
106
|
+
|
|
107
|
+
try {
|
|
108
|
+
return await fn();
|
|
109
|
+
} finally {
|
|
110
|
+
childProcess.spawn = realSpawn;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/** The OMEGA_*_PORT block a boot publishes, snapshotted so a case can put it back. */
|
|
115
|
+
function capturePortEnv() {
|
|
116
|
+
const keys = Object.keys(process.env).filter((key) => /^OMEGA_.*_PORT$/.test(key));
|
|
117
|
+
const prior = Object.fromEntries(keys.map((key) => [key, process.env[key]]));
|
|
118
|
+
|
|
119
|
+
return () => {
|
|
120
|
+
for (const key of Object.keys(process.env)) {
|
|
121
|
+
if (/^OMEGA_.*_PORT$/.test(key) && !(key in prior)) delete process.env[key];
|
|
122
|
+
}
|
|
123
|
+
Object.assign(process.env, prior);
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/** The published map this boot handed its child, as the child reads it. */
|
|
128
|
+
function publishedPorts(projectDir) {
|
|
129
|
+
return jetpack.read(path.join(projectDir, '.temp', 'ports.json'), 'json')?.ports || {};
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* A child that dies the way firebase-tools does when its auth port went to
|
|
134
|
+
* somebody else: the bind failure on stderr, then gone. The port defaults to
|
|
135
|
+
* the one the boot just published, so the fixture always names the port THIS
|
|
136
|
+
* attempt was actually given.
|
|
137
|
+
* @param {object} [options]
|
|
138
|
+
* @param {number} [options.port] - The port the failure names.
|
|
139
|
+
* @param {boolean} [options.close] - Emit `close` (false = the late-close case:
|
|
140
|
+
* the child outlives shutdown's races and the event lands after the retry).
|
|
141
|
+
*/
|
|
142
|
+
function bindFailureChild({ port, close = true } = {}) {
|
|
143
|
+
const child = fixtureChild();
|
|
144
|
+
|
|
145
|
+
setImmediate(() => {
|
|
146
|
+
// Dead before the boot can signal it: a stack that never bound anything
|
|
147
|
+
// has no process group to take down.
|
|
148
|
+
child.exitCode = 1;
|
|
149
|
+
child.stderr.emit('data', Buffer.from(`⚠ emulators: Error: listen EADDRINUSE: address already in use 127.0.0.1:${port || process.env.OMEGA_AUTH_PORT}\n`));
|
|
150
|
+
|
|
151
|
+
if (close) {
|
|
152
|
+
child.emit('close', 1, null);
|
|
153
|
+
}
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
return child;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/** A child that comes up. */
|
|
160
|
+
function readyChild() {
|
|
161
|
+
const child = fixtureChild();
|
|
162
|
+
|
|
163
|
+
setImmediate(() => child.stdout.emit('data', Buffer.from('[fixture] All emulators ready\n')));
|
|
164
|
+
|
|
165
|
+
return child;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
module.exports = defineCases({
|
|
169
|
+
description: 'emulator boot bumps and retries once when a port is taken mid-bind',
|
|
170
|
+
type: 'group',
|
|
171
|
+
timeout: 30000,
|
|
172
|
+
|
|
173
|
+
tests: [
|
|
174
|
+
{
|
|
175
|
+
name: 'a-port-taken-mid-bind-is-bumped-and-the-boot-retried-once',
|
|
176
|
+
async run({ assert }) {
|
|
177
|
+
const { projectDir, cleanup } = makeProject();
|
|
178
|
+
const { command } = bootCommand(projectDir);
|
|
179
|
+
const restoreEnv = capturePortEnv();
|
|
180
|
+
const attempts = [];
|
|
181
|
+
let child = null;
|
|
182
|
+
|
|
183
|
+
const fixtureSpawn = () => {
|
|
184
|
+
attempts.push(Number(process.env.OMEGA_AUTH_PORT));
|
|
185
|
+
child = attempts.length === 1 ? bindFailureChild() : readyChild();
|
|
186
|
+
return child;
|
|
187
|
+
};
|
|
188
|
+
|
|
189
|
+
try {
|
|
190
|
+
const { emulatorPorts, bumped } = await withSpawn(fixtureSpawn, () => command.startEmulators({ https: false }));
|
|
191
|
+
|
|
192
|
+
assert.equal(attempts.length, 2, 'the first boot died on the bind and exactly one retry followed');
|
|
193
|
+
assert.equal(attempts[1], attempts[0] + 1, 'the retry allocated auth off the port it could not bind');
|
|
194
|
+
assert.equal(emulatorPorts.auth, attempts[1], 'the stack that came up is the bumped one');
|
|
195
|
+
assert.ok(bumped.includes('auth'), 'the moved name is reported as bumped');
|
|
196
|
+
assert.equal(publishedPorts(projectDir).auth, attempts[1], 'the ports file siblings read carries the bumped port');
|
|
197
|
+
assert.equal(publishedPorts(projectDir).functions, emulatorPorts.functions, 'every other name kept its allocation');
|
|
198
|
+
} finally {
|
|
199
|
+
if (child) child.emit('close', 0, null);
|
|
200
|
+
restoreEnv();
|
|
201
|
+
cleanup();
|
|
202
|
+
}
|
|
203
|
+
},
|
|
204
|
+
},
|
|
205
|
+
|
|
206
|
+
{
|
|
207
|
+
name: 'a-bind-failure-on-a-port-this-run-never-asked-for-is-not-retried',
|
|
208
|
+
async run({ assert }) {
|
|
209
|
+
// The retry is for the race this run can do something about: a port of
|
|
210
|
+
// its OWN allocation. A failure naming anything else (a redis this
|
|
211
|
+
// machine runs, a port some other tool logged) is not a bump the
|
|
212
|
+
// allocator can make, so the boot fails the way it always did.
|
|
213
|
+
const { projectDir, cleanup } = makeProject();
|
|
214
|
+
const { command } = bootCommand(projectDir);
|
|
215
|
+
const restoreEnv = capturePortEnv();
|
|
216
|
+
const attempts = [];
|
|
217
|
+
let failure = null;
|
|
218
|
+
|
|
219
|
+
const fixtureSpawn = () => {
|
|
220
|
+
attempts.push(Number(process.env.OMEGA_AUTH_PORT));
|
|
221
|
+
return bindFailureChild({ port: 6379 });
|
|
222
|
+
};
|
|
223
|
+
|
|
224
|
+
try {
|
|
225
|
+
await withSpawn(fixtureSpawn, () => command.startEmulators({ https: false }));
|
|
226
|
+
} catch (error) {
|
|
227
|
+
failure = error;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
try {
|
|
231
|
+
assert.equal(attempts.length, 1, 'a port outside the allocation is not a bump, so nothing is retried');
|
|
232
|
+
assert.equal(failure?.addressInUsePort, undefined, 'the failure carries no port tag');
|
|
233
|
+
assert.match(failure.message, /exited before ready/, 'the boot fails the way it always did');
|
|
234
|
+
} finally {
|
|
235
|
+
restoreEnv();
|
|
236
|
+
cleanup();
|
|
237
|
+
}
|
|
238
|
+
},
|
|
239
|
+
},
|
|
240
|
+
|
|
241
|
+
{
|
|
242
|
+
name: 'a-late-close-from-the-failed-attempt-leaves-the-retrys-artifacts-alone',
|
|
243
|
+
async run({ assert }) {
|
|
244
|
+
// The first child can outlive shutdown's SIGTERM/SIGKILL races and
|
|
245
|
+
// close LATER, by which time the retry has published its own map into
|
|
246
|
+
// the same two files. Both attempts stamp this same process, so only
|
|
247
|
+
// the attempt token can tell the closing one it is no longer in charge.
|
|
248
|
+
const { projectDir, cleanup } = makeProject();
|
|
249
|
+
const { command } = bootCommand(projectDir);
|
|
250
|
+
const restoreEnv = capturePortEnv();
|
|
251
|
+
const children = [];
|
|
252
|
+
const resolvedConfig = path.join(projectDir, 'firebase.resolved.json');
|
|
253
|
+
|
|
254
|
+
const fixtureSpawn = () => {
|
|
255
|
+
const child = children.length === 0 ? bindFailureChild({ close: false }) : readyChild();
|
|
256
|
+
children.push(child);
|
|
257
|
+
return child;
|
|
258
|
+
};
|
|
259
|
+
|
|
260
|
+
try {
|
|
261
|
+
const { emulatorPorts } = await withSpawn(fixtureSpawn, () => command.startEmulators({ https: false }));
|
|
262
|
+
|
|
263
|
+
assert.equal(publishedPorts(projectDir).auth, emulatorPorts.auth, 'the retry published its map');
|
|
264
|
+
|
|
265
|
+
// The dead first attempt finally reports in.
|
|
266
|
+
children[0].emit('close', 1, null);
|
|
267
|
+
|
|
268
|
+
assert.equal(publishedPorts(projectDir).auth, emulatorPorts.auth, "the late close leaves the live stack's ports file published");
|
|
269
|
+
assert.ok(jetpack.exists(resolvedConfig), 'and leaves the config the live stack is running on');
|
|
270
|
+
} finally {
|
|
271
|
+
children.forEach((child) => child.emit('close', 0, null));
|
|
272
|
+
restoreEnv();
|
|
273
|
+
cleanup();
|
|
274
|
+
}
|
|
275
|
+
},
|
|
276
|
+
},
|
|
277
|
+
|
|
278
|
+
{
|
|
279
|
+
name: 'a-second-bind-failure-names-the-port-and-its-holder',
|
|
280
|
+
async run({ assert }) {
|
|
281
|
+
// Twice on the same wall is not a race any more: something is sitting
|
|
282
|
+
// on that port. The report says which, and who has it, and never
|
|
283
|
+
// signals them.
|
|
284
|
+
const { projectDir, cleanup } = makeProject();
|
|
285
|
+
const { command } = bootCommand(projectDir);
|
|
286
|
+
const restoreEnv = capturePortEnv();
|
|
287
|
+
const attempts = [];
|
|
288
|
+
const asked = [];
|
|
289
|
+
let failure = null;
|
|
290
|
+
|
|
291
|
+
command.describePortHolders = (port) => {
|
|
292
|
+
asked.push(port);
|
|
293
|
+
return [{ pid: 4242, command: FIRESTORE_JAR }];
|
|
294
|
+
};
|
|
295
|
+
|
|
296
|
+
const fixtureSpawn = () => {
|
|
297
|
+
attempts.push(Number(process.env.OMEGA_AUTH_PORT));
|
|
298
|
+
return bindFailureChild();
|
|
299
|
+
};
|
|
300
|
+
|
|
301
|
+
try {
|
|
302
|
+
await withSpawn(fixtureSpawn, () => command.startEmulators({ https: false }));
|
|
303
|
+
} catch (error) {
|
|
304
|
+
failure = error;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
try {
|
|
308
|
+
assert.ok(failure, 'a boot that cannot bind its ports twice fails loudly');
|
|
309
|
+
assert.equal(attempts.length, 2, 'ONE retry, never a loop');
|
|
310
|
+
assert.deepEqual(asked, [attempts[1]], 'the holder is looked up for the port the retry could not bind');
|
|
311
|
+
assert.match(failure.message, new RegExp(`port ${attempts[1]} \\(auth\\)`), 'the report names the port and the emulator that wanted it');
|
|
312
|
+
assert.match(failure.message, /held by pid 4242: java -jar cloud-firestore-emulator/, 'and the process holding it');
|
|
313
|
+
} finally {
|
|
314
|
+
restoreEnv();
|
|
315
|
+
cleanup();
|
|
316
|
+
}
|
|
317
|
+
},
|
|
318
|
+
},
|
|
319
|
+
|
|
320
|
+
{
|
|
321
|
+
name: 'the-stale-reap-probes-its-ports-only-after-the-pid-is-gone',
|
|
322
|
+
async run({ assert }) {
|
|
323
|
+
// A signal is not an exit: kill() returns while the kernel is still
|
|
324
|
+
// unwinding the process, so a probe in that same tick is a verdict
|
|
325
|
+
// about a shutdown that has not happened. The numbers go first, then
|
|
326
|
+
// the ports, and the port poll keeps asking until it reads free.
|
|
327
|
+
const projectDir = path.join(os.tmpdir(), `omega-retry-reap-${Date.now()}-${Math.random().toString(36).slice(2)}`);
|
|
328
|
+
const command = new EmulatorCommand({ firebaseProjectPath: projectDir, argv: {}, options: {} });
|
|
329
|
+
const lines = [];
|
|
330
|
+
const events = [];
|
|
331
|
+
const port = 49999;
|
|
332
|
+
let sigkilled = false;
|
|
333
|
+
let readsAfterKill = 0;
|
|
334
|
+
let probes = 0;
|
|
335
|
+
|
|
336
|
+
command.log = (message) => lines.push(String(message));
|
|
337
|
+
command.logWarning = (message) => lines.push(String(message));
|
|
338
|
+
|
|
339
|
+
jetpack.write(command.getTempPath('emulator-pids.json'), {
|
|
340
|
+
pids: [4001, 4002],
|
|
341
|
+
projectId: OURS,
|
|
342
|
+
rootPid: 4001,
|
|
343
|
+
ports: { firestore: port },
|
|
344
|
+
startedAt: new Date().toISOString(),
|
|
345
|
+
});
|
|
346
|
+
|
|
347
|
+
// 4001 (the dead run's root) is gone; 4002 is its orphaned jar, and it
|
|
348
|
+
// ignores SIGTERM, keeps reading alive for one poll past the SIGKILL,
|
|
349
|
+
// and holds its listener for one probe past that.
|
|
350
|
+
const seams = {
|
|
351
|
+
readProcess: (pid) => {
|
|
352
|
+
if (Number(pid) !== 4002) {
|
|
353
|
+
return null;
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
if (sigkilled) {
|
|
357
|
+
readsAfterKill++;
|
|
358
|
+
|
|
359
|
+
if (readsAfterKill > 1) {
|
|
360
|
+
events.push('gone');
|
|
361
|
+
return null;
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
events.push('unwinding');
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
return { ppid: ORPHANED, command: FIRESTORE_JAR };
|
|
368
|
+
},
|
|
369
|
+
kill: (pid, signal) => {
|
|
370
|
+
events.push(`signal:${signal}`);
|
|
371
|
+
sigkilled = sigkilled || signal === 'SIGKILL';
|
|
372
|
+
},
|
|
373
|
+
isFree: async (probed) => {
|
|
374
|
+
events.push(`probe:${probed}`);
|
|
375
|
+
probes++;
|
|
376
|
+
return probes > 1;
|
|
377
|
+
},
|
|
378
|
+
};
|
|
379
|
+
|
|
380
|
+
try {
|
|
381
|
+
await command.reapStaleRecordedProcesses(command.readEmulatorOwnership(), seams);
|
|
382
|
+
|
|
383
|
+
assert.deepEqual(
|
|
384
|
+
events,
|
|
385
|
+
['signal:SIGTERM', 'signal:SIGKILL', 'unwinding', 'gone', `probe:${port}`, `probe:${port}`],
|
|
386
|
+
'the reap waits out the process, THEN polls the port until it reads free',
|
|
387
|
+
);
|
|
388
|
+
assert.ok(!lines.join('\n').includes('still closing'), 'a port that came back free on the second ask is not reported as held');
|
|
389
|
+
} finally {
|
|
390
|
+
jetpack.remove(projectDir);
|
|
391
|
+
}
|
|
392
|
+
},
|
|
393
|
+
},
|
|
394
|
+
],
|
|
395
|
+
});
|