@wix/agent-skills 1.33.1 → 1.34.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 +2 -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 +13 -3
- 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/sites/manage-oauth-apps.md +1 -0
- package/skills/wix-manage/references/sites/upload-static-site.md +127 -8
- 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
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// Exercises BOTH of the handler's capabilities, not just discoverStructure -- a self-test
|
|
4
|
+
// that only ever called discoverStructure would report readiness even if queryStructure
|
|
5
|
+
// (the route that actually returns real data) were completely broken.
|
|
6
|
+
async function selfTest({ discoverStructure, queryStructure, guardedValueColumns }) {
|
|
7
|
+
const calls = [];
|
|
8
|
+
const httpClient = {
|
|
9
|
+
async get(url, options) {
|
|
10
|
+
calls.push({ method: 'GET', url, options });
|
|
11
|
+
return {
|
|
12
|
+
table: options.params.table,
|
|
13
|
+
columns: [
|
|
14
|
+
{ name: 'id', type: 'bigint(20) unsigned', nullable: false, key: 'primary' },
|
|
15
|
+
{ name: 'number', type: 'varchar(64)', nullable: false, key: 'unique' },
|
|
16
|
+
{ name: 'active', type: 'tinyint(1)', nullable: false, key: null },
|
|
17
|
+
],
|
|
18
|
+
};
|
|
19
|
+
},
|
|
20
|
+
async post(url, options) {
|
|
21
|
+
calls.push({ method: 'POST', url, options });
|
|
22
|
+
return {
|
|
23
|
+
rows: [{ id: '1', number: 'CARD0001', active: '1' }],
|
|
24
|
+
pagingMetadata: { cursors: { next: null }, hasNext: false, total: 1 },
|
|
25
|
+
redactionMetadata: { redactedValueCount: 0, redactedColumns: [] },
|
|
26
|
+
};
|
|
27
|
+
},
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
const discovered = await discoverStructure({ httpClient, siteBaseUrl: 'https://example.test', table: 'pimwick_gift_card' });
|
|
31
|
+
if (discovered.table !== 'pimwick_gift_card' || discovered.columns.length !== 3) {
|
|
32
|
+
throw new Error('fixture discovery did not return the expected table/columns shape');
|
|
33
|
+
}
|
|
34
|
+
const getCall = calls.find((call) => call.method === 'GET');
|
|
35
|
+
if (!getCall || getCall.options.params.table !== 'pimwick_gift_card') {
|
|
36
|
+
throw new Error('fixture discovery did not request the expected table param');
|
|
37
|
+
}
|
|
38
|
+
if (!getCall.url.endsWith('/wp-json/wix-wp-plugin/v2/structure')) {
|
|
39
|
+
throw new Error('fixture discovery did not hit the expected wix-wp-plugin-v2 route');
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const queried = await queryStructure({
|
|
43
|
+
httpClient,
|
|
44
|
+
siteBaseUrl: 'https://example.test',
|
|
45
|
+
structureRequest: {
|
|
46
|
+
table: 'pimwick_gift_card',
|
|
47
|
+
select: [{ column: 'id' }, { column: 'number' }, { column: 'active' }],
|
|
48
|
+
orderBy: [{ column: 'id', direction: 'asc' }],
|
|
49
|
+
},
|
|
50
|
+
limit: 10,
|
|
51
|
+
});
|
|
52
|
+
if (!Array.isArray(queried.rows) || queried.rows.length !== 1 || queried.rows[0].number !== 'CARD0001') {
|
|
53
|
+
throw new Error('fixture query did not return the expected row shape');
|
|
54
|
+
}
|
|
55
|
+
if (queried.pagingMetadata.hasNext !== false || queried.pagingMetadata.total !== 1) {
|
|
56
|
+
throw new Error('fixture query did not return the expected pagingMetadata shape');
|
|
57
|
+
}
|
|
58
|
+
const postCall = calls.find((call) => call.method === 'POST');
|
|
59
|
+
if (!postCall || !postCall.url.endsWith('/wp-json/wix-wp-plugin/v2/query/admin-key')) {
|
|
60
|
+
throw new Error('fixture query did not hit the expected wix-wp-plugin-v2 route');
|
|
61
|
+
}
|
|
62
|
+
const postedBody = JSON.parse(postCall.options.body);
|
|
63
|
+
if (postedBody.structureRequest.table !== 'pimwick_gift_card' || postedBody.limit !== 10) {
|
|
64
|
+
throw new Error('fixture query did not send the expected request body');
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// --- the safety metadata must survive the client, and its absence must fail ---
|
|
68
|
+
|
|
69
|
+
if (!queried.redactionMetadata || queried.redactionMetadata.redactedValueCount !== 0) {
|
|
70
|
+
throw new Error('fixture query dropped redactionMetadata, which every response carries');
|
|
71
|
+
}
|
|
72
|
+
if (queried.eavAccess !== null) {
|
|
73
|
+
throw new Error('a plain table must report eavAccess as null, not as a fabricated object');
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// A plugin too old to send redactionMetadata has no value guard at all. Accepting that
|
|
77
|
+
// response would report a guarded read that never happened, so the client must refuse it.
|
|
78
|
+
const legacyClient = {
|
|
79
|
+
async post() {
|
|
80
|
+
return { rows: [{ id: '1' }], pagingMetadata: { cursors: { next: null }, hasNext: false, total: 1 } };
|
|
81
|
+
},
|
|
82
|
+
};
|
|
83
|
+
let refusedLegacy = false;
|
|
84
|
+
try {
|
|
85
|
+
await queryStructure({
|
|
86
|
+
httpClient: legacyClient,
|
|
87
|
+
siteBaseUrl: 'https://example.test',
|
|
88
|
+
structureRequest: { table: 'pimwick_gift_card', select: [{ column: 'id' }], orderBy: [{ column: 'id', direction: 'asc' }] },
|
|
89
|
+
});
|
|
90
|
+
} catch (error) {
|
|
91
|
+
refusedLegacy = /redactionMetadata/.test(error.message);
|
|
92
|
+
}
|
|
93
|
+
if (!refusedLegacy) {
|
|
94
|
+
throw new Error('a response with no redactionMetadata must be refused, not defaulted to zero');
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// A key/value table: both routes must hand the caller enough to build a legal request,
|
|
98
|
+
// INCLUDING the second guarded value column on a multi-pair schema.
|
|
99
|
+
const eavClient = {
|
|
100
|
+
async get(url, options) {
|
|
101
|
+
return {
|
|
102
|
+
table: options.params.table,
|
|
103
|
+
columns: [
|
|
104
|
+
{ name: 'meta_id', type: 'bigint(20) unsigned', nullable: false, key: 'primary' },
|
|
105
|
+
{ name: 'meta_key', type: 'varchar(255)', nullable: true, key: 'index' },
|
|
106
|
+
{ name: 'meta_value', type: 'longtext', nullable: true, key: null },
|
|
107
|
+
{ name: 'name', type: 'varchar(64)', nullable: true, key: null },
|
|
108
|
+
{ name: 'value', type: 'longtext', nullable: true, key: null },
|
|
109
|
+
],
|
|
110
|
+
eavPair: {
|
|
111
|
+
keyColumn: 'meta_key',
|
|
112
|
+
valueColumn: 'meta_value',
|
|
113
|
+
additionalPairs: [{ keyColumn: 'name', valueColumn: 'value' }],
|
|
114
|
+
},
|
|
115
|
+
};
|
|
116
|
+
},
|
|
117
|
+
async post() {
|
|
118
|
+
return {
|
|
119
|
+
rows: [{ meta_key: 'last4', n: '12' }],
|
|
120
|
+
pagingMetadata: { cursors: { next: null }, hasNext: false, total: 1 },
|
|
121
|
+
redactionMetadata: { redactedValueCount: 1, redactedColumns: ['meta_value'] },
|
|
122
|
+
eavAccess: { keyColumn: 'meta_key', valueColumn: 'meta_value', tier: 'key-discovery', pinnedKeys: [] },
|
|
123
|
+
};
|
|
124
|
+
},
|
|
125
|
+
};
|
|
126
|
+
const eavDiscovered = await discoverStructure({ httpClient: eavClient, siteBaseUrl: 'https://example.test', table: 'dual_meta' });
|
|
127
|
+
if (!eavDiscovered.eavPair || eavDiscovered.eavPair.keyColumn !== 'meta_key') {
|
|
128
|
+
throw new Error('discoverStructure dropped eavPair -- the caller loses its only advance notice that a table is key-scoped');
|
|
129
|
+
}
|
|
130
|
+
if (guardedValueColumns(eavDiscovered.eavPair).join(',') !== 'meta_value,value') {
|
|
131
|
+
throw new Error('guardedValueColumns must report EVERY guarded value column, not only the first pair\'s');
|
|
132
|
+
}
|
|
133
|
+
const eavQueried = await queryStructure({
|
|
134
|
+
httpClient: eavClient,
|
|
135
|
+
siteBaseUrl: 'https://example.test',
|
|
136
|
+
structureRequest: { table: 'dual_meta', select: [{ column: 'meta_key' }], orderBy: [{ column: 'meta_key', direction: 'asc' }] },
|
|
137
|
+
});
|
|
138
|
+
if (!eavQueried.eavAccess || eavQueried.eavAccess.tier !== 'key-discovery') {
|
|
139
|
+
throw new Error('queryStructure dropped eavAccess -- the caller cannot tell the read was key-scoped');
|
|
140
|
+
}
|
|
141
|
+
if (eavQueried.redactionMetadata.redactedValueCount !== 1
|
|
142
|
+
|| eavQueried.redactionMetadata.redactedColumns[0] !== 'meta_value') {
|
|
143
|
+
throw new Error('queryStructure dropped the redaction count -- a redacted value would look like real data');
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
return true;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
module.exports = selfTest;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// Source policy only. The target adapter owns how these canonical values are written.
|
|
4
|
+
function mapWooInventory(source = {}, { parent } = {}) {
|
|
5
|
+
const gap = (reason) => ({ status: 'decision-needed', fields: {}, reason });
|
|
6
|
+
if (source.backorders_allowed === true || source.backordered === true ||
|
|
7
|
+
(source.backorders != null && source.backorders !== 'no') || source.stock_status === 'onbackorder') {
|
|
8
|
+
return gap('backorder-policy');
|
|
9
|
+
}
|
|
10
|
+
if (source.manage_stock === 'parent' ||
|
|
11
|
+
(parent && parent.manage_stock === true && source.manage_stock !== true)) {
|
|
12
|
+
return gap('shared-parent-stock');
|
|
13
|
+
}
|
|
14
|
+
if (!['instock', 'outofstock'].includes(source.stock_status)) return gap('missing-or-unknown-stock-status');
|
|
15
|
+
if (source.manage_stock === false) {
|
|
16
|
+
return { status: 'mapped', fields: { inventoryTracked: false, inStock: source.stock_status === 'instock' } };
|
|
17
|
+
}
|
|
18
|
+
if (source.manage_stock !== true) return gap('missing-or-unknown-tracking-method');
|
|
19
|
+
const quantity = source.stock_quantity;
|
|
20
|
+
if (!Number.isInteger(quantity) || quantity < 0 || quantity > 99999) return gap('invalid-stock-quantity');
|
|
21
|
+
if ((quantity > 0) !== (source.stock_status === 'instock')) return gap('stock-status-quantity-conflict');
|
|
22
|
+
return { status: 'mapped', fields: { inventoryTracked: true, inventoryQuantity: quantity } };
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
module.exports = { mapWooInventory };
|
|
@@ -12,7 +12,9 @@
|
|
|
12
12
|
// self-contained.
|
|
13
13
|
//
|
|
14
14
|
// Keep this file dependency-free (Node built-ins / global fetch only) so the
|
|
15
|
-
// vendored copy needs no install step.
|
|
15
|
+
// vendored copy needs no install step. The one sibling module it reaches for --
|
|
16
|
+
// ./gateway-summary.mjs -- is loaded lazily, inside fetchGatewaySummary(), so a
|
|
17
|
+
// vendored copy that never reads gateway configuration still runs standalone.
|
|
16
18
|
|
|
17
19
|
const DEFAULT_TIMEOUT_MS = 60000;
|
|
18
20
|
const DEFAULT_RATE_LIMIT_RPM = 120;
|
|
@@ -27,6 +29,18 @@ function sleep(ms) {
|
|
|
27
29
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
28
30
|
}
|
|
29
31
|
|
|
32
|
+
class DeadlineExceededError extends Error {
|
|
33
|
+
constructor() {
|
|
34
|
+
super('WordPress request deadline exceeded');
|
|
35
|
+
this.name = 'DeadlineExceededError';
|
|
36
|
+
this.code = 'deadline-exceeded';
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function remainingDeadlineMs(deadlineAt) {
|
|
41
|
+
return deadlineAt === null ? Infinity : Math.max(0, deadlineAt - Date.now());
|
|
42
|
+
}
|
|
43
|
+
|
|
30
44
|
// Configure the shared throttle. Call once before issuing requests.
|
|
31
45
|
function configureRateLimit({ rateLimitRpm = DEFAULT_RATE_LIMIT_RPM, maxRetries = DEFAULT_MAX_RETRIES } = {}) {
|
|
32
46
|
const rpm = Number.isFinite(rateLimitRpm) && rateLimitRpm >= 1 ? rateLimitRpm : DEFAULT_RATE_LIMIT_RPM;
|
|
@@ -34,13 +48,16 @@ function configureRateLimit({ rateLimitRpm = DEFAULT_RATE_LIMIT_RPM, maxRetries
|
|
|
34
48
|
rateState.maxRetries = Number.isFinite(maxRetries) && maxRetries >= 0 ? maxRetries : DEFAULT_MAX_RETRIES;
|
|
35
49
|
}
|
|
36
50
|
|
|
37
|
-
async function applyThrottle(progress) {
|
|
51
|
+
async function applyThrottle(progress, deadlineAt = null) {
|
|
38
52
|
if (rateState.minIntervalMs <= 0) {
|
|
39
53
|
return;
|
|
40
54
|
}
|
|
41
55
|
const elapsed = Date.now() - rateState.lastRequestAt;
|
|
42
56
|
const wait = rateState.minIntervalMs - elapsed;
|
|
43
57
|
if (wait > 0) {
|
|
58
|
+
// A per-media-chunk deadline includes pacing. Do not start a wait that cannot
|
|
59
|
+
// finish inside it; returning immediately is what keeps the stated worst-case bound real.
|
|
60
|
+
if (wait >= remainingDeadlineMs(deadlineAt)) throw new DeadlineExceededError();
|
|
44
61
|
if (progress) {
|
|
45
62
|
await progress.withHeartbeat({ phase: 'discovery', step: 'rate-limit', message: 'Still waiting for WordPress rate limit' }, () => sleep(wait));
|
|
46
63
|
} else {
|
|
@@ -102,13 +119,127 @@ function buildApiUrl(baseUrl, routePath, query = {}) {
|
|
|
102
119
|
return url;
|
|
103
120
|
}
|
|
104
121
|
|
|
105
|
-
|
|
122
|
+
// ---------------------------------------------------------------------------
|
|
123
|
+
// Payment-gateway route denial
|
|
124
|
+
//
|
|
125
|
+
// `GET /wc/v3/payment_gateways` (and `/{id}`) returns each gateway's ENTIRE settings object.
|
|
126
|
+
// On a site with a real gateway connected that includes the live API key and secret. Anything
|
|
127
|
+
// a tool returns is in the model's context, the transcript, and potentially a durable run
|
|
128
|
+
// artifact -- discovery's generic sampler writes sampled records to disk -- so there is no
|
|
129
|
+
// careful-handling mitigation available above this line.
|
|
130
|
+
//
|
|
131
|
+
// The denial sits HERE, in the transport, rather than in a caller, for one reason: discovery
|
|
132
|
+
// accepts `--include-route <path>` to force-sample any route. A control above that flag is a
|
|
133
|
+
// control an operator can switch off by accident. This one is below it, so no CLI argument and
|
|
134
|
+
// no future caller can route around it.
|
|
135
|
+
//
|
|
136
|
+
// It consults NOTHING but the route path. There is deliberately no `{ allowGatewayRoute }`, no
|
|
137
|
+
// `{ skipDenyList }`, no capability token, no environment variable and no "internal caller"
|
|
138
|
+
// parameter -- each of those is the exposure with extra steps. Their absence is asserted by
|
|
139
|
+
// tests/source-wordpress/gateway-route-deny-contract-test.js.
|
|
140
|
+
//
|
|
141
|
+
// Honest limit: this guards the shared transport, not the network. Code that builds a URL and
|
|
142
|
+
// calls global fetch itself is outside its reach; that is covered by the instructions in
|
|
143
|
+
// rp-source-wordpress/SKILL.md and the codegen prohibition in rp-import-codegen/SKILL.md, not
|
|
144
|
+
// by this function.
|
|
145
|
+
// ---------------------------------------------------------------------------
|
|
146
|
+
|
|
147
|
+
const GATEWAY_COLLECTION_ROUTE = '/wc/v3/payment_gateways';
|
|
148
|
+
|
|
149
|
+
// Both shapes: the collection and the parameterized item route. Matching only the collection
|
|
150
|
+
// would leave the exposure fully open -- the item route is the one that returns settings.
|
|
151
|
+
// `v\d+` rather than `v3` because wc/v1 and wc/v2 expose the same route.
|
|
152
|
+
const GATEWAY_ROUTE_PATTERN = /^\/wc\/v\d+\/payment_gateways(\/.*)?$/;
|
|
153
|
+
|
|
154
|
+
class GatewayRouteDeniedError extends Error {
|
|
155
|
+
constructor(routePath) {
|
|
156
|
+
super(
|
|
157
|
+
`Refusing to request "${routePath}": WooCommerce payment-gateway routes return each gateway's `
|
|
158
|
+
+ 'full settings object, including live API keys and secrets. Read gateway configuration through '
|
|
159
|
+
+ 'fetchGatewaySummary(), which reduces the response with lib/gateway-summary.mjs and returns names '
|
|
160
|
+
+ 'and states without credential values. No option, flag or override lifts this.',
|
|
161
|
+
);
|
|
162
|
+
this.name = 'GatewayRouteDeniedError';
|
|
163
|
+
this.code = 'GATEWAY_ROUTE_DENIED';
|
|
164
|
+
this.routePath = routePath;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// Normalize before matching, so a query string, a trailing slash, a doubled slash, a percent
|
|
169
|
+
// escape, an accidental /wp-json prefix or a mixed-case spelling cannot walk past the pattern.
|
|
170
|
+
function normalizeRouteForDeny(routePath) {
|
|
171
|
+
let route = typeof routePath === 'string' ? routePath : '';
|
|
172
|
+
try {
|
|
173
|
+
route = decodeURIComponent(route);
|
|
174
|
+
} catch {
|
|
175
|
+
// A malformed escape sequence is not a reason to skip the check — carry on with the raw text.
|
|
176
|
+
}
|
|
177
|
+
route = route.split('#')[0].split('?')[0].trim().toLowerCase();
|
|
178
|
+
route = route.replace(/\\/g, '/').replace(/\/{2,}/g, '/');
|
|
179
|
+
if (!route.startsWith('/')) {
|
|
180
|
+
route = `/${route}`;
|
|
181
|
+
}
|
|
182
|
+
route = route.replace(/^\/wp-json(?=\/|$)/, '').replace(/\/+$/, '');
|
|
183
|
+
return route === '' ? '/' : route;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/** Whether this route path returns payment-gateway configuration and must never be requested. */
|
|
187
|
+
function isDeniedGatewayRoute(routePath) {
|
|
188
|
+
return GATEWAY_ROUTE_PATTERN.test(normalizeRouteForDeny(routePath));
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
// The undenied transport. MODULE-PRIVATE, and it stays that way: exporting it, or adding a
|
|
192
|
+
// parameter to fetchJson that reaches it, recreates the hole the deny rule closes. The only
|
|
193
|
+
// caller outside fetchJson is fetchGatewaySummary below, which hands the raw response straight
|
|
194
|
+
// to a pure reducer and lets it go out of scope.
|
|
195
|
+
async function fetchJsonUnchecked(baseUrl, routePath, {
|
|
196
|
+
headers,
|
|
197
|
+
method = 'GET',
|
|
198
|
+
query,
|
|
199
|
+
body,
|
|
200
|
+
timeoutMs = DEFAULT_TIMEOUT_MS,
|
|
201
|
+
deadlineMs,
|
|
202
|
+
progress = null,
|
|
203
|
+
progressContext = {},
|
|
204
|
+
}) {
|
|
106
205
|
const url = buildApiUrl(baseUrl, routePath, query);
|
|
206
|
+
// One absolute deadline spans throttle waits, every attempt, response-body reads and every
|
|
207
|
+
// retry wait. Calls that omit deadlineMs retain the transport's existing per-attempt timeout.
|
|
208
|
+
const deadlineAt = Number.isFinite(deadlineMs) && deadlineMs >= 0 ? Date.now() + deadlineMs : null;
|
|
209
|
+
// `body` is a small, generic escape hatch for profile-declared entities whose read path
|
|
210
|
+
// is not a plain GET collection (see plugin-knowledge.js buildRequestOverrides) — it is
|
|
211
|
+
// never set on the default GET-with-query sampling path.
|
|
212
|
+
const requestInit = {
|
|
213
|
+
method,
|
|
214
|
+
headers,
|
|
215
|
+
...(body !== undefined ? { body } : {}),
|
|
216
|
+
};
|
|
217
|
+
|
|
218
|
+
const deadlineResult = (attempt, error = new DeadlineExceededError()) => ({
|
|
219
|
+
ok: false,
|
|
220
|
+
status: 0,
|
|
221
|
+
statusText: 'Deadline Exceeded',
|
|
222
|
+
url: url.toString(),
|
|
223
|
+
headers: {},
|
|
224
|
+
json: undefined,
|
|
225
|
+
text: '',
|
|
226
|
+
error,
|
|
227
|
+
retries: attempt,
|
|
228
|
+
});
|
|
107
229
|
|
|
108
230
|
for (let attempt = 0; ; attempt += 1) {
|
|
109
|
-
|
|
231
|
+
try {
|
|
232
|
+
await applyThrottle(progress, deadlineAt);
|
|
233
|
+
} catch (error) {
|
|
234
|
+
if (error && error.code === 'deadline-exceeded') return deadlineResult(attempt, error);
|
|
235
|
+
throw error;
|
|
236
|
+
}
|
|
237
|
+
const remaining = remainingDeadlineMs(deadlineAt);
|
|
238
|
+
if (remaining <= 0) return deadlineResult(attempt);
|
|
239
|
+
const attemptTimeoutMs = Math.min(timeoutMs, remaining);
|
|
240
|
+
const deadlineControlsAttempt = deadlineAt !== null && remaining <= timeoutMs;
|
|
110
241
|
const controller = new AbortController();
|
|
111
|
-
const timeout = setTimeout(() => controller.abort(),
|
|
242
|
+
const timeout = setTimeout(() => controller.abort(), attemptTimeoutMs);
|
|
112
243
|
|
|
113
244
|
try {
|
|
114
245
|
const response = progress
|
|
@@ -118,13 +249,11 @@ async function fetchJson(baseUrl, routePath, { headers, method = 'GET', query, t
|
|
|
118
249
|
...progressContext,
|
|
119
250
|
message: `Still waiting on WordPress ${method} ${routePath || '/'}`,
|
|
120
251
|
}, () => fetch(url, {
|
|
121
|
-
|
|
122
|
-
headers,
|
|
252
|
+
...requestInit,
|
|
123
253
|
signal: controller.signal,
|
|
124
254
|
}))
|
|
125
255
|
: await fetch(url, {
|
|
126
|
-
|
|
127
|
-
headers,
|
|
256
|
+
...requestInit,
|
|
128
257
|
signal: controller.signal,
|
|
129
258
|
});
|
|
130
259
|
const text = await response.text();
|
|
@@ -134,6 +263,7 @@ async function fetchJson(baseUrl, routePath, { headers, method = 'GET', query, t
|
|
|
134
263
|
// honoring Retry-After when the server provides it.
|
|
135
264
|
if ((response.status === 429 || response.status === 503) && attempt < rateState.maxRetries) {
|
|
136
265
|
const backoff = retryAfterMs(responseHeaders) ?? Math.min(MAX_BACKOFF_MS, 1000 * 2 ** attempt);
|
|
266
|
+
if (backoff >= remainingDeadlineMs(deadlineAt)) return deadlineResult(attempt);
|
|
137
267
|
if (progress) {
|
|
138
268
|
progress.warn(`WordPress ${response.status} response; backing off before retry`, {
|
|
139
269
|
phase: 'discovery',
|
|
@@ -175,6 +305,9 @@ async function fetchJson(baseUrl, routePath, { headers, method = 'GET', query, t
|
|
|
175
305
|
retries: attempt,
|
|
176
306
|
};
|
|
177
307
|
} catch (error) {
|
|
308
|
+
if (error.name === 'AbortError' && deadlineControlsAttempt) {
|
|
309
|
+
return deadlineResult(attempt);
|
|
310
|
+
}
|
|
178
311
|
return {
|
|
179
312
|
ok: false,
|
|
180
313
|
status: 0,
|
|
@@ -192,6 +325,61 @@ async function fetchJson(baseUrl, routePath, { headers, method = 'GET', query, t
|
|
|
192
325
|
}
|
|
193
326
|
}
|
|
194
327
|
|
|
328
|
+
/**
|
|
329
|
+
* The WordPress transport every reader uses.
|
|
330
|
+
*
|
|
331
|
+
* Identical to the core above except that it refuses payment-gateway routes BEFORE issuing the
|
|
332
|
+
* request. The refusal throws rather than returning a result object: a caller that treats a
|
|
333
|
+
* denial as "the route returned nothing" would carry on and record an empty entity, and a
|
|
334
|
+
* security control that reads as an empty result is not a control.
|
|
335
|
+
*/
|
|
336
|
+
async function fetchJson(baseUrl, routePath, options) {
|
|
337
|
+
if (isDeniedGatewayRoute(routePath)) {
|
|
338
|
+
throw new GatewayRouteDeniedError(routePath);
|
|
339
|
+
}
|
|
340
|
+
return fetchJsonUnchecked(baseUrl, routePath, options);
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
/**
|
|
344
|
+
* The ONE sanctioned way to read payment-gateway configuration.
|
|
345
|
+
*
|
|
346
|
+
* Note the direction of the dependency: this module imports the reducer, not the reverse. The
|
|
347
|
+
* raw response never leaves this function's scope -- it goes straight into a pure function that
|
|
348
|
+
* cannot make a request, and only that function's §1-shaped output is resolved. So there is no
|
|
349
|
+
* exemption to keep narrow, because there is no hole: `gateway-summary.mjs` has no transport to
|
|
350
|
+
* reach, and `fetchJson` has no way to be talked into the route.
|
|
351
|
+
*
|
|
352
|
+
* Refuses outright when the shared secret-value guard is not operational. A guard that quietly
|
|
353
|
+
* evaluates an empty pattern set returns display values verbatim, and an allowlisted
|
|
354
|
+
* `description` is free text a vendor controls -- so an unusable guard means we do not read.
|
|
355
|
+
*
|
|
356
|
+
* Loaded with dynamic import(), not require(): the reducer is ESM, this module is CommonJS and
|
|
357
|
+
* is vendored into generated migration projects, and import() is the one form that works from
|
|
358
|
+
* both on every Node version. Lazy, so a vendored copy that never reads gateway configuration
|
|
359
|
+
* -- which is every generated reader, by prohibition -- needs no sibling file at all.
|
|
360
|
+
*/
|
|
361
|
+
async function fetchGatewaySummary(baseUrl, { headers, timeoutMs = DEFAULT_TIMEOUT_MS, progress = null, progressContext = {} } = {}) {
|
|
362
|
+
const { reduceGatewayResponse, guardUnusableReason } = await import('./gateway-summary.mjs');
|
|
363
|
+
|
|
364
|
+
const guardProblem = guardUnusableReason();
|
|
365
|
+
if (guardProblem) {
|
|
366
|
+
throw new Error(
|
|
367
|
+
`Refusing to read payment-gateway configuration: the shared secret-value guard is not operational (${guardProblem}). `
|
|
368
|
+
+ 'Fix secret-value-patterns.v1.json before reading gateway settings.',
|
|
369
|
+
);
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
const response = await fetchJsonUnchecked(baseUrl, GATEWAY_COLLECTION_ROUTE, {
|
|
373
|
+
headers,
|
|
374
|
+
method: 'GET',
|
|
375
|
+
timeoutMs,
|
|
376
|
+
progress,
|
|
377
|
+
progressContext: { step: 'gateway-summary', ...progressContext },
|
|
378
|
+
});
|
|
379
|
+
|
|
380
|
+
return reduceGatewayResponse(response);
|
|
381
|
+
}
|
|
382
|
+
|
|
195
383
|
// Total record count for a collection. WordPress returns it in X-WP-Total;
|
|
196
384
|
// X-WP-TotalPages carries the page count. Header names are lowercased by fetch's
|
|
197
385
|
// Headers iterator, but accept the canonical casing too for resilience.
|
|
@@ -236,6 +424,7 @@ module.exports = {
|
|
|
236
424
|
DEFAULT_RATE_LIMIT_RPM,
|
|
237
425
|
DEFAULT_MAX_RETRIES,
|
|
238
426
|
MAX_BACKOFF_MS,
|
|
427
|
+
DeadlineExceededError,
|
|
239
428
|
sleep,
|
|
240
429
|
configureRateLimit,
|
|
241
430
|
retryAfterMs,
|
|
@@ -243,6 +432,12 @@ module.exports = {
|
|
|
243
432
|
normalizeBaseUrl,
|
|
244
433
|
buildApiUrl,
|
|
245
434
|
fetchJson,
|
|
435
|
+
// NOTE what is deliberately NOT here: the undenied transport, under any name. The gateway
|
|
436
|
+
// deny rule is only worth as much as this export list.
|
|
437
|
+
GATEWAY_COLLECTION_ROUTE,
|
|
438
|
+
GatewayRouteDeniedError,
|
|
439
|
+
isDeniedGatewayRoute,
|
|
440
|
+
fetchGatewaySummary,
|
|
246
441
|
parseTotalHeader,
|
|
247
442
|
parseTotalPagesHeader,
|
|
248
443
|
shouldContinueCollectionPaging,
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// Resolve a WordPress/WooCommerce image reference to the source's ORIGINAL, maximum-resolution
|
|
4
|
+
// file.
|
|
5
|
+
//
|
|
6
|
+
// An image reference in a WordPress-family payload is never one URL — it is a SET of candidate
|
|
7
|
+
// URLs for the same picture: the file the merchant uploaded, plus the crops WordPress generated
|
|
8
|
+
// from it. Which field holds which varies by route, and two routes on the SAME site disagree:
|
|
9
|
+
//
|
|
10
|
+
// wc/store/v1/products (public) images[].src IS the original
|
|
11
|
+
// wc/v3/products (authenticated) images[].src can be the SMALLEST crop, because the
|
|
12
|
+
// admin controller resolves it through WordPress's
|
|
13
|
+
// registered image sizes, which any theme or
|
|
14
|
+
// image-optimizer plugin is free to redefine
|
|
15
|
+
//
|
|
16
|
+
// So no caller may name a field. Every caller hands the whole reference to resolveImageUrl and
|
|
17
|
+
// gets back the biggest file available. Doing it any other way is how a whole catalog shipped as
|
|
18
|
+
// 150x150 thumbnails.
|
|
19
|
+
//
|
|
20
|
+
// It matters because the destination gives exactly one attempt: Wix Stores media takes ONE url
|
|
21
|
+
// per item and generates every derivative from it, with no way to raise the quality afterwards.
|
|
22
|
+
// Whatever this function returns is that product image's permanent ceiling.
|
|
23
|
+
|
|
24
|
+
// WordPress names every crop it generates by appending the dimensions to the filename, so a
|
|
25
|
+
// candidate WITHOUT that suffix is the uploaded original. This is a filename convention of the
|
|
26
|
+
// source platform, not a guarantee — do not reuse this module for a non-WordPress source
|
|
27
|
+
// without re-deriving the rule.
|
|
28
|
+
//
|
|
29
|
+
// The extension group repeats (`(\.ext)+`) because image optimizers append their own format
|
|
30
|
+
// rather than replacing the original one: WebP Express, EWWW and Imagify all emit
|
|
31
|
+
// `photo-150x150.jpg.webp` beside `photo-150x150.jpg`. Matching only the LAST extension made
|
|
32
|
+
// every such crop look like an uploaded original, so rule 3 below returned the first one it saw —
|
|
33
|
+
// a 150px thumbnail winning over a 1200px sibling, reported as `isCrop: false` so nothing flagged
|
|
34
|
+
// it either. That is unrecoverable once ingested, which is the whole reason this module exists.
|
|
35
|
+
const CROP_SUFFIX = /-(\d+)x(\d+)(\.[A-Za-z0-9]+)+$/;
|
|
36
|
+
|
|
37
|
+
// Fields that hold a single URL, across every WordPress-family shape we read:
|
|
38
|
+
// wc/v3 + wc/store/v1 product images -> src, thumbnail
|
|
39
|
+
// wp/v2 media -> source_url
|
|
40
|
+
const SINGLE_URL_FIELDS = ['src', 'thumbnail', 'source_url'];
|
|
41
|
+
|
|
42
|
+
function isNonEmptyString(value) {
|
|
43
|
+
return typeof value === 'string' && value.trim() !== '';
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function pathOf(url) {
|
|
47
|
+
// Compare against the path only. A query string can end in anything, and matching the crop
|
|
48
|
+
// suffix against it would misread `?v=-150x150` as a crop.
|
|
49
|
+
const withoutFragment = String(url).split('#')[0];
|
|
50
|
+
return withoutFragment.split('?')[0];
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// Width descriptors in a srcset entry ("<url> 800w") and the width baked into a crop filename
|
|
54
|
+
// are both ranking keys and nothing else. Never treat either as the image's true dimensions.
|
|
55
|
+
function declaredWidth(url, descriptorWidth) {
|
|
56
|
+
const match = CROP_SUFFIX.exec(pathOf(url));
|
|
57
|
+
const fromName = match ? Number(match[1]) : 0;
|
|
58
|
+
return Math.max(Number(descriptorWidth) || 0, fromName);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
function parseSrcset(srcset) {
|
|
62
|
+
if (!isNonEmptyString(srcset)) return [];
|
|
63
|
+
return srcset
|
|
64
|
+
.split(',')
|
|
65
|
+
.map((entry) => entry.trim())
|
|
66
|
+
.filter(Boolean)
|
|
67
|
+
.map((entry) => {
|
|
68
|
+
const parts = entry.split(/\s+/);
|
|
69
|
+
const url = parts[0];
|
|
70
|
+
const descriptor = parts.length > 1 ? parts[parts.length - 1] : '';
|
|
71
|
+
const width = /^\d+w$/.test(descriptor) ? Number(descriptor.slice(0, -1)) : 0;
|
|
72
|
+
return isNonEmptyString(url) ? { url, width } : null;
|
|
73
|
+
})
|
|
74
|
+
.filter(Boolean);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Every URL the record offers for this one picture, each with whatever width we can infer.
|
|
78
|
+
function collectCandidates(record) {
|
|
79
|
+
if (!record || typeof record !== 'object') return [];
|
|
80
|
+
const candidates = [];
|
|
81
|
+
|
|
82
|
+
for (const field of SINGLE_URL_FIELDS) {
|
|
83
|
+
if (isNonEmptyString(record[field])) candidates.push({ url: record[field], width: 0 });
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// wc/store/v1 exposes a second srcset for the thumbnail rendition; it occasionally carries a
|
|
87
|
+
// width the main one does not, and taking the max across both costs nothing.
|
|
88
|
+
for (const field of ['srcset', 'thumbnail_srcset']) {
|
|
89
|
+
candidates.push(...parseSrcset(record[field]));
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// wp/v2 media keeps its renditions in a nested map rather than a srcset string.
|
|
93
|
+
const sizes = record.media_details && record.media_details.sizes;
|
|
94
|
+
if (sizes && typeof sizes === 'object') {
|
|
95
|
+
for (const size of Object.values(sizes)) {
|
|
96
|
+
if (size && isNonEmptyString(size.source_url)) {
|
|
97
|
+
candidates.push({ url: size.source_url, width: Number(size.width) || 0 });
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
return candidates;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// A raw URL with non-ASCII characters is not fetchable by ordinary HTTP clients — our own
|
|
106
|
+
// verification tooling throws on it before the destination ever sees the request. Encode the
|
|
107
|
+
// path only: the host is already punycode or ASCII, and the query is left to the URL parser's
|
|
108
|
+
// own normalization so its parameter structure is never rewritten.
|
|
109
|
+
function encodeImageUrl(url) {
|
|
110
|
+
if (!isNonEmptyString(url)) return url;
|
|
111
|
+
try {
|
|
112
|
+
const parsed = new URL(url);
|
|
113
|
+
parsed.pathname = parsed.pathname
|
|
114
|
+
.split('/')
|
|
115
|
+
.map((segment) => encodeURIComponent(decodeURIComponent(segment)))
|
|
116
|
+
.join('/');
|
|
117
|
+
return parsed.toString();
|
|
118
|
+
} catch {
|
|
119
|
+
// Not an absolute URL. Hand it back untouched rather than mangling a relative path — the
|
|
120
|
+
// caller knows its own base and this module does not.
|
|
121
|
+
return url;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// The one entry point. Returns the encoded URL of the largest file the record offers, or null
|
|
126
|
+
// when it offers none. Never invents a URL: a record with no image is a fact to report, not a
|
|
127
|
+
// gap to fill with a placeholder.
|
|
128
|
+
function resolveImageUrl(record) {
|
|
129
|
+
const candidates = collectCandidates(record);
|
|
130
|
+
if (candidates.length === 0) return null;
|
|
131
|
+
|
|
132
|
+
const original = candidates.find((candidate) => !CROP_SUFFIX.test(pathOf(candidate.url)));
|
|
133
|
+
if (original) return encodeImageUrl(original.url);
|
|
134
|
+
|
|
135
|
+
// Only crops exist. Take the widest rather than failing — something always beats a thumbnail —
|
|
136
|
+
// and let the caller report it via resolvedIsCrop().
|
|
137
|
+
let best = candidates[0];
|
|
138
|
+
let bestWidth = declaredWidth(best.url, best.width);
|
|
139
|
+
for (const candidate of candidates.slice(1)) {
|
|
140
|
+
const width = declaredWidth(candidate.url, candidate.width);
|
|
141
|
+
if (width > bestWidth) {
|
|
142
|
+
best = candidate;
|
|
143
|
+
bestWidth = width;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
return encodeImageUrl(best.url);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
// True when the best available URL is still a generated crop, i.e. the source genuinely had no
|
|
150
|
+
// original to give. Callers MUST surface this: a migration may ship a small picture when the
|
|
151
|
+
// source only has a small picture, but it may not do so silently.
|
|
152
|
+
function resolvedIsCrop(url) {
|
|
153
|
+
return isNonEmptyString(url) && CROP_SUFFIX.test(pathOf(url));
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// Resolve a whole images[] array in order, dropping references that carry no URL at all.
|
|
157
|
+
// Order is load-bearing downstream: the first surviving item becomes the product's main media.
|
|
158
|
+
function resolveImageUrls(records) {
|
|
159
|
+
if (!Array.isArray(records)) return [];
|
|
160
|
+
return records
|
|
161
|
+
.map((record) => {
|
|
162
|
+
const url = resolveImageUrl(record);
|
|
163
|
+
if (!url) return null;
|
|
164
|
+
// The attachment id is what joins this product reference to wp/v2's media
|
|
165
|
+
// record. Preserve an explicit zero for an absent/invalid id so the confirmation boundary
|
|
166
|
+
// can fail closed with `no-source-id` rather than guessing from a filename.
|
|
167
|
+
const sourceId = Number(record && record.id);
|
|
168
|
+
const resolved = {
|
|
169
|
+
url,
|
|
170
|
+
sourceId: Number.isInteger(sourceId) && sourceId > 0 ? sourceId : 0,
|
|
171
|
+
isCrop: resolvedIsCrop(url),
|
|
172
|
+
};
|
|
173
|
+
if (isNonEmptyString(record && record.alt)) resolved.altText = record.alt;
|
|
174
|
+
if (isNonEmptyString(record && record.alt_text)) resolved.altText = record.alt_text;
|
|
175
|
+
if (isNonEmptyString(record && record.name)) resolved.displayName = record.name;
|
|
176
|
+
return resolved;
|
|
177
|
+
})
|
|
178
|
+
.filter(Boolean);
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
module.exports = {
|
|
182
|
+
resolveImageUrl,
|
|
183
|
+
resolveImageUrls,
|
|
184
|
+
resolvedIsCrop,
|
|
185
|
+
encodeImageUrl,
|
|
186
|
+
};
|