@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
|
@@ -0,0 +1,693 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
// Shopify private-data discovery, read through the Shopify CLI.
|
|
5
|
+
//
|
|
6
|
+
// node scripts/shopify-discovery.js --project <migrations-root>/<project> --store <shop>.myshopify.com
|
|
7
|
+
// [--reread <entity> ...] [--restart] [--progress-log <path>]
|
|
8
|
+
//
|
|
9
|
+
// Runs the discovery steps in a fixed order. Each step records its result in
|
|
10
|
+
// data/shopify-discovery/discovery-steps.json before the next starts, so a restart -- or a return
|
|
11
|
+
// after a merchant question -- runs only the steps not yet recorded and reads nothing it already
|
|
12
|
+
// captured. The last step writes data/shopify-discovery/source-coverage.json (rows: [] when
|
|
13
|
+
// clean). All recorded state is bound to the one store it was read from: a run for a different
|
|
14
|
+
// store stops with shopify_discovery_store_mismatch instead of mixing files, and --restart is the
|
|
15
|
+
// explicit way to discard the capture and begin again. source-profile.md and source-schema.json are synthesized from the capture afterwards and
|
|
16
|
+
// promoted with rp-discovery's promote-source-coverage.js --adapter shopify.
|
|
17
|
+
//
|
|
18
|
+
// Exit codes: 0 complete; 3 waiting on a merchant question (the run holds at
|
|
19
|
+
// awaiting_user_action); 2 stopped (the printed code says why; recorded steps are kept);
|
|
20
|
+
// 1 usage or unexpected error.
|
|
21
|
+
|
|
22
|
+
const crypto = require('node:crypto');
|
|
23
|
+
const fs = require('node:fs/promises');
|
|
24
|
+
const path = require('node:path');
|
|
25
|
+
const { createProgressLogger, parseProgressArgs } = require('../../../lib/progress-log.js');
|
|
26
|
+
const { buildShopifyCoverageRows, buildCoverageFile, ADAPTER_RAW_DIRS, SOURCE_COVERAGE_FILE, writeJsonAtomic } = require('../../../lib/source-coverage.js');
|
|
27
|
+
const { createUserAction, readUserAction } = require('../../../lib/user-actions.js');
|
|
28
|
+
const bulk = require('../lib/shopify-bulk.js');
|
|
29
|
+
const giftCards = require('../lib/shopify-gift-cards.js');
|
|
30
|
+
const { createStoreExecutor, ShopifyCliError } = require('../lib/shopify-cli.js');
|
|
31
|
+
const { ALL_READS, ORDER_WINDOW_READS, SAMPLE_LIMIT, operationName, at } = require('../lib/discovery-reads.js');
|
|
32
|
+
const { ShopifySessionStop, assertConnectionReady, recordAuthExpired, runSessionCheck } = require('../lib/shopify-session.js');
|
|
33
|
+
const protectedFields = require('../lib/shopify-protected-fields.js');
|
|
34
|
+
|
|
35
|
+
const RAW_DIR = ADAPTER_RAW_DIRS.shopify;
|
|
36
|
+
const STEPS_FILE = 'discovery-steps.json';
|
|
37
|
+
const ENTITIES_DIR = 'entities';
|
|
38
|
+
const STEPS_SCHEMA_VERSION = 1;
|
|
39
|
+
// What discovery hands to the mapper once it has been synthesized and promoted. They live outside
|
|
40
|
+
// the raw directory, so a restart cannot clear them: it refuses to switch stores once they exist.
|
|
41
|
+
const HANDOFF_FILES = Object.freeze(['source-profile.md', 'source-schema.json', SOURCE_COVERAGE_FILE]);
|
|
42
|
+
const STORE_PATTERN = /^[a-z0-9][a-z0-9-]*\.myshopify\.com$/;
|
|
43
|
+
// Connection records, not capture: a restart keeps them. The staff-account record
|
|
44
|
+
// outlives any capture -- the account exists until the owner removes it.
|
|
45
|
+
const CONNECTION_FILES = Object.freeze(['session-receipt.json', 'staff-access.json']);
|
|
46
|
+
const ORDER_WINDOW_FILE = 'order-window.json';
|
|
47
|
+
const ORDER_WINDOW_DAYS = 60;
|
|
48
|
+
|
|
49
|
+
class ShopifyDiscoveryStop extends Error {
|
|
50
|
+
constructor(code, message, details = {}) {
|
|
51
|
+
super(message);
|
|
52
|
+
this.name = 'ShopifyDiscoveryStop';
|
|
53
|
+
this.code = code;
|
|
54
|
+
this.details = details;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// ---------------------------------------------------------------------------------------------
|
|
59
|
+
// Store identity -- every recorded artifact belongs to exactly one store
|
|
60
|
+
// ---------------------------------------------------------------------------------------------
|
|
61
|
+
|
|
62
|
+
function normalizeStore(store) {
|
|
63
|
+
const value = typeof store === 'string' ? store.trim().toLowerCase() : '';
|
|
64
|
+
if (!STORE_PATTERN.test(value)) {
|
|
65
|
+
throw new ShopifyDiscoveryStop('shopify_store_invalid', 'store must be the *.myshopify.com domain the Shopify CLI session is bound to');
|
|
66
|
+
}
|
|
67
|
+
return value;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function storeMismatch(recorded, store, what) {
|
|
71
|
+
return new ShopifyDiscoveryStop(
|
|
72
|
+
'shopify_discovery_store_mismatch',
|
|
73
|
+
`Shopify discovery data in this project (${what}) was read from ${recorded || 'an unrecorded store'}, not ${store}. Nothing was read or changed. Run discovery for ${recorded || 'the original store'}, or restart discovery with --restart to discard the recorded capture and read ${store} from scratch.`,
|
|
74
|
+
{ recorded: recorded || null, store },
|
|
75
|
+
);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// ---------------------------------------------------------------------------------------------
|
|
79
|
+
// Step state
|
|
80
|
+
// ---------------------------------------------------------------------------------------------
|
|
81
|
+
|
|
82
|
+
async function readJson(file) {
|
|
83
|
+
try {
|
|
84
|
+
return JSON.parse(await fs.readFile(file, 'utf8'));
|
|
85
|
+
} catch (error) {
|
|
86
|
+
if (error.code === 'ENOENT') return undefined;
|
|
87
|
+
throw error;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
async function readSteps(rawDir, now, store) {
|
|
92
|
+
const state = await readJson(path.join(rawDir, STEPS_FILE));
|
|
93
|
+
if (state && state.schemaVersion === STEPS_SCHEMA_VERSION && state.steps && typeof state.steps === 'object') return state;
|
|
94
|
+
return { schemaVersion: STEPS_SCHEMA_VERSION, platform: 'shopify', store, startedAt: now(), steps: {} };
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// Refuse to continue on anything recorded for another store (or for none): the steps file, and
|
|
98
|
+
// every entity file already on disk, which is what a resume would otherwise accept.
|
|
99
|
+
async function assertBoundToStore(rawDir, store) {
|
|
100
|
+
const steps = await readJson(path.join(rawDir, STEPS_FILE));
|
|
101
|
+
if (steps && steps.store !== store) throw storeMismatch(steps.store, store, STEPS_FILE);
|
|
102
|
+
let names = [];
|
|
103
|
+
try {
|
|
104
|
+
names = await fs.readdir(path.join(rawDir, ENTITIES_DIR));
|
|
105
|
+
} catch (error) {
|
|
106
|
+
if (error.code !== 'ENOENT') throw error;
|
|
107
|
+
}
|
|
108
|
+
for (const name of names.filter((entry) => entry.endsWith('.json'))) {
|
|
109
|
+
const record = await readJson(path.join(rawDir, ENTITIES_DIR, name));
|
|
110
|
+
if (record && record.store !== store) throw storeMismatch(record.store, store, `${ENTITIES_DIR}/${name}`);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// The store the recorded capture belongs to: the steps file's, else any entity file's, else none.
|
|
115
|
+
async function recordedStore(rawDir) {
|
|
116
|
+
const steps = await readJson(path.join(rawDir, STEPS_FILE));
|
|
117
|
+
if (steps && typeof steps.store === 'string') return steps.store;
|
|
118
|
+
let names = [];
|
|
119
|
+
try {
|
|
120
|
+
names = await fs.readdir(path.join(rawDir, ENTITIES_DIR));
|
|
121
|
+
} catch (error) {
|
|
122
|
+
if (error.code !== 'ENOENT') throw error;
|
|
123
|
+
}
|
|
124
|
+
for (const name of names.filter((entry) => entry.endsWith('.json'))) {
|
|
125
|
+
const record = await readJson(path.join(rawDir, ENTITIES_DIR, name));
|
|
126
|
+
if (record && typeof record.store === 'string') return record.store;
|
|
127
|
+
}
|
|
128
|
+
return null;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
async function existingHandoffFiles(projectDir) {
|
|
132
|
+
const found = [];
|
|
133
|
+
for (const rel of HANDOFF_FILES) {
|
|
134
|
+
try {
|
|
135
|
+
await fs.access(path.join(projectDir, rel));
|
|
136
|
+
found.push(rel);
|
|
137
|
+
} catch (error) {
|
|
138
|
+
if (error.code !== 'ENOENT') throw error;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
return found;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// --restart: discard the whole Shopify raw directory so the next run reads from scratch and no
|
|
145
|
+
// file from the previous capture -- including files the technical steps add -- can survive by
|
|
146
|
+
// omission from a list. The mapper's handoff (source-profile.md, source-schema.json and the
|
|
147
|
+
// promoted coverage file) is outside that directory, so a restart that would leave the previous
|
|
148
|
+
// store's handoff in place for a different store is refused: that project belongs to the first
|
|
149
|
+
// store, and the other one needs its own migration project. A restart for the same store is
|
|
150
|
+
// allowed. Questions the previous run asked are tied to it; while one is still pending the run is
|
|
151
|
+
// holding at awaiting_user_action, so the restart also waits until it is answered.
|
|
152
|
+
async function restartDiscovery(projectDir, rawDir, store) {
|
|
153
|
+
const handoff = await existingHandoffFiles(projectDir);
|
|
154
|
+
const previousStore = await recordedStore(rawDir);
|
|
155
|
+
if (handoff.length && previousStore !== store) {
|
|
156
|
+
throw new ShopifyDiscoveryStop(
|
|
157
|
+
'shopify_restart_blocked_handoff',
|
|
158
|
+
`this project already hands ${previousStore || 'an unrecorded store'}'s discovery to mapping (${handoff.join(', ')}), so ${store} cannot be read into it. Nothing was read or changed. Start a new migration project for ${store}.`,
|
|
159
|
+
{ recorded: previousStore, store, handoff },
|
|
160
|
+
);
|
|
161
|
+
}
|
|
162
|
+
const previous = await readJson(path.join(rawDir, STEPS_FILE));
|
|
163
|
+
if (previous && previous.steps && previous.startedAt) {
|
|
164
|
+
for (const entry of Object.values(previous.steps)) {
|
|
165
|
+
for (const question of (entry.record && entry.record.questions) || []) {
|
|
166
|
+
try {
|
|
167
|
+
const action = await readUserAction(projectDir, questionRequestId(previous.startedAt, question.key));
|
|
168
|
+
if (action.status !== 'answered') {
|
|
169
|
+
throw new ShopifyDiscoveryStop('shopify_restart_blocked', `a merchant question from the previous discovery is still pending (${action.requestId}); answer it first, then restart`, { requestId: action.requestId });
|
|
170
|
+
}
|
|
171
|
+
} catch (error) {
|
|
172
|
+
if (error.code !== 'ENOENT') throw error;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
let names = [];
|
|
178
|
+
try {
|
|
179
|
+
names = await fs.readdir(rawDir);
|
|
180
|
+
} catch (error) {
|
|
181
|
+
if (error.code !== 'ENOENT') throw error;
|
|
182
|
+
}
|
|
183
|
+
for (const name of names) {
|
|
184
|
+
if (CONNECTION_FILES.includes(name) || name.startsWith('staff-access.json.unreadable-')) continue;
|
|
185
|
+
await fs.rm(path.join(rawDir, name), { recursive: true, force: true });
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
async function writeSteps(rawDir, state) {
|
|
190
|
+
await writeJsonAtomic(path.join(rawDir, STEPS_FILE), state);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
function entityFile(entity) {
|
|
194
|
+
return path.join(ENTITIES_DIR, `${entity}.json`);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
// ---------------------------------------------------------------------------------------------
|
|
198
|
+
// Step 1 -- capture: one count (where one exists) and up to SAMPLE_LIMIT samples per entity
|
|
199
|
+
// ---------------------------------------------------------------------------------------------
|
|
200
|
+
|
|
201
|
+
function errorEntries(read, errors) {
|
|
202
|
+
return (errors || []).map((error) => ({
|
|
203
|
+
read,
|
|
204
|
+
code: (error && error.extensions && error.extensions.code) || 'GRAPHQL_ERROR',
|
|
205
|
+
message: String((error && error.message) || 'GraphQL error').slice(0, 500),
|
|
206
|
+
}));
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
// A read Shopify throttled on all its calls is a failed read of that entity: a
|
|
210
|
+
// capture-failed row, never an empty entity. Every other CLI failure stops the step.
|
|
211
|
+
async function readOrThrottled(execute, query, variables = null) {
|
|
212
|
+
try {
|
|
213
|
+
return await execute(query, variables);
|
|
214
|
+
} catch (error) {
|
|
215
|
+
if (error instanceof ShopifyCliError && error.code === 'shopify_throttled') {
|
|
216
|
+
return { data: null, errors: [{ message: 'Shopify throttled this read on every call (31 s of backoff)', extensions: { code: 'shopify_throttled' } }] };
|
|
217
|
+
}
|
|
218
|
+
throw error;
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
async function captureEntity(read, { execute: rawExecute, sampleLimit, store }) {
|
|
223
|
+
const execute = (query, variables) => readOrThrottled(rawExecute, query, variables);
|
|
224
|
+
const record = { entity: read.entity, store, scopes: read.scopes, reads: [], count: null, countPrecision: null, countExact: false, samples: [], sampleCount: 0, errors: [] };
|
|
225
|
+
if (read.count) {
|
|
226
|
+
const name = operationName(read.count);
|
|
227
|
+
record.reads.push(name);
|
|
228
|
+
const result = await execute(read.count);
|
|
229
|
+
if (result.errors && result.errors.length) {
|
|
230
|
+
record.errors.push(...errorEntries(name, result.errors));
|
|
231
|
+
} else {
|
|
232
|
+
const counted = at(result.data, read.countPath);
|
|
233
|
+
record.count = counted && Number.isInteger(counted.count) ? counted.count : null;
|
|
234
|
+
record.countPrecision = counted && typeof counted.precision === 'string' ? counted.precision : null;
|
|
235
|
+
// Only an EXACT answer is a record count. Anything else (AT_LEAST, a missing precision) is a
|
|
236
|
+
// lower bound at best: `count` keeps it, `countExact` says it is not the store's total.
|
|
237
|
+
record.countExact = record.count !== null && record.countPrecision === 'EXACT';
|
|
238
|
+
if (record.count === null) record.errors.push({ read: name, code: 'COUNT_MISSING', message: 'the count read returned no count' });
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
const name = operationName(read.sample);
|
|
242
|
+
record.reads.push(name);
|
|
243
|
+
const result = await execute(read.sample, /\$first\b/.test(read.sample) ? { first: sampleLimit } : null);
|
|
244
|
+
if (result.errors && result.errors.length) {
|
|
245
|
+
record.errors.push(...errorEntries(name, result.errors));
|
|
246
|
+
} else {
|
|
247
|
+
const value = at(result.data, read.samplePath);
|
|
248
|
+
if (value === undefined || value === null) {
|
|
249
|
+
record.errors.push({ read: name, code: 'SAMPLE_MISSING', message: 'the sample read returned nothing at its path' });
|
|
250
|
+
} else if (Array.isArray(value.nodes)) {
|
|
251
|
+
record.samples = value.nodes.slice(0, sampleLimit);
|
|
252
|
+
} else if (Array.isArray(value)) {
|
|
253
|
+
record.samples = value.slice(0, sampleLimit);
|
|
254
|
+
} else {
|
|
255
|
+
record.samples = [value];
|
|
256
|
+
}
|
|
257
|
+
record.sampleCount = record.samples.length;
|
|
258
|
+
}
|
|
259
|
+
return record;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
async function captureStep(ctx) {
|
|
263
|
+
const failed = [];
|
|
264
|
+
const entities = [];
|
|
265
|
+
for (const read of ctx.reads) {
|
|
266
|
+
const rel = entityFile(read.entity);
|
|
267
|
+
const file = path.join(ctx.rawDir, rel);
|
|
268
|
+
let record = await readJson(file);
|
|
269
|
+
if (record && record.entity === read.entity && record.store !== ctx.store) {
|
|
270
|
+
throw storeMismatch(record.store, ctx.store, rel);
|
|
271
|
+
}
|
|
272
|
+
if (!record || record.entity !== read.entity) {
|
|
273
|
+
ctx.progress('Reading Shopify entity', { entity: read.entity });
|
|
274
|
+
record = { ...(await captureEntity(read, ctx)), capturedAt: ctx.now() };
|
|
275
|
+
await writeJsonAtomic(file, record);
|
|
276
|
+
}
|
|
277
|
+
entities.push({ entity: read.entity, count: record.count, countExact: record.countExact === true, sampleCount: record.sampleCount, file: rel });
|
|
278
|
+
if (record.errors.length) {
|
|
279
|
+
failed.push({ entity: read.entity, artifact: `${RAW_DIR}/${rel}`, reads: record.reads, errors: record.errors });
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
return { entities, failed };
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
// ---------------------------------------------------------------------------------------------
|
|
286
|
+
// Steps owned by the technical specs. Until a bundle ships a step's implementation, discovery
|
|
287
|
+
// stops at it: a run that skipped it would look complete while missing what it checks.
|
|
288
|
+
// ---------------------------------------------------------------------------------------------
|
|
289
|
+
|
|
290
|
+
function unavailableStep(id, checks) {
|
|
291
|
+
return {
|
|
292
|
+
id,
|
|
293
|
+
run: async () => {
|
|
294
|
+
throw new ShopifyDiscoveryStop(
|
|
295
|
+
'shopify_discovery_step_unavailable',
|
|
296
|
+
`Shopify discovery step "${id}" (${checks}) is not available in this version of the Shopify adapter, so Shopify private-data discovery cannot finish. Recorded steps are kept; re-run discovery once the step ships.`,
|
|
297
|
+
{ step: id },
|
|
298
|
+
);
|
|
299
|
+
},
|
|
300
|
+
};
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
const WITHHELD_DETAILS_STEP = Object.freeze({ id: 'withheld-details', run: protectedFields.runDiscoveryProbes });
|
|
304
|
+
|
|
305
|
+
// ---------------------------------------------------------------------------------------------
|
|
306
|
+
// Step 4 -- the order-history window
|
|
307
|
+
// ---------------------------------------------------------------------------------------------
|
|
308
|
+
|
|
309
|
+
// Through the CLI connector Shopify shows only the last ~60 days of orders, on every read path.
|
|
310
|
+
// Orders are complete only when the shop itself is younger than the window and no imported
|
|
311
|
+
// (back-dated) orders exist: the visible orders' dates are never used as proof.
|
|
312
|
+
const IMPORTED_ORDERS_KEY = 'imported-orders';
|
|
313
|
+
const ORDER_WINDOW_ROW_ID = 'shopify:orders-before-window';
|
|
314
|
+
|
|
315
|
+
function orderWindowRow(evidence) {
|
|
316
|
+
return {
|
|
317
|
+
coverageId: ORDER_WINDOW_ROW_ID,
|
|
318
|
+
platform: 'shopify',
|
|
319
|
+
capability: 'commerce.orders',
|
|
320
|
+
sourceEntity: 'orders-before-window',
|
|
321
|
+
routes: ['orders'],
|
|
322
|
+
reason: 'auth-gated',
|
|
323
|
+
evidence,
|
|
324
|
+
recoverability: 'requires-development',
|
|
325
|
+
disposition: null,
|
|
326
|
+
};
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
function windowEvidencePointer(record, answer) {
|
|
330
|
+
const parts = [
|
|
331
|
+
`shopCreatedAt=${record.shopCreatedAt || 'unreadable'}`,
|
|
332
|
+
`windowStart=${record.windowStart}`,
|
|
333
|
+
'session-receipt.json grantedScopes lacks read_all_orders',
|
|
334
|
+
];
|
|
335
|
+
if (record.backdatedOrder) parts.push(`order processedAt ${record.oldestProcessedAt} precedes shopCreatedAt`);
|
|
336
|
+
if (answer) parts.push(`imported orders: ${answer}`);
|
|
337
|
+
return parts.join('; ');
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
async function orderWindowStep(ctx) {
|
|
341
|
+
const [createdRead, oldestRead] = ORDER_WINDOW_READS;
|
|
342
|
+
const nowIso = ctx.now();
|
|
343
|
+
const windowStart = new Date(Date.parse(nowIso) - ORDER_WINDOW_DAYS * 24 * 60 * 60 * 1000).toISOString();
|
|
344
|
+
const record = { store: ctx.store, readAt: nowIso, windowDays: ORDER_WINDOW_DAYS, windowStart, shopCreatedAt: null, young: false, oldestProcessedAt: null, backdatedOrder: false, errors: [], rowRequired: true };
|
|
345
|
+
const created = await readOrThrottled(ctx.execute, createdRead.query);
|
|
346
|
+
const shopCreatedAt = created.data && created.data.shop && typeof created.data.shop.createdAt === 'string' ? created.data.shop.createdAt : null;
|
|
347
|
+
if (created.errors && created.errors.length) record.errors.push(...errorEntries(operationName(createdRead.query), created.errors));
|
|
348
|
+
if (shopCreatedAt && Number.isFinite(Date.parse(shopCreatedAt))) {
|
|
349
|
+
record.shopCreatedAt = shopCreatedAt;
|
|
350
|
+
record.young = Date.parse(shopCreatedAt) > Date.parse(windowStart);
|
|
351
|
+
} else if (!record.errors.length) {
|
|
352
|
+
record.errors.push({ read: operationName(createdRead.query), code: 'CREATED_AT_MISSING', message: 'shop.createdAt was not readable' });
|
|
353
|
+
}
|
|
354
|
+
if (record.young) {
|
|
355
|
+
const oldest = await readOrThrottled(ctx.execute, oldestRead.query);
|
|
356
|
+
if (oldest.errors && oldest.errors.length) {
|
|
357
|
+
record.errors.push(...errorEntries(operationName(oldestRead.query), oldest.errors));
|
|
358
|
+
} else {
|
|
359
|
+
const node = oldest.data && oldest.data.orders && Array.isArray(oldest.data.orders.nodes) ? oldest.data.orders.nodes[0] : null;
|
|
360
|
+
record.oldestProcessedAt = node && typeof node.processedAt === 'string' ? node.processedAt : null;
|
|
361
|
+
record.backdatedOrder = Boolean(record.oldestProcessedAt && Date.parse(record.oldestProcessedAt) < Date.parse(record.shopCreatedAt));
|
|
362
|
+
// A young store with no back-dated visible order: only the merchant can say whether orders
|
|
363
|
+
// were imported with dates Shopify keys the window on.
|
|
364
|
+
record.rowRequired = record.backdatedOrder;
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
await writeJsonAtomic(path.join(ctx.rawDir, ORDER_WINDOW_FILE), record);
|
|
368
|
+
const result = { ...record, file: ORDER_WINDOW_FILE };
|
|
369
|
+
if (record.young && !record.backdatedOrder && !record.errors.length) {
|
|
370
|
+
result.questions = [{
|
|
371
|
+
key: IMPORTED_ORDERS_KEY,
|
|
372
|
+
title: 'Imported Shopify orders',
|
|
373
|
+
prompt: 'Were orders imported into this Shopify store from another system?',
|
|
374
|
+
response: { mode: 'choice' },
|
|
375
|
+
choices: [
|
|
376
|
+
{ id: 'no', label: 'No' },
|
|
377
|
+
{ id: 'yes', label: 'Yes' },
|
|
378
|
+
{ id: 'unknown', label: 'I don\'t know' },
|
|
379
|
+
],
|
|
380
|
+
artifactRefs: [{ path: `${RAW_DIR}/${ORDER_WINDOW_FILE}`, mediaType: 'application/json' }],
|
|
381
|
+
}];
|
|
382
|
+
}
|
|
383
|
+
return result;
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
function orderWindowRows(record, answers) {
|
|
387
|
+
const asked = Array.isArray(record.questions) && record.questions.some((question) => question.key === IMPORTED_ORDERS_KEY);
|
|
388
|
+
if (asked) {
|
|
389
|
+
const answer = answers[IMPORTED_ORDERS_KEY];
|
|
390
|
+
const choice = answer && answer.answer ? answer.answer.choice : null;
|
|
391
|
+
if (choice === 'no') return [];
|
|
392
|
+
// `yes`, `unknown`, or no recorded answer: fail closed.
|
|
393
|
+
return [orderWindowRow({ artifact: answer ? answer.evidence : `${RAW_DIR}/${ORDER_WINDOW_FILE}`, pointer: windowEvidencePointer(record, choice || 'unanswered') })];
|
|
394
|
+
}
|
|
395
|
+
if (record.rowRequired === false) return [];
|
|
396
|
+
return [orderWindowRow({ artifact: `${RAW_DIR}/${ORDER_WINDOW_FILE}`, pointer: windowEvidencePointer(record, null) })];
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
const ORDER_WINDOW_STEP = Object.freeze({ id: 'order-window', run: orderWindowStep, rows: orderWindowRows });
|
|
400
|
+
|
|
401
|
+
const GIFT_CARD_CENSUS_STEP = Object.freeze({
|
|
402
|
+
id: 'gift-card-census',
|
|
403
|
+
run: (ctx) => giftCards.giftCardCensusStep(ctx, bulk),
|
|
404
|
+
rows: (record) => record.rows || [],
|
|
405
|
+
});
|
|
406
|
+
|
|
407
|
+
// ---------------------------------------------------------------------------------------------
|
|
408
|
+
// Step 5 -- questions to the merchant, raised by earlier steps as `record.questions[]`
|
|
409
|
+
// ---------------------------------------------------------------------------------------------
|
|
410
|
+
|
|
411
|
+
// Deterministic per discovery run and question, so a crash between creating the action and
|
|
412
|
+
// recording it never asks twice.
|
|
413
|
+
function questionRequestId(startedAt, key) {
|
|
414
|
+
const hex = crypto.createHash('sha256').update(`shopify-discovery\0${startedAt}\0${key}`).digest('hex');
|
|
415
|
+
return `uar_${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20, 32)}`;
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
async function ensureQuestion(ctx, question) {
|
|
419
|
+
const requestId = questionRequestId(ctx.state.startedAt, question.key);
|
|
420
|
+
try {
|
|
421
|
+
return await readUserAction(ctx.projectDir, requestId);
|
|
422
|
+
} catch (error) {
|
|
423
|
+
if (error.code !== 'ENOENT') throw error;
|
|
424
|
+
}
|
|
425
|
+
return createUserAction(ctx.projectDir, {
|
|
426
|
+
requestId,
|
|
427
|
+
kind: 'question',
|
|
428
|
+
stage: 'discovery',
|
|
429
|
+
title: question.title,
|
|
430
|
+
prompt: question.prompt,
|
|
431
|
+
response: { mode: question.response && question.response.mode ? question.response.mode : 'choice' },
|
|
432
|
+
choices: question.choices || [],
|
|
433
|
+
artifactRefs: question.artifactRefs || [],
|
|
434
|
+
});
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
async function questionsStep(ctx) {
|
|
438
|
+
const questions = [];
|
|
439
|
+
for (const [stepId, entry] of Object.entries(ctx.state.steps)) {
|
|
440
|
+
for (const question of (entry.record && entry.record.questions) || []) questions.push({ stepId, ...question });
|
|
441
|
+
}
|
|
442
|
+
const answers = {};
|
|
443
|
+
const pending = [];
|
|
444
|
+
for (const question of questions) {
|
|
445
|
+
const action = await ensureQuestion(ctx, question);
|
|
446
|
+
if (action.status === 'answered') {
|
|
447
|
+
answers[question.key] = { stepId: question.stepId, requestId: action.requestId, answer: action.answer, evidence: `orchestration/user-actions/${action.requestId}.json` };
|
|
448
|
+
} else {
|
|
449
|
+
pending.push(action.requestId);
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
if (pending.length) return { awaiting: pending };
|
|
453
|
+
return { answers };
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
// ---------------------------------------------------------------------------------------------
|
|
457
|
+
// Step 6 -- the coverage file and the raw-capture index
|
|
458
|
+
// ---------------------------------------------------------------------------------------------
|
|
459
|
+
|
|
460
|
+
function countCell(entry) {
|
|
461
|
+
if (entry.count === null) return '—';
|
|
462
|
+
return entry.countExact ? String(entry.count) : `≥ ${entry.count} (not exact)`;
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
function renderIndex(capture, rows, generatedAt) {
|
|
466
|
+
const lines = [
|
|
467
|
+
'# Shopify discovery capture',
|
|
468
|
+
'',
|
|
469
|
+
`Generated ${generatedAt}. Raw evidence only: \`source-profile.md\` and \`source-schema.json\` are synthesized from it.`,
|
|
470
|
+
'',
|
|
471
|
+
'| Entity | Count | Samples | File |',
|
|
472
|
+
'| --- | --- | --- | --- |',
|
|
473
|
+
...capture.entities.map((entry) => `| ${entry.entity} | ${countCell(entry)} | ${entry.sampleCount} | \`${entry.file}\` |`),
|
|
474
|
+
'',
|
|
475
|
+
`Coverage rows: ${rows.length} (\`source-coverage.json\`).`,
|
|
476
|
+
];
|
|
477
|
+
for (const row of rows) lines.push(`- \`${row.coverageId}\` — ${row.reason}`);
|
|
478
|
+
return `${lines.join('\n')}\n`;
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
async function coverageStep(ctx) {
|
|
482
|
+
const capture = ctx.state.steps.capture && ctx.state.steps.capture.record;
|
|
483
|
+
if (!capture) throw new ShopifyDiscoveryStop('shopify_discovery_state_invalid', 'the capture step is not recorded; re-run discovery');
|
|
484
|
+
const answers = (ctx.state.steps.questions && ctx.state.steps.questions.record && ctx.state.steps.questions.record.answers) || {};
|
|
485
|
+
const stepRows = [];
|
|
486
|
+
for (const step of ctx.steps) {
|
|
487
|
+
const entry = ctx.state.steps[step.id];
|
|
488
|
+
if (!entry || !entry.record || step.id === 'capture' || step.id === 'coverage') continue;
|
|
489
|
+
const rows = typeof step.rows === 'function' ? step.rows(entry.record, answers) : entry.record.rows;
|
|
490
|
+
if (Array.isArray(rows)) stepRows.push(...rows);
|
|
491
|
+
}
|
|
492
|
+
const generatedAt = ctx.now();
|
|
493
|
+
const rows = buildShopifyCoverageRows({ captureFailures: capture.failed, stepRows, rawDir: RAW_DIR });
|
|
494
|
+
const file = buildCoverageFile({ platform: 'shopify', adapter: 'shopify', rows, generatedAt });
|
|
495
|
+
await writeJsonAtomic(path.join(ctx.rawDir, 'source-coverage.json'), file);
|
|
496
|
+
await fs.writeFile(path.join(ctx.rawDir, 'README.md'), renderIndex(capture, file.rows, generatedAt), 'utf8');
|
|
497
|
+
return { rows: file.rows.map((row) => row.coverageId) };
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
// ---------------------------------------------------------------------------------------------
|
|
501
|
+
// The sequence
|
|
502
|
+
// ---------------------------------------------------------------------------------------------
|
|
503
|
+
|
|
504
|
+
const DEFAULT_STEPS = Object.freeze([
|
|
505
|
+
{ id: 'capture', run: captureStep },
|
|
506
|
+
WITHHELD_DETAILS_STEP,
|
|
507
|
+
GIFT_CARD_CENSUS_STEP,
|
|
508
|
+
ORDER_WINDOW_STEP,
|
|
509
|
+
{ id: 'questions', run: questionsStep },
|
|
510
|
+
{ id: 'coverage', run: coverageStep },
|
|
511
|
+
]);
|
|
512
|
+
|
|
513
|
+
// Forget what the named entities captured, so the next run reads exactly those again. The capture
|
|
514
|
+
// and coverage records are re-derived; every other recorded step is kept.
|
|
515
|
+
async function resetEntities(projectDir, rawDir, entities, now, store) {
|
|
516
|
+
if (!entities.length) return;
|
|
517
|
+
const known = new Set(ALL_READS.map((read) => read.entity));
|
|
518
|
+
for (const entity of entities) {
|
|
519
|
+
if (!known.has(entity)) throw new ShopifyDiscoveryStop('shopify_entity_unknown', `unknown Shopify entity ${entity}; known: ${[...known].join(', ')}`);
|
|
520
|
+
await fs.rm(path.join(rawDir, entityFile(entity)), { force: true });
|
|
521
|
+
}
|
|
522
|
+
const state = await readSteps(rawDir, now, store);
|
|
523
|
+
delete state.steps.capture;
|
|
524
|
+
delete state.steps.coverage;
|
|
525
|
+
if (await protectedFields.resetProbeEntities(projectDir, entities)) delete state.steps['withheld-details'];
|
|
526
|
+
await writeSteps(rawDir, state);
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
async function runDiscovery({
|
|
530
|
+
projectDir,
|
|
531
|
+
store,
|
|
532
|
+
execute,
|
|
533
|
+
steps = DEFAULT_STEPS,
|
|
534
|
+
reads = ALL_READS,
|
|
535
|
+
sampleLimit = SAMPLE_LIMIT,
|
|
536
|
+
reread = [],
|
|
537
|
+
restart = false,
|
|
538
|
+
now = () => new Date().toISOString(),
|
|
539
|
+
progress = () => {},
|
|
540
|
+
sessionCheck = async () => ({ ok: true }),
|
|
541
|
+
} = {}) {
|
|
542
|
+
if (!projectDir) throw new Error('projectDir is required');
|
|
543
|
+
if (typeof execute !== 'function') throw new Error('execute is required');
|
|
544
|
+
const boundStore = normalizeStore(store);
|
|
545
|
+
const rawDir = path.join(projectDir, RAW_DIR);
|
|
546
|
+
if (restart) await restartDiscovery(projectDir, rawDir, boundStore);
|
|
547
|
+
// Bind before anything is read or reset: a different store's data is refused here, and the
|
|
548
|
+
// store is recorded in the steps file before the first read of a new run.
|
|
549
|
+
await assertBoundToStore(rawDir, boundStore);
|
|
550
|
+
await fs.mkdir(path.join(rawDir, ENTITIES_DIR), { recursive: true });
|
|
551
|
+
await resetEntities(projectDir, rawDir, reread, now, boundStore);
|
|
552
|
+
const state = await readSteps(rawDir, now, boundStore);
|
|
553
|
+
if (!state.steps || typeof state.steps !== 'object') state.steps = {};
|
|
554
|
+
await writeSteps(rawDir, state);
|
|
555
|
+
|
|
556
|
+
const ran = [];
|
|
557
|
+
for (const step of steps) {
|
|
558
|
+
if (state.steps[step.id] && state.steps[step.id].status === 'done') continue;
|
|
559
|
+
progress(`Shopify discovery step ${step.id}`, { step: step.id });
|
|
560
|
+
const ctx = { projectDir, rawDir, store: boundStore, execute, reads, sampleLimit, now, progress, state, steps, sessionCheck };
|
|
561
|
+
let record;
|
|
562
|
+
try {
|
|
563
|
+
record = await step.run(ctx);
|
|
564
|
+
} catch (error) {
|
|
565
|
+
// The connection lapsed: hold at a re-approval request. Recorded steps and
|
|
566
|
+
// captured entities are kept, so the resumed run reads only what is not yet captured.
|
|
567
|
+
if (error instanceof ShopifyCliError && error.code === 'source_auth_expired') {
|
|
568
|
+
const action = await recordAuthExpired(projectDir, { stage: 'discovery', store: boundStore });
|
|
569
|
+
throw new ShopifyDiscoveryStop('source_auth_expired', `the Shopify connection for ${boundStore} expired during discovery step ${step.id}. Re-approval request ${action.requestId} is pending: run the Shopify session check (with --connect if asked), then answer it and run discovery again. Finished reads are not repeated.`, { step: step.id, requestId: action.requestId });
|
|
570
|
+
}
|
|
571
|
+
throw error;
|
|
572
|
+
}
|
|
573
|
+
ran.push(step.id);
|
|
574
|
+
if (record && Array.isArray(record.awaiting)) {
|
|
575
|
+
return { status: 'awaiting_user_action', requestIds: record.awaiting, stepsRun: ran };
|
|
576
|
+
}
|
|
577
|
+
state.steps[step.id] = { status: 'done', completedAt: now(), record: record || {} };
|
|
578
|
+
await writeSteps(rawDir, state);
|
|
579
|
+
}
|
|
580
|
+
const coverage = state.steps.coverage && state.steps.coverage.record;
|
|
581
|
+
return { status: 'complete', stepsRun: ran, rows: coverage ? coverage.rows : [] };
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
// ---------------------------------------------------------------------------------------------
|
|
585
|
+
// CLI
|
|
586
|
+
// ---------------------------------------------------------------------------------------------
|
|
587
|
+
|
|
588
|
+
function parseArgs(argv) {
|
|
589
|
+
const args = { project: null, store: null, reread: [], restart: false, confirmWithheldExport: null, help: false };
|
|
590
|
+
for (let i = 0; i < argv.length; i += 1) {
|
|
591
|
+
const arg = argv[i];
|
|
592
|
+
if (arg === '--help' || arg === '-h') args.help = true;
|
|
593
|
+
else if (arg === '--project') { args.project = argv[i + 1]; i += 1; }
|
|
594
|
+
else if (arg === '--store') { args.store = argv[i + 1]; i += 1; }
|
|
595
|
+
else if (arg === '--reread') { args.reread.push(argv[i + 1]); i += 1; }
|
|
596
|
+
else if (arg === '--restart') args.restart = true;
|
|
597
|
+
else if (arg === '--confirm-withheld-export') { args.confirmWithheldExport = argv[i + 1]; i += 1; }
|
|
598
|
+
else throw new Error(`unknown argument ${arg}`);
|
|
599
|
+
}
|
|
600
|
+
return args;
|
|
601
|
+
}
|
|
602
|
+
|
|
603
|
+
const USAGE = 'Usage: shopify-discovery.js --project <migrations-root>/<project> (--store <shop>.myshopify.com [--reread <entity> ...] [--restart] | --confirm-withheld-export owner-exported) [--progress-log <path>]\n';
|
|
604
|
+
|
|
605
|
+
async function main() {
|
|
606
|
+
const parsed = parseProgressArgs(process.argv.slice(2));
|
|
607
|
+
const logger = createProgressLogger({ script: 'skills/wix-replatform/resources/rp-source-shopify/scripts/shopify-discovery.js', ...parsed.progress });
|
|
608
|
+
let args;
|
|
609
|
+
try {
|
|
610
|
+
args = parseArgs(parsed.args);
|
|
611
|
+
} catch (error) {
|
|
612
|
+
process.stderr.write(`${error.message}\n${USAGE}`);
|
|
613
|
+
return 1;
|
|
614
|
+
}
|
|
615
|
+
if (args.help) { process.stdout.write(USAGE); return 0; }
|
|
616
|
+
if (!args.project || (!args.store && !args.confirmWithheldExport) || (args.store && args.confirmWithheldExport)) { process.stderr.write(USAGE); return 1; }
|
|
617
|
+
logger.start('Shopify discovery started', { phase: 'discovery' });
|
|
618
|
+
try {
|
|
619
|
+
if (args.confirmWithheldExport) {
|
|
620
|
+
try {
|
|
621
|
+
const confirmation = await protectedFields.confirmWithheldExport(path.resolve(args.project), args.confirmWithheldExport);
|
|
622
|
+
process.stdout.write(`${JSON.stringify({ ok: true, status: 'confirmed', file: protectedFields.WITHHELD_EXPORT_FILE, confirmation })}\n`);
|
|
623
|
+
logger.complete('Shopify withheld-details export confirmed', { phase: 'discovery' });
|
|
624
|
+
return 0;
|
|
625
|
+
} catch (error) {
|
|
626
|
+
throw new ShopifyDiscoveryStop('shopify_withheld_export_confirmation_failed', error.message);
|
|
627
|
+
}
|
|
628
|
+
}
|
|
629
|
+
const store = normalizeStore(args.store);
|
|
630
|
+
// Discovery starts only after a passing session check for this store, approved from a
|
|
631
|
+
// confirmed dedicated migration staff account.
|
|
632
|
+
await assertConnectionReady(path.resolve(args.project), store);
|
|
633
|
+
const execute = createStoreExecutor({ store });
|
|
634
|
+
const result = await runDiscovery({
|
|
635
|
+
projectDir: path.resolve(args.project),
|
|
636
|
+
store,
|
|
637
|
+
execute,
|
|
638
|
+
reread: args.reread,
|
|
639
|
+
restart: args.restart,
|
|
640
|
+
sessionCheck: async () => {
|
|
641
|
+
try {
|
|
642
|
+
await runSessionCheck({ projectDir: path.resolve(args.project), store, askFirstConnection: false });
|
|
643
|
+
return { ok: true };
|
|
644
|
+
} catch (error) {
|
|
645
|
+
if (error instanceof ShopifySessionStop || error instanceof ShopifyCliError) return { ok: false, error: { code: error.code, message: error.message } };
|
|
646
|
+
throw error;
|
|
647
|
+
}
|
|
648
|
+
},
|
|
649
|
+
progress: (message, fields) => logger.progress(message, { phase: 'discovery', ...fields }),
|
|
650
|
+
});
|
|
651
|
+
process.stdout.write(`${JSON.stringify({ ok: true, ...result })}\n`);
|
|
652
|
+
logger.complete(`Shopify discovery ${result.status}`, { phase: 'discovery' });
|
|
653
|
+
return result.status === 'complete' ? 0 : 3;
|
|
654
|
+
} catch (error) {
|
|
655
|
+
if (error instanceof ShopifyDiscoveryStop || error instanceof ShopifyCliError || error instanceof ShopifySessionStop) {
|
|
656
|
+
process.stdout.write(`${JSON.stringify({ ok: false, status: 'stopped', code: error.code, message: error.message })}\n`);
|
|
657
|
+
logger.error(error.message, { phase: 'discovery' });
|
|
658
|
+
return 2;
|
|
659
|
+
}
|
|
660
|
+
throw error;
|
|
661
|
+
}
|
|
662
|
+
}
|
|
663
|
+
|
|
664
|
+
if (require.main === module) {
|
|
665
|
+
main().then((code) => { process.exitCode = code; }).catch((error) => {
|
|
666
|
+
process.stderr.write(`${error.stack || error.message}\n`);
|
|
667
|
+
process.exitCode = 1;
|
|
668
|
+
});
|
|
669
|
+
}
|
|
670
|
+
|
|
671
|
+
module.exports = {
|
|
672
|
+
RAW_DIR,
|
|
673
|
+
STEPS_FILE,
|
|
674
|
+
DEFAULT_STEPS,
|
|
675
|
+
HANDOFF_FILES,
|
|
676
|
+
ShopifyDiscoveryStop,
|
|
677
|
+
captureEntity,
|
|
678
|
+
captureStep,
|
|
679
|
+
questionsStep,
|
|
680
|
+
coverageStep,
|
|
681
|
+
unavailableStep,
|
|
682
|
+
orderWindowStep,
|
|
683
|
+
orderWindowRows,
|
|
684
|
+
WITHHELD_DETAILS_STEP,
|
|
685
|
+
ORDER_WINDOW_STEP,
|
|
686
|
+
GIFT_CARD_CENSUS_STEP,
|
|
687
|
+
ORDER_WINDOW_FILE,
|
|
688
|
+
CONNECTION_FILES,
|
|
689
|
+
questionRequestId,
|
|
690
|
+
runDiscovery,
|
|
691
|
+
normalizeStore,
|
|
692
|
+
parseArgs,
|
|
693
|
+
};
|