@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,574 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Test: a previous boot's leftovers are reaped from the record that named them
|
|
3
|
+
* ([#721](https://github.com/Omega-JS-Stack/omega/issues/721)).
|
|
4
|
+
*
|
|
5
|
+
* The pre-boot reaper is PORT-driven: it only ever considers pids listening on
|
|
6
|
+
* the ports this run wants. The reload watcher binds nothing at all, so it is
|
|
7
|
+
* unreachable by construction — and the record that names it is overwritten by
|
|
8
|
+
* the very next boot, so a run that died without teardown leaves a nodemon
|
|
9
|
+
* nothing will ever name again. The record is therefore read, and reaped from,
|
|
10
|
+
* BEFORE it is overwritten.
|
|
11
|
+
*
|
|
12
|
+
* Run: npx omega test backend:cli/emulator-stale-reap
|
|
13
|
+
*
|
|
14
|
+
* A recorded pid is a NUMBER, and the OS hands numbers out again. This suite is
|
|
15
|
+
* about the gate that stands between that number and a signal, so every process
|
|
16
|
+
* here is a fixture: the seam that reads a `ps` row, the seam that signals, and
|
|
17
|
+
* the seam that probes a port are all injected, nothing is spawned, and nothing
|
|
18
|
+
* real is ever signalled. The rows are real ones from a booted sandbox emulator.
|
|
19
|
+
*/
|
|
20
|
+
const os = require('os');
|
|
21
|
+
const path = require('path');
|
|
22
|
+
const childProcess = require('child_process');
|
|
23
|
+
const { EventEmitter } = require('events');
|
|
24
|
+
const jetpack = require('fs-jetpack');
|
|
25
|
+
|
|
26
|
+
const EmulatorCommand = require('../../dist/cli/commands/emulator.js');
|
|
27
|
+
const defineCases = require('../../dist/vendor/devkit/test/define-cases.js');
|
|
28
|
+
|
|
29
|
+
const OURS = 'demo-sandbox-brand';
|
|
30
|
+
|
|
31
|
+
// Real rows from `ps -o command=` against a booted sandbox emulator.
|
|
32
|
+
const FIREBASE_PARENT = 'node /Users/ian/.nvm/versions/node/v22.22.1/bin/firebase emulators:start --only functions,firestore,auth,database,hosting,pubsub';
|
|
33
|
+
const FIRESTORE_JAR = 'java -jar cloud-firestore-emulator-v1.21.0.jar --host 127.0.0.1 --port 8080 --project_id demo-sandbox-brand';
|
|
34
|
+
const PUBSUB_JAR = 'java -jar cloud-pubsub-emulator-0.8.34-all.jar --host=127.0.0.1 --port=8085';
|
|
35
|
+
const NEIGHBOUR_JAR = FIRESTORE_JAR.replace(OURS, 'demo-other-brand');
|
|
36
|
+
// The whole reason this reap exists: a nodemon that binds no port, so no port
|
|
37
|
+
// sweep can ever reach it. It matches the machinery signature only because
|
|
38
|
+
// watch.js bakes the `emulator.log.reset` sentinel path into its --exec argv.
|
|
39
|
+
const NODEMON_WATCHER = 'node /Users/ian/.nvm/versions/node/v22.22.1/bin/nodemon --on-change-only --delay 1 --watch /omega/packages/backend/src --ext js,json --exec node -e "fs.writeFileSync(\'/omega/brands/sandbox-brand/targets/backend/.temp/emulator.log.reset\',\'\')"';
|
|
40
|
+
// What a recycled number looks like: the OS gave it to somebody else entirely.
|
|
41
|
+
const STRANGER = 'node /Users/ian/Developer/some-other-tool/server.js --serve';
|
|
42
|
+
|
|
43
|
+
// Where a dead run's survivors are parented. PID 1 is every orphan of it; a
|
|
44
|
+
// number handed to a LIVE stack hangs off THAT stack's firebase instead, and
|
|
45
|
+
// this record has never heard of it.
|
|
46
|
+
const ORPHANED = 1;
|
|
47
|
+
const ANOTHER_STACKS_FIREBASE = 7777;
|
|
48
|
+
|
|
49
|
+
// Comfortably past PID_RECORD_MAX_AGE_MS (12h) — a record whose numbers are no
|
|
50
|
+
// longer known to name the processes they named.
|
|
51
|
+
const EXPIRED_AT = new Date(Date.now() - 48 * 60 * 60 * 1000).toISOString();
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* An emulator command pointed at a throwaway project, with a PREVIOUS boot's
|
|
55
|
+
* record already on disk — the state this boot finds before it writes its own.
|
|
56
|
+
* @param {object} record - The record fields to write.
|
|
57
|
+
*/
|
|
58
|
+
function commandWithRecord({ pids, rootPid, ports = {}, projectId = OURS, startedAt = new Date().toISOString() }) {
|
|
59
|
+
const projectDir = path.join(os.tmpdir(), `omega-stale-${Date.now()}-${Math.random().toString(36).slice(2)}`);
|
|
60
|
+
const command = new EmulatorCommand({ firebaseProjectPath: projectDir, argv: {}, options: {} });
|
|
61
|
+
const lines = [];
|
|
62
|
+
|
|
63
|
+
command.log = (message) => lines.push(String(message));
|
|
64
|
+
command.logWarning = (message) => lines.push(String(message));
|
|
65
|
+
|
|
66
|
+
jetpack.write(command.getTempPath('emulator-pids.json'), {
|
|
67
|
+
pids: pids,
|
|
68
|
+
projectId: projectId,
|
|
69
|
+
rootPid: rootPid,
|
|
70
|
+
ports: ports,
|
|
71
|
+
startedAt: startedAt,
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
return { command, lines, cleanup: () => jetpack.remove(projectDir) };
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* A fixture process table plus the three seams the reap reads the world through.
|
|
79
|
+
*
|
|
80
|
+
* `readProcess` is the `ps -o ppid=,command=` seam, `kill` is the signal seam,
|
|
81
|
+
* and `isFree` is the port probe the settle wait polls — so a case states what
|
|
82
|
+
* is running, and reads back exactly what would have been signalled and which
|
|
83
|
+
* ports were waited on. Nothing leaves this process.
|
|
84
|
+
* @param {object} table - pid → { ppid, command } as ps would report it.
|
|
85
|
+
* @param {Function} [afterTerm] - What SIGTERM does to the table (defaults to
|
|
86
|
+
* the process exiting).
|
|
87
|
+
*/
|
|
88
|
+
function processTable(table, afterTerm) {
|
|
89
|
+
const live = new Map(Object.entries(table).map(([pid, row]) => [Number(pid), row]));
|
|
90
|
+
const signals = [];
|
|
91
|
+
const probed = [];
|
|
92
|
+
|
|
93
|
+
return {
|
|
94
|
+
signals: signals,
|
|
95
|
+
probed: probed,
|
|
96
|
+
signalled: (pid) => signals.filter((entry) => entry.pid === Number(pid)).map((entry) => entry.signal),
|
|
97
|
+
seams: {
|
|
98
|
+
readProcess: (pid) => live.get(Number(pid)) || null,
|
|
99
|
+
kill: (pid, signal) => {
|
|
100
|
+
signals.push({ pid: Number(pid), signal: signal });
|
|
101
|
+
|
|
102
|
+
if (signal === 'SIGTERM') {
|
|
103
|
+
(afterTerm || ((target) => live.delete(target)))(Number(pid), live);
|
|
104
|
+
} else {
|
|
105
|
+
live.delete(Number(pid));
|
|
106
|
+
}
|
|
107
|
+
},
|
|
108
|
+
isFree: async (port) => {
|
|
109
|
+
probed.push(port);
|
|
110
|
+
return true;
|
|
111
|
+
},
|
|
112
|
+
},
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* A throwaway backend target root whose emulator ports are nowhere near the
|
|
118
|
+
* classic map — the boot path resolves its ports from this file.
|
|
119
|
+
*/
|
|
120
|
+
function makeProject() {
|
|
121
|
+
const projectDir = path.join(os.tmpdir(), `omega-stale-boot-${Date.now()}-${Math.random().toString(36).slice(2)}`);
|
|
122
|
+
const base = 49000 + Math.floor(Math.random() * 8000);
|
|
123
|
+
const names = ['auth', 'functions', 'firestore', 'database', 'hosting', 'storage', 'pubsub', 'ui'];
|
|
124
|
+
|
|
125
|
+
jetpack.write(path.join(projectDir, 'firebase.json'), JSON.stringify({
|
|
126
|
+
emulators: Object.fromEntries(names.map((name, index) => [name, { port: base + index }])),
|
|
127
|
+
}, null, 2));
|
|
128
|
+
|
|
129
|
+
return { projectDir, cleanup: () => jetpack.remove(projectDir) };
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/** The `firebase emulators:start` child, as a fixture: no shell, no ports, no pid to signal. */
|
|
133
|
+
function fixtureChild() {
|
|
134
|
+
const child = new EventEmitter();
|
|
135
|
+
|
|
136
|
+
child.pid = -1;
|
|
137
|
+
child.stdout = new EventEmitter();
|
|
138
|
+
child.stderr = new EventEmitter();
|
|
139
|
+
child.exitCode = null;
|
|
140
|
+
child.signalCode = null;
|
|
141
|
+
|
|
142
|
+
return child;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Run `fn` with the given fixture standing in for `child_process.spawn`.
|
|
147
|
+
*
|
|
148
|
+
* The boot reaches spawn through `cli/utils/spawn-shell.js`, which reads
|
|
149
|
+
* `childProcess.spawn` at CALL time
|
|
150
|
+
* ([#769](https://github.com/Omega-JS-Stack/omega/issues/769)) — so the stand-in
|
|
151
|
+
* is installed for the DURATION of the boot (a load-time swap would be gone by
|
|
152
|
+
* the time the boot ran, and the boot would spawn a real emulator), and it is
|
|
153
|
+
* taken straight back out.
|
|
154
|
+
* @param {Function} spawn - Stands in for child_process.spawn.
|
|
155
|
+
* @param {Function} fn - What runs while it stands in.
|
|
156
|
+
*/
|
|
157
|
+
async function withSpawn(spawn, fn) {
|
|
158
|
+
const realSpawn = childProcess.spawn;
|
|
159
|
+
|
|
160
|
+
childProcess.spawn = spawn;
|
|
161
|
+
|
|
162
|
+
try {
|
|
163
|
+
return await fn();
|
|
164
|
+
} finally {
|
|
165
|
+
childProcess.spawn = realSpawn;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
module.exports = defineCases({
|
|
170
|
+
description: 'emulator pre-boot reap of a stale pid record',
|
|
171
|
+
type: 'group',
|
|
172
|
+
timeout: 30000,
|
|
173
|
+
|
|
174
|
+
tests: [
|
|
175
|
+
{
|
|
176
|
+
name: 'a-dead-runs-orphaned-watcher-is-reaped-from-its-record',
|
|
177
|
+
async run({ assert }) {
|
|
178
|
+
// The defect: the watcher binds nothing, so the port reaper cannot see
|
|
179
|
+
// it, and this boot is about to overwrite the only file that names it.
|
|
180
|
+
const { command, cleanup } = commandWithRecord({ pids: [4001, 4002], rootPid: 4001 });
|
|
181
|
+
const table = processTable({ 4002: { ppid: ORPHANED, command: NODEMON_WATCHER } });
|
|
182
|
+
|
|
183
|
+
try {
|
|
184
|
+
await command.reapStaleRecordedProcesses(command.readEmulatorOwnership(), table.seams);
|
|
185
|
+
|
|
186
|
+
assert.deepEqual(table.signalled(4002), ['SIGTERM'], 'the orphaned watcher is stopped by the record that named it');
|
|
187
|
+
assert.deepEqual(table.signalled(4001), [], 'the root is already gone — nothing to signal');
|
|
188
|
+
} finally {
|
|
189
|
+
cleanup();
|
|
190
|
+
}
|
|
191
|
+
},
|
|
192
|
+
},
|
|
193
|
+
|
|
194
|
+
{
|
|
195
|
+
name: 'a-recycled-pid-running-something-else-is-never-signalled',
|
|
196
|
+
async run({ assert }) {
|
|
197
|
+
// The number came back, attached to a stranger. The record says it is
|
|
198
|
+
// ours; the LIVE command line is the only thing that can disagree, and
|
|
199
|
+
// it does.
|
|
200
|
+
const { command, lines, cleanup } = commandWithRecord({ pids: [4001, 4002], rootPid: 4001 });
|
|
201
|
+
const table = processTable({ 4002: { ppid: ORPHANED, command: STRANGER } });
|
|
202
|
+
|
|
203
|
+
try {
|
|
204
|
+
await command.reapStaleRecordedProcesses(command.readEmulatorOwnership(), table.seams);
|
|
205
|
+
|
|
206
|
+
assert.deepEqual(table.signals, [], 'a recorded number now running a stranger is left alone');
|
|
207
|
+
assert.match(lines.join('\n'), /Left 1 recorded/);
|
|
208
|
+
} finally {
|
|
209
|
+
cleanup();
|
|
210
|
+
}
|
|
211
|
+
},
|
|
212
|
+
},
|
|
213
|
+
|
|
214
|
+
{
|
|
215
|
+
name: 'a-recycled-pid-on-another-brands-jar-is-left-alone',
|
|
216
|
+
async run({ assert }) {
|
|
217
|
+
// The harder recycling: the number came back as emulator machinery, so
|
|
218
|
+
// "is this a jar" passes. The jar names ITS project on its own command
|
|
219
|
+
// line, and it is not ours.
|
|
220
|
+
const { command, cleanup } = commandWithRecord({ pids: [4001, 4002], rootPid: 4001 });
|
|
221
|
+
const table = processTable({ 4002: { ppid: ORPHANED, command: NEIGHBOUR_JAR } });
|
|
222
|
+
|
|
223
|
+
try {
|
|
224
|
+
await command.reapStaleRecordedProcesses(command.readEmulatorOwnership(), table.seams);
|
|
225
|
+
|
|
226
|
+
assert.deepEqual(table.signals, [], "another brand's live jar must survive our recorded number");
|
|
227
|
+
} finally {
|
|
228
|
+
cleanup();
|
|
229
|
+
}
|
|
230
|
+
},
|
|
231
|
+
},
|
|
232
|
+
|
|
233
|
+
{
|
|
234
|
+
name: 'a-pid-whose-command-cannot-be-read-is-never-signalled',
|
|
235
|
+
async run({ assert }) {
|
|
236
|
+
// No command line is no evidence — the process is gone, or the read
|
|
237
|
+
// failed. Either way there is no proof of identity, so there is no
|
|
238
|
+
// kill order.
|
|
239
|
+
const { command, cleanup } = commandWithRecord({ pids: [4001, 4002], rootPid: 4001 });
|
|
240
|
+
const table = processTable({});
|
|
241
|
+
|
|
242
|
+
try {
|
|
243
|
+
await command.reapStaleRecordedProcesses(command.readEmulatorOwnership(), table.seams);
|
|
244
|
+
|
|
245
|
+
assert.deepEqual(table.signals, [], 'a pid with no readable command is never signalled');
|
|
246
|
+
} finally {
|
|
247
|
+
cleanup();
|
|
248
|
+
}
|
|
249
|
+
},
|
|
250
|
+
},
|
|
251
|
+
|
|
252
|
+
{
|
|
253
|
+
name: 'the-run-never-signals-itself',
|
|
254
|
+
async run({ assert }) {
|
|
255
|
+
// `omega emulator` matches the machinery signature by NAME, so a
|
|
256
|
+
// recorded number recycled onto this very process would read as a
|
|
257
|
+
// reapable leftover and the boot would SIGTERM itself.
|
|
258
|
+
const { command, cleanup } = commandWithRecord({ pids: [4001, process.pid], rootPid: 4001 });
|
|
259
|
+
const table = processTable({ [process.pid]: { ppid: process.ppid, command: 'node /omega/node_modules/.bin/omega emulator' } });
|
|
260
|
+
|
|
261
|
+
try {
|
|
262
|
+
await command.reapStaleRecordedProcesses(command.readEmulatorOwnership(), table.seams);
|
|
263
|
+
|
|
264
|
+
assert.deepEqual(table.signals, [], 'this process is never a reap target');
|
|
265
|
+
} finally {
|
|
266
|
+
cleanup();
|
|
267
|
+
}
|
|
268
|
+
},
|
|
269
|
+
},
|
|
270
|
+
|
|
271
|
+
{
|
|
272
|
+
name: 'a-live-root-means-the-record-is-not-stale',
|
|
273
|
+
async run({ assert }) {
|
|
274
|
+
// The record belongs to a run that is still UP. Its jars are that run's
|
|
275
|
+
// business, and this boot is a second stack beside it — reaping here
|
|
276
|
+
// would kill a live sibling emulator mid-session.
|
|
277
|
+
const { command, cleanup } = commandWithRecord({ pids: [4001, 4002, 4003], rootPid: 4001 });
|
|
278
|
+
const table = processTable({
|
|
279
|
+
4001: { ppid: 3999, command: FIREBASE_PARENT },
|
|
280
|
+
4002: { ppid: 4001, command: FIRESTORE_JAR },
|
|
281
|
+
4003: { ppid: 4001, command: PUBSUB_JAR },
|
|
282
|
+
});
|
|
283
|
+
|
|
284
|
+
try {
|
|
285
|
+
await command.reapStaleRecordedProcesses(command.readEmulatorOwnership(), table.seams);
|
|
286
|
+
|
|
287
|
+
assert.deepEqual(table.signals, [], 'a record whose root is alive is a LIVE record, not a leftover');
|
|
288
|
+
} finally {
|
|
289
|
+
cleanup();
|
|
290
|
+
}
|
|
291
|
+
},
|
|
292
|
+
},
|
|
293
|
+
|
|
294
|
+
{
|
|
295
|
+
name: 'a-record-with-no-root-pid-is-not-a-kill-order',
|
|
296
|
+
async run({ assert }) {
|
|
297
|
+
// Staleness is proved by the ROOT, and a record that never named one
|
|
298
|
+
// proves nothing. Read as "no root answering", a rootPid-less record
|
|
299
|
+
// over a LIVE stack of this very project reads as pure leftovers — and
|
|
300
|
+
// the reap takes the running firebase parent and its jars with it.
|
|
301
|
+
const { command, cleanup } = commandWithRecord({ pids: [4001, 4002, 4003], rootPid: undefined });
|
|
302
|
+
const table = processTable({
|
|
303
|
+
4001: { ppid: 3999, command: FIREBASE_PARENT },
|
|
304
|
+
4002: { ppid: 4001, command: FIRESTORE_JAR },
|
|
305
|
+
4003: { ppid: 4001, command: PUBSUB_JAR },
|
|
306
|
+
});
|
|
307
|
+
|
|
308
|
+
try {
|
|
309
|
+
await command.reapStaleRecordedProcesses(command.readEmulatorOwnership(), table.seams);
|
|
310
|
+
|
|
311
|
+
assert.deepEqual(table.signals, [], 'a record with no root pid supports no kill order');
|
|
312
|
+
} finally {
|
|
313
|
+
cleanup();
|
|
314
|
+
}
|
|
315
|
+
},
|
|
316
|
+
},
|
|
317
|
+
|
|
318
|
+
{
|
|
319
|
+
name: 'an-expired-record-names-nobody',
|
|
320
|
+
async run({ assert }) {
|
|
321
|
+
// Past the record's age bound the numbers are no longer known to name
|
|
322
|
+
// the processes they named, so the record supports no pid at all — the
|
|
323
|
+
// same rule every other path reads it by.
|
|
324
|
+
const { command, cleanup } = commandWithRecord({ pids: [4001, 4002], rootPid: 4001, startedAt: EXPIRED_AT });
|
|
325
|
+
const table = processTable({ 4002: { ppid: ORPHANED, command: FIRESTORE_JAR } });
|
|
326
|
+
|
|
327
|
+
try {
|
|
328
|
+
await command.reapStaleRecordedProcesses(command.readEmulatorOwnership(), table.seams);
|
|
329
|
+
|
|
330
|
+
assert.deepEqual(table.signals, [], 'an expired record is not a kill order');
|
|
331
|
+
} finally {
|
|
332
|
+
cleanup();
|
|
333
|
+
}
|
|
334
|
+
},
|
|
335
|
+
},
|
|
336
|
+
|
|
337
|
+
{
|
|
338
|
+
name: 'sigkill-escalates-only-while-the-identity-still-holds',
|
|
339
|
+
async run({ assert }) {
|
|
340
|
+
// The grace window is long enough for a pid to be freed and handed out
|
|
341
|
+
// again, and there is no apologising to a SIGKILL. 4002 takes the
|
|
342
|
+
// SIGTERM and the number comes back as a stranger; 4003 is still the
|
|
343
|
+
// jar it was, and gets the escalation.
|
|
344
|
+
const { command, lines, cleanup } = commandWithRecord({ pids: [4001, 4002, 4003], rootPid: 4001 });
|
|
345
|
+
const table = processTable(
|
|
346
|
+
{ 4002: { ppid: ORPHANED, command: PUBSUB_JAR }, 4003: { ppid: ORPHANED, command: FIRESTORE_JAR } },
|
|
347
|
+
(pid, live) => live.set(pid, pid === 4002 ? { ppid: ORPHANED, command: STRANGER } : live.get(pid)),
|
|
348
|
+
);
|
|
349
|
+
|
|
350
|
+
try {
|
|
351
|
+
await command.reapStaleRecordedProcesses(command.readEmulatorOwnership(), table.seams);
|
|
352
|
+
|
|
353
|
+
assert.deepEqual(table.signalled(4002), ['SIGTERM'], 'a number recycled inside the grace window is not SIGKILLed');
|
|
354
|
+
assert.deepEqual(table.signalled(4003), ['SIGTERM', 'SIGKILL'], 'a survivor that is still ours is taken');
|
|
355
|
+
// The count is what went DOWN, not what was ordered down: 4002 is
|
|
356
|
+
// spared here, so reporting it reaped would contradict the very next
|
|
357
|
+
// line of output.
|
|
358
|
+
assert.match(lines.join('\n'), /Reaped 1 recorded process left by a previous run \(1 needed SIGKILL\)/);
|
|
359
|
+
assert.match(lines.join('\n'), /Left 1 recorded pid alone/);
|
|
360
|
+
} finally {
|
|
361
|
+
cleanup();
|
|
362
|
+
}
|
|
363
|
+
},
|
|
364
|
+
},
|
|
365
|
+
|
|
366
|
+
{
|
|
367
|
+
name: 'a-recycled-pid-on-a-live-stacks-no-project-jar-is-left-alone',
|
|
368
|
+
async run({ assert }) {
|
|
369
|
+
// The residual the project-id proof cannot reach: the pubsub emulator
|
|
370
|
+
// names no project at all, so a recycled number running the NEIGHBOUR
|
|
371
|
+
// brand's LIVE pubsub jar reads as our own leftover on record
|
|
372
|
+
// membership alone. Its PARENT is the thing that disagrees — that jar
|
|
373
|
+
// hangs off a firebase this record has never heard of, while every
|
|
374
|
+
// survivor of the dead run is an orphan
|
|
375
|
+
// ([#730](https://github.com/Omega-JS-Stack/omega/issues/730)).
|
|
376
|
+
const { command, lines, cleanup } = commandWithRecord({ pids: [4001, 4002], rootPid: 4001 });
|
|
377
|
+
const table = processTable({ 4002: { ppid: ANOTHER_STACKS_FIREBASE, command: PUBSUB_JAR } });
|
|
378
|
+
|
|
379
|
+
try {
|
|
380
|
+
await command.reapStaleRecordedProcesses(command.readEmulatorOwnership(), table.seams);
|
|
381
|
+
|
|
382
|
+
assert.deepEqual(table.signals, [], "another brand's live jar must survive our recorded number, project id or not");
|
|
383
|
+
assert.match(lines.join('\n'), /Left 1 recorded pid alone/);
|
|
384
|
+
} finally {
|
|
385
|
+
cleanup();
|
|
386
|
+
}
|
|
387
|
+
},
|
|
388
|
+
},
|
|
389
|
+
|
|
390
|
+
{
|
|
391
|
+
name: 'a-jar-still-hanging-off-the-dead-run-is-reaped',
|
|
392
|
+
async run({ assert }) {
|
|
393
|
+
// The other half of the parent proof, so it cannot narrow to "orphans
|
|
394
|
+
// only": the `sh` root is gone but the firebase it spawned outlived it,
|
|
395
|
+
// and the jars still hang off THAT — a pid this very record names. The
|
|
396
|
+
// whole tree is the dead run's, and all of it is reapable.
|
|
397
|
+
const { command, cleanup } = commandWithRecord({ pids: [4001, 4002, 4003], rootPid: 4001 });
|
|
398
|
+
const table = processTable({
|
|
399
|
+
4002: { ppid: ORPHANED, command: FIREBASE_PARENT },
|
|
400
|
+
4003: { ppid: 4002, command: FIRESTORE_JAR },
|
|
401
|
+
});
|
|
402
|
+
|
|
403
|
+
try {
|
|
404
|
+
await command.reapStaleRecordedProcesses(command.readEmulatorOwnership(), table.seams);
|
|
405
|
+
|
|
406
|
+
assert.deepEqual(table.signalled(4002), ['SIGTERM'], "the dead run's own firebase parent is reaped");
|
|
407
|
+
assert.deepEqual(table.signalled(4003), ['SIGTERM'], 'and so is the jar still parented to it');
|
|
408
|
+
} finally {
|
|
409
|
+
cleanup();
|
|
410
|
+
}
|
|
411
|
+
},
|
|
412
|
+
},
|
|
413
|
+
|
|
414
|
+
{
|
|
415
|
+
name: 'a-reap-waits-for-the-recorded-ports-to-come-back',
|
|
416
|
+
async run({ assert }) {
|
|
417
|
+
// A SIGKILLed JVM holds its listener for a moment after kill() returns
|
|
418
|
+
// and the allocator probes these very ports a few lines later — the
|
|
419
|
+
// same race the port-driven reaper answers. A reap here is BY PID, so
|
|
420
|
+
// the record's own map is the set to wait on. `https` is not part of
|
|
421
|
+
// it: that port belonged to the dead run's in-process TLS proxy, never
|
|
422
|
+
// to a jar this reap could take.
|
|
423
|
+
const { command, cleanup } = commandWithRecord({
|
|
424
|
+
pids: [4001, 4002],
|
|
425
|
+
rootPid: 4001,
|
|
426
|
+
ports: { firestore: 8080, hosting: 5443, https: 5002 },
|
|
427
|
+
});
|
|
428
|
+
const table = processTable({ 4002: { ppid: ORPHANED, command: FIRESTORE_JAR } });
|
|
429
|
+
|
|
430
|
+
try {
|
|
431
|
+
await command.reapStaleRecordedProcesses(command.readEmulatorOwnership(), table.seams);
|
|
432
|
+
|
|
433
|
+
assert.deepEqual(table.signalled(4002), ['SIGTERM'], 'the recorded jar goes down');
|
|
434
|
+
assert.deepEqual([...new Set(table.probed)].sort(), [5443, 8080], "the reaped record's ports are waited on, https excluded");
|
|
435
|
+
} finally {
|
|
436
|
+
cleanup();
|
|
437
|
+
}
|
|
438
|
+
},
|
|
439
|
+
},
|
|
440
|
+
|
|
441
|
+
{
|
|
442
|
+
name: 'a-reap-that-took-nothing-waits-for-nothing',
|
|
443
|
+
async run({ assert }) {
|
|
444
|
+
// The wait is the price of a kill, not of a boot: a record that proved
|
|
445
|
+
// nothing reapable freed no port, so the allocator is not held up.
|
|
446
|
+
const { command, cleanup } = commandWithRecord({
|
|
447
|
+
pids: [4001, 4002],
|
|
448
|
+
rootPid: 4001,
|
|
449
|
+
ports: { firestore: 8080 },
|
|
450
|
+
});
|
|
451
|
+
const table = processTable({ 4002: { ppid: ORPHANED, command: STRANGER } });
|
|
452
|
+
|
|
453
|
+
try {
|
|
454
|
+
await command.reapStaleRecordedProcesses(command.readEmulatorOwnership(), table.seams);
|
|
455
|
+
|
|
456
|
+
assert.deepEqual(table.probed, [], 'nothing was reaped, so no port is waited on');
|
|
457
|
+
} finally {
|
|
458
|
+
cleanup();
|
|
459
|
+
}
|
|
460
|
+
},
|
|
461
|
+
},
|
|
462
|
+
|
|
463
|
+
{
|
|
464
|
+
name: 'the-boot-path-reaps-the-stale-record-before-it-overwrites-it',
|
|
465
|
+
async run({ assert }) {
|
|
466
|
+
// Nothing else in this suite executes the CALL, so deleting the line in
|
|
467
|
+
// startEmulators left every case green. This one drives the real boot
|
|
468
|
+
// path: the reap runs, it is handed the PREVIOUS record (the file this
|
|
469
|
+
// boot is about to replace), and the replacement happens after
|
|
470
|
+
// ([#730](https://github.com/Omega-JS-Stack/omega/issues/730)).
|
|
471
|
+
const { projectDir, cleanup } = makeProject();
|
|
472
|
+
const table = processTable({ 4002: { ppid: ORPHANED, command: NODEMON_WATCHER } });
|
|
473
|
+
const order = [];
|
|
474
|
+
const spawned = [];
|
|
475
|
+
const portEnv = Object.keys(process.env).filter((key) => /^OMEGA_.*_PORT$/.test(key));
|
|
476
|
+
const priorEnv = Object.fromEntries(portEnv.map((key) => [key, process.env[key]]));
|
|
477
|
+
let child = null;
|
|
478
|
+
|
|
479
|
+
// The one thing this boot may never do is spawn a real emulator: the
|
|
480
|
+
// fixture stands in for `spawn` itself, for as long as the boot runs.
|
|
481
|
+
const fixtureSpawn = (file, args) => {
|
|
482
|
+
spawned.push({ file, args });
|
|
483
|
+
child = fixtureChild();
|
|
484
|
+
// Emitted once the boot has attached its readiness handlers.
|
|
485
|
+
setImmediate(() => child.stdout.emit('data', Buffer.from('[fixture] All emulators ready\n')));
|
|
486
|
+
return child;
|
|
487
|
+
};
|
|
488
|
+
|
|
489
|
+
const command = new EmulatorCommand({ firebaseProjectPath: projectDir, argv: { https: false, seed: false }, options: {} });
|
|
490
|
+
const reap = EmulatorCommand.prototype.reapStaleRecordedProcesses;
|
|
491
|
+
|
|
492
|
+
command.log = () => {};
|
|
493
|
+
command.logWarning = () => {};
|
|
494
|
+
command.ensureStaged = () => {};
|
|
495
|
+
command.startStageWatch = () => ({ close: () => {} });
|
|
496
|
+
// The machine-wide sweep and the port preflight both signal REAL pids
|
|
497
|
+
// on REAL ports — never run them from a test. This case is about the
|
|
498
|
+
// record-driven reap beside them.
|
|
499
|
+
command.reapMachineOrphans = async () => {};
|
|
500
|
+
command.preflightEmulatorPorts = async () => [];
|
|
501
|
+
command.reapStaleRecordedProcesses = function (ownership) {
|
|
502
|
+
order.push('reap');
|
|
503
|
+
return reap.call(this, ownership, table.seams);
|
|
504
|
+
};
|
|
505
|
+
command.writeEmulatorPidRecord = () => { order.push('record'); return []; };
|
|
506
|
+
|
|
507
|
+
jetpack.write(path.join(projectDir, '.temp', 'emulator-pids.json'), {
|
|
508
|
+
pids: [4001, 4002],
|
|
509
|
+
projectId: OURS,
|
|
510
|
+
rootPid: 4001,
|
|
511
|
+
ports: {},
|
|
512
|
+
startedAt: new Date().toISOString(),
|
|
513
|
+
});
|
|
514
|
+
|
|
515
|
+
try {
|
|
516
|
+
await withSpawn(fixtureSpawn, () => command.startEmulators({ https: false }));
|
|
517
|
+
|
|
518
|
+
assert.equal(spawned.length, 1, 'the boot spawned exactly one child — the fixture, never a real emulator');
|
|
519
|
+
assert.deepEqual(order, ['reap', 'record'], 'the stale record is reaped BEFORE this boot overwrites it');
|
|
520
|
+
assert.deepEqual(table.signalled(4002), ['SIGTERM'], "the previous run's watcher is stopped by the boot path itself");
|
|
521
|
+
} finally {
|
|
522
|
+
// The child's close handler owns the log sink's timer.
|
|
523
|
+
if (child) child.emit('close', 0, null);
|
|
524
|
+
for (const key of Object.keys(process.env)) {
|
|
525
|
+
if (/^OMEGA_.*_PORT$/.test(key) && !(key in priorEnv)) delete process.env[key];
|
|
526
|
+
}
|
|
527
|
+
Object.assign(process.env, priorEnv);
|
|
528
|
+
cleanup();
|
|
529
|
+
}
|
|
530
|
+
},
|
|
531
|
+
},
|
|
532
|
+
|
|
533
|
+
// The read primitive itself (#730 review): `ps` exiting 1 is the one
|
|
534
|
+
// provable "gone". Any OTHER failure proves nothing — and it must come back
|
|
535
|
+
// TRUTHY, because the root gate turns a falsy root read into a kill order
|
|
536
|
+
// over the whole record. The sentinel also matches no identity proof, so a
|
|
537
|
+
// member read spares the pid instead of signalling on a guess.
|
|
538
|
+
{
|
|
539
|
+
name: 'an-unreadable-ps-reads-as-alive-never-as-gone',
|
|
540
|
+
async run({ assert }) {
|
|
541
|
+
const realExecSync = childProcess.execSync;
|
|
542
|
+
|
|
543
|
+
try {
|
|
544
|
+
childProcess.execSync = () => {
|
|
545
|
+
const gone = new Error('ps: no such process');
|
|
546
|
+
gone.status = 1;
|
|
547
|
+
throw gone;
|
|
548
|
+
};
|
|
549
|
+
assert.equal(
|
|
550
|
+
EmulatorCommand.readProcessInfo(4001),
|
|
551
|
+
null,
|
|
552
|
+
'ps exiting 1 is the provable answer: the pid is gone',
|
|
553
|
+
);
|
|
554
|
+
|
|
555
|
+
childProcess.execSync = () => {
|
|
556
|
+
throw new Error('spawn ps EAGAIN');
|
|
557
|
+
};
|
|
558
|
+
const unreadable = EmulatorCommand.readProcessInfo(4001);
|
|
559
|
+
|
|
560
|
+
assert.ok(unreadable, 'an exec failure is NOT proof of death — the root gate must read it as alive');
|
|
561
|
+
assert.ok(
|
|
562
|
+
!EmulatorCommand.isReapableRecordedProcess(
|
|
563
|
+
{ pid: 4001, ppid: unreadable.ppid, command: unreadable.command },
|
|
564
|
+
{ pids: [4001, 4002], rootPid: 4001, projectId: OURS },
|
|
565
|
+
),
|
|
566
|
+
'the sentinel proves no identity, so a member read spares the pid',
|
|
567
|
+
);
|
|
568
|
+
} finally {
|
|
569
|
+
childProcess.execSync = realExecSync;
|
|
570
|
+
}
|
|
571
|
+
},
|
|
572
|
+
},
|
|
573
|
+
],
|
|
574
|
+
});
|