@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,138 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Forms service (`forms.providers.slapform`) — the brand's contact form on
|
|
3
|
+
* Slapform (slapform.com): keeps the form's settings in sync and sets the
|
|
4
|
+
* form-owner account to the configured plan (Slapform's top tier by default)
|
|
5
|
+
* so the brand has full access. Forms live in Slapform's own Firestore, so this service is for
|
|
6
|
+
* the Slapform operator: it needs a service account for Slapform's Firebase
|
|
7
|
+
* project.
|
|
8
|
+
*
|
|
9
|
+
* Auth tiers (2b, Ian 2026-07-13):
|
|
10
|
+
* 1. Operator SA — SLAPFORM_SERVICE_ACCOUNT in the brand .env (path to
|
|
11
|
+
* the service-account JSON, absolute or brand-root-relative). Full
|
|
12
|
+
* create + manage: a missing formId with `forms.providers.slapform.templateFormId`
|
|
13
|
+
* configured (the company layer's shape donor) MINTS the brand's own
|
|
14
|
+
* form — product user (email = brand contact email, password via the
|
|
15
|
+
* account service's owner channels) + doc shape-templated from the
|
|
16
|
+
* donor — and writes the new id back into omega.json5. The ensures
|
|
17
|
+
* then converge name/settings/plan in the same run.
|
|
18
|
+
* 2. User API key — SLAPFORM_API_KEY (the product accepts
|
|
19
|
+
* user.api.privateKey): recognized, management via the product's
|
|
20
|
+
* public API lands when those routes are verified.
|
|
21
|
+
* 3. Dashboard — interactive runs offer the setup flow (open
|
|
22
|
+
* slapform.com, paste the form id back — comment-preserving
|
|
23
|
+
* writeback, with a Disable option that sets `slapform: false`).
|
|
24
|
+
* Non-interactive and dry runs skip cleanly.
|
|
25
|
+
*/
|
|
26
|
+
const chalk = require('chalk').default;
|
|
27
|
+
const { serviceInputSpec } = require('../../config.js');
|
|
28
|
+
const { createServiceRunner } = require('../../lib/service-runner.js');
|
|
29
|
+
const { requestServiceInput } = require('../../lib/service-input.js');
|
|
30
|
+
const { FirestoreREST, loadServiceAccount } = require('../../lib/firestore-rest.js');
|
|
31
|
+
const { createAuthAdmin } = require('../../lib/auth-admin.js');
|
|
32
|
+
const { resolveConfigValue, landValue } = require('../../lib/config-flow.js');
|
|
33
|
+
const { createProductAsset } = require('../../lib/product-create.js');
|
|
34
|
+
const { createPasswordResolver } = require('../account/lib/resolve-password.js');
|
|
35
|
+
|
|
36
|
+
const SLAPFORM_URL = 'https://slapform.com';
|
|
37
|
+
|
|
38
|
+
module.exports.run = createServiceRunner({
|
|
39
|
+
serviceDir: __dirname,
|
|
40
|
+
setup: async (context) => {
|
|
41
|
+
const config = context.brandConfig.forms?.providers?.slapform;
|
|
42
|
+
|
|
43
|
+
if (config === false || config?.enabled === false) {
|
|
44
|
+
return { skip: true, reason: 'forms.providers.slapform.enabled = false' };
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// Shared form: another brand owns its branding (the chatsy/replyify
|
|
48
|
+
// updateAgentInfo pattern) — never rename or re-enable it from here
|
|
49
|
+
if (config?.updateFormInfo === false) {
|
|
50
|
+
return { skip: true, reason: 'form managed by another brand (forms.providers.slapform.updateFormInfo = false)' };
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// The contact form lives on the brand's website
|
|
54
|
+
if (!context.brandConfig.targets?.web) {
|
|
55
|
+
return { skip: true, reason: 'no web target' };
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// Operator credentials first — create-on-missing needs them before the
|
|
59
|
+
// id resolution. Tests inject fakes via context.slapformDb/-AuthAdmin.
|
|
60
|
+
let db = context.slapformDb;
|
|
61
|
+
let authAdmin = context.slapformAuthAdmin;
|
|
62
|
+
if (!db) {
|
|
63
|
+
const envPath = process.env.SLAPFORM_SERVICE_ACCOUNT;
|
|
64
|
+
if (envPath) {
|
|
65
|
+
const serviceAccount = loadServiceAccount(envPath, context.brandRoot);
|
|
66
|
+
db = new FirestoreREST(serviceAccount);
|
|
67
|
+
authAdmin = createAuthAdmin(serviceAccount);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const brand = context.brandConfig.brand || {};
|
|
72
|
+
const dryRun = context.options?.dryRun || false;
|
|
73
|
+
let formId = config?.formId;
|
|
74
|
+
|
|
75
|
+
// 2b create-on-missing: operator SA + a template donor → a missing form
|
|
76
|
+
// means MINT the brand's own (product user + doc), write the id back,
|
|
77
|
+
// and let the ensures below converge it in this same run.
|
|
78
|
+
if (!formId && db && authAdmin && config?.templateFormId && brand.contact?.email) {
|
|
79
|
+
const created = await createProductAsset({
|
|
80
|
+
db,
|
|
81
|
+
authAdmin,
|
|
82
|
+
collection: 'forms',
|
|
83
|
+
templateId: config.templateFormId,
|
|
84
|
+
email: brand.contact.email,
|
|
85
|
+
resolvePassword: createPasswordResolver({
|
|
86
|
+
brandRoot: context.brandRoot,
|
|
87
|
+
domain: new URL(brand.url || 'https://invalid.test').hostname,
|
|
88
|
+
brand,
|
|
89
|
+
dryRun,
|
|
90
|
+
}),
|
|
91
|
+
dryRun,
|
|
92
|
+
log: (line) => console.log(` ${line}`),
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
if (!created) {
|
|
96
|
+
return { skip: true, reason: 'dry run — form creation planned (from forms.providers.slapform.templateFormId)' };
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
landValue(context, 'forms.providers.slapform.formId', created.id);
|
|
100
|
+
console.log(` ${chalk.green('✓')} forms.providers.slapform.formId = ${chalk.cyan(created.id)} written to omega.json5`);
|
|
101
|
+
formId = created.id;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
if (!formId) {
|
|
105
|
+
formId = await resolveConfigValue(context, {
|
|
106
|
+
path: 'forms.providers.slapform.formId',
|
|
107
|
+
label: 'Slapform contact form',
|
|
108
|
+
instructions: [
|
|
109
|
+
`1. Create an account at ${chalk.cyan(SLAPFORM_URL)} (if you haven't already)`,
|
|
110
|
+
`2. Create a contact form for ${chalk.cyan(brand.name || context.brandId)}`,
|
|
111
|
+
],
|
|
112
|
+
entry: { url: SLAPFORM_URL, message: 'Slapform form ID:' },
|
|
113
|
+
disablePath: 'forms.providers.slapform',
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
if (!formId) {
|
|
117
|
+
return { skip: true, reason: 'no forms.providers.slapform.formId configured — set forms.providers.slapform.templateFormId + the operator SA to mint one automatically, create one at https://slapform.com (paste back interactively), or set it in omega.json5' };
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
if (!db) {
|
|
121
|
+
if (process.env.SLAPFORM_API_KEY) {
|
|
122
|
+
return {
|
|
123
|
+
skip: true,
|
|
124
|
+
reason: 'SLAPFORM_API_KEY recognized, but product-API management is not wired yet — use the operator SA (SLAPFORM_SERVICE_ACCOUNT) or the dashboard',
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// The shared setup contract (#608): the operator SA is asked for right
|
|
129
|
+
// here — most brands are not the Slapform operator and answer Disable,
|
|
130
|
+
// which retires the ask for good.
|
|
131
|
+
const gate = await requestServiceInput(context, serviceInputSpec('forms'));
|
|
132
|
+
if (gate) return gate;
|
|
133
|
+
db = new FirestoreREST(loadServiceAccount(process.env.SLAPFORM_SERVICE_ACCOUNT, context.brandRoot));
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
return { db, formId };
|
|
137
|
+
},
|
|
138
|
+
});
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Notifications collection migration — converges push-subscription docs to
|
|
3
|
+
* the canonical @omega.js/backend + @omega.js/client shape.
|
|
4
|
+
*
|
|
5
|
+
* Fixes:
|
|
6
|
+
* - Renames `uid` field to `owner` and deletes `uid`
|
|
7
|
+
* - Flattens `owner.uid` (object) to `owner` (string)
|
|
8
|
+
* - Moves legacy created/updated → metadata.created/metadata.updated
|
|
9
|
+
* - Moves `url` to `context.client.url` and builds the full context structure
|
|
10
|
+
* - Folds the legacy `attribution.utm` blob into `attribution.first`/`last`
|
|
11
|
+
* - Adds empty `attribution` when missing
|
|
12
|
+
* - Trims whitespace on all string values
|
|
13
|
+
*
|
|
14
|
+
* Validates:
|
|
15
|
+
* - All fields match the expected schema
|
|
16
|
+
*/
|
|
17
|
+
const { runMigration, FieldValue } = require('../lib/migration-runner.js');
|
|
18
|
+
const { createMetadataFix } = require('../lib/ensure-metadata.js');
|
|
19
|
+
const { validateDocument } = require('../lib/schema-validator.js');
|
|
20
|
+
const { createSanitizeFix } = require('../lib/sanitize-strings.js');
|
|
21
|
+
const { createAttributionFoldFix } = require('../lib/attribution-touch.js');
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Default context structure from @omega.js/client's getContext()
|
|
25
|
+
*/
|
|
26
|
+
const DEFAULT_CONTEXT = {
|
|
27
|
+
client: {
|
|
28
|
+
language: null,
|
|
29
|
+
mobile: null,
|
|
30
|
+
device: null,
|
|
31
|
+
platform: null,
|
|
32
|
+
browser: null,
|
|
33
|
+
vendor: null,
|
|
34
|
+
runtime: null,
|
|
35
|
+
userAgent: null,
|
|
36
|
+
url: null,
|
|
37
|
+
},
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Notifications collection schema
|
|
42
|
+
* Based on @omega.js/client's notifications _saveSubscription()
|
|
43
|
+
*/
|
|
44
|
+
const schema = {
|
|
45
|
+
token: { type: 'string', required: true },
|
|
46
|
+
owner: { type: 'string', required: true, nullable: true },
|
|
47
|
+
tags: { type: 'array', required: true, itemType: 'string' },
|
|
48
|
+
attribution: { type: 'object', required: true },
|
|
49
|
+
metadata: {
|
|
50
|
+
type: 'object',
|
|
51
|
+
required: true,
|
|
52
|
+
properties: {
|
|
53
|
+
created: {
|
|
54
|
+
type: 'object',
|
|
55
|
+
required: true,
|
|
56
|
+
properties: {
|
|
57
|
+
timestamp: { type: 'string', required: true },
|
|
58
|
+
timestampUNIX: { type: 'number', required: true },
|
|
59
|
+
},
|
|
60
|
+
},
|
|
61
|
+
updated: {
|
|
62
|
+
type: 'object',
|
|
63
|
+
required: true,
|
|
64
|
+
properties: {
|
|
65
|
+
timestamp: { type: 'string', required: true },
|
|
66
|
+
timestampUNIX: { type: 'number', required: true },
|
|
67
|
+
},
|
|
68
|
+
},
|
|
69
|
+
},
|
|
70
|
+
},
|
|
71
|
+
context: {
|
|
72
|
+
type: 'object',
|
|
73
|
+
required: true,
|
|
74
|
+
properties: {
|
|
75
|
+
client: {
|
|
76
|
+
type: 'object',
|
|
77
|
+
required: true,
|
|
78
|
+
properties: {
|
|
79
|
+
language: { type: 'string', required: true, nullable: true },
|
|
80
|
+
mobile: { type: 'boolean', required: true, nullable: true },
|
|
81
|
+
device: { type: 'string', required: true, nullable: true },
|
|
82
|
+
platform: { type: 'string', required: true, nullable: true },
|
|
83
|
+
browser: { type: 'string', required: true, nullable: true },
|
|
84
|
+
vendor: { type: 'string', required: true, nullable: true },
|
|
85
|
+
runtime: { type: 'string', required: true, nullable: true },
|
|
86
|
+
userAgent: { type: 'string', required: true, nullable: true },
|
|
87
|
+
url: { type: 'string', required: true, nullable: true },
|
|
88
|
+
},
|
|
89
|
+
},
|
|
90
|
+
},
|
|
91
|
+
},
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Notifications collection migration handler.
|
|
96
|
+
*
|
|
97
|
+
* @param {Object} context - Handler context
|
|
98
|
+
* @returns {Object} Migration results
|
|
99
|
+
*/
|
|
100
|
+
module.exports = async function ensureNotifications(context) {
|
|
101
|
+
return runMigration(context, {
|
|
102
|
+
collection: 'notifications',
|
|
103
|
+
|
|
104
|
+
fixes: [
|
|
105
|
+
// Fix: uid → owner (rename + delete uid)
|
|
106
|
+
(data) => {
|
|
107
|
+
if (data.uid === undefined) {
|
|
108
|
+
return null;
|
|
109
|
+
}
|
|
110
|
+
const updates = { uid: FieldValue.delete() };
|
|
111
|
+
if (data.owner === undefined) {
|
|
112
|
+
updates.owner = data.uid;
|
|
113
|
+
}
|
|
114
|
+
return updates;
|
|
115
|
+
},
|
|
116
|
+
|
|
117
|
+
// Fix: owner.uid (object) → owner (string)
|
|
118
|
+
(data) => {
|
|
119
|
+
if (typeof data.owner !== 'object' || data.owner?.uid === undefined) {
|
|
120
|
+
return null;
|
|
121
|
+
}
|
|
122
|
+
return { owner: data.owner.uid };
|
|
123
|
+
},
|
|
124
|
+
|
|
125
|
+
// Fix: Move created/updated → metadata.created/metadata.updated
|
|
126
|
+
// Falls back to the document's server createTime/updateTime if missing
|
|
127
|
+
createMetadataFix({
|
|
128
|
+
legacyCreatedFields: ['created'],
|
|
129
|
+
legacyUpdatedFields: ['updated'],
|
|
130
|
+
}),
|
|
131
|
+
|
|
132
|
+
// Fix: build full context structure with all fields
|
|
133
|
+
(data) => {
|
|
134
|
+
const existing = data.context || {};
|
|
135
|
+
const existingClient = existing.client || {};
|
|
136
|
+
|
|
137
|
+
// Merge existing values over defaults
|
|
138
|
+
const mergedClient = { ...DEFAULT_CONTEXT.client, ...existingClient };
|
|
139
|
+
|
|
140
|
+
// If old url field exists, use it as context.client.url
|
|
141
|
+
if (data.url && !existingClient.url) {
|
|
142
|
+
mergedClient.url = data.url;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
const merged = { client: mergedClient };
|
|
146
|
+
|
|
147
|
+
// Check if anything changed
|
|
148
|
+
const isComplete = data.context
|
|
149
|
+
&& JSON.stringify(data.context) === JSON.stringify(merged)
|
|
150
|
+
&& !data.url;
|
|
151
|
+
|
|
152
|
+
if (isComplete) {
|
|
153
|
+
return null;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
const updates = { context: merged };
|
|
157
|
+
if (data.url) {
|
|
158
|
+
updates.url = FieldValue.delete();
|
|
159
|
+
}
|
|
160
|
+
return updates;
|
|
161
|
+
},
|
|
162
|
+
|
|
163
|
+
// Fix: fold the legacy attribution.utm blob → attribution.first/last.
|
|
164
|
+
// A subscription copies the client's stored attribution verbatim
|
|
165
|
+
// (@omega.js/client notifications _saveSubscription), so docs written
|
|
166
|
+
// before #384 carry the same blob users and payments do. Placed before
|
|
167
|
+
// the attribution backfill to match every other surface; unlike users
|
|
168
|
+
// (whose DEFAULT_USER husks make the order load-bearing) the backfill
|
|
169
|
+
// here only fires when attribution is absent, so the order is inert.
|
|
170
|
+
createAttributionFoldFix(),
|
|
171
|
+
|
|
172
|
+
// Fix: add empty attribution when missing
|
|
173
|
+
(data) => {
|
|
174
|
+
if (data.attribution !== undefined) {
|
|
175
|
+
return null;
|
|
176
|
+
}
|
|
177
|
+
return { attribution: {} };
|
|
178
|
+
},
|
|
179
|
+
|
|
180
|
+
// Fix: trim whitespace on all string values
|
|
181
|
+
createSanitizeFix(),
|
|
182
|
+
],
|
|
183
|
+
|
|
184
|
+
// Validate against schema
|
|
185
|
+
validate: (data) => {
|
|
186
|
+
return validateDocument(data, schema);
|
|
187
|
+
},
|
|
188
|
+
});
|
|
189
|
+
};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Orders collection migration — converges `payments-orders` documents to the
|
|
3
|
+
* current attribution shape.
|
|
4
|
+
*
|
|
5
|
+
* An order copies the checkout context off its payments-intents doc verbatim,
|
|
6
|
+
* so orders written before #384 still carry the legacy `attribution.utm` blob
|
|
7
|
+
* and resolve to no campaign data at all on a server conversion send.
|
|
8
|
+
*
|
|
9
|
+
* Fixes:
|
|
10
|
+
* - Folds legacy `attribution.utm` → `attribution.first` + `attribution.last`
|
|
11
|
+
*
|
|
12
|
+
* No schema validation: an order's shape is owned by the payments webhook
|
|
13
|
+
* pipeline (provider payloads, refunds, discounts) — this migration touches
|
|
14
|
+
* attribution only and has no business declaring the rest.
|
|
15
|
+
*/
|
|
16
|
+
const { runMigration } = require('../lib/migration-runner.js');
|
|
17
|
+
const { createAttributionFoldFix } = require('../lib/attribution-touch.js');
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Orders collection migration handler.
|
|
21
|
+
*
|
|
22
|
+
* @param {Object} context - Handler context
|
|
23
|
+
* @returns {Object} Migration results
|
|
24
|
+
*/
|
|
25
|
+
module.exports = async function ensureOrders(context) {
|
|
26
|
+
return runMigration(context, {
|
|
27
|
+
collection: 'payments-orders',
|
|
28
|
+
|
|
29
|
+
fixes: [
|
|
30
|
+
// Fix: legacy attribution blob → first/last touches
|
|
31
|
+
createAttributionFoldFix(),
|
|
32
|
+
],
|
|
33
|
+
});
|
|
34
|
+
};
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Payment-provider rename migration ([#428](https://github.com/Omega-JS-Stack/omega/issues/428))
|
|
3
|
+
* — the DATA half of the word change. #425 renamed the config block
|
|
4
|
+
* (`payment.processors` → `payment.providers`) and #428 finished the job: the
|
|
5
|
+
* singular word is `provider` in code, on the API, and on every document the
|
|
6
|
+
* payment pipeline writes. Documents written BEFORE the cutover still carry
|
|
7
|
+
* the old key, and nothing dual-reads it, so this sweep moves them.
|
|
8
|
+
*
|
|
9
|
+
* Five collections carry the field, each at its own path:
|
|
10
|
+
* - `users` — `subscription.payment.processor`
|
|
11
|
+
* - `payments-orders` — `processor`
|
|
12
|
+
* - `payments-intents` — `processor`
|
|
13
|
+
* - `payments-webhooks` — `processor`
|
|
14
|
+
* - `payments-disputes` — `alert.processor`
|
|
15
|
+
*
|
|
16
|
+
* Idempotent by construction: a document with no legacy key is a strict no-op,
|
|
17
|
+
* and one that somehow carries BOTH keeps `provider` (written by the current
|
|
18
|
+
* code, so it is the newer of the two) and drops only the leftover. A null
|
|
19
|
+
* value still moves — `null` is what the schema stores for an account that
|
|
20
|
+
* never paid, and leaving the retired key behind is the thing this exists to
|
|
21
|
+
* stop.
|
|
22
|
+
*
|
|
23
|
+
* No schema validation: the payment collections' shapes are owned by the
|
|
24
|
+
* webhook pipeline, and this migration touches ONE field.
|
|
25
|
+
*
|
|
26
|
+
* Like every migration, a run is an AUDIT until `--execute`:
|
|
27
|
+
* npx omega manage --migration=payment-provider # counts, writes nothing
|
|
28
|
+
* npx omega manage --migration=payment-provider --execute # performs it
|
|
29
|
+
*/
|
|
30
|
+
const { runMigration, FieldValue } = require('../lib/migration-runner.js');
|
|
31
|
+
|
|
32
|
+
// Every collection the payment pipeline stamps the provider onto, with the
|
|
33
|
+
// path the field sits at in that collection's documents.
|
|
34
|
+
const TARGETS = [
|
|
35
|
+
{ collection: 'users', legacy: 'subscription.payment.processor', current: 'subscription.payment.provider' },
|
|
36
|
+
{ collection: 'payments-orders', legacy: 'processor', current: 'provider' },
|
|
37
|
+
{ collection: 'payments-intents', legacy: 'processor', current: 'provider' },
|
|
38
|
+
{ collection: 'payments-webhooks', legacy: 'processor', current: 'provider' },
|
|
39
|
+
{ collection: 'payments-disputes', legacy: 'alert.processor', current: 'alert.provider' },
|
|
40
|
+
];
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Read a dot-notation path off a document, distinguishing "absent" from a
|
|
44
|
+
* stored null.
|
|
45
|
+
*
|
|
46
|
+
* @param {Object} data - The document object
|
|
47
|
+
* @param {string} path - Dot-notation field path
|
|
48
|
+
* @returns {*} The value, or undefined when any segment is missing
|
|
49
|
+
*/
|
|
50
|
+
function readPath(data, path) {
|
|
51
|
+
let target = data;
|
|
52
|
+
|
|
53
|
+
for (const part of path.split('.')) {
|
|
54
|
+
if (target === null || typeof target !== 'object' || !(part in target)) {
|
|
55
|
+
return undefined;
|
|
56
|
+
}
|
|
57
|
+
target = target[part];
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return target;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Create the rename fix for one collection's field path.
|
|
65
|
+
*
|
|
66
|
+
* @param {string} legacy - The retired dot-notation path (`…processor`)
|
|
67
|
+
* @param {string} current - The path it moves to (`…provider`)
|
|
68
|
+
* @returns {Function} Fix function for runMigration: (data) => updates or null
|
|
69
|
+
*/
|
|
70
|
+
function createProviderRenameFix(legacy, current) {
|
|
71
|
+
return (data) => {
|
|
72
|
+
const legacyValue = readPath(data, legacy);
|
|
73
|
+
if (legacyValue === undefined) {
|
|
74
|
+
return null;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Already renamed (by the current code, or by an earlier run) — the new
|
|
78
|
+
// field is the newer of the two, so only the leftover goes.
|
|
79
|
+
if (readPath(data, current) !== undefined) {
|
|
80
|
+
return { [legacy]: FieldValue.delete() };
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
return {
|
|
84
|
+
[current]: legacyValue,
|
|
85
|
+
[legacy]: FieldValue.delete(),
|
|
86
|
+
};
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Payment-provider rename migration handler.
|
|
92
|
+
*
|
|
93
|
+
* @param {Object} context - Handler context
|
|
94
|
+
* @returns {Object} Migration results, one stats block per collection
|
|
95
|
+
*/
|
|
96
|
+
module.exports = async function ensurePaymentProvider(context) {
|
|
97
|
+
const output = {};
|
|
98
|
+
let status;
|
|
99
|
+
const warnings = [];
|
|
100
|
+
|
|
101
|
+
for (const target of TARGETS) {
|
|
102
|
+
const result = await runMigration(context, {
|
|
103
|
+
collection: target.collection,
|
|
104
|
+
fixes: [createProviderRenameFix(target.legacy, target.current)],
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
// Namespaced: three of these collections are ALSO migrated by another
|
|
108
|
+
// handler in the same walk, and the service runner merges every
|
|
109
|
+
// operation's output into one flat map — a bare `users` key would
|
|
110
|
+
// silently overwrite the users migration's stats.
|
|
111
|
+
for (const [collection, stats] of Object.entries(result.output || {})) {
|
|
112
|
+
output[`payment-provider:${collection}`] = stats;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// A REST failure is credentials or permissions, which every remaining
|
|
116
|
+
// collection would hit identically — stop and report rather than five
|
|
117
|
+
// copies of the same error.
|
|
118
|
+
if (result.status === 'error') {
|
|
119
|
+
return { ...result, output };
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
if (result.status === 'warned') {
|
|
123
|
+
status = 'warned';
|
|
124
|
+
warnings.push(`${target.collection}: ${result.reason}`);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
return status ? { output, status, reason: warnings.join('; ') } : { output };
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
module.exports.TARGETS = TARGETS;
|
|
132
|
+
module.exports.createProviderRenameFix = createProviderRenameFix;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Payments-intents collection migration — converges `payments-intents`
|
|
3
|
+
* documents to the current attribution shape.
|
|
4
|
+
*
|
|
5
|
+
* The intent is where the browser's attribution lands at checkout (the
|
|
6
|
+
* webhook reads it back onto the order), so intents written before #384 hold
|
|
7
|
+
* the legacy `attribution.utm` blob and are the upstream copy of the same
|
|
8
|
+
* degradation the orders migration cures.
|
|
9
|
+
*
|
|
10
|
+
* Fixes:
|
|
11
|
+
* - Folds legacy `attribution.utm` → `attribution.first` + `attribution.last`
|
|
12
|
+
*
|
|
13
|
+
* No schema validation: the intent's shape is owned by the payments intent
|
|
14
|
+
* route — this migration touches attribution only.
|
|
15
|
+
*/
|
|
16
|
+
const { runMigration } = require('../lib/migration-runner.js');
|
|
17
|
+
const { createAttributionFoldFix } = require('../lib/attribution-touch.js');
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Payments-intents collection migration handler.
|
|
21
|
+
*
|
|
22
|
+
* @param {Object} context - Handler context
|
|
23
|
+
* @returns {Object} Migration results
|
|
24
|
+
*/
|
|
25
|
+
module.exports = async function ensurePaymentsIntents(context) {
|
|
26
|
+
return runMigration(context, {
|
|
27
|
+
collection: 'payments-intents',
|
|
28
|
+
|
|
29
|
+
fixes: [
|
|
30
|
+
// Fix: legacy attribution blob → first/last touches
|
|
31
|
+
createAttributionFoldFix(),
|
|
32
|
+
],
|
|
33
|
+
});
|
|
34
|
+
};
|