@wix/agent-skills 1.33.1 → 1.35.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/README.md +3 -0
- package/package.json +1 -1
- package/skills/wix-export/SKILL.md +83 -0
- package/skills/wix-harmony-editor/.publish-manifest.json +8 -0
- package/skills/wix-harmony-editor/COPY-SITE.md +494 -0
- package/skills/wix-harmony-editor/SKILL.md +317 -0
- package/skills/wix-harmony-editor/scripts/copy/build-description.mjs +249 -0
- package/skills/wix-harmony-editor/scripts/copy/check-description.mjs +225 -0
- package/skills/wix-harmony-editor/scripts/copy/check-mirror.mjs +89 -0
- package/skills/wix-harmony-editor/scripts/copy/compare-preview.mjs +76 -0
- package/skills/wix-harmony-editor/scripts/copy/deploy-description.mjs +212 -0
- package/skills/wix-harmony-editor/scripts/copy/desc-hash.mjs +44 -0
- package/skills/wix-harmony-editor/scripts/copy/editor-run.mjs +45 -0
- package/skills/wix-harmony-editor/scripts/copy/export-page.mjs +53 -0
- package/skills/wix-harmony-editor/scripts/copy/find-interactions.mjs +76 -0
- package/skills/wix-harmony-editor/scripts/copy/hide-scrollbars.mjs +16 -0
- package/skills/wix-harmony-editor/scripts/copy/import-media.mjs +150 -0
- package/skills/wix-harmony-editor/scripts/copy/link-url.mjs +27 -0
- package/skills/wix-harmony-editor/scripts/copy/lint-api.mjs +56 -0
- package/skills/wix-harmony-editor/scripts/copy/measure-source.mjs +211 -0
- package/skills/wix-harmony-editor/scripts/copy/merge-mirrors.mjs +29 -0
- package/skills/wix-harmony-editor/scripts/copy/mirror-site.mjs +92 -0
- package/skills/wix-harmony-editor/scripts/copy/mobile-stage.mjs +56 -0
- package/skills/wix-harmony-editor/scripts/copy/preview-widths.mjs +73 -0
- package/skills/wix-harmony-editor/scripts/copy/render-plate.mjs +67 -0
- package/skills/wix-harmony-editor/scripts/copy/serve-mirror.mjs +102 -0
- package/skills/wix-harmony-editor/scripts/copy/snapshot-capabilities.mjs +40 -0
- package/skills/wix-harmony-editor/scripts/copy/split-sections.mjs +191 -0
- package/skills/wix-harmony-editor/scripts/copy/upload-media-manager.mjs +61 -0
- package/skills/wix-harmony-editor/scripts/launch.sh +359 -0
- package/skills/wix-headless/SKILL.md +7 -2
- package/skills/wix-headless/references/CAPABILITIES.md +6 -1
- package/skills/wix-headless/references/DISCOVERY.md +2 -1
- package/skills/wix-headless/references/SDK_HANDOFF.md +6 -1
- package/skills/wix-headless/references/SEED.md +3 -2
- package/skills/wix-headless/references/SETUP.md +1 -0
- package/skills/wix-headless/references/inline-recipes/experience-donations.md +102 -0
- package/skills/wix-headless/references/inline-recipes/how-to-code-donations.md +146 -0
- package/skills/wix-headless/references/inline-recipes/setup-donations.md +15 -0
- package/skills/wix-headless/references/managed/CREATE.md +1 -1
- package/skills/wix-headless-kit/SKILL.md +110 -21
- package/skills/wix-headless-kit/guides/api-run.md +15 -13
- package/skills/wix-headless-kit/guides/existing-site.md +31 -0
- package/skills/wix-headless-kit/guides/migration.md +49 -17
- package/skills/wix-headless-kit/install/agents-md.mjs +1 -1
- package/skills/wix-headless-kit/install/context.mjs +61 -6
- package/skills/wix-headless-kit/install/pins.json +1 -1
- package/skills/wix-headless-kit/install/setup.mjs +107 -12
- package/skills/wix-headless-replatform/.publish-manifest.json +8 -0
- package/skills/wix-headless-replatform/SKILL.md +116 -0
- package/skills/wix-headless-replatform/agents/openai.yaml +6 -0
- package/skills/wix-headless-replatform/references/control-and-visual-fidelity-contract.md +43 -0
- package/skills/wix-headless-replatform/references/extraction-schema.md +187 -0
- package/skills/wix-headless-replatform/references/interaction-runtime-contract.md +137 -0
- package/skills/wix-headless-replatform/references/layout-blueprint-contract.md +41 -0
- package/skills/wix-headless-replatform/references/output-contract.md +93 -0
- package/skills/wix-headless-replatform/references/post-build-gap-contract.md +125 -0
- package/skills/wix-headless-replatform/references/qa-checklist.md +83 -0
- package/skills/wix-headless-replatform/references/safety.md +19 -0
- package/skills/wix-headless-replatform/references/ui-normalization-contract.md +70 -0
- package/skills/wix-headless-replatform/references/workflow.md +157 -0
- package/skills/wix-headless-replatform/registry/README.md +20 -0
- package/skills/wix-headless-replatform/registry/approvals/button/shadcn-default-ac60ef5.json +28 -0
- package/skills/wix-headless-replatform/registry/items/button/shadcn-default-ac60ef5/button.tsx +54 -0
- package/skills/wix-headless-replatform/registry/items/button/shadcn-default-ac60ef5/capabilities.json +60 -0
- package/skills/wix-headless-replatform/registry/items/button/shadcn-default-ac60ef5/contract.md +48 -0
- package/skills/wix-headless-replatform/registry/licenses/shadcn-ui-ac60ef5-MIT.txt +21 -0
- package/skills/wix-headless-replatform/registry/registry.json +36 -0
- package/skills/wix-headless-replatform/resources/rp-facelift/SKILL.md +32 -0
- package/skills/wix-headless-replatform/resources/rp-project-context/SKILL.md +62 -0
- package/skills/wix-headless-replatform/resources/rp-qa-gap-loop/SKILL.md +64 -0
- package/skills/wix-headless-replatform/resources/rp-source-evidence/SKILL.md +42 -0
- package/skills/wix-headless-replatform/resources/rp-ui-implementation/SKILL.md +73 -0
- package/skills/wix-headless-replatform/schemas/build-plan.schema.json +10 -0
- package/skills/wix-headless-replatform/schemas/candidate.schema.json +19 -0
- package/skills/wix-headless-replatform/schemas/common.schema.json +33 -0
- package/skills/wix-headless-replatform/schemas/decision-patch.schema.json +10 -0
- package/skills/wix-headless-replatform/schemas/decision-request.schema.json +10 -0
- package/skills/wix-headless-replatform/schemas/extraction-gap.schema.json +28 -0
- package/skills/wix-headless-replatform/schemas/extraction-manifest.schema.json +34 -0
- package/skills/wix-headless-replatform/schemas/final-report.schema.json +10 -0
- package/skills/wix-headless-replatform/schemas/foundation.schema.json +11 -0
- package/skills/wix-headless-replatform/schemas/metadata.schema.json +11 -0
- package/skills/wix-headless-replatform/schemas/observation-packet.schema.json +17 -0
- package/skills/wix-headless-replatform/schemas/page-capture.schema.json +11 -0
- package/skills/wix-headless-replatform/schemas/page-resolution.schema.json +33 -0
- package/skills/wix-headless-replatform/schemas/shared-chrome.schema.json +11 -0
- package/skills/wix-headless-replatform/schemas/unit.schema.json +40 -0
- package/skills/wix-headless-replatform/scripts/assemble-extraction.mjs +844 -0
- package/skills/wix-headless-replatform/scripts/benchmark-extraction.mjs +163 -0
- package/skills/wix-headless-replatform/scripts/browser-extraction-preflight.mjs +42 -0
- package/skills/wix-headless-replatform/scripts/build-extracted-homepage.mjs +228 -0
- package/skills/wix-headless-replatform/scripts/clear-wix-starter.mjs +87 -0
- package/skills/wix-headless-replatform/scripts/create-wix-project.mjs +505 -0
- package/skills/wix-headless-replatform/scripts/discover-urls.mjs +142 -0
- package/skills/wix-headless-replatform/scripts/extract-assets.mjs +140 -0
- package/skills/wix-headless-replatform/scripts/extract-design-system.mjs +637 -0
- package/skills/wix-headless-replatform/scripts/extract-interactions.mjs +1903 -0
- package/skills/wix-headless-replatform/scripts/extract-page.mjs +2461 -0
- package/skills/wix-headless-replatform/scripts/extract-seo.mjs +25 -0
- package/skills/wix-headless-replatform/scripts/extract-tokens.mjs +63 -0
- package/skills/wix-headless-replatform/scripts/finalize-extraction-report.mjs +126 -0
- package/skills/wix-headless-replatform/scripts/finalize-gap-review.mjs +180 -0
- package/skills/wix-headless-replatform/scripts/finalize-gap-review.test.mjs +98 -0
- package/skills/wix-headless-replatform/scripts/finalize-migration-website.mjs +103 -0
- package/skills/wix-headless-replatform/scripts/generate-control-state-contract.mjs +176 -0
- package/skills/wix-headless-replatform/scripts/generate-design-md.mjs +261 -0
- package/skills/wix-headless-replatform/scripts/generate-extraction-validators.mjs +25 -0
- package/skills/wix-headless-replatform/scripts/generate-invoice-download-backend.mjs +342 -0
- package/skills/wix-headless-replatform/scripts/generate-layout-blueprint.mjs +140 -0
- package/skills/wix-headless-replatform/scripts/generate-repeater-cms.mjs +22 -0
- package/skills/wix-headless-replatform/scripts/generate-route-plan.mjs +143 -0
- package/skills/wix-headless-replatform/scripts/generate-scene-contract.mjs +288 -0
- package/skills/wix-headless-replatform/scripts/generate-ui-normalization.mjs +266 -0
- package/skills/wix-headless-replatform/scripts/generate-visual-assets.mjs +111 -0
- package/skills/wix-headless-replatform/scripts/lib/browser-tooling.mjs +570 -0
- package/skills/wix-headless-replatform/scripts/lib/common.mjs +329 -0
- package/skills/wix-headless-replatform/scripts/lib/component-capabilities.mjs +121 -0
- package/skills/wix-headless-replatform/scripts/lib/component-registry.mjs +282 -0
- package/skills/wix-headless-replatform/scripts/lib/content-boundary.mjs +61 -0
- package/skills/wix-headless-replatform/scripts/lib/extraction-contract.mjs +374 -0
- package/skills/wix-headless-replatform/scripts/lib/extraction-detectors.mjs +243 -0
- package/skills/wix-headless-replatform/scripts/lib/extraction-validators.generated.mjs +1139 -0
- package/skills/wix-headless-replatform/scripts/lib/font-contract.mjs +326 -0
- package/skills/wix-headless-replatform/scripts/lib/frontend-automation-state.mjs +184 -0
- package/skills/wix-headless-replatform/scripts/lib/gap-analysis.mjs +396 -0
- package/skills/wix-headless-replatform/scripts/lib/html-extract.mjs +168 -0
- package/skills/wix-headless-replatform/scripts/lib/interaction-bootstrap.mjs +10 -0
- package/skills/wix-headless-replatform/scripts/lib/interaction-runtime.mjs +194 -0
- package/skills/wix-headless-replatform/scripts/lib/interaction-timeline.mjs +348 -0
- package/skills/wix-headless-replatform/scripts/lib/layout-blueprint/classifiers.mjs +141 -0
- package/skills/wix-headless-replatform/scripts/lib/layout-blueprint/geometry.mjs +43 -0
- package/skills/wix-headless-replatform/scripts/lib/layout-blueprint/vocabulary.mjs +18 -0
- package/skills/wix-headless-replatform/scripts/lib/ui-normalization.css +64 -0
- package/skills/wix-headless-replatform/scripts/optimize-svg.mjs +31 -0
- package/skills/wix-headless-replatform/scripts/post-build-gap.mjs +358 -0
- package/skills/wix-headless-replatform/scripts/provision-repeater-cms.mjs +25 -0
- package/skills/wix-headless-replatform/scripts/record-gap-decision.mjs +39 -0
- package/skills/wix-headless-replatform/scripts/replay-extraction.mjs +107 -0
- package/skills/wix-headless-replatform/scripts/resolve-home-page.mjs +96 -0
- package/skills/wix-headless-replatform/scripts/site-clone.mjs +658 -0
- package/skills/wix-headless-replatform/scripts/validate-font-contract.mjs +29 -0
- package/skills/wix-headless-replatform/scripts/verify-interactions.mjs +669 -0
- package/skills/wix-headless-replatform/scripts/visual-qa.mjs +370 -0
- package/skills/wix-headless-templates/donations/INSTRUCTIONS.md +37 -24
- package/skills/wix-headless-templates/donations/app/components/donations/DonateForm.tsx +49 -23
- package/skills/wix-headless-templates/donations/app/components/donations/DonationReceipt.tsx +6 -5
- package/skills/wix-headless-templates/donations/app/components/donations/GoalProgress.tsx +5 -5
- package/skills/wix-headless-templates/donations/app/wix/donations/campaigns.ts +4 -4
- package/skills/wix-headless-templates/donations/app/wix/donations/donate.ts +7 -3
- package/skills/wix-headless-templates/donations/app/wix/donations/donation-store.ts +2 -2
- package/skills/wix-headless-templates/donations/app/wix/donations/donations-core.ts +12 -9
- package/skills/wix-headless-templates/donations/project/src/components/donations/DonateForm.tsx +49 -23
- package/skills/wix-headless-templates/donations/project/src/components/donations/DonationReceipt.tsx +6 -5
- package/skills/wix-headless-templates/donations/project/src/components/donations/GoalProgress.tsx +5 -5
- package/skills/wix-headless-templates/donations/project/src/wix/donations/campaigns.ts +4 -4
- package/skills/wix-headless-templates/donations/project/src/wix/donations/donate.ts +7 -3
- package/skills/wix-headless-templates/donations/project/src/wix/donations/donation-store.ts +2 -2
- package/skills/wix-headless-templates/donations/project/src/wix/donations/donations-core.ts +12 -9
- package/skills/wix-headless-templates/donations/rest/campaigns.ts +4 -4
- package/skills/wix-headless-templates/donations/rest/donate.ts +7 -3
- package/skills/wix-headless-templates/donations/seed/SEED.md +12 -7
- package/skills/wix-headless-templates/donations/tests/donation-contract.test.mjs +71 -0
- package/skills/wix-headless-templates/donations/tests/donation-form.test.cjs +137 -0
- package/skills/wix-headless-templates/restaurants/INSTRUCTIONS.md +28 -14
- package/skills/wix-headless-templates/restaurants/app/components/restaurants/OrderCartDrawer.tsx +87 -5
- package/skills/wix-headless-templates/restaurants/app/hooks/restaurants/useOrderCart.ts +9 -1
- package/skills/wix-headless-templates/restaurants/app/wix/restaurants/order-store.ts +33 -4
- package/skills/wix-headless-templates/restaurants/app/wix/restaurants/ordering-core.ts +100 -5
- package/skills/wix-headless-templates/restaurants/app/wix/restaurants/ordering.ts +101 -15
- package/skills/wix-headless-templates/restaurants/app/wix/restaurants/types.ts +35 -1
- package/skills/wix-headless-templates/restaurants/project/src/components/restaurants/OrderCartDrawer.tsx +87 -5
- package/skills/wix-headless-templates/restaurants/project/src/hooks/restaurants/useOrderCart.ts +9 -1
- package/skills/wix-headless-templates/restaurants/project/src/wix/restaurants/order-store.ts +33 -4
- package/skills/wix-headless-templates/restaurants/project/src/wix/restaurants/ordering-core.ts +100 -5
- package/skills/wix-headless-templates/restaurants/project/src/wix/restaurants/ordering.ts +101 -15
- package/skills/wix-headless-templates/restaurants/project/src/wix/restaurants/types.ts +35 -1
- package/skills/wix-headless-templates/restaurants/rest/ordering.ts +91 -14
- package/skills/wix-import/SKILL.md +90 -0
- package/skills/wix-manage/SKILL.md +14 -4
- package/skills/wix-manage/references/blog/how-to-create-blog-posts.md +2 -0
- package/skills/wix-manage/references/dashboard-navigation/dashboard-navigation.md +2 -1
- package/skills/wix-manage/references/dashboard-navigation/routes.json +249 -0
- package/skills/wix-manage/references/donations/create-and-update-donation-campaigns.md +139 -0
- package/skills/wix-manage/references/events/events-dashboard-navigation.md +81 -0
- package/skills/wix-manage/references/seo/manage-content-plan.md +207 -222
- package/skills/wix-manage/references/sites/manage-oauth-apps.md +1 -0
- package/skills/wix-manage/references/sites/upload-static-site.md +128 -8
- package/skills/wix-readme/SKILL.md +166 -0
- package/skills/wix-replatform/.publish-manifest.json +5 -5
- package/skills/wix-replatform/CLI.md +162 -0
- package/skills/wix-replatform/README.md +52 -0
- package/skills/wix-replatform/SKILL.md +229 -684
- package/skills/wix-replatform/console/account.css +1 -0
- package/skills/wix-replatform/console/app.css +1 -0
- package/skills/wix-replatform/console/app.js +117 -0
- package/skills/wix-replatform/console/index.html +4 -0
- package/skills/wix-replatform/console/json.css +11 -0
- package/skills/wix-replatform/lib/agent-adapters/index.js +71 -0
- package/skills/wix-replatform/lib/app-page-routing.js +75 -0
- package/skills/wix-replatform/lib/artifact-freshness.js +11 -1
- package/skills/wix-replatform/lib/blocked-data-requests.js +427 -0
- package/skills/wix-replatform/lib/census-reconciliation.js +426 -0
- package/skills/wix-replatform/lib/completion-report.js +1393 -13
- package/skills/wix-replatform/lib/config-env.js +85 -11
- package/skills/wix-replatform/lib/confirmed-pictures.js +212 -0
- package/skills/wix-replatform/lib/dependency-readiness.js +423 -0
- package/skills/wix-replatform/lib/dependency-recovery.js +21 -0
- package/skills/wix-replatform/lib/destination-choice.js +163 -0
- package/skills/wix-replatform/lib/destination-handoff.js +62 -0
- package/skills/wix-replatform/lib/destination-http.js +81 -0
- package/skills/wix-replatform/lib/destination-route.js +98 -0
- package/skills/wix-replatform/lib/destination.js +919 -0
- package/skills/wix-replatform/lib/discovered-census.js +231 -0
- package/skills/wix-replatform/lib/discovered-set-status.js +255 -0
- package/skills/wix-replatform/lib/document-url-guard.js +203 -0
- package/skills/wix-replatform/lib/entity-qa-attestation.js +339 -0
- package/skills/wix-replatform/lib/entity-verification.js +18 -0
- package/skills/wix-replatform/lib/execution-capability.js +120 -0
- package/skills/wix-replatform/lib/execution-log.js +170 -0
- package/skills/wix-replatform/lib/execution-manifest.js +20 -2
- package/skills/wix-replatform/lib/execution-state.js +22 -0
- package/skills/wix-replatform/lib/expectations-ledger.js +96 -0
- package/skills/wix-replatform/lib/generated-plugin-handoff.js +140 -0
- package/skills/wix-replatform/lib/import-readiness-contract.js +23 -0
- package/skills/wix-replatform/lib/import-recovery.js +800 -6
- package/skills/wix-replatform/lib/imported-redirect-targets.js +608 -0
- package/skills/wix-replatform/lib/internal-link-reconciliation.js +166 -0
- package/skills/wix-replatform/lib/link-audit.js +173 -0
- package/skills/wix-replatform/lib/link-census.js +194 -0
- package/skills/wix-replatform/lib/link-plan.js +148 -0
- package/skills/wix-replatform/lib/link-verification.js +274 -0
- package/skills/wix-replatform/lib/link-write-journal.js +42 -0
- package/skills/wix-replatform/lib/local-state.js +869 -30
- package/skills/wix-replatform/lib/member-completion.js +658 -0
- package/skills/wix-replatform/lib/member-crosswalk.js +69 -0
- package/skills/wix-replatform/lib/member-outcome-registry.js +265 -0
- package/skills/wix-replatform/lib/migration-completion.js +311 -0
- package/skills/wix-replatform/lib/operator-identity.js +47 -0
- package/skills/wix-replatform/lib/orchestration-decisions.js +248 -0
- package/skills/wix-replatform/lib/orchestration-preflight.js +401 -19
- package/skills/wix-replatform/lib/orchestration-router.js +608 -32
- package/skills/wix-replatform/lib/orchestration-state.js +188 -12
- package/skills/wix-replatform/lib/order-reference-readiness.js +30 -0
- package/skills/wix-replatform/lib/payments-outcome-registry.js +200 -0
- package/skills/wix-replatform/lib/plugin-cms-fallback.js +618 -0
- package/skills/wix-replatform/lib/preservation-approval-stamp.js +54 -0
- package/skills/wix-replatform/lib/product-media-deferral.js +96 -0
- package/skills/wix-replatform/lib/progress-log.js +19 -3
- package/skills/wix-replatform/lib/read-back-approval.js +184 -0
- package/skills/wix-replatform/lib/read-back-comparison.js +136 -0
- package/skills/wix-replatform/lib/read-back-contract.js +243 -0
- package/skills/wix-replatform/lib/read-back-extract.js +118 -0
- package/skills/wix-replatform/lib/read-back-gate.js +734 -0
- package/skills/wix-replatform/lib/read-back-reads.js +94 -0
- package/skills/wix-replatform/lib/read-back-state.js +107 -0
- package/skills/wix-replatform/lib/read-back-summary.js +81 -0
- package/skills/wix-replatform/lib/rerun-conflicts.js +334 -0
- package/skills/wix-replatform/lib/run-controller.js +401 -0
- package/skills/wix-replatform/lib/seo-outcome-registry.js +45 -0
- package/skills/wix-replatform/lib/setup-verification.js +148 -0
- package/skills/wix-replatform/lib/source-access.js +231 -0
- package/skills/wix-replatform/lib/source-coverage.js +1130 -0
- package/skills/wix-replatform/lib/source-secrets.js +277 -0
- package/skills/wix-replatform/lib/structured-link-patch.js +59 -0
- package/skills/wix-replatform/lib/task-state.js +110 -0
- package/skills/wix-replatform/lib/url-preservation-report.js +319 -0
- package/skills/wix-replatform/lib/url-preservation-state.js +349 -1
- package/skills/wix-replatform/lib/url-redirect-plan.js +728 -0
- package/skills/wix-replatform/lib/url-verification.js +315 -0
- package/skills/wix-replatform/lib/user-action-effects.js +42 -0
- package/skills/wix-replatform/lib/user-actions.js +264 -0
- package/skills/wix-replatform/lib/website-handoff.js +1220 -0
- package/skills/wix-replatform/lib/wix-client-callers.js +54 -0
- package/skills/wix-replatform/lib/wix-dashboard-url.js +35 -0
- package/skills/wix-replatform/lib/write-verification-state.js +92 -0
- package/skills/wix-replatform/lib/write-verification.js +274 -0
- package/skills/wix-replatform/resources/rp-destination/SKILL.md +137 -0
- package/skills/wix-replatform/resources/rp-discovery/SKILL.md +189 -16
- package/skills/wix-replatform/resources/rp-discovery/scripts/promote-source-coverage.js +47 -0
- package/skills/wix-replatform/resources/rp-execute-import/SKILL.md +869 -29
- package/skills/wix-replatform/resources/rp-execute-import/scripts/shipping-estimate-audit.js +70 -0
- package/skills/wix-replatform/resources/rp-execute-setup/SKILL.md +195 -29
- package/skills/wix-replatform/resources/rp-execute-setup/scripts/execute-setup.js +442 -0
- package/skills/wix-replatform/resources/rp-execution-policy/SKILL.md +112 -0
- package/skills/wix-replatform/resources/rp-execution-policy/lib/coupon-currency-plan-report.js +143 -0
- package/skills/wix-replatform/resources/rp-execution-policy/lib/payments-report.js +244 -0
- package/skills/wix-replatform/resources/rp-import-codegen/SKILL.md +2082 -38
- package/skills/wix-replatform/resources/rp-mapper/SKILL.md +528 -11
- package/skills/wix-replatform/resources/rp-mapper/lib/structure-bridge-planning.js +303 -0
- package/skills/wix-replatform/resources/rp-mapper/scripts/coverage-reconcile.js +88 -0
- package/skills/wix-replatform/resources/rp-mapper/wix-business-solutions-taxonomy.md +6 -5
- package/skills/wix-replatform/resources/rp-preflight/SKILL.md +40 -0
- package/skills/wix-replatform/resources/rp-project-intake/SKILL.md +55 -0
- package/skills/wix-replatform/resources/rp-quick-runtime/SKILL.md +60 -0
- package/skills/wix-replatform/resources/rp-quick-runtime/lib/import-progress.js +89 -0
- package/skills/wix-replatform/resources/rp-quick-runtime/lib/limit-recovery.js +36 -0
- package/skills/wix-replatform/resources/rp-quick-shopify/SKILL.md +123 -0
- package/skills/wix-replatform/resources/rp-quick-shopify/quick-mode.json +124 -0
- package/skills/wix-replatform/resources/rp-quick-shopify/scripts/quick-mode.js +522 -0
- package/skills/wix-replatform/resources/rp-quick-woocommerce/SKILL.md +56 -0
- package/skills/wix-replatform/resources/rp-quick-woocommerce/quick-mode.json +91 -0
- package/skills/wix-replatform/resources/rp-quick-woocommerce/scripts/quick-mode.js +255 -0
- package/skills/wix-replatform/resources/rp-setup-discovery/SKILL.md +80 -10
- package/skills/wix-replatform/resources/rp-setup-discovery/scripts/quick-setup-plan.js +44 -0
- package/skills/wix-replatform/resources/rp-source-csv/SKILL.md +3 -0
- package/skills/wix-replatform/resources/rp-source-csv/lib/csv-fileset.js +0 -0
- package/skills/wix-replatform/resources/rp-source-csv/scripts/csv-discovery.js +21 -1
- package/skills/wix-replatform/resources/rp-source-inputs/SKILL.md +66 -0
- package/skills/wix-replatform/resources/rp-source-sfcc/SKILL.md +153 -0
- package/skills/wix-replatform/resources/rp-source-shopify/SKILL.md +394 -0
- package/skills/wix-replatform/resources/rp-source-shopify/lib/discovery-reads.js +200 -0
- package/skills/wix-replatform/resources/rp-source-shopify/lib/import-findings.js +34 -0
- package/skills/wix-replatform/resources/rp-source-shopify/lib/shopify-bulk-sqlite-worker.js +44 -0
- package/skills/wix-replatform/resources/rp-source-shopify/lib/shopify-bulk.js +1470 -0
- package/skills/wix-replatform/resources/rp-source-shopify/lib/shopify-cli.js +446 -0
- package/skills/wix-replatform/resources/rp-source-shopify/lib/shopify-gift-cards.js +474 -0
- package/skills/wix-replatform/resources/rp-source-shopify/lib/shopify-protected-fields.js +879 -0
- package/skills/wix-replatform/resources/rp-source-shopify/lib/shopify-session.js +426 -0
- package/skills/wix-replatform/resources/rp-source-shopify/queries/articles.graphql +24 -0
- package/skills/wix-replatform/resources/rp-source-shopify/queries/blogs.graphql +18 -0
- package/skills/wix-replatform/resources/rp-source-shopify/queries/collections.graphql +40 -0
- package/skills/wix-replatform/resources/rp-source-shopify/queries/customers.graphql +76 -0
- package/skills/wix-replatform/resources/rp-source-shopify/queries/delivery-profiles.graphql +51 -0
- package/skills/wix-replatform/resources/rp-source-shopify/queries/discounts.graphql +35 -0
- package/skills/wix-replatform/resources/rp-source-shopify/queries/files.graphql +20 -0
- package/skills/wix-replatform/resources/rp-source-shopify/queries/gift-cards.graphql +18 -0
- package/skills/wix-replatform/resources/rp-source-shopify/queries/inventory.graphql +31 -0
- package/skills/wix-replatform/resources/rp-source-shopify/queries/locations.graphql +21 -0
- package/skills/wix-replatform/resources/rp-source-shopify/queries/menus.graphql +21 -0
- package/skills/wix-replatform/resources/rp-source-shopify/queries/metaobjects.graphql +30 -0
- package/skills/wix-replatform/resources/rp-source-shopify/queries/orders-core.graphql +150 -0
- package/skills/wix-replatform/resources/rp-source-shopify/queries/orders-fulfillments.graphql +36 -0
- package/skills/wix-replatform/resources/rp-source-shopify/queries/orders-refunds.graphql +48 -0
- package/skills/wix-replatform/resources/rp-source-shopify/queries/pages.graphql +20 -0
- package/skills/wix-replatform/resources/rp-source-shopify/queries/probe-customers-address.graphql +8 -0
- package/skills/wix-replatform/resources/rp-source-shopify/queries/probe-customers-email.graphql +6 -0
- package/skills/wix-replatform/resources/rp-source-shopify/queries/probe-customers-name.graphql +8 -0
- package/skills/wix-replatform/resources/rp-source-shopify/queries/probe-customers-phone.graphql +8 -0
- package/skills/wix-replatform/resources/rp-source-shopify/queries/probe-orders-address.graphql +12 -0
- package/skills/wix-replatform/resources/rp-source-shopify/queries/probe-orders-email.graphql +6 -0
- package/skills/wix-replatform/resources/rp-source-shopify/queries/probe-orders-name.graphql +13 -0
- package/skills/wix-replatform/resources/rp-source-shopify/queries/probe-orders-phone.graphql +13 -0
- package/skills/wix-replatform/resources/rp-source-shopify/queries/products.graphql +73 -0
- package/skills/wix-replatform/resources/rp-source-shopify/queries/url-redirects.graphql +13 -0
- package/skills/wix-replatform/resources/rp-source-shopify/scripts/shopify-discovery.js +693 -0
- package/skills/wix-replatform/resources/rp-source-shopify/scripts/shopify-extract.js +283 -0
- package/skills/wix-replatform/resources/rp-source-shopify/scripts/shopify-gift-card-remedy.js +191 -0
- package/skills/wix-replatform/resources/rp-source-shopify/scripts/shopify-session-check.js +115 -0
- package/skills/wix-replatform/resources/rp-source-shopify/source-schema.example.json +201 -0
- package/skills/wix-replatform/resources/rp-source-wordpress/PLUGIN-READ-PLANS.md +146 -0
- package/skills/wix-replatform/resources/rp-source-wordpress/SKILL.md +736 -22
- package/skills/wix-replatform/resources/rp-source-wordpress/lib/blocked-data-handlers.js +73 -0
- package/skills/wix-replatform/resources/rp-source-wordpress/lib/checkout-field-csv-parser.js +115 -0
- package/skills/wix-replatform/resources/rp-source-wordpress/lib/checkout-field-csv-parser.test-fixture.js +91 -0
- package/skills/wix-replatform/resources/rp-source-wordpress/lib/coupon-discovery.js +440 -0
- package/skills/wix-replatform/resources/rp-source-wordpress/lib/currency-gate.js +125 -0
- package/skills/wix-replatform/resources/rp-source-wordpress/lib/gateway-source-keys.js +252 -0
- package/skills/wix-replatform/resources/rp-source-wordpress/lib/gateway-source-keys.json +183 -0
- package/skills/wix-replatform/resources/rp-source-wordpress/lib/gateway-summary.mjs +333 -0
- package/skills/wix-replatform/resources/rp-source-wordpress/lib/invoice-discovery.js +426 -0
- package/skills/wix-replatform/resources/rp-source-wordpress/lib/plugin-disposition.js +400 -0
- package/skills/wix-replatform/resources/rp-source-wordpress/lib/plugin-entity-read-plan.js +633 -0
- package/skills/wix-replatform/resources/rp-source-wordpress/lib/plugin-knowledge.js +1127 -0
- package/skills/wix-replatform/resources/rp-source-wordpress/lib/refund-corroboration.js +194 -0
- package/skills/wix-replatform/resources/rp-source-wordpress/lib/refund-corroboration.json +100 -0
- package/skills/wix-replatform/resources/rp-source-wordpress/lib/sampled-ids-batch.js +157 -0
- package/skills/wix-replatform/resources/rp-source-wordpress/lib/secret-value-guard.js +234 -0
- package/skills/wix-replatform/resources/rp-source-wordpress/lib/store-currency.js +101 -0
- package/skills/wix-replatform/resources/rp-source-wordpress/lib/structure-bridge-reader.js +755 -0
- package/skills/wix-replatform/resources/rp-source-wordpress/lib/wix-wp-plugin-v2-client.js +1074 -0
- package/skills/wix-replatform/resources/rp-source-wordpress/lib/wix-wp-plugin-v2-client.test-fixture.js +149 -0
- package/skills/wix-replatform/resources/rp-source-wordpress/lib/woo-inventory.js +25 -0
- package/skills/wix-replatform/resources/rp-source-wordpress/lib/wp-http.js +204 -9
- package/skills/wix-replatform/resources/rp-source-wordpress/lib/wp-image-url.js +186 -0
- package/skills/wix-replatform/resources/rp-source-wordpress/lib/wp-plugin-detect.js +1422 -0
- package/skills/wix-replatform/resources/rp-source-wordpress/lib/wp-redirect-sources.js +343 -0
- package/skills/wix-replatform/resources/rp-source-wordpress/lib/wp-route-classifier.js +262 -26
- package/skills/wix-replatform/resources/rp-source-wordpress/lib/yoast-product-seo-evidence.js +272 -0
- package/skills/wix-replatform/resources/rp-source-wordpress/plugins/README.md +373 -0
- package/skills/wix-replatform/resources/rp-source-wordpress/plugins/advanced-custom-fields.json +101 -0
- package/skills/wix-replatform/resources/rp-source-wordpress/plugins/back-in-stock-notifier-for-woocommerce.json +81 -0
- package/skills/wix-replatform/resources/rp-source-wordpress/plugins/capabilities-pending-decision.json +128 -0
- package/skills/wix-replatform/resources/rp-source-wordpress/plugins/cms-fallback-eligible.json +18 -0
- package/skills/wix-replatform/resources/rp-source-wordpress/plugins/contact-form-7.json +104 -0
- package/skills/wix-replatform/resources/rp-source-wordpress/plugins/facebook-for-woocommerce.json +44 -0
- package/skills/wix-replatform/resources/rp-source-wordpress/plugins/fingerprint-aliases.json +49 -0
- package/skills/wix-replatform/resources/rp-source-wordpress/plugins/free-gifts-for-woocommerce.json +94 -0
- package/skills/wix-replatform/resources/rp-source-wordpress/plugins/index.json +863 -0
- package/skills/wix-replatform/resources/rp-source-wordpress/plugins/mailpoet.json +52 -0
- package/skills/wix-replatform/resources/rp-source-wordpress/plugins/membership-for-woocommerce.json +161 -0
- package/skills/wix-replatform/resources/rp-source-wordpress/plugins/mwb-bookings-for-woocommerce.json +180 -0
- package/skills/wix-replatform/resources/rp-source-wordpress/plugins/no-migration-needed.json +286 -0
- package/skills/wix-replatform/resources/rp-source-wordpress/plugins/pricing-deals-for-woocommerce.json +79 -0
- package/skills/wix-replatform/resources/rp-source-wordpress/plugins/product-extras-for-woocommerce.json +120 -0
- package/skills/wix-replatform/resources/rp-source-wordpress/plugins/pw-woocommerce-gift-cards.json +128 -0
- package/skills/wix-replatform/resources/rp-source-wordpress/plugins/requires-development.json +88 -0
- package/skills/wix-replatform/resources/rp-source-wordpress/plugins/seo-by-rank-math.json +80 -0
- package/skills/wix-replatform/resources/rp-source-wordpress/plugins/seriously-simple-podcasting.json +46 -0
- package/skills/wix-replatform/resources/rp-source-wordpress/plugins/strong-testimonials.json +55 -0
- package/skills/wix-replatform/resources/rp-source-wordpress/plugins/subscriptions-for-woocommerce.json +99 -0
- package/skills/wix-replatform/resources/rp-source-wordpress/plugins/tablepress.json +55 -0
- package/skills/wix-replatform/resources/rp-source-wordpress/plugins/the-events-calendar.json +160 -0
- package/skills/wix-replatform/resources/rp-source-wordpress/plugins/ti-woocommerce-wishlist.json +81 -0
- package/skills/wix-replatform/resources/rp-source-wordpress/plugins/woo-checkout-field-editor-pro.json +60 -0
- package/skills/wix-replatform/resources/rp-source-wordpress/plugins/woo-discount-rules.json +74 -0
- package/skills/wix-replatform/resources/rp-source-wordpress/plugins/woo-product-bundle.json +75 -0
- package/skills/wix-replatform/resources/rp-source-wordpress/plugins/woocommerce-gift-cards.json +60 -0
- package/skills/wix-replatform/resources/rp-source-wordpress/plugins/woocommerce-other-payment-gateway.json +44 -0
- package/skills/wix-replatform/resources/rp-source-wordpress/plugins/woocommerce-pdf-invoices-packing-slips.json +57 -0
- package/skills/wix-replatform/resources/rp-source-wordpress/plugins/woocommerce-product-addon.json +141 -0
- package/skills/wix-replatform/resources/rp-source-wordpress/plugins/woocommerce-progressive-discounts.json +54 -0
- package/skills/wix-replatform/resources/rp-source-wordpress/plugins/wordpress-seo.json +158 -0
- package/skills/wix-replatform/resources/rp-source-wordpress/plugins/wpc-composite-products.json +97 -0
- package/skills/wix-replatform/resources/rp-source-wordpress/plugins/wpforms-lite.json +86 -0
- package/skills/wix-replatform/resources/rp-source-wordpress/scripts/capture-store-settings.js +90 -0
- package/skills/wix-replatform/resources/rp-source-wordpress/scripts/plugin-knowledge-validate.js +51 -0
- package/skills/wix-replatform/resources/rp-source-wordpress/scripts/plugin-knowledge.js +103 -0
- package/skills/wix-replatform/resources/rp-source-wordpress/scripts/wp-discovery.js +1668 -33
- package/skills/wix-replatform/resources/rp-source-wordpress/scripts/wp-plugin-inventory.js +273 -0
- package/skills/wix-replatform/resources/rp-source-wordpress/secret-value-patterns.v1.json +11 -0
- package/skills/wix-replatform/resources/rp-source-wordpress/sub-parts.json +13 -0
- package/skills/wix-replatform/resources/rp-target-wix/SKILL.md +446 -32
- package/skills/wix-replatform/resources/rp-target-wix/app-page-routing-capabilities.json +36 -0
- package/skills/wix-replatform/resources/rp-target-wix/domains/README.md +38 -2
- package/skills/wix-replatform/resources/rp-target-wix/domains/SERVICE-PLUGINS.md +322 -0
- package/skills/wix-replatform/resources/rp-target-wix/domains/blog/docs-survey.json +70 -0
- package/skills/wix-replatform/resources/rp-target-wix/domains/blog/domain.json +19 -9
- package/skills/wix-replatform/resources/rp-target-wix/domains/blog/entities/category.json +42 -8
- package/skills/wix-replatform/resources/rp-target-wix/domains/blog/entities/comment.json +54 -8
- package/skills/wix-replatform/resources/rp-target-wix/domains/blog/entities/post.json +66 -10
- package/skills/wix-replatform/resources/rp-target-wix/domains/blog/entities/tag.json +38 -7
- package/skills/wix-replatform/resources/rp-target-wix/domains/bookings/docs-survey.json +332 -0
- package/skills/wix-replatform/resources/rp-target-wix/domains/bookings/domain.json +75 -0
- package/skills/wix-replatform/resources/rp-target-wix/domains/bookings/entities/booking.json +181 -0
- package/skills/wix-replatform/resources/rp-target-wix/domains/bookings/entities/service-add-on.json +130 -0
- package/skills/wix-replatform/resources/rp-target-wix/domains/bookings/entities/service.json +180 -0
- package/skills/wix-replatform/resources/rp-target-wix/domains/cms/docs-survey.json +161 -0
- package/skills/wix-replatform/resources/rp-target-wix/domains/cms/domain.json +15 -4
- package/skills/wix-replatform/resources/rp-target-wix/domains/cms/entities/collection.json +39 -7
- package/skills/wix-replatform/resources/rp-target-wix/domains/cms/entities/data-item.json +47 -8
- package/skills/wix-replatform/resources/rp-target-wix/domains/cms/entities/reference.json +7 -1
- package/skills/wix-replatform/resources/rp-target-wix/domains/crm/docs-survey.json +204 -0
- package/skills/wix-replatform/resources/rp-target-wix/domains/crm/domain.json +17 -4
- package/skills/wix-replatform/resources/rp-target-wix/domains/crm/entities/contact.json +159 -15
- package/skills/wix-replatform/resources/rp-target-wix/domains/crm/entities/email-subscription.json +80 -12
- package/skills/wix-replatform/resources/rp-target-wix/domains/crm/entities/label.json +48 -8
- package/skills/wix-replatform/resources/rp-target-wix/domains/ecom/docs-survey.json +306 -0
- package/skills/wix-replatform/resources/rp-target-wix/domains/ecom/domain.json +30 -7
- package/skills/wix-replatform/resources/rp-target-wix/domains/ecom/entities/delivery-profile.json +171 -0
- package/skills/wix-replatform/resources/rp-target-wix/domains/ecom/entities/discount-rule.json +182 -0
- package/skills/wix-replatform/resources/rp-target-wix/domains/ecom/entities/order-applied-discount.json +129 -0
- package/skills/wix-replatform/resources/rp-target-wix/domains/ecom/entities/order-invoice-document.json +192 -0
- package/skills/wix-replatform/resources/rp-target-wix/domains/ecom/entities/order-line-item-options.json +123 -0
- package/skills/wix-replatform/resources/rp-target-wix/domains/ecom/entities/order-line-item.json +60 -12
- package/skills/wix-replatform/resources/rp-target-wix/domains/ecom/entities/order-merchant-note.json +112 -0
- package/skills/wix-replatform/resources/rp-target-wix/domains/ecom/entities/order-payment.json +191 -0
- package/skills/wix-replatform/resources/rp-target-wix/domains/ecom/entities/order-refund.json +140 -13
- package/skills/wix-replatform/resources/rp-target-wix/domains/ecom/entities/order.json +383 -18
- package/skills/wix-replatform/resources/rp-target-wix/domains/ecom/entities/pickup-location.json +122 -0
- package/skills/wix-replatform/resources/rp-target-wix/domains/ecom/entities/shipping-option.json +98 -0
- package/skills/wix-replatform/resources/rp-target-wix/domains/ecom/entities/wishlist-item.json +86 -0
- package/skills/wix-replatform/resources/rp-target-wix/domains/events/docs-survey.json +128 -0
- package/skills/wix-replatform/resources/rp-target-wix/domains/events/domain.json +38 -0
- package/skills/wix-replatform/resources/rp-target-wix/domains/events/entities/category.json +73 -0
- package/skills/wix-replatform/resources/rp-target-wix/domains/events/entities/event.json +107 -0
- package/skills/wix-replatform/resources/rp-target-wix/domains/events/entities/registration-form.json +89 -0
- package/skills/wix-replatform/resources/rp-target-wix/domains/events/entities/rsvp.json +118 -0
- package/skills/wix-replatform/resources/rp-target-wix/domains/events/entities/ticket-definition.json +93 -0
- package/skills/wix-replatform/resources/rp-target-wix/domains/forms/docs-survey.json +86 -0
- package/skills/wix-replatform/resources/rp-target-wix/domains/forms/domain.json +56 -0
- package/skills/wix-replatform/resources/rp-target-wix/domains/forms/entities/form-submission.json +121 -0
- package/skills/wix-replatform/resources/rp-target-wix/domains/forms/entities/form.json +134 -0
- package/skills/wix-replatform/resources/rp-target-wix/domains/gift-cards/docs-survey.json +41 -0
- package/skills/wix-replatform/resources/rp-target-wix/domains/gift-cards/domain.json +50 -0
- package/skills/wix-replatform/resources/rp-target-wix/domains/gift-cards/entities/gift-card-product.json +87 -0
- package/skills/wix-replatform/resources/rp-target-wix/domains/gift-cards/entities/gift-card.json +130 -0
- package/skills/wix-replatform/resources/rp-target-wix/domains/index.json +914 -24
- package/skills/wix-replatform/resources/rp-target-wix/domains/media/docs-survey.json +41 -0
- package/skills/wix-replatform/resources/rp-target-wix/domains/media/domain.json +14 -4
- package/skills/wix-replatform/resources/rp-target-wix/domains/media/entities/media-file.json +45 -8
- package/skills/wix-replatform/resources/rp-target-wix/domains/media/entities/media-folder.json +41 -7
- package/skills/wix-replatform/resources/rp-target-wix/domains/members/docs-survey.json +119 -0
- package/skills/wix-replatform/resources/rp-target-wix/domains/members/domain.json +13 -3
- package/skills/wix-replatform/resources/rp-target-wix/domains/members/entities/badge.json +41 -7
- package/skills/wix-replatform/resources/rp-target-wix/domains/members/entities/custom-field.json +82 -0
- package/skills/wix-replatform/resources/rp-target-wix/domains/members/entities/member-about.json +77 -0
- package/skills/wix-replatform/resources/rp-target-wix/domains/members/entities/member.json +165 -13
- package/skills/wix-replatform/resources/rp-target-wix/domains/pricing-plans/docs-survey.json +41 -0
- package/skills/wix-replatform/resources/rp-target-wix/domains/pricing-plans/domain.json +46 -0
- package/skills/wix-replatform/resources/rp-target-wix/domains/pricing-plans/entities/plan-order.json +137 -0
- package/skills/wix-replatform/resources/rp-target-wix/domains/pricing-plans/entities/plan.json +133 -0
- package/skills/wix-replatform/resources/rp-target-wix/domains/sales-channels/docs-survey.json +7 -0
- package/skills/wix-replatform/resources/rp-target-wix/domains/sales-channels/domain.json +36 -0
- package/skills/wix-replatform/resources/rp-target-wix/domains/sales-channels/entities/amazon-shop-connect.json +71 -0
- package/skills/wix-replatform/resources/rp-target-wix/domains/sales-channels/entities/ebay-shop-connect.json +67 -0
- package/skills/wix-replatform/resources/rp-target-wix/domains/sales-channels/entities/google-youtube-connect.json +72 -0
- package/skills/wix-replatform/resources/rp-target-wix/domains/sales-channels/entities/meta-catalog-connect.json +74 -0
- package/skills/wix-replatform/resources/rp-target-wix/domains/sales-channels/entities/pinterest-catalog-connect.json +69 -0
- package/skills/wix-replatform/resources/rp-target-wix/domains/sales-channels/entities/tiktok-catalog-connect.json +61 -0
- package/skills/wix-replatform/resources/rp-target-wix/domains/schema.json +28 -1
- package/skills/wix-replatform/resources/rp-target-wix/domains/seo/docs-survey.json +109 -0
- package/skills/wix-replatform/resources/rp-target-wix/domains/seo/domain.json +73 -0
- package/skills/wix-replatform/resources/rp-target-wix/domains/seo/entities/item-seo-tags.json +148 -0
- package/skills/wix-replatform/resources/rp-target-wix/domains/seo/entities/seo-pattern.json +91 -0
- package/skills/wix-replatform/resources/rp-target-wix/domains/seo/entities/site-seo-tags.json +79 -0
- package/skills/wix-replatform/resources/rp-target-wix/domains/site/docs-survey.json +32 -0
- package/skills/wix-replatform/resources/rp-target-wix/domains/site/domain.json +49 -0
- package/skills/wix-replatform/resources/rp-target-wix/domains/site/entities/business-contact.json +103 -0
- package/skills/wix-replatform/resources/rp-target-wix/domains/stores/docs-survey.json +203 -0
- package/skills/wix-replatform/resources/rp-target-wix/domains/stores/domain.json +27 -10
- package/skills/wix-replatform/resources/rp-target-wix/domains/stores/entities/back-in-stock-request.json +119 -0
- package/skills/wix-replatform/resources/rp-target-wix/domains/stores/entities/brand.json +111 -0
- package/skills/wix-replatform/resources/rp-target-wix/domains/stores/entities/category.json +52 -8
- package/skills/wix-replatform/resources/rp-target-wix/domains/stores/entities/coupon.json +214 -10
- package/skills/wix-replatform/resources/rp-target-wix/domains/stores/entities/inventory-item.json +93 -13
- package/skills/wix-replatform/resources/rp-target-wix/domains/stores/entities/product-customization.json +111 -0
- package/skills/wix-replatform/resources/rp-target-wix/domains/stores/entities/product-tag.json +52 -10
- package/skills/wix-replatform/resources/rp-target-wix/domains/stores/entities/product.json +145 -14
- package/skills/wix-replatform/resources/rp-target-wix/domains/stores/entities/promotion.json +84 -0
- package/skills/wix-replatform/resources/rp-target-wix/domains/stores/entities/review.json +178 -0
- package/skills/wix-replatform/resources/rp-target-wix/domains/stores/entities/subscription-product.json +87 -0
- package/skills/wix-replatform/resources/rp-target-wix/domains/tax/docs-survey.json +106 -0
- package/skills/wix-replatform/resources/rp-target-wix/domains/tax/domain.json +64 -0
- package/skills/wix-replatform/resources/rp-target-wix/domains/tax/entities/manual-tax-mapping.json +119 -0
- package/skills/wix-replatform/resources/rp-target-wix/domains/tax/entities/tax-group.json +94 -0
- package/skills/wix-replatform/resources/rp-target-wix/domains/tax/entities/tax-region.json +113 -0
- package/skills/wix-replatform/resources/rp-target-wix/domains/tax/entities/tax-settings.json +65 -0
- package/skills/wix-replatform/resources/rp-target-wix/lib/blog-author-attribution.js +165 -0
- package/skills/wix-replatform/resources/rp-target-wix/lib/blog-post-build-client.js +60 -0
- package/skills/wix-replatform/resources/rp-target-wix/lib/blog-post-build-duplicates.js +201 -0
- package/skills/wix-replatform/resources/rp-target-wix/lib/blog-post-build-ledger.js +306 -0
- package/skills/wix-replatform/resources/rp-target-wix/lib/blog-post-build-report.js +229 -0
- package/skills/wix-replatform/resources/rp-target-wix/lib/blog-post-build-stage.js +55 -0
- package/skills/wix-replatform/resources/rp-target-wix/lib/blog-post-build.js +715 -0
- package/skills/wix-replatform/resources/rp-target-wix/lib/blog-post-media.js +567 -0
- package/skills/wix-replatform/resources/rp-target-wix/lib/bulk-results.js +73 -0
- package/skills/wix-replatform/resources/rp-target-wix/lib/contact-extended-fields.js +194 -0
- package/skills/wix-replatform/resources/rp-target-wix/lib/contact-import.js +133 -0
- package/skills/wix-replatform/resources/rp-target-wix/lib/contract-ledger.js +13 -4
- package/skills/wix-replatform/resources/rp-target-wix/lib/coupon-redemption-drift.js +491 -0
- package/skills/wix-replatform/resources/rp-target-wix/lib/customer-member.js +104 -0
- package/skills/wix-replatform/resources/rp-target-wix/lib/data-extension-schema.js +673 -0
- package/skills/wix-replatform/resources/rp-target-wix/lib/domain-knowledge.js +453 -2
- package/skills/wix-replatform/resources/rp-target-wix/lib/gift-card-balance-reconciliation.js +119 -0
- package/skills/wix-replatform/resources/rp-target-wix/lib/gift-card-build.js +566 -0
- package/skills/wix-replatform/resources/rp-target-wix/lib/gift-card-redemption-build.js +249 -0
- package/skills/wix-replatform/resources/rp-target-wix/lib/order-applied-discount-build.js +63 -0
- package/skills/wix-replatform/resources/rp-target-wix/lib/order-buyer.js +187 -0
- package/skills/wix-replatform/resources/rp-target-wix/lib/order-channel-build.js +64 -0
- package/skills/wix-replatform/resources/rp-target-wix/lib/order-history.js +1027 -0
- package/skills/wix-replatform/resources/rp-target-wix/lib/order-invoice-contract.js +90 -0
- package/skills/wix-replatform/resources/rp-target-wix/lib/order-payment-mapping.js +420 -0
- package/skills/wix-replatform/resources/rp-target-wix/lib/pricing-plan-definition.js +177 -0
- package/skills/wix-replatform/resources/rp-target-wix/lib/product-import.js +151 -0
- package/skills/wix-replatform/resources/rp-target-wix/lib/product-seo.js +723 -0
- package/skills/wix-replatform/resources/rp-target-wix/lib/seo-redirects.js +353 -0
- package/skills/wix-replatform/resources/rp-target-wix/lib/shipping-build.js +1437 -0
- package/skills/wix-replatform/resources/rp-target-wix/lib/shipping-option-stage.js +354 -0
- package/skills/wix-replatform/resources/rp-target-wix/lib/store-config-build.js +134 -0
- package/skills/wix-replatform/resources/rp-target-wix/lib/stores-category-attach.js +221 -0
- package/skills/wix-replatform/resources/rp-target-wix/lib/stores-inventory.js +248 -0
- package/skills/wix-replatform/resources/rp-target-wix/lib/stores-verification.js +86 -3
- package/skills/wix-replatform/resources/rp-target-wix/lib/tax-build.js +231 -0
- package/skills/wix-replatform/resources/rp-target-wix/lib/url-mapper-transport.js +28 -0
- package/skills/wix-replatform/resources/rp-target-wix/lib/value-utils.js +14 -0
- package/skills/wix-replatform/resources/rp-target-wix/lib/variant-correlation.js +34 -0
- package/skills/wix-replatform/resources/rp-target-wix/lib/wix-build.js +166 -15
- package/skills/wix-replatform/resources/rp-target-wix/lib/wix-target-spec.js +19 -2
- package/skills/wix-replatform/resources/rp-target-wix/lib/wix-writers.js +4079 -257
- package/skills/wix-replatform/resources/rp-target-wix/lib/write-verification.js +3 -0
- package/skills/wix-replatform/resources/rp-target-wix/scripts/docs-survey-sync.js +150 -0
- package/skills/wix-replatform/resources/rp-target-wix/scripts/domain-knowledge-validate.js +40 -2
- package/skills/wix-replatform/resources/rp-target-wix/scripts/verify-stores.js +6 -1
- package/skills/wix-replatform/resources/rp-telemetry/SKILL.md +148 -8
- package/skills/wix-replatform/resources/rp-telemetry/lib/bi-sink.js +83 -15
- package/skills/wix-replatform/resources/rp-telemetry/lib/telemetry-recorder.js +1119 -215
- package/skills/wix-replatform/resources/rp-telemetry/lib/transcript-digest.js +318 -0
- package/skills/wix-replatform/resources/rp-telemetry/scripts/meter-from-audit.js +2 -2
- package/skills/wix-replatform/resources/rp-telemetry/scripts/rp-telemetry.js +106 -4
- package/skills/wix-replatform/resources/rp-website-continuation/SKILL.md +94 -0
- package/skills/wix-replatform/scripts/census-reconciliation.js +25 -0
- package/skills/wix-replatform/scripts/cms-fallback.js +89 -0
- package/skills/wix-replatform/scripts/discovered-census.js +26 -0
- package/skills/wix-replatform/scripts/discovered-set-status.js +33 -0
- package/skills/wix-replatform/scripts/entity-qa-attestation.js +130 -0
- package/skills/wix-replatform/scripts/execution-health-check.js +415 -0
- package/skills/wix-replatform/scripts/execution-manifest-validate.js +1 -1
- package/skills/wix-replatform/scripts/execution-state-prepare.js +1 -1
- package/skills/wix-replatform/scripts/expectations-ledger.js +44 -0
- package/skills/wix-replatform/scripts/import-contract-verify.js +183 -0
- package/skills/wix-replatform/scripts/internal-link-audit.js +90 -0
- package/skills/wix-replatform/scripts/item-seo-tags-verify.js +205 -0
- package/skills/wix-replatform/scripts/migration-completion.js +76 -0
- package/skills/wix-replatform/scripts/orchestration-preflight.js +21 -2
- package/skills/wix-replatform/scripts/orchestration-route.js +32 -1
- package/skills/wix-replatform/scripts/orchestration-state.js +146 -10
- package/skills/wix-replatform/scripts/read-back-gate.js +175 -0
- package/skills/wix-replatform/scripts/replatform-console.js +146 -0
- package/skills/wix-replatform/scripts/replatform.js +436 -0
- package/skills/wix-replatform/scripts/source-secrets.js +77 -0
- package/skills/wix-replatform/scripts/url-redirects.js +286 -0
- package/skills/wix-replatform/scripts/user-action.js +58 -0
- package/skills/wix-replatform/scripts/website-handoff-generate.js +64 -0
- package/skills/wix-replatform/scripts/wix-dashboard-url.js +54 -0
- package/skills/wix-replatform/scripts/wix-destination.js +143 -0
- package/skills/wix-replatform/scripts/wix-headless-scaffold.js +762 -0
- package/skills/wix-vibe-headless/SKILL.md +7 -3
- package/skills/wix-vibe-headless/install/deploy.cjs +61 -34
- package/skills/wix-vibe-headless/platforms/base44.md +1 -0
- package/skills/wix-vibe-headless/references/donations/INSTRUCTIONS.md +88 -0
- package/skills/wix-vibe-headless/references/donations/app/rest/wix-donations.js +112 -0
- package/skills/wix-vibe-headless/references/donations/seed/SEED.md +11 -0
- package/skills/wix-vibe-headless/references/donations/tests/donations.test.mjs +258 -0
- package/skills/wix-vibe-headless/references/restaurants/INSTRUCTIONS.md +5 -2
- package/skills/wix-vibe-headless/references/restaurants/app/context/OrderCartContext.jsx +4 -1
- package/skills/wix-vibe-headless/references/restaurants/app/rest/wix-restaurants-ordering.js +67 -3
- package/skills/wix-vibe-headless/references/shared/app/rest/wix-client.js +4 -3
- package/skills/wix-replatform/resources/rp-target-wix/SPEC-product-reviews-and-blog-authorship.md +0 -330
|
@@ -1,9 +1,17 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
const { isDeniedGatewayRoute } = require('./wp-http.js');
|
|
4
|
+
|
|
3
5
|
const ROUTE_CATEGORIES = new Set([
|
|
4
6
|
'backend_data',
|
|
5
7
|
'backend_metadata',
|
|
6
8
|
'public_commerce_data',
|
|
9
|
+
// A route whose response carries live credentials. Distinct from the other exclusions
|
|
10
|
+
// because those describe scope ("this is presentation, not data"), while this one describes
|
|
11
|
+
// danger: the route holds data we genuinely want (which gateways exist, which are enabled)
|
|
12
|
+
// wrapped around a secret we must never receive. Naming it makes the intent visible in the
|
|
13
|
+
// classification output instead of surfacing only as a transport-level refusal.
|
|
14
|
+
'excluded_credential_bearing',
|
|
7
15
|
'excluded_frontend',
|
|
8
16
|
'excluded_template_editor',
|
|
9
17
|
'excluded_runtime_session',
|
|
@@ -102,8 +110,20 @@ const BACKEND_DATA_RULES = [
|
|
|
102
110
|
['/wc/v3/orders*', 'wc.data.orders', 'WooCommerce orders are canonical store data'],
|
|
103
111
|
['/wc/v3/refunds*', 'wc.data.refunds', 'WooCommerce refunds are canonical store data'],
|
|
104
112
|
['/wc/v3/customers*', 'wc.data.customers', 'WooCommerce customers are canonical store data'],
|
|
113
|
+
// Must precede /wc/v3/taxes* (first-match-wins) — it's a prefix of that route.
|
|
114
|
+
['/wc/v3/taxes/classes*', 'wc.data.tax-classes', 'WooCommerce tax classes are canonical store data'],
|
|
105
115
|
['/wc/v3/taxes*', 'wc.data.taxes', 'WooCommerce taxes are canonical store data'],
|
|
106
|
-
|
|
116
|
+
// The store's OWN configuration: address, currency, which countries it sells to, whether tax
|
|
117
|
+
// is calculated. Canonical store data, not marketplace noise — it was landing in
|
|
118
|
+
// excluded_unsupported and was never sampled on any run, so a migrated site published with an
|
|
119
|
+
// empty business address and nobody noticed.
|
|
120
|
+
// NOTE the REST index advertises the PARAMETERIZED form `/wc/v3/settings/(?P<group>...)`, not
|
|
121
|
+
// this literal, so this rule alone does not cause a fetch — the group is read directly by the
|
|
122
|
+
// caller, the same way a shipping zone's /locations and /methods sub-resources are. The rule
|
|
123
|
+
// exists so that when the literal IS advertised it is classified as data rather than excluded.
|
|
124
|
+
['/wc/v3/settings/general', 'wc.data.store-settings-general', 'WooCommerce general settings hold the store address, currency and selling countries — canonical store configuration'],
|
|
125
|
+
['/wc/v3/shipping/zones', 'wc.data.shipping-zones', 'WooCommerce shipping zones are canonical store configuration'],
|
|
126
|
+
['/wc/v3/shipping_methods', 'wc.data.shipping-method-types', 'WooCommerce shipping method types are canonical store configuration'],
|
|
107
127
|
];
|
|
108
128
|
|
|
109
129
|
const BACKEND_METADATA_RULES = [
|
|
@@ -121,12 +141,70 @@ const BACKEND_METADATA_RULES = [
|
|
|
121
141
|
},
|
|
122
142
|
];
|
|
123
143
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
144
|
+
// Route -> extra query parameters the sampler must send to see the WHOLE collection.
|
|
145
|
+
//
|
|
146
|
+
// A WP REST collection route is free to apply a default filter when the caller sends no
|
|
147
|
+
// parameters, and several do. Discovery samples with `per_page` and nothing else, so it
|
|
148
|
+
// silently sees the filtered subset and the plan under-counts — the entity looks smaller
|
|
149
|
+
// than it is and the hidden records never reach the mapper. This is a CLASS of bug, not one
|
|
150
|
+
// route: any route with a defaulted status/type/scope filter has it.
|
|
151
|
+
//
|
|
152
|
+
// The fix is a table, not a special case in the sampler: add the route and the parameters
|
|
153
|
+
// that turn the filter off, with the reason. Kept next to the other route pattern tables
|
|
154
|
+
// (BACKEND_DATA_RULES et al.) because these are facts about core routes; patterns use the
|
|
155
|
+
// same `*` suffix matching, longest pattern wins, and a route with no entry gets `{}`.
|
|
156
|
+
const ROUTE_DEFAULT_QUERY_RULES = [
|
|
157
|
+
[
|
|
158
|
+
'/wc/v3/products/reviews*',
|
|
159
|
+
{ status: 'all' },
|
|
160
|
+
'WooCommerce defaults product reviews to status=approved, hiding hold/spam/trash rows; observed live 2026-08-16: on-hold reviews are invisible to the plan unless status=all is passed',
|
|
161
|
+
],
|
|
128
162
|
];
|
|
129
163
|
|
|
164
|
+
function defaultQueryRuleFor(routePath) {
|
|
165
|
+
const normalized = normalizeRoutePath(routePath);
|
|
166
|
+
return ROUTE_DEFAULT_QUERY_RULES
|
|
167
|
+
.filter(([pattern]) => routeMatchesPattern(normalized, pattern))
|
|
168
|
+
.sort((a, b) => b[0].length - a[0].length)[0] || null;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
// The query parameters to add when sampling `routePath`, or {} when the route has no
|
|
172
|
+
// documented default filter. Copied so a caller cannot mutate the rule table; callers merge
|
|
173
|
+
// their own paging parameters over the result.
|
|
174
|
+
function defaultQueryFor(routePath) {
|
|
175
|
+
const rule = defaultQueryRuleFor(routePath);
|
|
176
|
+
return rule ? { ...rule[1] } : {};
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// The human-readable reason a default query applies, for the discovery note that tells a
|
|
180
|
+
// reader why this route was sampled with extra parameters. Null when none applies.
|
|
181
|
+
function defaultQueryReasonFor(routePath) {
|
|
182
|
+
const rule = defaultQueryRuleFor(routePath);
|
|
183
|
+
return rule ? rule[2] : null;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
// Plugin route rules are DATA, not code: they come from the declarative profiles under
|
|
187
|
+
// plugins/. Adding or correcting a plugin is a JSON edit plus a fixture, never a change
|
|
188
|
+
// here. Loaded once and memoized; tests inject rules directly via overrides.pluginRules.
|
|
189
|
+
let memoizedPluginRules = null;
|
|
190
|
+
|
|
191
|
+
function defaultPluginRules() {
|
|
192
|
+
if (memoizedPluginRules) return memoizedPluginRules;
|
|
193
|
+
try {
|
|
194
|
+
// Required lazily so this module stays usable (with no plugin rules) if the profile
|
|
195
|
+
// directory is absent, e.g. a partial install.
|
|
196
|
+
const { pluginsRoot, buildRouteRules } = require('./plugin-knowledge.js');
|
|
197
|
+
memoizedPluginRules = buildRouteRules(pluginsRoot());
|
|
198
|
+
} catch (error) {
|
|
199
|
+
memoizedPluginRules = { dataRules: [], excludeRules: [], loadError: error.message };
|
|
200
|
+
}
|
|
201
|
+
return memoizedPluginRules;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
function resetPluginRuleCache() {
|
|
205
|
+
memoizedPluginRules = null;
|
|
206
|
+
}
|
|
207
|
+
|
|
130
208
|
const LEGACY_WC_PREFIXES = [
|
|
131
209
|
'/wc/v1/products',
|
|
132
210
|
'/wc/v1/coupons',
|
|
@@ -134,14 +212,14 @@ const LEGACY_WC_PREFIXES = [
|
|
|
134
212
|
'/wc/v1/refunds',
|
|
135
213
|
'/wc/v1/customers',
|
|
136
214
|
'/wc/v1/taxes',
|
|
137
|
-
'/wc/v1/
|
|
215
|
+
'/wc/v1/taxes/classes',
|
|
138
216
|
'/wc/v2/products',
|
|
139
217
|
'/wc/v2/coupons',
|
|
140
218
|
'/wc/v2/orders',
|
|
141
219
|
'/wc/v2/refunds',
|
|
142
220
|
'/wc/v2/customers',
|
|
143
221
|
'/wc/v2/taxes',
|
|
144
|
-
'/wc/v2/
|
|
222
|
+
'/wc/v2/taxes/classes',
|
|
145
223
|
];
|
|
146
224
|
|
|
147
225
|
function normalizeRoutePath(routePath) {
|
|
@@ -163,6 +241,23 @@ function routeMatchesPattern(routePath, pattern) {
|
|
|
163
241
|
return route === pattern;
|
|
164
242
|
}
|
|
165
243
|
|
|
244
|
+
// A WP REST index parameterized route looks like /wc/v3/orders/(?P<id>[\d]+)/notes.
|
|
245
|
+
// Normalizing every parameter segment to the same {parentId} placeholder a plugin-rest-child
|
|
246
|
+
// entity's `route` template uses lets that template be checked against the index without
|
|
247
|
+
// needing to know (or match) the parameter's name.
|
|
248
|
+
function normalizeIndexRouteTemplate(routePath) {
|
|
249
|
+
return routePath.replace(/\(\?P<[^>]+>[^)]*\)/g, '{parentId}');
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
// Whether the site's REST index advertises a route matching a plugin-rest-child entity's
|
|
253
|
+
// templated route (e.g. /wc/v3/orders/{parentId}/notes). This is a presence check only — it
|
|
254
|
+
// says the sub-resource exists on this site, not that any parent record actually has data
|
|
255
|
+
// there; that requires a live per-parent sample (see wp-discovery.js sampleChildEntities).
|
|
256
|
+
function childRouteAdvertised(restIndexRoutes, template) {
|
|
257
|
+
const routes = restIndexRoutes && typeof restIndexRoutes === 'object' ? Object.keys(restIndexRoutes) : [];
|
|
258
|
+
return routes.some((route) => normalizeIndexRouteTemplate(route) === template);
|
|
259
|
+
}
|
|
260
|
+
|
|
166
261
|
function findMatchingRule(routePath, rules) {
|
|
167
262
|
for (const rule of rules) {
|
|
168
263
|
const [pattern, ruleId, reason] = rule;
|
|
@@ -173,6 +268,21 @@ function findMatchingRule(routePath, rules) {
|
|
|
173
268
|
return null;
|
|
174
269
|
}
|
|
175
270
|
|
|
271
|
+
// Route patterns for the credential-bearing category, listed so coreRulePatterns() can refuse a
|
|
272
|
+
// plugin profile that tries to declare one of them as a data route. The MATCH itself is
|
|
273
|
+
// isDeniedGatewayRoute() in wp-http.js — one definition of "this is a gateway route" driving
|
|
274
|
+
// both the classifier and the transport deny, so the two layers cannot drift into disagreeing
|
|
275
|
+
// about which routes they cover.
|
|
276
|
+
const CREDENTIAL_BEARING_PATTERNS = [
|
|
277
|
+
'/wc/v1/payment_gateways*',
|
|
278
|
+
'/wc/v2/payment_gateways*',
|
|
279
|
+
'/wc/v3/payment_gateways*',
|
|
280
|
+
];
|
|
281
|
+
|
|
282
|
+
const CREDENTIAL_BEARING_REASON =
|
|
283
|
+
'WooCommerce payment-gateway routes return each gateway\'s full settings object, including live '
|
|
284
|
+
+ 'API keys and secrets; read gateway identity and enablement through fetchGatewaySummary() instead';
|
|
285
|
+
|
|
176
286
|
function actionForCategory(category) {
|
|
177
287
|
if (category === 'backend_data' || category === 'public_commerce_data') {
|
|
178
288
|
return 'sample';
|
|
@@ -191,7 +301,7 @@ function makeClassification(candidate, category, reason, ruleId, extra = {}) {
|
|
|
191
301
|
reason,
|
|
192
302
|
ruleId,
|
|
193
303
|
sampleByDefault: category === 'backend_data',
|
|
194
|
-
canIncludeByOverride: category !== 'backend_data',
|
|
304
|
+
canIncludeByOverride: category !== 'backend_data' && category !== 'excluded_credential_bearing',
|
|
195
305
|
includedByOverride: false,
|
|
196
306
|
excludedByOverride: false,
|
|
197
307
|
effectiveAction: actionForCategory(category),
|
|
@@ -268,23 +378,72 @@ function classifyLegacyWooCommerceRoute(candidate, routeSet) {
|
|
|
268
378
|
);
|
|
269
379
|
}
|
|
270
380
|
|
|
381
|
+
const EXCLUSION_RULE_GROUPS = [
|
|
382
|
+
['excluded_frontend', FRONTEND_RULES],
|
|
383
|
+
['excluded_template_editor', TEMPLATE_EDITOR_RULES],
|
|
384
|
+
['excluded_runtime_session', RUNTIME_RULES],
|
|
385
|
+
['excluded_admin_dashboard', ADMIN_RULES],
|
|
386
|
+
['excluded_marketplace_setup', MARKETPLACE_RULES],
|
|
387
|
+
['excluded_diagnostics', DIAGNOSTIC_RULES],
|
|
388
|
+
['excluded_integration', INTEGRATION_RULES],
|
|
389
|
+
];
|
|
390
|
+
|
|
391
|
+
function findExclusion(routePath) {
|
|
392
|
+
for (const [category, rules] of EXCLUSION_RULE_GROUPS) {
|
|
393
|
+
const rule = findMatchingRule(routePath, rules);
|
|
394
|
+
if (rule) return { category, ...rule };
|
|
395
|
+
}
|
|
396
|
+
return null;
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
// Every route pattern owned by the classifier itself. Exported so the plugin knowledge
|
|
400
|
+
// validator can refuse a profile route that silently shadows a core rule.
|
|
401
|
+
function coreRulePatterns() {
|
|
402
|
+
const patterns = new Set(CREDENTIAL_BEARING_PATTERNS);
|
|
403
|
+
for (const [, rules] of EXCLUSION_RULE_GROUPS) {
|
|
404
|
+
for (const [pattern] of rules) patterns.add(pattern);
|
|
405
|
+
}
|
|
406
|
+
for (const [pattern] of BACKEND_DATA_RULES) patterns.add(pattern);
|
|
407
|
+
for (const rule of BACKEND_METADATA_RULES) patterns.add(rule.pattern);
|
|
408
|
+
return patterns;
|
|
409
|
+
}
|
|
410
|
+
|
|
271
411
|
function classifyBaseRoute(candidate, routeSet, options = {}) {
|
|
272
412
|
const routePath = candidate.routePath;
|
|
273
|
-
const
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
413
|
+
const pluginRules = options.pluginRules || { dataRules: [], excludeRules: [] };
|
|
414
|
+
|
|
415
|
+
// FIRST, above the plugin profile rules and above every exclusion family. A profile's
|
|
416
|
+
// explicitly-listed data route beats an exclusion family by design, which is exactly why this
|
|
417
|
+
// check has to sit above that mechanism rather than inside it — a credential-bearing route is
|
|
418
|
+
// not a scope judgement a plugin author gets to overturn.
|
|
419
|
+
if (isDeniedGatewayRoute(routePath)) {
|
|
420
|
+
return makeClassification(candidate, 'excluded_credential_bearing', CREDENTIAL_BEARING_REASON, 'wc.credential-bearing.payment-gateways');
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
// Precedence: profile excludeRoutes > profile data routes > existing
|
|
424
|
+
// category rules > collection-shape fallback > unsupported.default. Profile data routes
|
|
425
|
+
// beat exclusion families because an explicitly listed route IS the per-capability
|
|
426
|
+
// opt-in; profiles cannot use a broad wildcard to reopen a family (validator enforces
|
|
427
|
+
// at least two concrete leading segments).
|
|
428
|
+
const pluginExclusion = findMatchingRule(routePath, pluginRules.excludeRules);
|
|
429
|
+
if (pluginExclusion) {
|
|
430
|
+
const existing = findExclusion(routePath);
|
|
431
|
+
return makeClassification(
|
|
432
|
+
candidate,
|
|
433
|
+
existing ? existing.category : 'excluded_unsupported',
|
|
434
|
+
pluginExclusion.reason,
|
|
435
|
+
pluginExclusion.ruleId,
|
|
436
|
+
);
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
const pluginData = findMatchingRule(routePath, pluginRules.dataRules);
|
|
440
|
+
if (pluginData) {
|
|
441
|
+
return makeClassification(candidate, 'backend_data', pluginData.reason, pluginData.ruleId);
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
const exclusion = findExclusion(routePath);
|
|
445
|
+
if (exclusion) {
|
|
446
|
+
return makeClassification(candidate, exclusion.category, exclusion.reason, exclusion.ruleId);
|
|
288
447
|
}
|
|
289
448
|
|
|
290
449
|
const storeCatalogClassification = classifyStoreCatalogRoute(candidate, routeSet, options);
|
|
@@ -309,9 +468,24 @@ function classifyBaseRoute(candidate, routeSet, options = {}) {
|
|
|
309
468
|
});
|
|
310
469
|
}
|
|
311
470
|
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
471
|
+
// Registered non-core post types and taxonomies are persisted-record collections by
|
|
472
|
+
// definition, so /wp/v2/types + /wp/v2/taxonomies are positive evidence rather than a
|
|
473
|
+
// heuristic. This is the rule that makes custom post types discoverable at all:
|
|
474
|
+
// VERIFIED LIVE 2026-07-30 that the WordPress REST index advertises `schema` on ZERO
|
|
475
|
+
// routes, so the collection-shape fallbacks below — which
|
|
476
|
+
// require hasSchema() — never fire in production. Without this rule a plugin CPT is
|
|
477
|
+
// invisible unless someone hardcodes its route.
|
|
478
|
+
const registered = options.registeredRestBases instanceof Map
|
|
479
|
+
? options.registeredRestBases.get(routePath)
|
|
480
|
+
: null;
|
|
481
|
+
if (registered) {
|
|
482
|
+
return makeClassification(
|
|
483
|
+
candidate,
|
|
484
|
+
'backend_data',
|
|
485
|
+
`${registered.kind === 'taxonomy' ? 'taxonomy' : 'post type'} "${registered.slug}" is registered and REST-visible, so its collection holds persisted records`,
|
|
486
|
+
'wp.data.registered-type',
|
|
487
|
+
{ registeredType: registered.slug, registeredKind: registered.kind, hierarchical: registered.hierarchical === true },
|
|
488
|
+
);
|
|
315
489
|
}
|
|
316
490
|
|
|
317
491
|
if (candidate.namespace === 'wp/v2' && candidateHasCollectionShape(candidate) && hasSchema(candidate)) {
|
|
@@ -355,9 +529,46 @@ function normalizeOverrides(overrides = {}) {
|
|
|
355
529
|
excludeRoutes: normalizeList(overrides.excludeRoutes).map(normalizeRoutePath),
|
|
356
530
|
overrideReason: overrides.overrideReason ? String(overrides.overrideReason) : null,
|
|
357
531
|
commerceMode: overrides.commerceMode === 'public' ? 'public' : 'authenticated',
|
|
532
|
+
// Tests and callers may inject rules; otherwise the checked-in profiles are used.
|
|
533
|
+
pluginRules: overrides.pluginRules || defaultPluginRules(),
|
|
534
|
+
registeredRestBases: overrides.registeredRestBases instanceof Map ? overrides.registeredRestBases : null,
|
|
358
535
|
};
|
|
359
536
|
}
|
|
360
537
|
|
|
538
|
+
// Build the route -> registered-type lookup consumed by the wp.data.registered-type rule.
|
|
539
|
+
// Core types/taxonomies are excluded: they already have explicit allowlist rules, or are
|
|
540
|
+
// deliberately excluded site-composition surfaces.
|
|
541
|
+
const CORE_POST_TYPE_SLUGS = new Set([
|
|
542
|
+
'post', 'page', 'attachment', 'nav_menu_item', 'wp_block', 'wp_template',
|
|
543
|
+
'wp_template_part', 'wp_navigation', 'wp_font_family', 'wp_font_face', 'wp_global_styles',
|
|
544
|
+
'product', 'product_variation', 'shop_order', 'shop_order_refund', 'shop_coupon',
|
|
545
|
+
]);
|
|
546
|
+
const CORE_TAXONOMY_SLUGS = new Set([
|
|
547
|
+
'category', 'post_tag', 'nav_menu', 'link_category', 'post_format', 'wp_pattern_category',
|
|
548
|
+
'product_cat', 'product_tag', 'product_brand', 'product_shipping_class', 'product_type', 'product_visibility',
|
|
549
|
+
]);
|
|
550
|
+
|
|
551
|
+
function buildRegisteredRestBases({ types = null, taxonomies = null } = {}) {
|
|
552
|
+
const map = new Map();
|
|
553
|
+
const add = (kind, slug, entry, coreSlugs) => {
|
|
554
|
+
if (!entry || coreSlugs.has(slug)) return;
|
|
555
|
+
if (entry.show_in_rest === false) return;
|
|
556
|
+
const restBase = entry.rest_base || entry.slug || slug;
|
|
557
|
+
if (!restBase) return;
|
|
558
|
+
const namespace = entry.rest_namespace || 'wp/v2';
|
|
559
|
+
map.set(`/${namespace}/${restBase}`, {
|
|
560
|
+
kind,
|
|
561
|
+
slug,
|
|
562
|
+
restBase,
|
|
563
|
+
hierarchical: entry.hierarchical === true,
|
|
564
|
+
attachedToTypes: Array.isArray(entry.types) ? [...entry.types] : [],
|
|
565
|
+
});
|
|
566
|
+
};
|
|
567
|
+
for (const [slug, entry] of Object.entries(types || {})) add('post-type', slug, entry, CORE_POST_TYPE_SLUGS);
|
|
568
|
+
for (const [slug, entry] of Object.entries(taxonomies || {})) add('taxonomy', slug, entry, CORE_TAXONOMY_SLUGS);
|
|
569
|
+
return map;
|
|
570
|
+
}
|
|
571
|
+
|
|
361
572
|
function isIncludedCategory(category, includeExcludedCategories) {
|
|
362
573
|
return includeExcludedCategories.includes(category) || includeExcludedCategories.includes('all');
|
|
363
574
|
}
|
|
@@ -406,8 +617,19 @@ function classifyRoutes(candidates, overrides = {}) {
|
|
|
406
617
|
};
|
|
407
618
|
}
|
|
408
619
|
|
|
620
|
+
// `--include-route` and `--include-excluded-category` are operator overrides for scope
|
|
621
|
+
// judgements. They are not an override for a route that hands back live credentials, so a
|
|
622
|
+
// credential-bearing route stays `skip` no matter what was passed. The transport refuses it
|
|
623
|
+
// as well (wp-http.js); this layer is what keeps the CLI's own report honest rather than
|
|
624
|
+
// promising a sample it will never take.
|
|
409
625
|
const includeRoute = normalizedOverrides.includeRoutes.includes(candidate.routePath);
|
|
410
626
|
const includeCategory = isIncludedCategory(classification.category, normalizedOverrides.includeExcludedCategories);
|
|
627
|
+
if ((includeRoute || includeCategory) && classification.category === 'excluded_credential_bearing') {
|
|
628
|
+
return {
|
|
629
|
+
...classification,
|
|
630
|
+
reason: `${classification.reason}; requested by override and refused`,
|
|
631
|
+
};
|
|
632
|
+
}
|
|
411
633
|
if (includeRoute || includeCategory) {
|
|
412
634
|
return {
|
|
413
635
|
...classification,
|
|
@@ -437,8 +659,22 @@ function summarizeSkippedByCategory(classifications) {
|
|
|
437
659
|
|
|
438
660
|
module.exports = {
|
|
439
661
|
ROUTE_CATEGORIES,
|
|
662
|
+
CREDENTIAL_BEARING_PATTERNS,
|
|
663
|
+
// Re-exported so the plugin-profile validator can refuse a credential-bearing route without
|
|
664
|
+
// reaching into the transport module itself.
|
|
665
|
+
isCredentialBearingRoute: isDeniedGatewayRoute,
|
|
440
666
|
classifyRoutes,
|
|
441
667
|
normalizeOverrides,
|
|
442
668
|
routeMatchesPattern,
|
|
669
|
+
childRouteAdvertised,
|
|
443
670
|
summarizeSkippedByCategory,
|
|
671
|
+
coreRulePatterns,
|
|
672
|
+
ROUTE_DEFAULT_QUERY_RULES,
|
|
673
|
+
defaultQueryFor,
|
|
674
|
+
defaultQueryReasonFor,
|
|
675
|
+
defaultPluginRules,
|
|
676
|
+
resetPluginRuleCache,
|
|
677
|
+
buildRegisteredRestBases,
|
|
678
|
+
CORE_POST_TYPE_SLUGS,
|
|
679
|
+
CORE_TAXONOMY_SLUGS,
|
|
444
680
|
};
|
|
@@ -0,0 +1,272 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// Per-field Yoast override evidence for WooCommerce products.
|
|
4
|
+
//
|
|
5
|
+
// `yoast_head_json` is Yoast's RENDERED output: it can carry a title for every product while the
|
|
6
|
+
// raw override meta holds none. Importing the rendered text turns an inherited template into
|
|
7
|
+
// hundreds of hard per-product overrides. So this module
|
|
8
|
+
// decides, per product and per field, whether the SOURCE proves an override, and records how it
|
|
9
|
+
// knows. Rendered output alone is never proof; it only supplies the decoded value once the raw
|
|
10
|
+
// meta has proven the field was overridden.
|
|
11
|
+
//
|
|
12
|
+
// Deterministic by design. The only I/O is the caller-supplied `queryPage` (a bound
|
|
13
|
+
// wix-wp-plugin-v2 `queryStructure`), so every branch is unit-testable offline.
|
|
14
|
+
|
|
15
|
+
const FIELD_KEYS = Object.freeze({
|
|
16
|
+
title: '_yoast_wpseo_title',
|
|
17
|
+
description: '_yoast_wpseo_metadesc',
|
|
18
|
+
focusKeyword: '_yoast_wpseo_focuskw',
|
|
19
|
+
});
|
|
20
|
+
// Exact allow-list; never widened by key discovery.
|
|
21
|
+
const ALLOWED_KEYS = Object.freeze(Object.values(FIELD_KEYS));
|
|
22
|
+
const SEO_FIELDS = Object.freeze(Object.keys(FIELD_KEYS));
|
|
23
|
+
const HEAD_FIELD = Object.freeze({ title: 'title', description: 'description' });
|
|
24
|
+
const STATES = Object.freeze(['override', 'inherit', 'unknown']);
|
|
25
|
+
|
|
26
|
+
// A post_id list is sent inline in the `where` clause, so keep one batch well inside a request.
|
|
27
|
+
const DEFAULT_BRIDGE_BATCH = 50;
|
|
28
|
+
const MAX_BRIDGE_BATCH = 200;
|
|
29
|
+
const MAX_BRIDGE_PAGES = 1000;
|
|
30
|
+
|
|
31
|
+
function isBlank(value) {
|
|
32
|
+
return value == null || String(value).trim() === '';
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const NAMED_ENTITIES = Object.freeze({
|
|
36
|
+
amp: '&', lt: '<', gt: '>', quot: '"', apos: "'", nbsp: ' ', ndash: '–', mdash: '—',
|
|
37
|
+
hellip: '…', lsquo: '‘', rsquo: '’', ldquo: '“', rdquo: '”', laquo: '«',
|
|
38
|
+
raquo: '»', copy: '©', reg: '®', trade: '™', middot: '·', bull: '•',
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
// Exactly ONE decoding pass. `&amp;` becomes `&`, never `&`: decoding repeatedly would
|
|
42
|
+
// corrupt a title that legitimately contains an entity-looking string.
|
|
43
|
+
function decodeEntitiesOnce(value) {
|
|
44
|
+
return String(value).replace(/&(#x[0-9a-f]+|#\d+|[a-z]+);/gi, (match, body) => {
|
|
45
|
+
if (body[0] === '#') {
|
|
46
|
+
const code = body[1] === 'x' || body[1] === 'X' ? parseInt(body.slice(2), 16) : parseInt(body.slice(1), 10);
|
|
47
|
+
return Number.isInteger(code) && code > 0 && code <= 0x10ffff ? String.fromCodePoint(code) : match;
|
|
48
|
+
}
|
|
49
|
+
const named = NAMED_ENTITIES[body.toLowerCase()];
|
|
50
|
+
return named === undefined ? match : named;
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function sanitizeRendered(value) {
|
|
55
|
+
if (typeof value !== 'string') return null;
|
|
56
|
+
const decoded = decodeEntitiesOnce(value).trim();
|
|
57
|
+
return decoded === '' ? null : decoded;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// Channel 1: the product post's REST `meta` object. A key counts only when `meta` contains it;
|
|
61
|
+
// a response without the key (not registered for the product type, or unauthenticated) leaves
|
|
62
|
+
// that key unresolved -- never "no override" -- so it can fall through to the bridge.
|
|
63
|
+
function restEvidence({ response, path = null } = {}) {
|
|
64
|
+
const meta = response && typeof response.meta === 'object' && !Array.isArray(response.meta) ? response.meta : null;
|
|
65
|
+
const out = {};
|
|
66
|
+
for (const key of ALLOWED_KEYS) {
|
|
67
|
+
if (meta && Object.prototype.hasOwnProperty.call(meta, key)) {
|
|
68
|
+
out[key] = { resolved: true, raw: meta[key], evidenceRef: { path, keyPresentInMeta: true } };
|
|
69
|
+
} else {
|
|
70
|
+
out[key] = { resolved: false, reason: meta ? 'key-absent-from-rest-meta' : 'rest-meta-unavailable', evidenceRef: { path } };
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
return out;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function pinnedKeysOf(eavAccess, keyColumn) {
|
|
77
|
+
if (!eavAccess) return null;
|
|
78
|
+
const pairs = [eavAccess, ...(eavAccess.additionalPairs || [])];
|
|
79
|
+
const pair = pairs.find((p) => p && p.keyColumn === keyColumn);
|
|
80
|
+
if (!pair || pair.tier !== 'key-scoped' || !Array.isArray(pair.pinnedKeys)) return null;
|
|
81
|
+
return pair.pinnedKeys;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// Channel 2: wix-wp-plugin-v2 key-scoped postmeta read, paginated to exhaustion.
|
|
85
|
+
// `queryPage({ structureRequest, cursor })` resolves to queryStructure's `{ rows, pagingMetadata,
|
|
86
|
+
// eavAccess }`. A batch is COMPLETE only when every page succeeded, the response proved a
|
|
87
|
+
// key-scoped read of every queried key, and the last page reported no next cursor. Anything else
|
|
88
|
+
// leaves the batch incomplete -- and only that batch.
|
|
89
|
+
async function readBridgeEvidence({ queryPage, table, productIds, keys = ALLOWED_KEYS, batchSize = DEFAULT_BRIDGE_BATCH, keyColumn = 'meta_key', valueColumn = 'meta_value', idColumn = 'post_id', orderColumn = 'meta_id' } = {}) {
|
|
90
|
+
if (typeof queryPage !== 'function') throw new Error('readBridgeEvidence: queryPage is required');
|
|
91
|
+
if (!table || typeof table !== 'string') throw new Error('readBridgeEvidence: table (the prefixed postmeta table) is required');
|
|
92
|
+
if (!Array.isArray(productIds)) throw new Error('readBridgeEvidence: productIds must be an array');
|
|
93
|
+
if (!Number.isInteger(batchSize) || batchSize < 1 || batchSize > MAX_BRIDGE_BATCH) {
|
|
94
|
+
throw new Error(`readBridgeEvidence: batchSize must be 1..${MAX_BRIDGE_BATCH}`);
|
|
95
|
+
}
|
|
96
|
+
const wanted = [...new Set(keys)];
|
|
97
|
+
if (!wanted.length || wanted.some((key) => !ALLOWED_KEYS.includes(key))) {
|
|
98
|
+
throw new Error(`readBridgeEvidence: keys must be a non-empty subset of ${ALLOWED_KEYS.join(', ')}`);
|
|
99
|
+
}
|
|
100
|
+
const ids = [...new Set(productIds.map(String))];
|
|
101
|
+
const batches = [];
|
|
102
|
+
for (let start = 0, index = 0; start < ids.length; start += batchSize, index += 1) {
|
|
103
|
+
const batchIds = ids.slice(start, start + batchSize);
|
|
104
|
+
const structureRequest = {
|
|
105
|
+
table,
|
|
106
|
+
select: [{ column: orderColumn }, { column: idColumn }, { column: keyColumn }, { column: valueColumn }],
|
|
107
|
+
where: [
|
|
108
|
+
{ column: keyColumn, op: 'in', value: wanted },
|
|
109
|
+
{ column: idColumn, op: 'in', value: batchIds.map((id) => (/^\d+$/.test(id) ? Number(id) : id)) },
|
|
110
|
+
],
|
|
111
|
+
orderBy: [{ column: orderColumn, direction: 'asc' }],
|
|
112
|
+
};
|
|
113
|
+
const batch = { batchId: `yoast-bridge-${index}`, productIds: batchIds, keys: wanted, pageCount: 0, complete: false, finalHasNext: null, reason: null, failedPage: null, rows: [] };
|
|
114
|
+
let cursor;
|
|
115
|
+
for (;;) {
|
|
116
|
+
if (batch.pageCount >= MAX_BRIDGE_PAGES) { batch.reason = 'page-limit-exceeded'; break; }
|
|
117
|
+
let page;
|
|
118
|
+
try {
|
|
119
|
+
page = await queryPage({ structureRequest, cursor });
|
|
120
|
+
} catch (error) {
|
|
121
|
+
batch.failedPage = batch.pageCount + 1;
|
|
122
|
+
batch.reason = `page ${batch.failedPage} failed: ${error && error.message ? error.message : String(error)}`;
|
|
123
|
+
break;
|
|
124
|
+
}
|
|
125
|
+
batch.pageCount += 1;
|
|
126
|
+
const pinned = pinnedKeysOf(page && page.eavAccess, keyColumn);
|
|
127
|
+
if (!pinned || wanted.some((key) => !pinned.includes(key))) {
|
|
128
|
+
batch.failedPage = batch.pageCount;
|
|
129
|
+
batch.reason = `page ${batch.pageCount} did not prove a key-scoped read of every queried key`;
|
|
130
|
+
break;
|
|
131
|
+
}
|
|
132
|
+
if (!page || !Array.isArray(page.rows) || !page.pagingMetadata || typeof page.pagingMetadata.hasNext !== 'boolean') {
|
|
133
|
+
batch.failedPage = batch.pageCount;
|
|
134
|
+
batch.reason = `page ${batch.pageCount} had no rows/pagingMetadata`;
|
|
135
|
+
break;
|
|
136
|
+
}
|
|
137
|
+
for (const row of page.rows) {
|
|
138
|
+
batch.rows.push({ productId: String(row[idColumn]), key: row[keyColumn], value: row[valueColumn] });
|
|
139
|
+
}
|
|
140
|
+
batch.finalHasNext = page.pagingMetadata.hasNext;
|
|
141
|
+
if (!page.pagingMetadata.hasNext) { batch.complete = true; break; }
|
|
142
|
+
const next = page.pagingMetadata.cursors && page.pagingMetadata.cursors.next;
|
|
143
|
+
if (!next) { batch.reason = `page ${batch.pageCount} reported hasNext without a cursor (truncated)`; break; }
|
|
144
|
+
cursor = next;
|
|
145
|
+
}
|
|
146
|
+
batches.push(batch);
|
|
147
|
+
}
|
|
148
|
+
return batches;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
function resolveOverrideValue(field, raw, yoastHeadJson) {
|
|
152
|
+
if (field === 'focusKeyword') return { value: String(raw).trim() };
|
|
153
|
+
const rendered = sanitizeRendered(yoastHeadJson && yoastHeadJson[HEAD_FIELD[field]]);
|
|
154
|
+
if (rendered !== null) return { value: rendered };
|
|
155
|
+
const trimmed = String(raw).trim();
|
|
156
|
+
if (!trimmed.includes('%%')) return { value: trimmed };
|
|
157
|
+
return { unknown: 'override-has-yoast-variables-and-no-resolved-value' };
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// The per-product audit receipt. It is stored with the extraction and is NOT hashed as a
|
|
161
|
+
// whole; only `seoHashProjection` (rp-target-wix/lib/product-seo.js) feeds the source hash.
|
|
162
|
+
function buildProductSeoReceipt({ productId, capturedAt, rest = null, bridgeBatch = null, yoastHeadJson = null } = {}) {
|
|
163
|
+
if (productId == null || String(productId) === '') throw new Error('buildProductSeoReceipt: productId is required');
|
|
164
|
+
if (!capturedAt) throw new Error('buildProductSeoReceipt: capturedAt is required');
|
|
165
|
+
const id = String(productId);
|
|
166
|
+
const fields = {};
|
|
167
|
+
for (const field of SEO_FIELDS) {
|
|
168
|
+
const key = FIELD_KEYS[field];
|
|
169
|
+
const failures = [];
|
|
170
|
+
let raw;
|
|
171
|
+
let provenance = null;
|
|
172
|
+
const restKey = rest && rest[key];
|
|
173
|
+
if (restKey && restKey.resolved) {
|
|
174
|
+
raw = restKey.raw;
|
|
175
|
+
provenance = { channel: 'rest', readComplete: true, evidenceRef: { path: restKey.evidenceRef.path, keyPresentInMeta: true } };
|
|
176
|
+
} else {
|
|
177
|
+
failures.push(restKey ? `rest: ${restKey.reason}` : 'rest: not read');
|
|
178
|
+
if (bridgeBatch && bridgeBatch.complete && bridgeBatch.productIds.includes(id) && bridgeBatch.keys.includes(key)) {
|
|
179
|
+
const row = bridgeBatch.rows.find((r) => r.productId === id && r.key === key);
|
|
180
|
+
raw = row ? row.value : undefined;
|
|
181
|
+
provenance = {
|
|
182
|
+
channel: 'bridge',
|
|
183
|
+
readComplete: true,
|
|
184
|
+
evidenceRef: { batchId: bridgeBatch.batchId, productIds: bridgeBatch.productIds, pageCount: bridgeBatch.pageCount, finalHasNext: false, rowPresent: Boolean(row) },
|
|
185
|
+
};
|
|
186
|
+
} else {
|
|
187
|
+
failures.push(!bridgeBatch ? 'bridge: unavailable' : `bridge: ${bridgeBatch.reason || 'key not read for this product'}`);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
if (!provenance) {
|
|
191
|
+
fields[field] = { state: 'unknown', rawPresent: false, provenance: { channel: 'none', readComplete: false, evidenceRef: { failures } } };
|
|
192
|
+
continue;
|
|
193
|
+
}
|
|
194
|
+
const rawPresent = raw !== undefined && raw !== null;
|
|
195
|
+
if (!rawPresent || isBlank(raw)) {
|
|
196
|
+
fields[field] = { state: 'inherit', rawPresent, provenance };
|
|
197
|
+
continue;
|
|
198
|
+
}
|
|
199
|
+
const resolved = resolveOverrideValue(field, raw, yoastHeadJson);
|
|
200
|
+
if (resolved.unknown) {
|
|
201
|
+
fields[field] = { state: 'unknown', rawPresent, provenance: { ...provenance, evidenceRef: { ...provenance.evidenceRef, failures: [resolved.unknown] } } };
|
|
202
|
+
} else {
|
|
203
|
+
fields[field] = { state: 'override', rawPresent, value: resolved.value, provenance };
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
return { productId: id, capturedAt, fields };
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
// Receipts for a whole extraction. `products` rows: { id, yoast_head_json?, restResponse?,
|
|
210
|
+
// restPath? }. `bridgeBatches` is readBridgeEvidence's output (or [] when the bridge is absent).
|
|
211
|
+
function buildProductSeoReceipts({ products, bridgeBatches = [], capturedAt } = {}) {
|
|
212
|
+
if (!Array.isArray(products)) throw new Error('buildProductSeoReceipts: products must be an array');
|
|
213
|
+
const batchFor = new Map();
|
|
214
|
+
for (const batch of bridgeBatches || []) for (const id of batch.productIds) batchFor.set(String(id), batch);
|
|
215
|
+
return products.map((product) => buildProductSeoReceipt({
|
|
216
|
+
productId: product.id,
|
|
217
|
+
capturedAt,
|
|
218
|
+
rest: product.restResponse ? restEvidence({ response: product.restResponse, path: product.restPath || null }) : null,
|
|
219
|
+
bridgeBatch: batchFor.get(String(product.id)) || null,
|
|
220
|
+
yoastHeadJson: product.yoast_head_json || null,
|
|
221
|
+
}));
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
// Canonical-record projection of a receipt (`product.seoEvidence`). `rendered` carries the
|
|
225
|
+
// sanitized rendered title/description ONLY so an owner's `materialize` choice has a value to
|
|
226
|
+
// write; it is never proof and never written without that choice.
|
|
227
|
+
function seoEvidenceFromReceipt(receipt, { yoastHeadJson = null, permalink = null } = {}) {
|
|
228
|
+
const out = {};
|
|
229
|
+
for (const field of SEO_FIELDS) {
|
|
230
|
+
const f = receipt.fields[field];
|
|
231
|
+
out[field] = f.state === 'override' ? { state: 'override', value: f.value } : { state: f.state };
|
|
232
|
+
}
|
|
233
|
+
out.rendered = {
|
|
234
|
+
title: sanitizeRendered(yoastHeadJson && yoastHeadJson.title),
|
|
235
|
+
description: sanitizeRendered(yoastHeadJson && yoastHeadJson.description),
|
|
236
|
+
};
|
|
237
|
+
out.canonical = classifyProductCanonical(yoastHeadJson, permalink);
|
|
238
|
+
return out;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
// A computed self-canonical (the product's own source permalink) is never written: Wix
|
|
242
|
+
// generates its own. A canonical pointing anywhere else may be intentional, but REST cannot prove
|
|
243
|
+
// it and no policy for foreign canonicals is approved, so it is flagged, never written.
|
|
244
|
+
function normalizeUrl(value) {
|
|
245
|
+
try {
|
|
246
|
+
const url = new URL(String(value));
|
|
247
|
+
return `${url.host.toLowerCase()}${decodeURI(url.pathname).replace(/\/+$/, '')}`;
|
|
248
|
+
} catch (e) {
|
|
249
|
+
return null;
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
function classifyProductCanonical(yoastHeadJson, permalink) {
|
|
253
|
+
const canonical = yoastHeadJson && yoastHeadJson.canonical;
|
|
254
|
+
if (isBlank(canonical)) return 'none';
|
|
255
|
+
if (permalink && normalizeUrl(canonical) && normalizeUrl(canonical) === normalizeUrl(permalink)) return 'self';
|
|
256
|
+
return 'pending_policy';
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
module.exports = {
|
|
260
|
+
FIELD_KEYS,
|
|
261
|
+
ALLOWED_KEYS,
|
|
262
|
+
SEO_FIELDS,
|
|
263
|
+
STATES,
|
|
264
|
+
DEFAULT_BRIDGE_BATCH,
|
|
265
|
+
decodeEntitiesOnce,
|
|
266
|
+
restEvidence,
|
|
267
|
+
readBridgeEvidence,
|
|
268
|
+
buildProductSeoReceipt,
|
|
269
|
+
buildProductSeoReceipts,
|
|
270
|
+
seoEvidenceFromReceipt,
|
|
271
|
+
classifyProductCanonical,
|
|
272
|
+
};
|