@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,139 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Canonical top-level key order for brand omega.json5 files — "omega
|
|
3
|
+
* reorders the keys so the order is consistent" (Ian), with comments
|
|
4
|
+
* traveling alongside their keys. Applied on every config writeback and
|
|
5
|
+
* exposed standalone.
|
|
6
|
+
*
|
|
7
|
+
* The order is the legacy omega-manager brand-config order extended with
|
|
8
|
+
* the new-world sections. Unknown keys keep their relative order after the
|
|
9
|
+
* known ones. Only the TOP level is ordered — nested layout stays exactly
|
|
10
|
+
* as authored.
|
|
11
|
+
*
|
|
12
|
+
* Loss-proof by construction: the root object's inner region is cut into
|
|
13
|
+
* contiguous TILES, one per top-level entry — each tile runs from the end
|
|
14
|
+
* of the previous entry's last line to the end of its own last line, so
|
|
15
|
+
* leading comment blocks, blank lines, and same-line trailing comments all
|
|
16
|
+
* belong to exactly one tile. Reordering permutes whole tiles and never
|
|
17
|
+
* synthesizes text (beyond trailing commas, which JSON5 allows everywhere).
|
|
18
|
+
* The result must JSON5-parse to data deep-equal to the input or this
|
|
19
|
+
* throws and the caller writes nothing.
|
|
20
|
+
*/
|
|
21
|
+
const { isDeepStrictEqual } = require('node:util');
|
|
22
|
+
const JSON5 = require('json5');
|
|
23
|
+
|
|
24
|
+
const { parseRoot } = require('./edit.js');
|
|
25
|
+
|
|
26
|
+
// `targets` goes LAST (Ian 2026-07-14) — it's the per-target override layer,
|
|
27
|
+
// so it reads best after every shared section it can override.
|
|
28
|
+
// The de-branding rekey (#23) collapsed several vendor-named top-level keys
|
|
29
|
+
// into role-shaped homes — `repo`, `edge`, `captcha`, `search`, `forms`,
|
|
30
|
+
// `inbound` — and folded `firebase`/`gcp` into `cloud`. Only the TOP level is
|
|
31
|
+
// ordered, so each fold is one entry here; the nesting under it is authored.
|
|
32
|
+
// Every SHARED_SCHEMA top-level key belongs here — the drift guard in
|
|
33
|
+
// test/order.test.js fails the moment the schema grows one this list misses
|
|
34
|
+
// (#503: socials, github, directory, ports, client had drifted out), and its
|
|
35
|
+
// REVERSE guard fails on a key that is neither schema-known nor a named
|
|
36
|
+
// manager-owned block (#484 retired `testing`: no schema rule, and the testing
|
|
37
|
+
// service reads no config at all, so converters were carrying a dead key).
|
|
38
|
+
const CANONICAL_TOP_LEVEL_ORDER = [
|
|
39
|
+
'enabled', 'parent', 'brand', 'url', 'company', 'socials', 'account', 'local', 'ports',
|
|
40
|
+
'repo', 'github', 'domain',
|
|
41
|
+
'edge', 'cloud', 'captcha', 'analytics',
|
|
42
|
+
'monitoring', 'advertising', 'features', 'payment', 'connections', 'sponsorships',
|
|
43
|
+
'marketing', 'blog', 'devlog', 'reviews', 'seo', 'search',
|
|
44
|
+
'dataRequest', 'forms', 'inbound',
|
|
45
|
+
'server', 'assets', 'directory',
|
|
46
|
+
'certificates', 'theme', 'ai', 'translation', 'client', 'migrations', 'targets',
|
|
47
|
+
];
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Reorder a brand omega.json5 source's top-level keys into canonical order,
|
|
51
|
+
* comments riding with their keys. Returns the source unchanged when there
|
|
52
|
+
* is nothing to reorder (or when the file's shape rules out safe tiling —
|
|
53
|
+
* multiple entries on one line).
|
|
54
|
+
*
|
|
55
|
+
* @param {string} source - omega.json5 text (must parse).
|
|
56
|
+
* @returns {string} Reordered source with identical data.
|
|
57
|
+
*/
|
|
58
|
+
function applyCanonicalOrder(source) {
|
|
59
|
+
const original = JSON5.parse(source);
|
|
60
|
+
|
|
61
|
+
// Every entry needs a trailing comma before tiles can be permuted — the
|
|
62
|
+
// original last entry may lack one and would break mid-file. Insert from
|
|
63
|
+
// the end so offsets stay valid, then re-parse.
|
|
64
|
+
let text = source;
|
|
65
|
+
const scan = parseRoot(text);
|
|
66
|
+
if (scan.entries.length < 2) {
|
|
67
|
+
return source;
|
|
68
|
+
}
|
|
69
|
+
const missingCommas = scan.entries
|
|
70
|
+
.filter((entry) => !entry.hasComma)
|
|
71
|
+
.sort((a, b) => b.valueNode.end - a.valueNode.end);
|
|
72
|
+
for (const entry of missingCommas) {
|
|
73
|
+
text = `${text.slice(0, entry.valueNode.end)},${text.slice(entry.valueNode.end)}`;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const root = parseRoot(text);
|
|
77
|
+
|
|
78
|
+
// Prefix: everything through the end of the line the '{' sits on
|
|
79
|
+
const firstNewline = text.indexOf('\n', root.start);
|
|
80
|
+
if (firstNewline === -1) {
|
|
81
|
+
return source; // single-line root — nothing to tile
|
|
82
|
+
}
|
|
83
|
+
const prefixEnd = firstNewline + 1;
|
|
84
|
+
|
|
85
|
+
const lineEndAfter = (pos) => {
|
|
86
|
+
const nl = text.indexOf('\n', pos);
|
|
87
|
+
return nl === -1 ? pos : nl + 1;
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
const tiles = [];
|
|
91
|
+
let cursor = prefixEnd;
|
|
92
|
+
for (const entry of root.entries) {
|
|
93
|
+
const end = lineEndAfter(entry.commaEnd);
|
|
94
|
+
if (end <= cursor) {
|
|
95
|
+
return source; // two entries share a line — tiling would tear it
|
|
96
|
+
}
|
|
97
|
+
tiles.push({ key: entry.key, text: text.slice(cursor, end) });
|
|
98
|
+
cursor = end;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// Tail: anything between the last entry's line and the closing brace's
|
|
102
|
+
// line (detached trailing comments) stays where it is
|
|
103
|
+
const braceLineStart = text.lastIndexOf('\n', root.closeStart - 1) + 1;
|
|
104
|
+
const tail = text.slice(cursor, Math.max(cursor, braceLineStart));
|
|
105
|
+
|
|
106
|
+
const rank = (key) => {
|
|
107
|
+
// `targets` is last by POLICY — even unknown keys (which rank after the
|
|
108
|
+
// known ones, relative order kept) never sort past it.
|
|
109
|
+
if (key === 'targets') {
|
|
110
|
+
return Number.MAX_SAFE_INTEGER;
|
|
111
|
+
}
|
|
112
|
+
const index = CANONICAL_TOP_LEVEL_ORDER.indexOf(key);
|
|
113
|
+
return index === -1 ? CANONICAL_TOP_LEVEL_ORDER.length : index;
|
|
114
|
+
};
|
|
115
|
+
const ordered = [...tiles].sort((a, b) => rank(a.key) - rank(b.key));
|
|
116
|
+
|
|
117
|
+
if (ordered.every((tile, index) => tile === tiles[index]) && text === source) {
|
|
118
|
+
return source; // already canonical, nothing inserted
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
const result = text.slice(0, prefixEnd)
|
|
122
|
+
+ ordered.map((tile) => tile.text).join('')
|
|
123
|
+
+ tail
|
|
124
|
+
+ text.slice(Math.max(cursor, braceLineStart));
|
|
125
|
+
|
|
126
|
+
let parsed;
|
|
127
|
+
try {
|
|
128
|
+
parsed = JSON5.parse(result);
|
|
129
|
+
} catch (e) {
|
|
130
|
+
throw new Error(`Canonical reorder produced unparseable output — nothing written: ${e.message}`);
|
|
131
|
+
}
|
|
132
|
+
if (!isDeepStrictEqual(parsed, original)) {
|
|
133
|
+
throw new Error('Canonical reorder changed the config data — nothing written');
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
return result;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
module.exports = { applyCanonicalOrder, CANONICAL_TOP_LEVEL_ORDER };
|
|
@@ -0,0 +1,374 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Port auto-allocation (N7) — classic defaults, probe at boot, bump-if-taken.
|
|
3
|
+
*
|
|
4
|
+
* The allocator is boot-time only: when the classic defaults are free (the
|
|
5
|
+
* single-brand case) resolution returns them untouched and dev behaves
|
|
6
|
+
* exactly as it always has. When a port is taken (a second brand's stack is
|
|
7
|
+
* up), that port bumps +1 until free — per port, with a shared claimed-set so
|
|
8
|
+
* two names never land on the same number.
|
|
9
|
+
*
|
|
10
|
+
* The RESOLVED map publishes two ways (the CLI that booted the stack owns
|
|
11
|
+
* both): a ports file (`<projectDir>/.temp/ports.json`, pid-stamped, deleted
|
|
12
|
+
* on clean shutdown) for sibling processes of the same brand, and
|
|
13
|
+
* `OMEGA_<NAME>_PORT` env vars injected into spawned children for URL
|
|
14
|
+
* getters. Browser code receives `dev.ports` via the injected dev config —
|
|
15
|
+
* it can read neither env nor files.
|
|
16
|
+
*
|
|
17
|
+
* A port is not always the whole fact: the website's dev ORIGIN carries a
|
|
18
|
+
* protocol too (mkcert HTTPS by default), and a sibling reading `website:
|
|
19
|
+
* 4000` cannot guess it. The publisher writes the resolved origin string
|
|
20
|
+
* beside the map in the same file, and `readSiblingOrigin` reads it back
|
|
21
|
+
* ([#262](https://github.com/Omega-JS-Stack/omega/issues/262)).
|
|
22
|
+
*
|
|
23
|
+
* Under local HTTPS the map carries two hosting entries: `https` is the
|
|
24
|
+
* public origin (the mkcert proxy) and `hosting` is the proxy's INTERNAL
|
|
25
|
+
* plain-http port. A consumer process targets `https`, never `hosting`
|
|
26
|
+
* ([#795](https://github.com/Omega-JS-Stack/omega/issues/795)).
|
|
27
|
+
*
|
|
28
|
+
* Explicit pins (config `ports` section) never bump: a pinned port that is
|
|
29
|
+
* busy is a hard error naming the pin, because the user asked for exactly
|
|
30
|
+
* that port.
|
|
31
|
+
*/
|
|
32
|
+
|
|
33
|
+
const fs = require('fs');
|
|
34
|
+
const net = require('net');
|
|
35
|
+
const path = require('path');
|
|
36
|
+
const { findBrandRoot } = require('./load.js');
|
|
37
|
+
|
|
38
|
+
// The classic defaults every framework has always used — allocation starts
|
|
39
|
+
// here, and single-brand dev never leaves them.
|
|
40
|
+
const CLASSIC_PORTS = {
|
|
41
|
+
auth: 9099,
|
|
42
|
+
functions: 5001,
|
|
43
|
+
firestore: 8080,
|
|
44
|
+
database: 9000,
|
|
45
|
+
hosting: 5002,
|
|
46
|
+
storage: 9199,
|
|
47
|
+
pubsub: 8085,
|
|
48
|
+
ui: 4050,
|
|
49
|
+
website: 4000,
|
|
50
|
+
livereload: 35729,
|
|
51
|
+
cdp: 9222,
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
const PORTS_FILE = 'ports.json';
|
|
55
|
+
|
|
56
|
+
// The dev website origin every surface assumes when no live website published
|
|
57
|
+
// one — the classic port, over the protocol `omega dev` speaks by default (the
|
|
58
|
+
// mkcert proxy). An assumption, and every fallback says so out loud (#262).
|
|
59
|
+
const CLASSIC_DEV_ORIGIN = `https://localhost:${CLASSIC_PORTS.website}`;
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Attempt one bind (the probe primitive). On macOS/BSD, wildcard and
|
|
63
|
+
* specific-address listeners COEXIST on the same port — so no single bind
|
|
64
|
+
* can see every listener; isPortFree composes four.
|
|
65
|
+
* @param {object} listenOptions - net listen options ({ port } = wildcard).
|
|
66
|
+
* @param {boolean} [ignoreMissingFamily] - Treat address-family-unavailable
|
|
67
|
+
* errors (no IPv6 on this host) as free rather than busy.
|
|
68
|
+
* @returns {Promise<boolean>} True when the bind succeeded.
|
|
69
|
+
*/
|
|
70
|
+
function bindProbe(listenOptions, ignoreMissingFamily = false) {
|
|
71
|
+
return new Promise((resolve) => {
|
|
72
|
+
const server = net.createServer();
|
|
73
|
+
server.once('error', (error) => {
|
|
74
|
+
if (ignoreMissingFamily && ['EADDRNOTAVAIL', 'EAFNOSUPPORT', 'EINVAL'].includes(error.code)) {
|
|
75
|
+
return resolve(true);
|
|
76
|
+
}
|
|
77
|
+
resolve(false);
|
|
78
|
+
});
|
|
79
|
+
server.listen(listenOptions, () => {
|
|
80
|
+
server.close(() => resolve(true));
|
|
81
|
+
});
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Is this port free for a dev server to take? Bind-probe, not connect-probe
|
|
87
|
+
* — and FOUR binds, because on macOS/BSD specific-address and wildcard
|
|
88
|
+
* listeners coexist per port, and so do the two wildcard families: a
|
|
89
|
+
* 127.0.0.1 probe misses an IPv6-wildcard listener (`*:port`), a wildcard
|
|
90
|
+
* probe misses a 127.0.0.1-specific one, a `localhost` server can sit on ::1
|
|
91
|
+
* alone, and the bare-`{ port }` bind lands on the IPv6 wildcard `::`, which
|
|
92
|
+
* coexists with a foreign `0.0.0.0` holder (Docker, `nc -l`, any
|
|
93
|
+
* non-loopback dev server). Free means all of 127.0.0.1, ::1 (when the host
|
|
94
|
+
* has IPv6), 0.0.0.0, and the `::` wildcard bind succeed — matching what
|
|
95
|
+
* firebase-tools' own connect-probe will conclude at boot.
|
|
96
|
+
* @param {number} port - Port to probe.
|
|
97
|
+
* @returns {Promise<boolean>} True when the port is free.
|
|
98
|
+
*/
|
|
99
|
+
async function isPortFree(port) {
|
|
100
|
+
return (await bindProbe({ port, host: '127.0.0.1' }))
|
|
101
|
+
&& (await bindProbe({ port, host: '::1' }, true))
|
|
102
|
+
&& (await bindProbe({ port, host: '0.0.0.0' }))
|
|
103
|
+
&& (await bindProbe({ port }));
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Resolve a port map: each wanted port keeps its value when free, bumps +1
|
|
108
|
+
* until free when taken. Pinned ports (explicit config) never bump — busy
|
|
109
|
+
* pin throws.
|
|
110
|
+
*
|
|
111
|
+
* @param {object} options
|
|
112
|
+
* @param {object} options.wanted - Name → desired port (usually the classic
|
|
113
|
+
* defaults or a brand's firebase.json values).
|
|
114
|
+
* @param {object} [options.pins] - Name → explicitly-configured port (config
|
|
115
|
+
* `ports` section). Pinned names use the pin verbatim; busy → throw.
|
|
116
|
+
* @param {Set<number>} [options.claimed] - Ports already claimed in this
|
|
117
|
+
* process run (shared across resolvePorts calls for multi-family boots).
|
|
118
|
+
* @returns {Promise<{ ports: object, bumped: string[] }>} Resolved map + the
|
|
119
|
+
* names that moved off their wanted value.
|
|
120
|
+
*/
|
|
121
|
+
async function resolvePorts({ wanted, pins = {}, claimed = new Set() }) {
|
|
122
|
+
const ports = {};
|
|
123
|
+
const bumped = [];
|
|
124
|
+
|
|
125
|
+
for (const [name, wantedPort] of Object.entries(wanted)) {
|
|
126
|
+
const pin = pins[name];
|
|
127
|
+
|
|
128
|
+
if (typeof pin === 'number') {
|
|
129
|
+
if (claimed.has(pin) || !(await isPortFree(pin))) {
|
|
130
|
+
throw new Error(`Port ${pin} (pinned via config ports.${name}) is already in use — free it or change the pin`);
|
|
131
|
+
}
|
|
132
|
+
ports[name] = pin;
|
|
133
|
+
claimed.add(pin);
|
|
134
|
+
continue;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
let candidate = wantedPort;
|
|
138
|
+
while (claimed.has(candidate) || !(await isPortFree(candidate))) {
|
|
139
|
+
candidate += 1;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
if (candidate !== wantedPort) {
|
|
143
|
+
bumped.push(name);
|
|
144
|
+
}
|
|
145
|
+
ports[name] = candidate;
|
|
146
|
+
claimed.add(candidate);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
return { ports, bumped };
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* Publish the resolved map for sibling processes of the same brand.
|
|
154
|
+
* @param {string} projectDir - The project directory (owns `.temp/`).
|
|
155
|
+
* @param {object} ports - Resolved name → port map.
|
|
156
|
+
* @param {object} [facts] - Resolved non-port facts published beside the map
|
|
157
|
+
* ({ origin }, the website's resolved dev origin — protocol included).
|
|
158
|
+
* @returns {string} The file path written.
|
|
159
|
+
*/
|
|
160
|
+
function writePortsFile(projectDir, ports, facts = {}) {
|
|
161
|
+
const dir = path.join(projectDir, '.temp');
|
|
162
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
163
|
+
const file = path.join(dir, PORTS_FILE);
|
|
164
|
+
fs.writeFileSync(file, JSON.stringify({ ports, ...facts, pid: process.pid, startedAt: new Date().toISOString() }, null, 2));
|
|
165
|
+
return file;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Read a live ports file's WHOLE payload (the map plus the facts published
|
|
170
|
+
* beside it). Returns null when absent, unparseable, or stale (the writing
|
|
171
|
+
* process is no longer running).
|
|
172
|
+
* @param {string} projectDir - The project directory.
|
|
173
|
+
* @returns {object|null} The parsed payload, or null.
|
|
174
|
+
*/
|
|
175
|
+
function readPortsData(projectDir) {
|
|
176
|
+
const file = path.join(projectDir, '.temp', PORTS_FILE);
|
|
177
|
+
|
|
178
|
+
let parsed;
|
|
179
|
+
try {
|
|
180
|
+
parsed = JSON.parse(fs.readFileSync(file, 'utf8'));
|
|
181
|
+
} catch (error) {
|
|
182
|
+
return null;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
if (!parsed || typeof parsed !== 'object' || !parsed.ports) {
|
|
186
|
+
return null;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
// Stale check: the allocator deletes the file on clean shutdown, so a
|
|
190
|
+
// surviving file with a dead pid is a crash leftover — ignore it.
|
|
191
|
+
if (parsed.pid) {
|
|
192
|
+
try {
|
|
193
|
+
process.kill(parsed.pid, 0);
|
|
194
|
+
} catch (error) {
|
|
195
|
+
return null;
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
return parsed;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
/**
|
|
203
|
+
* Read a live ports file. Returns null when absent, unparseable, or stale
|
|
204
|
+
* (the writing process is no longer running).
|
|
205
|
+
* @param {string} projectDir - The project directory.
|
|
206
|
+
* @returns {object|null} The resolved name → port map, or null.
|
|
207
|
+
*/
|
|
208
|
+
function readPortsFile(projectDir) {
|
|
209
|
+
const data = readPortsData(projectDir);
|
|
210
|
+
return data ? data.ports : null;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
/**
|
|
214
|
+
* Remove the ports file (clean shutdown).
|
|
215
|
+
* @param {string} projectDir - The project directory.
|
|
216
|
+
*/
|
|
217
|
+
function clearPortsFile(projectDir) {
|
|
218
|
+
try {
|
|
219
|
+
fs.unlinkSync(path.join(projectDir, '.temp', PORTS_FILE));
|
|
220
|
+
} catch (error) {
|
|
221
|
+
// Absent is fine.
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
/**
|
|
226
|
+
* Merge the live ports files of the sibling targets in the same brand — a
|
|
227
|
+
* running backend's resolved emulator map, as the website/desktop/extension
|
|
228
|
+
* target beside it sees it. Dead-pid leftovers are ignored by readPortsFile; the
|
|
229
|
+
* caller's OWN target dir is skipped (a previous run of the same process).
|
|
230
|
+
*
|
|
231
|
+
* Read at USE time, never once at boot: the ports file is pid-stamped and
|
|
232
|
+
* deleted on shutdown, so a boot-time read races the sibling that has not
|
|
233
|
+
* booted yet and goes stale the moment an emulator restarts on new numbers
|
|
234
|
+
* ([#300](https://github.com/Omega-JS-Stack/omega/issues/300)).
|
|
235
|
+
*
|
|
236
|
+
* No brand root (standalone consumer) → empty map, and the caller falls back
|
|
237
|
+
* to the classic ports.
|
|
238
|
+
* @param {string} targetDir - The reading target's root (its own file is skipped).
|
|
239
|
+
* @returns {object} Merged name → port map.
|
|
240
|
+
*/
|
|
241
|
+
function readSiblingPorts(targetDir) {
|
|
242
|
+
const merged = {};
|
|
243
|
+
|
|
244
|
+
for (const dir of siblingTargetDirs(targetDir)) {
|
|
245
|
+
Object.assign(merged, readPortsFile(dir) || {});
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
return merged;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
/**
|
|
252
|
+
* The resolved dev WEBSITE ORIGIN a sibling target of the same brand published —
|
|
253
|
+
* protocol and port together, because a port alone cannot say whether the dev
|
|
254
|
+
* server speaks TLS (mkcert is the default) and every client that links to the
|
|
255
|
+
* website in dev needs the whole origin
|
|
256
|
+
* ([#262](https://github.com/Omega-JS-Stack/omega/issues/262)).
|
|
257
|
+
*
|
|
258
|
+
* Read at USE time like readSiblingPorts, and null when no sibling is live —
|
|
259
|
+
* the caller falls back to the classic assumption and says so.
|
|
260
|
+
* @param {string} targetDir - The reading target's root (its own file is skipped).
|
|
261
|
+
* @returns {string|null} The published origin, or null.
|
|
262
|
+
*/
|
|
263
|
+
function readSiblingOrigin(targetDir) {
|
|
264
|
+
for (const dir of siblingTargetDirs(targetDir)) {
|
|
265
|
+
const origin = readPortsData(dir)?.origin;
|
|
266
|
+
if (origin) {
|
|
267
|
+
return origin;
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
return null;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
/**
|
|
275
|
+
* The sibling target dirs of the target that asks: every `targets/<name>` of
|
|
276
|
+
* the same brand except its own. No brand root (standalone consumer) → none.
|
|
277
|
+
* @param {string} targetDir - The reading target's root.
|
|
278
|
+
* @returns {string[]} Absolute sibling target dirs.
|
|
279
|
+
*/
|
|
280
|
+
function siblingTargetDirs(targetDir) {
|
|
281
|
+
const brandRoot = findBrandRoot(targetDir);
|
|
282
|
+
if (!brandRoot) {
|
|
283
|
+
return [];
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
const targetsDir = path.join(brandRoot, 'targets');
|
|
287
|
+
const dirs = [];
|
|
288
|
+
|
|
289
|
+
for (const entry of fs.existsSync(targetsDir) ? fs.readdirSync(targetsDir, { withFileTypes: true }) : []) {
|
|
290
|
+
if (!entry.isDirectory() || entry.name.startsWith('.')) {
|
|
291
|
+
continue;
|
|
292
|
+
}
|
|
293
|
+
const dir = path.join(targetsDir, entry.name);
|
|
294
|
+
if (path.resolve(dir) === path.resolve(targetDir)) {
|
|
295
|
+
continue;
|
|
296
|
+
}
|
|
297
|
+
dirs.push(dir);
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
return dirs;
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
/**
|
|
304
|
+
* Env-var name for a port ('auth' → 'OMEGA_AUTH_PORT').
|
|
305
|
+
* @param {string} name - Port name.
|
|
306
|
+
* @returns {string} Env var name.
|
|
307
|
+
*/
|
|
308
|
+
function envName(name) {
|
|
309
|
+
return `OMEGA_${name.toUpperCase()}_PORT`;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
/**
|
|
313
|
+
* Resolved map → the OMEGA_*_PORT env block to inject into spawned children.
|
|
314
|
+
* @param {object} ports - Resolved name → port map.
|
|
315
|
+
* @returns {object} Env var name → string port.
|
|
316
|
+
*/
|
|
317
|
+
function portsToEnv(ports) {
|
|
318
|
+
const env = {};
|
|
319
|
+
for (const [name, port] of Object.entries(ports)) {
|
|
320
|
+
env[envName(name)] = String(port);
|
|
321
|
+
}
|
|
322
|
+
return env;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
/**
|
|
326
|
+
* Read a port from the environment (`OMEGA_<NAME>_PORT`).
|
|
327
|
+
* @param {string} name - Port name ('auth', 'hosting', ...).
|
|
328
|
+
* @param {object} [env] - Env object (defaults to process.env).
|
|
329
|
+
* @returns {number|null} The port, or null when unset/invalid.
|
|
330
|
+
*/
|
|
331
|
+
function envPort(name, env = process.env) {
|
|
332
|
+
const raw = env[envName(name)];
|
|
333
|
+
const port = Number.parseInt(raw, 10);
|
|
334
|
+
return Number.isInteger(port) && port > 0 ? port : null;
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
/**
|
|
338
|
+
* Every `OMEGA_<NAME>_PORT` in an environment as a resolved map — the inverse
|
|
339
|
+
* of portsToEnv, for a spawned child reading the whole map its parent
|
|
340
|
+
* injected rather than one name at a time.
|
|
341
|
+
* @param {object} [env] - Env object (defaults to process.env).
|
|
342
|
+
* @returns {object} Name → port map (lowercased names, invalid values dropped).
|
|
343
|
+
*/
|
|
344
|
+
function envPorts(env = process.env) {
|
|
345
|
+
const ports = {};
|
|
346
|
+
for (const key of Object.keys(env)) {
|
|
347
|
+
const match = /^OMEGA_([A-Z0-9]+)_PORT$/.exec(key);
|
|
348
|
+
if (!match) {
|
|
349
|
+
continue;
|
|
350
|
+
}
|
|
351
|
+
const name = match[1].toLowerCase();
|
|
352
|
+
const port = envPort(name, env);
|
|
353
|
+
if (port) {
|
|
354
|
+
ports[name] = port;
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
return ports;
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
module.exports = {
|
|
361
|
+
CLASSIC_PORTS,
|
|
362
|
+
CLASSIC_DEV_ORIGIN,
|
|
363
|
+
isPortFree,
|
|
364
|
+
resolvePorts,
|
|
365
|
+
writePortsFile,
|
|
366
|
+
readPortsFile,
|
|
367
|
+
clearPortsFile,
|
|
368
|
+
readSiblingPorts,
|
|
369
|
+
readSiblingOrigin,
|
|
370
|
+
envName,
|
|
371
|
+
portsToEnv,
|
|
372
|
+
envPort,
|
|
373
|
+
envPorts,
|
|
374
|
+
};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The `role.providers.<provider>` shape (#425) — every role names its vendors
|
|
3
|
+
* the same way, so "which provider did the brand pick?" is ONE question with
|
|
4
|
+
* one answer here instead of a hand-rolled read per service.
|
|
5
|
+
*
|
|
6
|
+
* The tri-state is unchanged, it just moved into key presence:
|
|
7
|
+
* - no `providers` block, or an empty one → nothing chosen (the role's
|
|
8
|
+
* service skips, exactly what a null `provider` used to mean)
|
|
9
|
+
* - `{ namecheap: {…} }` → chosen, with its settings
|
|
10
|
+
* - `{ namecheap: false }` → deliberately disabled
|
|
11
|
+
*
|
|
12
|
+
* Roles that can only ever have one live provider (domain's registrar,
|
|
13
|
+
* translation's engine, devlog's writer) read the chosen one through this;
|
|
14
|
+
* roles that run several at once (payment, analytics) iterate the block
|
|
15
|
+
* themselves — presence per vendor is the whole gate there.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* The chosen provider key in a `providers` block.
|
|
20
|
+
*
|
|
21
|
+
* @param {object} [providers] - A role's `providers` map
|
|
22
|
+
* @returns {string|null} - The provider name, or null when none is chosen
|
|
23
|
+
*/
|
|
24
|
+
function chosenProvider(providers) {
|
|
25
|
+
if (!providers || typeof providers !== 'object' || Array.isArray(providers)) {
|
|
26
|
+
return null;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
return Object.keys(providers).find((name) => providers[name] !== false) || null;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
module.exports = { chosenProvider };
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @omega.js/config repo — the SINGLE derivation of the brand's GitHub repo
|
|
3
|
+
* (owner + name), shared by every surface that targets the brand repo (web
|
|
4
|
+
* `omega deploy --direct`, the manager's github service setup/repo/pages,
|
|
5
|
+
* the backend CMS routes that commit posts).
|
|
6
|
+
*
|
|
7
|
+
* One optional key: `repo.providers.github.repo` (or, on a backend load, the
|
|
8
|
+
* target-overlaid `targets.backend.github.repo`, which wins) — either a bare name
|
|
9
|
+
* ("omega-brand") or an "owner/name" slug ("itw-creative-works/omega-brand").
|
|
10
|
+
* Defaults: name falls to `<brand.id>-omega`, owner falls to `repo.providers.github.org`.
|
|
11
|
+
* That name is the `<brand.id>-<role>` repo rule (Ian 2026-09-07,
|
|
12
|
+
* [#809](https://github.com/Omega-JS-Stack/omega/issues/809)): every repo a brand
|
|
13
|
+
* owns is its id plus the role it plays, `omega` for the source monorepo beside
|
|
14
|
+
* the `releases` one below, so nobody types a repo name to get the right one.
|
|
15
|
+
* The slug's owner slot carries the legacy omega-manager orgMain/orgWebsite
|
|
16
|
+
* split (Ian 2026-07-19): most ITW brands house the brand repo under the paid
|
|
17
|
+
* company org (itw-creative-works) while `repo.providers.github.org` keeps
|
|
18
|
+
* naming the brand's own org for org-profile reconciliation. The retired `repoWebsite` URL key
|
|
19
|
+
* (2026-07-19, Ian: "we no longer need it — that was for when the website
|
|
20
|
+
* lived NOT in the monorepo") is superseded by this slug: one repo per
|
|
21
|
+
* brand, named by the brand.
|
|
22
|
+
*
|
|
23
|
+
* Born from the 2026-07-18 launch-night collision: the bare brand-id
|
|
24
|
+
* fallback resolved brand "omega" to Omega-JS-Stack/omega — the framework
|
|
25
|
+
* MONOREPO — instead of the brand repo.
|
|
26
|
+
*/
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Parse a `repo.providers.github.repo` value: "owner/name" slug or bare "name".
|
|
30
|
+
*
|
|
31
|
+
* @param {string} value - e.g. "itw-creative-works/omega-brand" or "omega-brand"
|
|
32
|
+
* @returns {{ owner: string, name: string }} owner is '' for bare names.
|
|
33
|
+
*/
|
|
34
|
+
function parseRepoSlug(value) {
|
|
35
|
+
const trimmed = (value || '').trim();
|
|
36
|
+
if (!trimmed) return { owner: '', name: '' };
|
|
37
|
+
const slash = trimmed.indexOf('/');
|
|
38
|
+
if (slash === -1) return { owner: '', name: trimmed };
|
|
39
|
+
return { owner: trimmed.slice(0, slash), name: trimmed.slice(slash + 1) };
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* The github keys the derivation reads: the shared `repo.providers.github`
|
|
44
|
+
* block, overlaid by the target's own `github` entry (a backend load composes
|
|
45
|
+
* `targets.backend.github` — the CMS's content identity — onto the top level,
|
|
46
|
+
* and per the merge chain the target wins).
|
|
47
|
+
*
|
|
48
|
+
* @param {object} config - Composed omega config (brand + local layers).
|
|
49
|
+
* @returns {object} Merged `{ org, repo, … }` keys.
|
|
50
|
+
*/
|
|
51
|
+
function githubKeys(config) {
|
|
52
|
+
return { ...(config?.repo?.providers?.github || {}), ...(config?.github || {}) };
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* The brand repo's bare name (no owner): a typed slug or bare name, else the
|
|
57
|
+
* `<brand.id>-omega` default of the `<brand.id>-<role>` rule.
|
|
58
|
+
*
|
|
59
|
+
* @param {object} config - Composed omega config (brand + local layers).
|
|
60
|
+
* @returns {string} Repo name ('' when nothing in the chain resolves).
|
|
61
|
+
*/
|
|
62
|
+
function brandRepoName(config) {
|
|
63
|
+
const github = githubKeys(config);
|
|
64
|
+
// The id half is trimmed like a typed slug: the role suffix is appended to
|
|
65
|
+
// it, so untrimmed whitespace would sit INSIDE the composed name.
|
|
66
|
+
const id = (config?.brand?.id || '').trim();
|
|
67
|
+
|
|
68
|
+
return parseRepoSlug(github.repo).name
|
|
69
|
+
|| (id ? `${id}-omega` : '');
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* The brand repo's owner (GitHub org or user).
|
|
74
|
+
*
|
|
75
|
+
* @param {object} config - Composed omega config (brand + local layers).
|
|
76
|
+
* @returns {string} Owner ('' when nothing in the chain resolves).
|
|
77
|
+
*/
|
|
78
|
+
function brandRepoOwner(config) {
|
|
79
|
+
const github = githubKeys(config);
|
|
80
|
+
return parseRepoSlug(github.repo).owner || github.org || '';
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* The brand repo as ONE finished value: owner, name, and the "owner/name" slug
|
|
85
|
+
* the GitHub API takes. This is the form a FRAMEWORK hands to consumer code —
|
|
86
|
+
* @omega.js/backend exposes it as `config.resolved.github` ([#290](https://github.com/Omega-JS-Stack/omega/issues/290)),
|
|
87
|
+
* because a brand target cannot require this private package and must never
|
|
88
|
+
* re-derive the merge rules for itself.
|
|
89
|
+
*
|
|
90
|
+
* @param {object} config - Composed omega config (brand + local layers).
|
|
91
|
+
* @returns {{ owner: string, name: string, repo: string }} `repo` is the slug, '' unless BOTH halves resolve (half an address addresses nothing).
|
|
92
|
+
*/
|
|
93
|
+
function brandRepo(config) {
|
|
94
|
+
const owner = brandRepoOwner(config);
|
|
95
|
+
const name = brandRepoName(config);
|
|
96
|
+
|
|
97
|
+
return { owner, name, repo: owner && name ? `${owner}/${name}` : '' };
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* The releases keys the derivation reads: the desktop target's own `releases`
|
|
102
|
+
* block, overlaid by the top-level one a desktop-resolved config carries (the
|
|
103
|
+
* merge chain overlays `targets.desktop` onto the top level, so the overlay is
|
|
104
|
+
* the resolved value). Both shapes are live: the site global reads a raw config,
|
|
105
|
+
* where the block sits under the target, while every desktop verb reads the
|
|
106
|
+
* resolved one.
|
|
107
|
+
*
|
|
108
|
+
* @param {object} config - Composed omega config (raw or desktop-resolved).
|
|
109
|
+
* @returns {object} Merged `{ enabled, owner, repo }` keys.
|
|
110
|
+
*/
|
|
111
|
+
function releasesKeys(config) {
|
|
112
|
+
const target = config?.targets?.desktop;
|
|
113
|
+
const entry = target && typeof target === 'object' && !Array.isArray(target) ? target.releases : undefined;
|
|
114
|
+
|
|
115
|
+
return { ...(entry || {}), ...(config?.releases || {}) };
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* The brand's ONE public releases repo: where the versioned `v<x.y.z>` releases
|
|
120
|
+
* that feed electron-updater live, and where the website's versionless
|
|
121
|
+
* `/releases/latest/download/<asset>` links point ([#620](https://github.com/Omega-JS-Stack/omega/issues/620),
|
|
122
|
+
* [#799](https://github.com/Omega-JS-Stack/omega/issues/799)). One repo per
|
|
123
|
+
* brand, named after it: `<brand.id>-releases` by default, under the brand
|
|
124
|
+
* repo's own owner, so a brand that declares nothing still has an address.
|
|
125
|
+
*
|
|
126
|
+
* This is the ONE home of that rule. Every reader takes it from here (the site
|
|
127
|
+
* global's download links, @omega.js/desktop's electron-builder publish block,
|
|
128
|
+
* its release-repo provisioning, its finalize-release upload), so the feed a
|
|
129
|
+
* shipped app polls and the URL a download button carries can never disagree.
|
|
130
|
+
*
|
|
131
|
+
* @param {object} config - Composed omega config (raw or desktop-resolved).
|
|
132
|
+
* @returns {{ owner: string, name: string, repo: string }} `repo` is the slug, '' unless BOTH halves resolve (half an address addresses nothing).
|
|
133
|
+
*/
|
|
134
|
+
function releasesRepo(config) {
|
|
135
|
+
const releases = releasesKeys(config);
|
|
136
|
+
const owner = releases.owner || brandRepoOwner(config);
|
|
137
|
+
const name = releases.repo || (config?.brand?.id ? `${config.brand.id}-releases` : '');
|
|
138
|
+
|
|
139
|
+
return { owner, name, repo: owner && name ? `${owner}/${name}` : '' };
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
module.exports = { parseRepoSlug, brandRepoName, brandRepoOwner, brandRepo, releasesRepo };
|