@omega.js/manager 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/.claude-plugin/marketplace.json +14 -0
- package/LICENSE +98 -0
- package/README.md +165 -0
- package/bin/omega +2 -0
- package/bin/omg +2 -0
- package/claude-plugin/.claude-plugin/plugin.json +11 -0
- package/claude-plugin/.mcp.json +9 -0
- package/claude-plugin/README.md +139 -0
- package/claude-plugin/hooks/gate/mark.sh +58 -0
- package/claude-plugin/hooks/gate/run.sh +97 -0
- package/claude-plugin/hooks/guard/run.sh +249 -0
- package/claude-plugin/hooks/hooks.json +63 -0
- package/claude-plugin/hooks/inject/run.sh +127 -0
- package/claude-plugin/hooks/lib/omega-gate.sh +20 -0
- package/claude-plugin/hooks/lib/omega-scope.sh +41 -0
- package/claude-plugin/hooks/lib/omega-skills.sh +209 -0
- package/claude-plugin/hooks/quality/run.sh +132 -0
- package/claude-plugin/hooks/shape/run.sh +45 -0
- package/claude-plugin/mcp-router-launch.js +29 -0
- package/claude-plugin/skills/README.md +48 -0
- package/claude-plugin/skills/accessibility/SKILL.md +31 -0
- package/claude-plugin/skills/analytics/SKILL.md +30 -0
- package/claude-plugin/skills/backend/SKILL.md +25 -0
- package/claude-plugin/skills/brandcheck/SKILL.md +29 -0
- package/claude-plugin/skills/browser/SKILL.md +64 -0
- package/claude-plugin/skills/client/SKILL.md +24 -0
- package/claude-plugin/skills/desktop/SKILL.md +25 -0
- package/claude-plugin/skills/extension/SKILL.md +25 -0
- package/claude-plugin/skills/main/SKILL.md +54 -0
- package/claude-plugin/skills/manager/SKILL.md +25 -0
- package/claude-plugin/skills/seo/SKILL.md +36 -0
- package/claude-plugin/skills/theme/SKILL.md +33 -0
- package/claude-plugin/skills/web/SKILL.md +29 -0
- package/dist/cli-run.js +34 -0
- package/dist/cli.js +29 -0
- package/dist/commands/build.js +17 -0
- package/dist/commands/clean.js +16 -0
- package/dist/commands/company.js +46 -0
- package/dist/commands/deploy.js +143 -0
- package/dist/commands/dev.js +437 -0
- package/dist/commands/devlog.js +25 -0
- package/dist/commands/help.js +48 -0
- package/dist/commands/manage.js +53 -0
- package/dist/commands/migrate.js +76 -0
- package/dist/commands/onboard.js +31 -0
- package/dist/commands/pipeline.js +319 -0
- package/dist/commands/test.js +380 -0
- package/dist/commands/update.js +128 -0
- package/dist/commands/version.js +8 -0
- package/dist/company-init.js +167 -0
- package/dist/company.js +283 -0
- package/dist/config.js +1359 -0
- package/dist/devlog/index.js +226 -0
- package/dist/devlog/lib/collect-commits.js +136 -0
- package/dist/devlog/lib/generate-post.js +201 -0
- package/dist/devlog/lib/ghostii.js +122 -0
- package/dist/devlog/lib/project-map.js +98 -0
- package/dist/devlog/lib/publish-website.js +88 -0
- package/dist/index.js +45 -0
- package/dist/lib/agents-md.js +201 -0
- package/dist/lib/analytics-secret.js +22 -0
- package/dist/lib/argv.js +21 -0
- package/dist/lib/auth-admin.js +120 -0
- package/dist/lib/automation-client.js +210 -0
- package/dist/lib/backend-marketing.js +49 -0
- package/dist/lib/brand.js +240 -0
- package/dist/lib/bundle-id.js +53 -0
- package/dist/lib/claude-settings.js +125 -0
- package/dist/lib/company-scaffold.js +213 -0
- package/dist/lib/company.js +227 -0
- package/dist/lib/config-flow.js +350 -0
- package/dist/lib/config-write.js +41 -0
- package/dist/lib/custom-target.js +75 -0
- package/dist/lib/domain-utils.js +19 -0
- package/dist/lib/duration.js +39 -0
- package/dist/lib/env-order.js +236 -0
- package/dist/lib/env-secret.js +78 -0
- package/dist/lib/firestore-rest.js +326 -0
- package/dist/lib/framework-bin.js +156 -0
- package/dist/lib/gitignore.js +63 -0
- package/dist/lib/google-auth.js +495 -0
- package/dist/lib/google-token.js +66 -0
- package/dist/lib/jwt.js +31 -0
- package/dist/lib/legacy-oauth.js +59 -0
- package/dist/lib/node-version.js +127 -0
- package/dist/lib/owner-plan.js +78 -0
- package/dist/lib/package-scripts.js +152 -0
- package/dist/lib/preflight.js +470 -0
- package/dist/lib/product-create.js +144 -0
- package/dist/lib/run-command.js +74 -0
- package/dist/lib/run-gates.js +70 -0
- package/dist/lib/run-output.js +42 -0
- package/dist/lib/run-summary.js +384 -0
- package/dist/lib/scaffold.js +427 -0
- package/dist/lib/service-input.js +207 -0
- package/dist/lib/service-runner.js +466 -0
- package/dist/lib/stale.js +24 -0
- package/dist/lib/target-selection.js +155 -0
- package/dist/lib/verb-fanout.js +128 -0
- package/dist/lib/verify-live.js +188 -0
- package/dist/manage.js +311 -0
- package/dist/omega-bin.js +7 -0
- package/dist/onboard.js +532 -0
- package/dist/services/account/ensure/users.js +259 -0
- package/dist/services/account/index.js +97 -0
- package/dist/services/account/lib/backend-client.js +107 -0
- package/dist/services/account/lib/password.js +36 -0
- package/dist/services/account/lib/resolve-password.js +100 -0
- package/dist/services/advertising/ensure/sites.js +101 -0
- package/dist/services/advertising/index.js +101 -0
- package/dist/services/advertising/lib/adsense-api.js +41 -0
- package/dist/services/ai/ensure/keys.js +21 -0
- package/dist/services/ai/index.js +36 -0
- package/dist/services/analytics/ensure/google-firebase-link.js +230 -0
- package/dist/services/analytics/ensure/google-streams.js +256 -0
- package/dist/services/analytics/ensure/meta-pixel.js +22 -0
- package/dist/services/analytics/ensure/tiktok-pixel.js +22 -0
- package/dist/services/analytics/index.js +134 -0
- package/dist/services/analytics/lib/analytics-api.js +156 -0
- package/dist/services/analytics/lib/meta-api.js +83 -0
- package/dist/services/analytics/lib/pixel-account.js +78 -0
- package/dist/services/analytics/lib/pixel-provision.js +152 -0
- package/dist/services/analytics/lib/pixel-specs.js +57 -0
- package/dist/services/analytics/lib/pixel-token.js +88 -0
- package/dist/services/analytics/lib/property-flow.js +77 -0
- package/dist/services/analytics/lib/tiktok-api.js +157 -0
- package/dist/services/analytics/lib/tiktok-auth.js +153 -0
- package/dist/services/assets/ensure/logo-gen.js +68 -0
- package/dist/services/assets/index.js +109 -0
- package/dist/services/assets/lib/assets-config.js +168 -0
- package/dist/services/assets/lib/brandmark-api.js +160 -0
- package/dist/services/assets/lib/derived.js +113 -0
- package/dist/services/assets/lib/font-loader.js +67 -0
- package/dist/services/assets/lib/reconcile.js +122 -0
- package/dist/services/assets/lib/reset.js +118 -0
- package/dist/services/assets/lib/svg-logo-generator.js +154 -0
- package/dist/services/assets/lib/svg-to-black.js +32 -0
- package/dist/services/assets/write/favicons.js +82 -0
- package/dist/services/assets/write/icons.js +64 -0
- package/dist/services/assets/write/process.js +96 -0
- package/dist/services/assets/write/reconcile.js +30 -0
- package/dist/services/assets/write/social-icons.js +108 -0
- package/dist/services/assets/write/templates.js +345 -0
- package/dist/services/bookmark/ensure/sync.js +255 -0
- package/dist/services/bookmark/index.js +17 -0
- package/dist/services/campaigns/ensure/contact-person.js +40 -0
- package/dist/services/campaigns/ensure/custom-fields.js +84 -0
- package/dist/services/campaigns/ensure/domain-auth.js +92 -0
- package/dist/services/campaigns/ensure/event-webhook.js +89 -0
- package/dist/services/campaigns/ensure/link-branding.js +187 -0
- package/dist/services/campaigns/ensure/list.js +50 -0
- package/dist/services/campaigns/ensure/segments.js +109 -0
- package/dist/services/campaigns/ensure/sender-identity.js +153 -0
- package/dist/services/campaigns/ensure/unsubscribe-groups.js +116 -0
- package/dist/services/campaigns/index.js +79 -0
- package/dist/services/campaigns/lib/dns-sync.js +81 -0
- package/dist/services/campaigns/lib/segment-query.js +138 -0
- package/dist/services/campaigns/lib/sendgrid-api.js +287 -0
- package/dist/services/captcha/ensure/site-key.js +83 -0
- package/dist/services/captcha/index.js +78 -0
- package/dist/services/captcha/lib/console-url.js +45 -0
- package/dist/services/captcha/lib/recaptcha-api.js +36 -0
- package/dist/services/certificates/ensure/api-key.js +22 -0
- package/dist/services/certificates/ensure/bundle-ids.js +115 -0
- package/dist/services/certificates/ensure/certificates.js +187 -0
- package/dist/services/certificates/ensure/profiles.js +143 -0
- package/dist/services/certificates/index.js +225 -0
- package/dist/services/certificates/lib/apple-api.js +183 -0
- package/dist/services/certificates/lib/certificate-manager.js +252 -0
- package/dist/services/certificates/lib/identifier-manager.js +107 -0
- package/dist/services/certificates/lib/keychain.js +135 -0
- package/dist/services/certificates/lib/manual-walkthrough.js +165 -0
- package/dist/services/certificates/lib/profile-manager.js +115 -0
- package/dist/services/chat/data/baseline-knowledge.md +96 -0
- package/dist/services/chat/ensure/chat.js +106 -0
- package/dist/services/chat/ensure/user.js +45 -0
- package/dist/services/chat/index.js +139 -0
- package/dist/services/chat/lib/baseline-knowledge.js +137 -0
- package/dist/services/cloud/ensure/authentication.js +267 -0
- package/dist/services/cloud/ensure/billing.js +120 -0
- package/dist/services/cloud/ensure/cloud-messaging.js +105 -0
- package/dist/services/cloud/ensure/database.js +60 -0
- package/dist/services/cloud/ensure/firestore.js +79 -0
- package/dist/services/cloud/ensure/functions.js +49 -0
- package/dist/services/cloud/ensure/hosting.js +398 -0
- package/dist/services/cloud/ensure/oauth-consent.js +248 -0
- package/dist/services/cloud/ensure/project-settings.js +72 -0
- package/dist/services/cloud/ensure/sdk-config.js +95 -0
- package/dist/services/cloud/ensure/service-account.js +152 -0
- package/dist/services/cloud/ensure/services.js +103 -0
- package/dist/services/cloud/ensure/storage.js +47 -0
- package/dist/services/cloud/index.js +130 -0
- package/dist/services/cloud/lib/access-heal.js +130 -0
- package/dist/services/cloud/lib/firebase-api.js +662 -0
- package/dist/services/cloud/lib/project-flow.js +102 -0
- package/dist/services/directory/ensure/entry.js +48 -0
- package/dist/services/directory/index.js +64 -0
- package/dist/services/directory/lib/blocks.js +104 -0
- package/dist/services/disperse/index.js +45 -0
- package/dist/services/disperse/write/certs.js +117 -0
- package/dist/services/domain/ensure/nameservers.js +179 -0
- package/dist/services/domain/index.js +69 -0
- package/dist/services/domain/lib/namecheap-api.js +167 -0
- package/dist/services/domain/lib/registrars.js +46 -0
- package/dist/services/domain/lib/whitelist-walkthrough.js +76 -0
- package/dist/services/edge/ensure/cache-rules.js +105 -0
- package/dist/services/edge/ensure/dns-records.js +304 -0
- package/dist/services/edge/ensure/email-routing.js +292 -0
- package/dist/services/edge/ensure/rules-configuration.js +98 -0
- package/dist/services/edge/ensure/rules-managed-transforms.js +101 -0
- package/dist/services/edge/ensure/rules-redirect.js +107 -0
- package/dist/services/edge/ensure/rules-response-headers.js +90 -0
- package/dist/services/edge/ensure/rules-security.js +142 -0
- package/dist/services/edge/ensure/speed-scheduled-tests.js +98 -0
- package/dist/services/edge/ensure/workers.js +219 -0
- package/dist/services/edge/ensure/zone-settings.js +108 -0
- package/dist/services/edge/ensure/zone.js +183 -0
- package/dist/services/edge/index.js +73 -0
- package/dist/services/edge/lib/cloudflare-api.js +84 -0
- package/dist/services/edge/lib/dns-records-helpers.js +518 -0
- package/dist/services/edge/lib/read-cache.js +16 -0
- package/dist/services/edge/lib/ruleset-helper.js +108 -0
- package/dist/services/edge/workers/omega-api-proxy.js +43 -0
- package/dist/services/email/data/baseline-filter.md +4 -0
- package/dist/services/email/data/baseline-knowledge.md +86 -0
- package/dist/services/email/ensure/agent.js +107 -0
- package/dist/services/email/ensure/user.js +45 -0
- package/dist/services/email/index.js +138 -0
- package/dist/services/email/lib/baseline.js +82 -0
- package/dist/services/email/lib/knowledge-file.js +53 -0
- package/dist/services/forms/ensure/form.js +46 -0
- package/dist/services/forms/ensure/user.js +45 -0
- package/dist/services/forms/index.js +138 -0
- package/dist/services/migrations/ensure/notifications.js +189 -0
- package/dist/services/migrations/ensure/orders.js +34 -0
- package/dist/services/migrations/ensure/payment-provider.js +132 -0
- package/dist/services/migrations/ensure/payments-intents.js +34 -0
- package/dist/services/migrations/ensure/state-retirement.js +266 -0
- package/dist/services/migrations/ensure/targets-rename.js +124 -0
- package/dist/services/migrations/ensure/users.js +1176 -0
- package/dist/services/migrations/index.js +101 -0
- package/dist/services/migrations/lib/attribution-touch.js +64 -0
- package/dist/services/migrations/lib/ensure-metadata.js +144 -0
- package/dist/services/migrations/lib/migration-runner.js +473 -0
- package/dist/services/migrations/lib/sanitize-strings.js +112 -0
- package/dist/services/migrations/lib/schema-validator.js +154 -0
- package/dist/services/monitoring/ensure/dsn.js +54 -0
- package/dist/services/monitoring/ensure/projects.js +135 -0
- package/dist/services/monitoring/index.js +54 -0
- package/dist/services/monitoring/lib/sentry-api.js +94 -0
- package/dist/services/newsletter/ensure/custom-fields.js +90 -0
- package/dist/services/newsletter/ensure/publication.js +94 -0
- package/dist/services/newsletter/ensure/segments.js +140 -0
- package/dist/services/newsletter/ensure/webhook.js +108 -0
- package/dist/services/newsletter/index.js +64 -0
- package/dist/services/newsletter/lib/beehiiv-api.js +124 -0
- package/dist/services/newsletter/lib/segment-automation.js +577 -0
- package/dist/services/payment/ensure/chargebee-account.js +30 -0
- package/dist/services/payment/ensure/chargebee-products.js +359 -0
- package/dist/services/payment/ensure/chargebee-webhook.js +113 -0
- package/dist/services/payment/ensure/paypal-account.js +36 -0
- package/dist/services/payment/ensure/paypal-products.js +374 -0
- package/dist/services/payment/ensure/paypal-webhook.js +128 -0
- package/dist/services/payment/ensure/stripe-account.js +93 -0
- package/dist/services/payment/ensure/stripe-disputes.js +56 -0
- package/dist/services/payment/ensure/stripe-products.js +245 -0
- package/dist/services/payment/ensure/stripe-radar.js +74 -0
- package/dist/services/payment/ensure/stripe-webhook.js +130 -0
- package/dist/services/payment/index.js +163 -0
- package/dist/services/payment/lib/chargebee-api.js +338 -0
- package/dist/services/payment/lib/payment-utils.js +116 -0
- package/dist/services/payment/lib/paypal-api.js +354 -0
- package/dist/services/payment/lib/provider-setup.js +134 -0
- package/dist/services/payment/lib/stripe-api.js +152 -0
- package/dist/services/repo/ensure/org.js +70 -0
- package/dist/services/repo/ensure/pages.js +72 -0
- package/dist/services/repo/ensure/repo.js +90 -0
- package/dist/services/repo/index.js +52 -0
- package/dist/services/repo/lib/github-api.js +196 -0
- package/dist/services/search/ensure/ga-link.js +57 -0
- package/dist/services/search/ensure/property.js +137 -0
- package/dist/services/search/ensure/sitemaps.js +70 -0
- package/dist/services/search/index.js +61 -0
- package/dist/services/search/lib/search-console-api.js +92 -0
- package/dist/services/seo/ensure/github-repos.js +271 -0
- package/dist/services/seo/index.js +55 -0
- package/dist/services/seo/lib/gh-api.js +161 -0
- package/dist/services/seo/templates/developer-tool/.github/workflows/maintenance.yml +25 -0
- package/dist/services/seo/templates/developer-tool/.nvmrc +1 -0
- package/dist/services/seo/templates/developer-tool/_README.md.js +121 -0
- package/dist/services/seo/templates/developer-tool/_package.json.js +33 -0
- package/dist/services/seo/templates/developer-tool/src/index.js +120 -0
- package/dist/services/seo/templates/index.js +57 -0
- package/dist/services/server/ensure/brands.js +63 -0
- package/dist/services/server/index.js +42 -0
- package/dist/services/testing/ensure/target-checks.js +97 -0
- package/dist/services/testing/index.js +11 -0
- package/dist/services/testing/lib/checks.js +467 -0
- package/dist/services/update/index.js +20 -0
- package/dist/services/update/lib/cache.js +59 -0
- package/dist/services/update/lib/fingerprint.js +157 -0
- package/dist/services/update/write/targets.js +206 -0
- package/dist/services/workspace/ensure/agents.js +42 -0
- package/dist/services/workspace/ensure/claude-settings.js +34 -0
- package/dist/services/workspace/ensure/config.js +54 -0
- package/dist/services/workspace/ensure/defaults.js +60 -0
- package/dist/services/workspace/ensure/env-keys.js +55 -0
- package/dist/services/workspace/ensure/env-order.js +66 -0
- package/dist/services/workspace/ensure/env-rules.js +97 -0
- package/dist/services/workspace/ensure/gitignore.js +18 -0
- package/dist/services/workspace/ensure/scripts.js +126 -0
- package/dist/services/workspace/ensure/structure.js +97 -0
- package/dist/services/workspace/ensure/translation-sdk.js +148 -0
- package/dist/services/workspace/ensure/workflows.js +54 -0
- package/dist/services/workspace/index.js +8 -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/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/certs.js +199 -0
- package/dist/vendor/devkit/ci-workflows.js +520 -0
- package/dist/vendor/devkit/cli-router.js +156 -0
- package/dist/vendor/devkit/command-path.js +46 -0
- package/dist/vendor/devkit/deploy-record.js +180 -0
- package/dist/vendor/devkit/flows.js +317 -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/omega-bin.js +345 -0
- package/dist/vendor/devkit/prompt.js +187 -0
- package/dist/vendor/devkit/safe-install.js +18 -0
- package/dist/vendor/devkit/stop-signals.js +28 -0
- package/dist/vendor/devkit/test/scope.js +162 -0
- package/dist/vendor/devkit/translate/cache.js +84 -0
- package/dist/vendor/devkit/translate/engine.js +243 -0
- package/dist/vendor/devkit/translate/index.js +49 -0
- package/dist/vendor/devkit/translate/languages.js +134 -0
- package/dist/vendor/devkit/translate/providers.js +188 -0
- package/dist/vendor/devkit/update.js +569 -0
- package/docs/AGENTS.md +200 -0
- package/docs/account.md +45 -0
- package/docs/advertising.md +46 -0
- package/docs/ai.md +34 -0
- package/docs/analytics.md +69 -0
- package/docs/assets.md +57 -0
- package/docs/bookmark.md +26 -0
- package/docs/brand.md +151 -0
- package/docs/campaigns.md +96 -0
- package/docs/captcha.md +46 -0
- package/docs/certificates.md +68 -0
- package/docs/chat.md +47 -0
- package/docs/cloud.md +110 -0
- package/docs/company.md +64 -0
- package/docs/directory.md +140 -0
- package/docs/disperse.md +46 -0
- package/docs/domain.md +56 -0
- package/docs/edge.md +234 -0
- package/docs/email.md +42 -0
- package/docs/forms.md +48 -0
- package/docs/index.md +109 -0
- package/docs/migration.md +203 -0
- package/docs/migrations.md +56 -0
- package/docs/monitoring.md +41 -0
- package/docs/newsletter.md +48 -0
- package/docs/payment.md +83 -0
- package/docs/repo.md +48 -0
- package/docs/search.md +44 -0
- package/docs/seo.md +34 -0
- package/docs/server.md +37 -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/testing.md +34 -0
- package/docs/update.md +36 -0
- package/docs/workspace.md +64 -0
- package/package.json +88 -0
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Migrations service — runs migrations on the brand's Firestore collections
|
|
3
|
+
* and (`local: true` operations) on the brand's own files. Only runs when the
|
|
4
|
+
* --migration flag is set (bare = all migrations, --migration=<name> = just
|
|
5
|
+
* that one), so a normal manage run never touches collection data. Even then
|
|
6
|
+
* the run is an AUDIT: it prints what every fix WOULD do and writes nothing
|
|
7
|
+
* until `--execute`.
|
|
8
|
+
*
|
|
9
|
+
* The framework (runner, validator, snapshots) plus the two canonical
|
|
10
|
+
* @omega.js/backend-schema migrations (notifications, users) are ported from
|
|
11
|
+
* omega-manager; its other 25 registered migrations are company-instance
|
|
12
|
+
* one-offs (per-target data repairs) and stay there. firebase-admin is
|
|
13
|
+
* replaced by the shared Identity Toolkit + FirestoreREST clients over the
|
|
14
|
+
* brand's own service account. The orders and payments-intents migrations are
|
|
15
|
+
* native to OMEGA: they carry the same #384 attribution fold as users and
|
|
16
|
+
* notifications onto the two payment collections. payment-provider is native
|
|
17
|
+
* too — the #428 word rename's data half, sweeping the stored `processor`
|
|
18
|
+
* field to `provider` across all five payment-touching collections.
|
|
19
|
+
* Two are `local: true` — they work on the brand's own files, so they need
|
|
20
|
+
* neither a backend target nor a service account: state-retirement moves the
|
|
21
|
+
* retired .omega/state.json CONTENT into config + .env and leaves the file's
|
|
22
|
+
* machine records untouched (#434, #479), and targets-rename
|
|
23
|
+
* moves a pre-#443 brand's apps/ folder to targets/. The rename is also the
|
|
24
|
+
* one migration a walk never reaches on the brand it fixes (discovery fails
|
|
25
|
+
* loud on the old shape), so `--migration=targets-rename` runs it alone from
|
|
26
|
+
* runManage; here it only ever re-checks a converged brand.
|
|
27
|
+
*
|
|
28
|
+
* Add new migrations by creating handlers in ensure/ and registering them
|
|
29
|
+
* in config.js OPERATIONS.migrations.
|
|
30
|
+
*/
|
|
31
|
+
const { join } = require('node:path');
|
|
32
|
+
const jetpack = require('fs-jetpack');
|
|
33
|
+
const chalk = require('chalk').default;
|
|
34
|
+
|
|
35
|
+
const { createServiceRunner } = require('../../lib/service-runner.js');
|
|
36
|
+
const { FirestoreREST, loadServiceAccount } = require('../../lib/firestore-rest.js');
|
|
37
|
+
const { createAuthAdmin } = require('../../lib/auth-admin.js');
|
|
38
|
+
|
|
39
|
+
const SERVICE_ACCOUNT_PATH = join('.omega', 'secrets', 'service-account.json');
|
|
40
|
+
|
|
41
|
+
module.exports.run = createServiceRunner({
|
|
42
|
+
serviceDir: __dirname,
|
|
43
|
+
setup: (context) => {
|
|
44
|
+
const { options, operations } = context;
|
|
45
|
+
|
|
46
|
+
if (!options?.migration) {
|
|
47
|
+
return { skip: true, reason: '--migration flag not set' };
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// Filter to a specific migration if a name was provided (--migration=users)
|
|
51
|
+
const migrationName = typeof options.migration === 'string' ? options.migration : null;
|
|
52
|
+
const filteredOperations = migrationName
|
|
53
|
+
? operations.filter((op) => op.name === migrationName)
|
|
54
|
+
: operations;
|
|
55
|
+
|
|
56
|
+
if (migrationName && filteredOperations.length === 0) {
|
|
57
|
+
console.log(` ${chalk.yellow('⚠')} ${chalk.yellow(`Migration "${chalk.cyan(migrationName)}" not found. Available: ${chalk.cyan(operations.map((op) => op.name).join(', '))}`)}`);
|
|
58
|
+
|
|
59
|
+
return { skip: true, reason: `migration "${migrationName}" not found` };
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// Log skipped migrations
|
|
63
|
+
if (migrationName) {
|
|
64
|
+
for (const op of operations.filter((o) => o.name !== migrationName)) {
|
|
65
|
+
console.log(` ${chalk.dim(`⊘ ${op.name}: skipped (--migration=${migrationName})`)}`);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// Firestore gates apply only to the migrations that actually touch it —
|
|
70
|
+
// a `local: true` migration works on the brand's own files, so it runs on
|
|
71
|
+
// a brand with no backend at all
|
|
72
|
+
const needsFirestore = filteredOperations.some((op) => !op.local);
|
|
73
|
+
|
|
74
|
+
const targets = context.brandConfig.targets || {};
|
|
75
|
+
if (needsFirestore && !targets.backend) {
|
|
76
|
+
return { skip: true, reason: 'no backend target' };
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// Skip for shared Firebase projects — migrations iterate whole collections,
|
|
80
|
+
// so the owning brand's run covers the project; per-shared-brand runs would
|
|
81
|
+
// just repeat the same migration against the same Firestore
|
|
82
|
+
if (needsFirestore && context.brandConfig.cloud?.shared === true) {
|
|
83
|
+
return { skip: true, reason: 'shared Firebase project (owning brand runs migrations)' };
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// Tests inject fakes via context
|
|
87
|
+
let authAdmin = context.authAdmin;
|
|
88
|
+
let firestore = context.firestore;
|
|
89
|
+
if (needsFirestore && !authAdmin) {
|
|
90
|
+
if (!jetpack.exists(join(context.brandRoot, SERVICE_ACCOUNT_PATH))) {
|
|
91
|
+
return { skip: true, reason: `no service account at ${SERVICE_ACCOUNT_PATH} (run the cloud service first)` };
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
const serviceAccount = loadServiceAccount(SERVICE_ACCOUNT_PATH, context.brandRoot);
|
|
95
|
+
authAdmin = createAuthAdmin(serviceAccount);
|
|
96
|
+
firestore = new FirestoreREST(serviceAccount);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
return { operations: filteredOperations, authAdmin, firestore };
|
|
100
|
+
},
|
|
101
|
+
});
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Attribution fold fix — converts the pre-#384 attribution blob
|
|
3
|
+
* (`attribution.utm`, last-tagged-wins) into the touch model
|
|
4
|
+
* (`attribution.first` + `attribution.last`) every current reader expects.
|
|
5
|
+
*
|
|
6
|
+
* The same fold runs on every surface that stores attribution: user docs,
|
|
7
|
+
* payments-orders, payments-intents. The client already ships the identical
|
|
8
|
+
* fold for its localStorage copy (@omega.js/web core/js/core/query-strings.js
|
|
9
|
+
* migrateLegacyAttribution) — this is its server-side mirror, so a browser and
|
|
10
|
+
* its documents converge on the same shape.
|
|
11
|
+
*
|
|
12
|
+
* What the old blob cannot answer stays unanswered: the true first touch is
|
|
13
|
+
* unrecoverable (the blob only ever held the newest tagged visit), so both
|
|
14
|
+
* slots take the same touch; `clickIds` and `referrer` were never captured, so
|
|
15
|
+
* they are omitted/null rather than invented as empty husks — the capture
|
|
16
|
+
* convention writes a key only when the visit carried one.
|
|
17
|
+
*/
|
|
18
|
+
const { FieldValue } = require('./migration-runner.js');
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Create a migration fix that folds a legacy `attribution.utm` blob into
|
|
22
|
+
* `attribution.first` / `attribution.last` and deletes the blob.
|
|
23
|
+
*
|
|
24
|
+
* Idempotent: a document already carrying a touch keeps it (only a leftover
|
|
25
|
+
* blob is dropped), and a document with no blob is a strict no-op — nothing,
|
|
26
|
+
* including `attribution` itself, is ever synthesized.
|
|
27
|
+
*
|
|
28
|
+
* @returns {Function} Fix function for runMigration: (data) => updates or null
|
|
29
|
+
*/
|
|
30
|
+
function createAttributionFoldFix() {
|
|
31
|
+
return (data) => {
|
|
32
|
+
const attribution = data.attribution;
|
|
33
|
+
if (!attribution || typeof attribution !== 'object') {
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const legacy = attribution.utm;
|
|
38
|
+
if (!legacy || typeof legacy !== 'object') {
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Already folded (by an earlier run, or by the client writing through) —
|
|
43
|
+
// the touches are newer than this blob, so only the blob goes.
|
|
44
|
+
if (attribution.first || attribution.last) {
|
|
45
|
+
return { 'attribution.utm': FieldValue.delete() };
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const touch = {
|
|
49
|
+
...(legacy.tags && Object.keys(legacy.tags).length > 0 ? { tags: legacy.tags } : {}),
|
|
50
|
+
referrer: null,
|
|
51
|
+
url: legacy.url || null,
|
|
52
|
+
page: legacy.page || null,
|
|
53
|
+
timestamp: legacy.timestamp || null,
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
return {
|
|
57
|
+
'attribution.first': touch,
|
|
58
|
+
'attribution.last': { ...touch },
|
|
59
|
+
'attribution.utm': FieldValue.delete(),
|
|
60
|
+
};
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
module.exports = { createAttributionFoldFix };
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Metadata timestamp fix — moves legacy created/updated fields into
|
|
3
|
+
* metadata.created/metadata.updated, falling back to the document's server
|
|
4
|
+
* create/update times. The REST client surfaces those as ISO strings
|
|
5
|
+
* (doc.createTime/doc.updateTime), not admin-SDK Timestamp objects.
|
|
6
|
+
*/
|
|
7
|
+
const { FieldValue } = require('./migration-runner.js');
|
|
8
|
+
|
|
9
|
+
const EPOCH = '1970-01-01T00:00:00.000Z';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Convert a document server timestamp (ISO string from doc.createTime /
|
|
13
|
+
* doc.updateTime) to our standard { timestamp, timestampUNIX } format.
|
|
14
|
+
*/
|
|
15
|
+
function serverTimestampToObject(isoString) {
|
|
16
|
+
if (!isoString) {
|
|
17
|
+
return null;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const date = new Date(isoString);
|
|
21
|
+
|
|
22
|
+
return {
|
|
23
|
+
timestamp: date.toISOString(),
|
|
24
|
+
timestampUNIX: Math.round(date.getTime() / 1000),
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Check if a metadata timestamp is missing or is the epoch default
|
|
30
|
+
*/
|
|
31
|
+
function isMissingOrEpoch(ts) {
|
|
32
|
+
if (!ts) {
|
|
33
|
+
return true;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
if (typeof ts === 'object' && ts.timestamp === EPOCH && ts.timestampUNIX === 0) {
|
|
37
|
+
return true;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Creates a fix function that moves legacy fields into metadata.created/metadata.updated,
|
|
45
|
+
* then falls back to the document's createTime/updateTime for any that are still missing.
|
|
46
|
+
*
|
|
47
|
+
* This should be added as the LAST metadata-related fix in any migration, after any legacy
|
|
48
|
+
* field renames have already been applied.
|
|
49
|
+
*
|
|
50
|
+
* @param {Object} options
|
|
51
|
+
* @param {Array<string>} options.legacyCreatedFields - Legacy field paths to check for created (e.g. ['created', 'dateAdded'])
|
|
52
|
+
* @param {Array<string>} options.legacyUpdatedFields - Legacy field paths to check for updated (e.g. ['updated', 'edited'])
|
|
53
|
+
* @returns {Function} Fix function: (data, doc) => updates or null
|
|
54
|
+
*/
|
|
55
|
+
function createMetadataFix(options = {}) {
|
|
56
|
+
const legacyCreatedFields = options.legacyCreatedFields || ['created'];
|
|
57
|
+
const legacyUpdatedFields = options.legacyUpdatedFields || ['updated'];
|
|
58
|
+
|
|
59
|
+
return (data, doc) => {
|
|
60
|
+
const updates = {};
|
|
61
|
+
let hasUpdates = false;
|
|
62
|
+
|
|
63
|
+
// Step 1: Move legacy created fields → metadata.created, and clean up all legacy fields
|
|
64
|
+
for (const field of legacyCreatedFields) {
|
|
65
|
+
const value = getNestedValue(data, field);
|
|
66
|
+
if (!value) {
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// Use the first legacy value for metadata.created if not already set
|
|
71
|
+
if (!data.metadata?.created && !updates['metadata.created']) {
|
|
72
|
+
updates['metadata.created'] = value;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// Always delete the legacy field
|
|
76
|
+
updates[field] = FieldValue.delete();
|
|
77
|
+
hasUpdates = true;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// Step 2: Move legacy updated fields → metadata.updated, and clean up all legacy fields
|
|
81
|
+
for (const field of legacyUpdatedFields) {
|
|
82
|
+
const value = getNestedValue(data, field);
|
|
83
|
+
if (!value) {
|
|
84
|
+
continue;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// Use the first legacy value for metadata.updated if not already set
|
|
88
|
+
if (!data.metadata?.updated && !updates['metadata.updated']) {
|
|
89
|
+
updates['metadata.updated'] = value;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// Always delete the legacy field
|
|
93
|
+
updates[field] = FieldValue.delete();
|
|
94
|
+
hasUpdates = true;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// Step 3: Determine effective metadata after legacy migration
|
|
98
|
+
const effectiveCreated = updates['metadata.created'] || data.metadata?.created;
|
|
99
|
+
const effectiveUpdated = updates['metadata.updated'] || data.metadata?.updated;
|
|
100
|
+
|
|
101
|
+
// Step 4: Fall back to document server timestamps for missing/epoch metadata
|
|
102
|
+
const docCreated = serverTimestampToObject(doc.createTime);
|
|
103
|
+
const docUpdated = serverTimestampToObject(doc.updateTime);
|
|
104
|
+
|
|
105
|
+
if (isMissingOrEpoch(effectiveCreated)) {
|
|
106
|
+
// Try doc.createTime, then doc.updateTime, then effectiveUpdated
|
|
107
|
+
const fallback = docCreated || docUpdated || effectiveUpdated;
|
|
108
|
+
|
|
109
|
+
if (fallback && !isMissingOrEpoch(fallback)) {
|
|
110
|
+
updates['metadata.created'] = fallback;
|
|
111
|
+
hasUpdates = true;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
if (isMissingOrEpoch(effectiveUpdated)) {
|
|
116
|
+
// Try doc.updateTime, then the resolved created value
|
|
117
|
+
const resolvedCreated = updates['metadata.created'] || effectiveCreated;
|
|
118
|
+
const fallback = docUpdated || docCreated || resolvedCreated;
|
|
119
|
+
|
|
120
|
+
if (fallback && !isMissingOrEpoch(fallback)) {
|
|
121
|
+
updates['metadata.updated'] = fallback;
|
|
122
|
+
hasUpdates = true;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
return hasUpdates ? updates : null;
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Get a nested value from an object using dot-notation path
|
|
132
|
+
*/
|
|
133
|
+
function getNestedValue(obj, path) {
|
|
134
|
+
const parts = path.split('.');
|
|
135
|
+
let value = obj;
|
|
136
|
+
|
|
137
|
+
for (const part of parts) {
|
|
138
|
+
value = value?.[part];
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
return value;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
module.exports = { createMetadataFix };
|