@wix/agent-skills 1.33.1 → 1.34.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (616) hide show
  1. package/README.md +2 -0
  2. package/package.json +1 -1
  3. package/skills/wix-export/SKILL.md +83 -0
  4. package/skills/wix-harmony-editor/.publish-manifest.json +8 -0
  5. package/skills/wix-harmony-editor/COPY-SITE.md +494 -0
  6. package/skills/wix-harmony-editor/SKILL.md +317 -0
  7. package/skills/wix-harmony-editor/scripts/copy/build-description.mjs +249 -0
  8. package/skills/wix-harmony-editor/scripts/copy/check-description.mjs +225 -0
  9. package/skills/wix-harmony-editor/scripts/copy/check-mirror.mjs +89 -0
  10. package/skills/wix-harmony-editor/scripts/copy/compare-preview.mjs +76 -0
  11. package/skills/wix-harmony-editor/scripts/copy/deploy-description.mjs +212 -0
  12. package/skills/wix-harmony-editor/scripts/copy/desc-hash.mjs +44 -0
  13. package/skills/wix-harmony-editor/scripts/copy/editor-run.mjs +45 -0
  14. package/skills/wix-harmony-editor/scripts/copy/export-page.mjs +53 -0
  15. package/skills/wix-harmony-editor/scripts/copy/find-interactions.mjs +76 -0
  16. package/skills/wix-harmony-editor/scripts/copy/hide-scrollbars.mjs +16 -0
  17. package/skills/wix-harmony-editor/scripts/copy/import-media.mjs +150 -0
  18. package/skills/wix-harmony-editor/scripts/copy/link-url.mjs +27 -0
  19. package/skills/wix-harmony-editor/scripts/copy/lint-api.mjs +56 -0
  20. package/skills/wix-harmony-editor/scripts/copy/measure-source.mjs +211 -0
  21. package/skills/wix-harmony-editor/scripts/copy/merge-mirrors.mjs +29 -0
  22. package/skills/wix-harmony-editor/scripts/copy/mirror-site.mjs +92 -0
  23. package/skills/wix-harmony-editor/scripts/copy/mobile-stage.mjs +56 -0
  24. package/skills/wix-harmony-editor/scripts/copy/preview-widths.mjs +73 -0
  25. package/skills/wix-harmony-editor/scripts/copy/render-plate.mjs +67 -0
  26. package/skills/wix-harmony-editor/scripts/copy/serve-mirror.mjs +102 -0
  27. package/skills/wix-harmony-editor/scripts/copy/snapshot-capabilities.mjs +40 -0
  28. package/skills/wix-harmony-editor/scripts/copy/split-sections.mjs +191 -0
  29. package/skills/wix-harmony-editor/scripts/copy/upload-media-manager.mjs +61 -0
  30. package/skills/wix-harmony-editor/scripts/launch.sh +359 -0
  31. package/skills/wix-headless/SKILL.md +7 -2
  32. package/skills/wix-headless/references/CAPABILITIES.md +6 -1
  33. package/skills/wix-headless/references/DISCOVERY.md +2 -1
  34. package/skills/wix-headless/references/SDK_HANDOFF.md +6 -1
  35. package/skills/wix-headless/references/SEED.md +3 -2
  36. package/skills/wix-headless/references/SETUP.md +1 -0
  37. package/skills/wix-headless/references/inline-recipes/experience-donations.md +102 -0
  38. package/skills/wix-headless/references/inline-recipes/how-to-code-donations.md +146 -0
  39. package/skills/wix-headless/references/inline-recipes/setup-donations.md +15 -0
  40. package/skills/wix-headless/references/managed/CREATE.md +1 -1
  41. package/skills/wix-headless-kit/SKILL.md +110 -21
  42. package/skills/wix-headless-kit/guides/api-run.md +15 -13
  43. package/skills/wix-headless-kit/guides/existing-site.md +31 -0
  44. package/skills/wix-headless-kit/guides/migration.md +49 -17
  45. package/skills/wix-headless-kit/install/agents-md.mjs +1 -1
  46. package/skills/wix-headless-kit/install/context.mjs +61 -6
  47. package/skills/wix-headless-kit/install/pins.json +1 -1
  48. package/skills/wix-headless-kit/install/setup.mjs +107 -12
  49. package/skills/wix-headless-replatform/.publish-manifest.json +8 -0
  50. package/skills/wix-headless-replatform/SKILL.md +116 -0
  51. package/skills/wix-headless-replatform/agents/openai.yaml +6 -0
  52. package/skills/wix-headless-replatform/references/control-and-visual-fidelity-contract.md +43 -0
  53. package/skills/wix-headless-replatform/references/extraction-schema.md +187 -0
  54. package/skills/wix-headless-replatform/references/interaction-runtime-contract.md +137 -0
  55. package/skills/wix-headless-replatform/references/layout-blueprint-contract.md +41 -0
  56. package/skills/wix-headless-replatform/references/output-contract.md +93 -0
  57. package/skills/wix-headless-replatform/references/post-build-gap-contract.md +125 -0
  58. package/skills/wix-headless-replatform/references/qa-checklist.md +83 -0
  59. package/skills/wix-headless-replatform/references/safety.md +19 -0
  60. package/skills/wix-headless-replatform/references/ui-normalization-contract.md +70 -0
  61. package/skills/wix-headless-replatform/references/workflow.md +157 -0
  62. package/skills/wix-headless-replatform/registry/README.md +20 -0
  63. package/skills/wix-headless-replatform/registry/approvals/button/shadcn-default-ac60ef5.json +28 -0
  64. package/skills/wix-headless-replatform/registry/items/button/shadcn-default-ac60ef5/button.tsx +54 -0
  65. package/skills/wix-headless-replatform/registry/items/button/shadcn-default-ac60ef5/capabilities.json +60 -0
  66. package/skills/wix-headless-replatform/registry/items/button/shadcn-default-ac60ef5/contract.md +48 -0
  67. package/skills/wix-headless-replatform/registry/licenses/shadcn-ui-ac60ef5-MIT.txt +21 -0
  68. package/skills/wix-headless-replatform/registry/registry.json +36 -0
  69. package/skills/wix-headless-replatform/resources/rp-facelift/SKILL.md +32 -0
  70. package/skills/wix-headless-replatform/resources/rp-project-context/SKILL.md +62 -0
  71. package/skills/wix-headless-replatform/resources/rp-qa-gap-loop/SKILL.md +64 -0
  72. package/skills/wix-headless-replatform/resources/rp-source-evidence/SKILL.md +42 -0
  73. package/skills/wix-headless-replatform/resources/rp-ui-implementation/SKILL.md +73 -0
  74. package/skills/wix-headless-replatform/schemas/build-plan.schema.json +10 -0
  75. package/skills/wix-headless-replatform/schemas/candidate.schema.json +19 -0
  76. package/skills/wix-headless-replatform/schemas/common.schema.json +33 -0
  77. package/skills/wix-headless-replatform/schemas/decision-patch.schema.json +10 -0
  78. package/skills/wix-headless-replatform/schemas/decision-request.schema.json +10 -0
  79. package/skills/wix-headless-replatform/schemas/extraction-gap.schema.json +28 -0
  80. package/skills/wix-headless-replatform/schemas/extraction-manifest.schema.json +34 -0
  81. package/skills/wix-headless-replatform/schemas/final-report.schema.json +10 -0
  82. package/skills/wix-headless-replatform/schemas/foundation.schema.json +11 -0
  83. package/skills/wix-headless-replatform/schemas/metadata.schema.json +11 -0
  84. package/skills/wix-headless-replatform/schemas/observation-packet.schema.json +17 -0
  85. package/skills/wix-headless-replatform/schemas/page-capture.schema.json +11 -0
  86. package/skills/wix-headless-replatform/schemas/page-resolution.schema.json +33 -0
  87. package/skills/wix-headless-replatform/schemas/shared-chrome.schema.json +11 -0
  88. package/skills/wix-headless-replatform/schemas/unit.schema.json +40 -0
  89. package/skills/wix-headless-replatform/scripts/assemble-extraction.mjs +844 -0
  90. package/skills/wix-headless-replatform/scripts/benchmark-extraction.mjs +163 -0
  91. package/skills/wix-headless-replatform/scripts/browser-extraction-preflight.mjs +42 -0
  92. package/skills/wix-headless-replatform/scripts/build-extracted-homepage.mjs +228 -0
  93. package/skills/wix-headless-replatform/scripts/clear-wix-starter.mjs +87 -0
  94. package/skills/wix-headless-replatform/scripts/create-wix-project.mjs +505 -0
  95. package/skills/wix-headless-replatform/scripts/discover-urls.mjs +142 -0
  96. package/skills/wix-headless-replatform/scripts/extract-assets.mjs +140 -0
  97. package/skills/wix-headless-replatform/scripts/extract-design-system.mjs +637 -0
  98. package/skills/wix-headless-replatform/scripts/extract-interactions.mjs +1903 -0
  99. package/skills/wix-headless-replatform/scripts/extract-page.mjs +2461 -0
  100. package/skills/wix-headless-replatform/scripts/extract-seo.mjs +25 -0
  101. package/skills/wix-headless-replatform/scripts/extract-tokens.mjs +63 -0
  102. package/skills/wix-headless-replatform/scripts/finalize-extraction-report.mjs +126 -0
  103. package/skills/wix-headless-replatform/scripts/finalize-gap-review.mjs +180 -0
  104. package/skills/wix-headless-replatform/scripts/finalize-gap-review.test.mjs +98 -0
  105. package/skills/wix-headless-replatform/scripts/finalize-migration-website.mjs +103 -0
  106. package/skills/wix-headless-replatform/scripts/generate-control-state-contract.mjs +176 -0
  107. package/skills/wix-headless-replatform/scripts/generate-design-md.mjs +261 -0
  108. package/skills/wix-headless-replatform/scripts/generate-extraction-validators.mjs +25 -0
  109. package/skills/wix-headless-replatform/scripts/generate-invoice-download-backend.mjs +342 -0
  110. package/skills/wix-headless-replatform/scripts/generate-layout-blueprint.mjs +140 -0
  111. package/skills/wix-headless-replatform/scripts/generate-repeater-cms.mjs +22 -0
  112. package/skills/wix-headless-replatform/scripts/generate-route-plan.mjs +143 -0
  113. package/skills/wix-headless-replatform/scripts/generate-scene-contract.mjs +288 -0
  114. package/skills/wix-headless-replatform/scripts/generate-ui-normalization.mjs +266 -0
  115. package/skills/wix-headless-replatform/scripts/generate-visual-assets.mjs +111 -0
  116. package/skills/wix-headless-replatform/scripts/lib/browser-tooling.mjs +570 -0
  117. package/skills/wix-headless-replatform/scripts/lib/common.mjs +329 -0
  118. package/skills/wix-headless-replatform/scripts/lib/component-capabilities.mjs +121 -0
  119. package/skills/wix-headless-replatform/scripts/lib/component-registry.mjs +282 -0
  120. package/skills/wix-headless-replatform/scripts/lib/content-boundary.mjs +61 -0
  121. package/skills/wix-headless-replatform/scripts/lib/extraction-contract.mjs +374 -0
  122. package/skills/wix-headless-replatform/scripts/lib/extraction-detectors.mjs +243 -0
  123. package/skills/wix-headless-replatform/scripts/lib/extraction-validators.generated.mjs +1139 -0
  124. package/skills/wix-headless-replatform/scripts/lib/font-contract.mjs +326 -0
  125. package/skills/wix-headless-replatform/scripts/lib/frontend-automation-state.mjs +184 -0
  126. package/skills/wix-headless-replatform/scripts/lib/gap-analysis.mjs +396 -0
  127. package/skills/wix-headless-replatform/scripts/lib/html-extract.mjs +168 -0
  128. package/skills/wix-headless-replatform/scripts/lib/interaction-bootstrap.mjs +10 -0
  129. package/skills/wix-headless-replatform/scripts/lib/interaction-runtime.mjs +194 -0
  130. package/skills/wix-headless-replatform/scripts/lib/interaction-timeline.mjs +348 -0
  131. package/skills/wix-headless-replatform/scripts/lib/layout-blueprint/classifiers.mjs +141 -0
  132. package/skills/wix-headless-replatform/scripts/lib/layout-blueprint/geometry.mjs +43 -0
  133. package/skills/wix-headless-replatform/scripts/lib/layout-blueprint/vocabulary.mjs +18 -0
  134. package/skills/wix-headless-replatform/scripts/lib/ui-normalization.css +64 -0
  135. package/skills/wix-headless-replatform/scripts/optimize-svg.mjs +31 -0
  136. package/skills/wix-headless-replatform/scripts/post-build-gap.mjs +358 -0
  137. package/skills/wix-headless-replatform/scripts/provision-repeater-cms.mjs +25 -0
  138. package/skills/wix-headless-replatform/scripts/record-gap-decision.mjs +39 -0
  139. package/skills/wix-headless-replatform/scripts/replay-extraction.mjs +107 -0
  140. package/skills/wix-headless-replatform/scripts/resolve-home-page.mjs +96 -0
  141. package/skills/wix-headless-replatform/scripts/site-clone.mjs +658 -0
  142. package/skills/wix-headless-replatform/scripts/validate-font-contract.mjs +29 -0
  143. package/skills/wix-headless-replatform/scripts/verify-interactions.mjs +669 -0
  144. package/skills/wix-headless-replatform/scripts/visual-qa.mjs +370 -0
  145. package/skills/wix-headless-templates/donations/INSTRUCTIONS.md +37 -24
  146. package/skills/wix-headless-templates/donations/app/components/donations/DonateForm.tsx +49 -23
  147. package/skills/wix-headless-templates/donations/app/components/donations/DonationReceipt.tsx +6 -5
  148. package/skills/wix-headless-templates/donations/app/components/donations/GoalProgress.tsx +5 -5
  149. package/skills/wix-headless-templates/donations/app/wix/donations/campaigns.ts +4 -4
  150. package/skills/wix-headless-templates/donations/app/wix/donations/donate.ts +7 -3
  151. package/skills/wix-headless-templates/donations/app/wix/donations/donation-store.ts +2 -2
  152. package/skills/wix-headless-templates/donations/app/wix/donations/donations-core.ts +12 -9
  153. package/skills/wix-headless-templates/donations/project/src/components/donations/DonateForm.tsx +49 -23
  154. package/skills/wix-headless-templates/donations/project/src/components/donations/DonationReceipt.tsx +6 -5
  155. package/skills/wix-headless-templates/donations/project/src/components/donations/GoalProgress.tsx +5 -5
  156. package/skills/wix-headless-templates/donations/project/src/wix/donations/campaigns.ts +4 -4
  157. package/skills/wix-headless-templates/donations/project/src/wix/donations/donate.ts +7 -3
  158. package/skills/wix-headless-templates/donations/project/src/wix/donations/donation-store.ts +2 -2
  159. package/skills/wix-headless-templates/donations/project/src/wix/donations/donations-core.ts +12 -9
  160. package/skills/wix-headless-templates/donations/rest/campaigns.ts +4 -4
  161. package/skills/wix-headless-templates/donations/rest/donate.ts +7 -3
  162. package/skills/wix-headless-templates/donations/seed/SEED.md +12 -7
  163. package/skills/wix-headless-templates/donations/tests/donation-contract.test.mjs +71 -0
  164. package/skills/wix-headless-templates/donations/tests/donation-form.test.cjs +137 -0
  165. package/skills/wix-headless-templates/restaurants/INSTRUCTIONS.md +28 -14
  166. package/skills/wix-headless-templates/restaurants/app/components/restaurants/OrderCartDrawer.tsx +87 -5
  167. package/skills/wix-headless-templates/restaurants/app/hooks/restaurants/useOrderCart.ts +9 -1
  168. package/skills/wix-headless-templates/restaurants/app/wix/restaurants/order-store.ts +33 -4
  169. package/skills/wix-headless-templates/restaurants/app/wix/restaurants/ordering-core.ts +100 -5
  170. package/skills/wix-headless-templates/restaurants/app/wix/restaurants/ordering.ts +101 -15
  171. package/skills/wix-headless-templates/restaurants/app/wix/restaurants/types.ts +35 -1
  172. package/skills/wix-headless-templates/restaurants/project/src/components/restaurants/OrderCartDrawer.tsx +87 -5
  173. package/skills/wix-headless-templates/restaurants/project/src/hooks/restaurants/useOrderCart.ts +9 -1
  174. package/skills/wix-headless-templates/restaurants/project/src/wix/restaurants/order-store.ts +33 -4
  175. package/skills/wix-headless-templates/restaurants/project/src/wix/restaurants/ordering-core.ts +100 -5
  176. package/skills/wix-headless-templates/restaurants/project/src/wix/restaurants/ordering.ts +101 -15
  177. package/skills/wix-headless-templates/restaurants/project/src/wix/restaurants/types.ts +35 -1
  178. package/skills/wix-headless-templates/restaurants/rest/ordering.ts +91 -14
  179. package/skills/wix-import/SKILL.md +90 -0
  180. package/skills/wix-manage/SKILL.md +13 -3
  181. package/skills/wix-manage/references/dashboard-navigation/dashboard-navigation.md +2 -1
  182. package/skills/wix-manage/references/dashboard-navigation/routes.json +249 -0
  183. package/skills/wix-manage/references/donations/create-and-update-donation-campaigns.md +139 -0
  184. package/skills/wix-manage/references/events/events-dashboard-navigation.md +81 -0
  185. package/skills/wix-manage/references/sites/manage-oauth-apps.md +1 -0
  186. package/skills/wix-manage/references/sites/upload-static-site.md +127 -8
  187. package/skills/wix-replatform/.publish-manifest.json +5 -5
  188. package/skills/wix-replatform/CLI.md +162 -0
  189. package/skills/wix-replatform/README.md +52 -0
  190. package/skills/wix-replatform/SKILL.md +229 -684
  191. package/skills/wix-replatform/console/account.css +1 -0
  192. package/skills/wix-replatform/console/app.css +1 -0
  193. package/skills/wix-replatform/console/app.js +117 -0
  194. package/skills/wix-replatform/console/index.html +4 -0
  195. package/skills/wix-replatform/console/json.css +11 -0
  196. package/skills/wix-replatform/lib/agent-adapters/index.js +71 -0
  197. package/skills/wix-replatform/lib/app-page-routing.js +75 -0
  198. package/skills/wix-replatform/lib/artifact-freshness.js +11 -1
  199. package/skills/wix-replatform/lib/blocked-data-requests.js +427 -0
  200. package/skills/wix-replatform/lib/census-reconciliation.js +426 -0
  201. package/skills/wix-replatform/lib/completion-report.js +1393 -13
  202. package/skills/wix-replatform/lib/config-env.js +85 -11
  203. package/skills/wix-replatform/lib/confirmed-pictures.js +212 -0
  204. package/skills/wix-replatform/lib/dependency-readiness.js +423 -0
  205. package/skills/wix-replatform/lib/dependency-recovery.js +21 -0
  206. package/skills/wix-replatform/lib/destination-choice.js +163 -0
  207. package/skills/wix-replatform/lib/destination-handoff.js +62 -0
  208. package/skills/wix-replatform/lib/destination-http.js +81 -0
  209. package/skills/wix-replatform/lib/destination-route.js +98 -0
  210. package/skills/wix-replatform/lib/destination.js +919 -0
  211. package/skills/wix-replatform/lib/discovered-census.js +231 -0
  212. package/skills/wix-replatform/lib/discovered-set-status.js +255 -0
  213. package/skills/wix-replatform/lib/document-url-guard.js +203 -0
  214. package/skills/wix-replatform/lib/entity-qa-attestation.js +339 -0
  215. package/skills/wix-replatform/lib/entity-verification.js +18 -0
  216. package/skills/wix-replatform/lib/execution-capability.js +120 -0
  217. package/skills/wix-replatform/lib/execution-log.js +170 -0
  218. package/skills/wix-replatform/lib/execution-manifest.js +20 -2
  219. package/skills/wix-replatform/lib/execution-state.js +22 -0
  220. package/skills/wix-replatform/lib/expectations-ledger.js +96 -0
  221. package/skills/wix-replatform/lib/generated-plugin-handoff.js +140 -0
  222. package/skills/wix-replatform/lib/import-readiness-contract.js +23 -0
  223. package/skills/wix-replatform/lib/import-recovery.js +800 -6
  224. package/skills/wix-replatform/lib/imported-redirect-targets.js +608 -0
  225. package/skills/wix-replatform/lib/internal-link-reconciliation.js +166 -0
  226. package/skills/wix-replatform/lib/link-audit.js +173 -0
  227. package/skills/wix-replatform/lib/link-census.js +194 -0
  228. package/skills/wix-replatform/lib/link-plan.js +148 -0
  229. package/skills/wix-replatform/lib/link-verification.js +274 -0
  230. package/skills/wix-replatform/lib/link-write-journal.js +42 -0
  231. package/skills/wix-replatform/lib/local-state.js +869 -30
  232. package/skills/wix-replatform/lib/member-completion.js +658 -0
  233. package/skills/wix-replatform/lib/member-crosswalk.js +69 -0
  234. package/skills/wix-replatform/lib/member-outcome-registry.js +265 -0
  235. package/skills/wix-replatform/lib/migration-completion.js +311 -0
  236. package/skills/wix-replatform/lib/operator-identity.js +47 -0
  237. package/skills/wix-replatform/lib/orchestration-decisions.js +248 -0
  238. package/skills/wix-replatform/lib/orchestration-preflight.js +401 -19
  239. package/skills/wix-replatform/lib/orchestration-router.js +608 -32
  240. package/skills/wix-replatform/lib/orchestration-state.js +188 -12
  241. package/skills/wix-replatform/lib/order-reference-readiness.js +30 -0
  242. package/skills/wix-replatform/lib/payments-outcome-registry.js +200 -0
  243. package/skills/wix-replatform/lib/plugin-cms-fallback.js +618 -0
  244. package/skills/wix-replatform/lib/preservation-approval-stamp.js +54 -0
  245. package/skills/wix-replatform/lib/product-media-deferral.js +96 -0
  246. package/skills/wix-replatform/lib/progress-log.js +19 -3
  247. package/skills/wix-replatform/lib/read-back-approval.js +184 -0
  248. package/skills/wix-replatform/lib/read-back-comparison.js +136 -0
  249. package/skills/wix-replatform/lib/read-back-contract.js +243 -0
  250. package/skills/wix-replatform/lib/read-back-extract.js +118 -0
  251. package/skills/wix-replatform/lib/read-back-gate.js +734 -0
  252. package/skills/wix-replatform/lib/read-back-reads.js +94 -0
  253. package/skills/wix-replatform/lib/read-back-state.js +107 -0
  254. package/skills/wix-replatform/lib/read-back-summary.js +81 -0
  255. package/skills/wix-replatform/lib/rerun-conflicts.js +334 -0
  256. package/skills/wix-replatform/lib/run-controller.js +401 -0
  257. package/skills/wix-replatform/lib/seo-outcome-registry.js +45 -0
  258. package/skills/wix-replatform/lib/setup-verification.js +148 -0
  259. package/skills/wix-replatform/lib/source-access.js +231 -0
  260. package/skills/wix-replatform/lib/source-coverage.js +1130 -0
  261. package/skills/wix-replatform/lib/source-secrets.js +277 -0
  262. package/skills/wix-replatform/lib/structured-link-patch.js +59 -0
  263. package/skills/wix-replatform/lib/task-state.js +110 -0
  264. package/skills/wix-replatform/lib/url-preservation-report.js +319 -0
  265. package/skills/wix-replatform/lib/url-preservation-state.js +349 -1
  266. package/skills/wix-replatform/lib/url-redirect-plan.js +728 -0
  267. package/skills/wix-replatform/lib/url-verification.js +315 -0
  268. package/skills/wix-replatform/lib/user-action-effects.js +42 -0
  269. package/skills/wix-replatform/lib/user-actions.js +264 -0
  270. package/skills/wix-replatform/lib/website-handoff.js +1220 -0
  271. package/skills/wix-replatform/lib/wix-client-callers.js +54 -0
  272. package/skills/wix-replatform/lib/wix-dashboard-url.js +35 -0
  273. package/skills/wix-replatform/lib/write-verification-state.js +92 -0
  274. package/skills/wix-replatform/lib/write-verification.js +274 -0
  275. package/skills/wix-replatform/resources/rp-destination/SKILL.md +137 -0
  276. package/skills/wix-replatform/resources/rp-discovery/SKILL.md +189 -16
  277. package/skills/wix-replatform/resources/rp-discovery/scripts/promote-source-coverage.js +47 -0
  278. package/skills/wix-replatform/resources/rp-execute-import/SKILL.md +869 -29
  279. package/skills/wix-replatform/resources/rp-execute-import/scripts/shipping-estimate-audit.js +70 -0
  280. package/skills/wix-replatform/resources/rp-execute-setup/SKILL.md +195 -29
  281. package/skills/wix-replatform/resources/rp-execute-setup/scripts/execute-setup.js +442 -0
  282. package/skills/wix-replatform/resources/rp-execution-policy/SKILL.md +112 -0
  283. package/skills/wix-replatform/resources/rp-execution-policy/lib/coupon-currency-plan-report.js +143 -0
  284. package/skills/wix-replatform/resources/rp-execution-policy/lib/payments-report.js +244 -0
  285. package/skills/wix-replatform/resources/rp-import-codegen/SKILL.md +2082 -38
  286. package/skills/wix-replatform/resources/rp-mapper/SKILL.md +528 -11
  287. package/skills/wix-replatform/resources/rp-mapper/lib/structure-bridge-planning.js +303 -0
  288. package/skills/wix-replatform/resources/rp-mapper/scripts/coverage-reconcile.js +88 -0
  289. package/skills/wix-replatform/resources/rp-mapper/wix-business-solutions-taxonomy.md +6 -5
  290. package/skills/wix-replatform/resources/rp-preflight/SKILL.md +40 -0
  291. package/skills/wix-replatform/resources/rp-project-intake/SKILL.md +55 -0
  292. package/skills/wix-replatform/resources/rp-quick-runtime/SKILL.md +60 -0
  293. package/skills/wix-replatform/resources/rp-quick-runtime/lib/import-progress.js +89 -0
  294. package/skills/wix-replatform/resources/rp-quick-runtime/lib/limit-recovery.js +36 -0
  295. package/skills/wix-replatform/resources/rp-quick-shopify/SKILL.md +123 -0
  296. package/skills/wix-replatform/resources/rp-quick-shopify/quick-mode.json +124 -0
  297. package/skills/wix-replatform/resources/rp-quick-shopify/scripts/quick-mode.js +522 -0
  298. package/skills/wix-replatform/resources/rp-quick-woocommerce/SKILL.md +56 -0
  299. package/skills/wix-replatform/resources/rp-quick-woocommerce/quick-mode.json +91 -0
  300. package/skills/wix-replatform/resources/rp-quick-woocommerce/scripts/quick-mode.js +255 -0
  301. package/skills/wix-replatform/resources/rp-setup-discovery/SKILL.md +80 -10
  302. package/skills/wix-replatform/resources/rp-setup-discovery/scripts/quick-setup-plan.js +44 -0
  303. package/skills/wix-replatform/resources/rp-source-csv/SKILL.md +3 -0
  304. package/skills/wix-replatform/resources/rp-source-csv/lib/csv-fileset.js +0 -0
  305. package/skills/wix-replatform/resources/rp-source-csv/scripts/csv-discovery.js +21 -1
  306. package/skills/wix-replatform/resources/rp-source-inputs/SKILL.md +66 -0
  307. package/skills/wix-replatform/resources/rp-source-sfcc/SKILL.md +153 -0
  308. package/skills/wix-replatform/resources/rp-source-shopify/SKILL.md +394 -0
  309. package/skills/wix-replatform/resources/rp-source-shopify/lib/discovery-reads.js +200 -0
  310. package/skills/wix-replatform/resources/rp-source-shopify/lib/import-findings.js +34 -0
  311. package/skills/wix-replatform/resources/rp-source-shopify/lib/shopify-bulk-sqlite-worker.js +44 -0
  312. package/skills/wix-replatform/resources/rp-source-shopify/lib/shopify-bulk.js +1470 -0
  313. package/skills/wix-replatform/resources/rp-source-shopify/lib/shopify-cli.js +446 -0
  314. package/skills/wix-replatform/resources/rp-source-shopify/lib/shopify-gift-cards.js +474 -0
  315. package/skills/wix-replatform/resources/rp-source-shopify/lib/shopify-protected-fields.js +879 -0
  316. package/skills/wix-replatform/resources/rp-source-shopify/lib/shopify-session.js +426 -0
  317. package/skills/wix-replatform/resources/rp-source-shopify/queries/articles.graphql +24 -0
  318. package/skills/wix-replatform/resources/rp-source-shopify/queries/blogs.graphql +18 -0
  319. package/skills/wix-replatform/resources/rp-source-shopify/queries/collections.graphql +40 -0
  320. package/skills/wix-replatform/resources/rp-source-shopify/queries/customers.graphql +76 -0
  321. package/skills/wix-replatform/resources/rp-source-shopify/queries/delivery-profiles.graphql +51 -0
  322. package/skills/wix-replatform/resources/rp-source-shopify/queries/discounts.graphql +35 -0
  323. package/skills/wix-replatform/resources/rp-source-shopify/queries/files.graphql +20 -0
  324. package/skills/wix-replatform/resources/rp-source-shopify/queries/gift-cards.graphql +18 -0
  325. package/skills/wix-replatform/resources/rp-source-shopify/queries/inventory.graphql +31 -0
  326. package/skills/wix-replatform/resources/rp-source-shopify/queries/locations.graphql +21 -0
  327. package/skills/wix-replatform/resources/rp-source-shopify/queries/menus.graphql +21 -0
  328. package/skills/wix-replatform/resources/rp-source-shopify/queries/metaobjects.graphql +30 -0
  329. package/skills/wix-replatform/resources/rp-source-shopify/queries/orders-core.graphql +150 -0
  330. package/skills/wix-replatform/resources/rp-source-shopify/queries/orders-fulfillments.graphql +36 -0
  331. package/skills/wix-replatform/resources/rp-source-shopify/queries/orders-refunds.graphql +48 -0
  332. package/skills/wix-replatform/resources/rp-source-shopify/queries/pages.graphql +20 -0
  333. package/skills/wix-replatform/resources/rp-source-shopify/queries/probe-customers-address.graphql +8 -0
  334. package/skills/wix-replatform/resources/rp-source-shopify/queries/probe-customers-email.graphql +6 -0
  335. package/skills/wix-replatform/resources/rp-source-shopify/queries/probe-customers-name.graphql +8 -0
  336. package/skills/wix-replatform/resources/rp-source-shopify/queries/probe-customers-phone.graphql +8 -0
  337. package/skills/wix-replatform/resources/rp-source-shopify/queries/probe-orders-address.graphql +12 -0
  338. package/skills/wix-replatform/resources/rp-source-shopify/queries/probe-orders-email.graphql +6 -0
  339. package/skills/wix-replatform/resources/rp-source-shopify/queries/probe-orders-name.graphql +13 -0
  340. package/skills/wix-replatform/resources/rp-source-shopify/queries/probe-orders-phone.graphql +13 -0
  341. package/skills/wix-replatform/resources/rp-source-shopify/queries/products.graphql +73 -0
  342. package/skills/wix-replatform/resources/rp-source-shopify/queries/url-redirects.graphql +13 -0
  343. package/skills/wix-replatform/resources/rp-source-shopify/scripts/shopify-discovery.js +693 -0
  344. package/skills/wix-replatform/resources/rp-source-shopify/scripts/shopify-extract.js +283 -0
  345. package/skills/wix-replatform/resources/rp-source-shopify/scripts/shopify-gift-card-remedy.js +191 -0
  346. package/skills/wix-replatform/resources/rp-source-shopify/scripts/shopify-session-check.js +115 -0
  347. package/skills/wix-replatform/resources/rp-source-shopify/source-schema.example.json +201 -0
  348. package/skills/wix-replatform/resources/rp-source-wordpress/PLUGIN-READ-PLANS.md +146 -0
  349. package/skills/wix-replatform/resources/rp-source-wordpress/SKILL.md +736 -22
  350. package/skills/wix-replatform/resources/rp-source-wordpress/lib/blocked-data-handlers.js +73 -0
  351. package/skills/wix-replatform/resources/rp-source-wordpress/lib/checkout-field-csv-parser.js +115 -0
  352. package/skills/wix-replatform/resources/rp-source-wordpress/lib/checkout-field-csv-parser.test-fixture.js +91 -0
  353. package/skills/wix-replatform/resources/rp-source-wordpress/lib/coupon-discovery.js +440 -0
  354. package/skills/wix-replatform/resources/rp-source-wordpress/lib/currency-gate.js +125 -0
  355. package/skills/wix-replatform/resources/rp-source-wordpress/lib/gateway-source-keys.js +252 -0
  356. package/skills/wix-replatform/resources/rp-source-wordpress/lib/gateway-source-keys.json +183 -0
  357. package/skills/wix-replatform/resources/rp-source-wordpress/lib/gateway-summary.mjs +333 -0
  358. package/skills/wix-replatform/resources/rp-source-wordpress/lib/invoice-discovery.js +426 -0
  359. package/skills/wix-replatform/resources/rp-source-wordpress/lib/plugin-disposition.js +400 -0
  360. package/skills/wix-replatform/resources/rp-source-wordpress/lib/plugin-entity-read-plan.js +633 -0
  361. package/skills/wix-replatform/resources/rp-source-wordpress/lib/plugin-knowledge.js +1127 -0
  362. package/skills/wix-replatform/resources/rp-source-wordpress/lib/refund-corroboration.js +194 -0
  363. package/skills/wix-replatform/resources/rp-source-wordpress/lib/refund-corroboration.json +100 -0
  364. package/skills/wix-replatform/resources/rp-source-wordpress/lib/sampled-ids-batch.js +157 -0
  365. package/skills/wix-replatform/resources/rp-source-wordpress/lib/secret-value-guard.js +234 -0
  366. package/skills/wix-replatform/resources/rp-source-wordpress/lib/store-currency.js +101 -0
  367. package/skills/wix-replatform/resources/rp-source-wordpress/lib/structure-bridge-reader.js +755 -0
  368. package/skills/wix-replatform/resources/rp-source-wordpress/lib/wix-wp-plugin-v2-client.js +1074 -0
  369. package/skills/wix-replatform/resources/rp-source-wordpress/lib/wix-wp-plugin-v2-client.test-fixture.js +149 -0
  370. package/skills/wix-replatform/resources/rp-source-wordpress/lib/woo-inventory.js +25 -0
  371. package/skills/wix-replatform/resources/rp-source-wordpress/lib/wp-http.js +204 -9
  372. package/skills/wix-replatform/resources/rp-source-wordpress/lib/wp-image-url.js +186 -0
  373. package/skills/wix-replatform/resources/rp-source-wordpress/lib/wp-plugin-detect.js +1422 -0
  374. package/skills/wix-replatform/resources/rp-source-wordpress/lib/wp-redirect-sources.js +343 -0
  375. package/skills/wix-replatform/resources/rp-source-wordpress/lib/wp-route-classifier.js +262 -26
  376. package/skills/wix-replatform/resources/rp-source-wordpress/lib/yoast-product-seo-evidence.js +272 -0
  377. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/README.md +373 -0
  378. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/advanced-custom-fields.json +101 -0
  379. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/back-in-stock-notifier-for-woocommerce.json +81 -0
  380. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/capabilities-pending-decision.json +128 -0
  381. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/cms-fallback-eligible.json +18 -0
  382. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/contact-form-7.json +104 -0
  383. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/facebook-for-woocommerce.json +44 -0
  384. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/fingerprint-aliases.json +49 -0
  385. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/free-gifts-for-woocommerce.json +94 -0
  386. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/index.json +863 -0
  387. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/mailpoet.json +52 -0
  388. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/membership-for-woocommerce.json +161 -0
  389. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/mwb-bookings-for-woocommerce.json +180 -0
  390. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/no-migration-needed.json +286 -0
  391. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/pricing-deals-for-woocommerce.json +79 -0
  392. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/product-extras-for-woocommerce.json +120 -0
  393. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/pw-woocommerce-gift-cards.json +128 -0
  394. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/requires-development.json +88 -0
  395. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/seo-by-rank-math.json +80 -0
  396. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/seriously-simple-podcasting.json +46 -0
  397. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/strong-testimonials.json +55 -0
  398. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/subscriptions-for-woocommerce.json +99 -0
  399. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/tablepress.json +55 -0
  400. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/the-events-calendar.json +160 -0
  401. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/ti-woocommerce-wishlist.json +81 -0
  402. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/woo-checkout-field-editor-pro.json +60 -0
  403. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/woo-discount-rules.json +74 -0
  404. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/woo-product-bundle.json +75 -0
  405. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/woocommerce-gift-cards.json +60 -0
  406. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/woocommerce-other-payment-gateway.json +44 -0
  407. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/woocommerce-pdf-invoices-packing-slips.json +57 -0
  408. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/woocommerce-product-addon.json +141 -0
  409. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/woocommerce-progressive-discounts.json +54 -0
  410. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/wordpress-seo.json +158 -0
  411. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/wpc-composite-products.json +97 -0
  412. package/skills/wix-replatform/resources/rp-source-wordpress/plugins/wpforms-lite.json +86 -0
  413. package/skills/wix-replatform/resources/rp-source-wordpress/scripts/capture-store-settings.js +90 -0
  414. package/skills/wix-replatform/resources/rp-source-wordpress/scripts/plugin-knowledge-validate.js +51 -0
  415. package/skills/wix-replatform/resources/rp-source-wordpress/scripts/plugin-knowledge.js +103 -0
  416. package/skills/wix-replatform/resources/rp-source-wordpress/scripts/wp-discovery.js +1668 -33
  417. package/skills/wix-replatform/resources/rp-source-wordpress/scripts/wp-plugin-inventory.js +273 -0
  418. package/skills/wix-replatform/resources/rp-source-wordpress/secret-value-patterns.v1.json +11 -0
  419. package/skills/wix-replatform/resources/rp-source-wordpress/sub-parts.json +13 -0
  420. package/skills/wix-replatform/resources/rp-target-wix/SKILL.md +446 -32
  421. package/skills/wix-replatform/resources/rp-target-wix/app-page-routing-capabilities.json +36 -0
  422. package/skills/wix-replatform/resources/rp-target-wix/domains/README.md +38 -2
  423. package/skills/wix-replatform/resources/rp-target-wix/domains/SERVICE-PLUGINS.md +322 -0
  424. package/skills/wix-replatform/resources/rp-target-wix/domains/blog/docs-survey.json +70 -0
  425. package/skills/wix-replatform/resources/rp-target-wix/domains/blog/domain.json +19 -9
  426. package/skills/wix-replatform/resources/rp-target-wix/domains/blog/entities/category.json +42 -8
  427. package/skills/wix-replatform/resources/rp-target-wix/domains/blog/entities/comment.json +54 -8
  428. package/skills/wix-replatform/resources/rp-target-wix/domains/blog/entities/post.json +66 -10
  429. package/skills/wix-replatform/resources/rp-target-wix/domains/blog/entities/tag.json +38 -7
  430. package/skills/wix-replatform/resources/rp-target-wix/domains/bookings/docs-survey.json +332 -0
  431. package/skills/wix-replatform/resources/rp-target-wix/domains/bookings/domain.json +75 -0
  432. package/skills/wix-replatform/resources/rp-target-wix/domains/bookings/entities/booking.json +181 -0
  433. package/skills/wix-replatform/resources/rp-target-wix/domains/bookings/entities/service-add-on.json +130 -0
  434. package/skills/wix-replatform/resources/rp-target-wix/domains/bookings/entities/service.json +180 -0
  435. package/skills/wix-replatform/resources/rp-target-wix/domains/cms/docs-survey.json +161 -0
  436. package/skills/wix-replatform/resources/rp-target-wix/domains/cms/domain.json +15 -4
  437. package/skills/wix-replatform/resources/rp-target-wix/domains/cms/entities/collection.json +39 -7
  438. package/skills/wix-replatform/resources/rp-target-wix/domains/cms/entities/data-item.json +47 -8
  439. package/skills/wix-replatform/resources/rp-target-wix/domains/cms/entities/reference.json +7 -1
  440. package/skills/wix-replatform/resources/rp-target-wix/domains/crm/docs-survey.json +204 -0
  441. package/skills/wix-replatform/resources/rp-target-wix/domains/crm/domain.json +17 -4
  442. package/skills/wix-replatform/resources/rp-target-wix/domains/crm/entities/contact.json +159 -15
  443. package/skills/wix-replatform/resources/rp-target-wix/domains/crm/entities/email-subscription.json +80 -12
  444. package/skills/wix-replatform/resources/rp-target-wix/domains/crm/entities/label.json +48 -8
  445. package/skills/wix-replatform/resources/rp-target-wix/domains/ecom/docs-survey.json +306 -0
  446. package/skills/wix-replatform/resources/rp-target-wix/domains/ecom/domain.json +30 -7
  447. package/skills/wix-replatform/resources/rp-target-wix/domains/ecom/entities/delivery-profile.json +171 -0
  448. package/skills/wix-replatform/resources/rp-target-wix/domains/ecom/entities/discount-rule.json +182 -0
  449. package/skills/wix-replatform/resources/rp-target-wix/domains/ecom/entities/order-applied-discount.json +129 -0
  450. package/skills/wix-replatform/resources/rp-target-wix/domains/ecom/entities/order-invoice-document.json +192 -0
  451. package/skills/wix-replatform/resources/rp-target-wix/domains/ecom/entities/order-line-item-options.json +123 -0
  452. package/skills/wix-replatform/resources/rp-target-wix/domains/ecom/entities/order-line-item.json +60 -12
  453. package/skills/wix-replatform/resources/rp-target-wix/domains/ecom/entities/order-merchant-note.json +112 -0
  454. package/skills/wix-replatform/resources/rp-target-wix/domains/ecom/entities/order-payment.json +191 -0
  455. package/skills/wix-replatform/resources/rp-target-wix/domains/ecom/entities/order-refund.json +140 -13
  456. package/skills/wix-replatform/resources/rp-target-wix/domains/ecom/entities/order.json +383 -18
  457. package/skills/wix-replatform/resources/rp-target-wix/domains/ecom/entities/pickup-location.json +122 -0
  458. package/skills/wix-replatform/resources/rp-target-wix/domains/ecom/entities/shipping-option.json +98 -0
  459. package/skills/wix-replatform/resources/rp-target-wix/domains/ecom/entities/wishlist-item.json +86 -0
  460. package/skills/wix-replatform/resources/rp-target-wix/domains/events/docs-survey.json +128 -0
  461. package/skills/wix-replatform/resources/rp-target-wix/domains/events/domain.json +38 -0
  462. package/skills/wix-replatform/resources/rp-target-wix/domains/events/entities/category.json +73 -0
  463. package/skills/wix-replatform/resources/rp-target-wix/domains/events/entities/event.json +107 -0
  464. package/skills/wix-replatform/resources/rp-target-wix/domains/events/entities/registration-form.json +89 -0
  465. package/skills/wix-replatform/resources/rp-target-wix/domains/events/entities/rsvp.json +118 -0
  466. package/skills/wix-replatform/resources/rp-target-wix/domains/events/entities/ticket-definition.json +93 -0
  467. package/skills/wix-replatform/resources/rp-target-wix/domains/forms/docs-survey.json +86 -0
  468. package/skills/wix-replatform/resources/rp-target-wix/domains/forms/domain.json +56 -0
  469. package/skills/wix-replatform/resources/rp-target-wix/domains/forms/entities/form-submission.json +121 -0
  470. package/skills/wix-replatform/resources/rp-target-wix/domains/forms/entities/form.json +134 -0
  471. package/skills/wix-replatform/resources/rp-target-wix/domains/gift-cards/docs-survey.json +41 -0
  472. package/skills/wix-replatform/resources/rp-target-wix/domains/gift-cards/domain.json +50 -0
  473. package/skills/wix-replatform/resources/rp-target-wix/domains/gift-cards/entities/gift-card-product.json +87 -0
  474. package/skills/wix-replatform/resources/rp-target-wix/domains/gift-cards/entities/gift-card.json +130 -0
  475. package/skills/wix-replatform/resources/rp-target-wix/domains/index.json +914 -24
  476. package/skills/wix-replatform/resources/rp-target-wix/domains/media/docs-survey.json +41 -0
  477. package/skills/wix-replatform/resources/rp-target-wix/domains/media/domain.json +14 -4
  478. package/skills/wix-replatform/resources/rp-target-wix/domains/media/entities/media-file.json +45 -8
  479. package/skills/wix-replatform/resources/rp-target-wix/domains/media/entities/media-folder.json +41 -7
  480. package/skills/wix-replatform/resources/rp-target-wix/domains/members/docs-survey.json +119 -0
  481. package/skills/wix-replatform/resources/rp-target-wix/domains/members/domain.json +13 -3
  482. package/skills/wix-replatform/resources/rp-target-wix/domains/members/entities/badge.json +41 -7
  483. package/skills/wix-replatform/resources/rp-target-wix/domains/members/entities/custom-field.json +82 -0
  484. package/skills/wix-replatform/resources/rp-target-wix/domains/members/entities/member-about.json +77 -0
  485. package/skills/wix-replatform/resources/rp-target-wix/domains/members/entities/member.json +165 -13
  486. package/skills/wix-replatform/resources/rp-target-wix/domains/pricing-plans/docs-survey.json +41 -0
  487. package/skills/wix-replatform/resources/rp-target-wix/domains/pricing-plans/domain.json +46 -0
  488. package/skills/wix-replatform/resources/rp-target-wix/domains/pricing-plans/entities/plan-order.json +137 -0
  489. package/skills/wix-replatform/resources/rp-target-wix/domains/pricing-plans/entities/plan.json +133 -0
  490. package/skills/wix-replatform/resources/rp-target-wix/domains/sales-channels/docs-survey.json +7 -0
  491. package/skills/wix-replatform/resources/rp-target-wix/domains/sales-channels/domain.json +36 -0
  492. package/skills/wix-replatform/resources/rp-target-wix/domains/sales-channels/entities/amazon-shop-connect.json +71 -0
  493. package/skills/wix-replatform/resources/rp-target-wix/domains/sales-channels/entities/ebay-shop-connect.json +67 -0
  494. package/skills/wix-replatform/resources/rp-target-wix/domains/sales-channels/entities/google-youtube-connect.json +72 -0
  495. package/skills/wix-replatform/resources/rp-target-wix/domains/sales-channels/entities/meta-catalog-connect.json +74 -0
  496. package/skills/wix-replatform/resources/rp-target-wix/domains/sales-channels/entities/pinterest-catalog-connect.json +69 -0
  497. package/skills/wix-replatform/resources/rp-target-wix/domains/sales-channels/entities/tiktok-catalog-connect.json +61 -0
  498. package/skills/wix-replatform/resources/rp-target-wix/domains/schema.json +28 -1
  499. package/skills/wix-replatform/resources/rp-target-wix/domains/seo/docs-survey.json +109 -0
  500. package/skills/wix-replatform/resources/rp-target-wix/domains/seo/domain.json +73 -0
  501. package/skills/wix-replatform/resources/rp-target-wix/domains/seo/entities/item-seo-tags.json +148 -0
  502. package/skills/wix-replatform/resources/rp-target-wix/domains/seo/entities/seo-pattern.json +91 -0
  503. package/skills/wix-replatform/resources/rp-target-wix/domains/seo/entities/site-seo-tags.json +79 -0
  504. package/skills/wix-replatform/resources/rp-target-wix/domains/site/docs-survey.json +32 -0
  505. package/skills/wix-replatform/resources/rp-target-wix/domains/site/domain.json +49 -0
  506. package/skills/wix-replatform/resources/rp-target-wix/domains/site/entities/business-contact.json +103 -0
  507. package/skills/wix-replatform/resources/rp-target-wix/domains/stores/docs-survey.json +203 -0
  508. package/skills/wix-replatform/resources/rp-target-wix/domains/stores/domain.json +27 -10
  509. package/skills/wix-replatform/resources/rp-target-wix/domains/stores/entities/back-in-stock-request.json +119 -0
  510. package/skills/wix-replatform/resources/rp-target-wix/domains/stores/entities/brand.json +111 -0
  511. package/skills/wix-replatform/resources/rp-target-wix/domains/stores/entities/category.json +52 -8
  512. package/skills/wix-replatform/resources/rp-target-wix/domains/stores/entities/coupon.json +214 -10
  513. package/skills/wix-replatform/resources/rp-target-wix/domains/stores/entities/inventory-item.json +93 -13
  514. package/skills/wix-replatform/resources/rp-target-wix/domains/stores/entities/product-customization.json +111 -0
  515. package/skills/wix-replatform/resources/rp-target-wix/domains/stores/entities/product-tag.json +52 -10
  516. package/skills/wix-replatform/resources/rp-target-wix/domains/stores/entities/product.json +145 -14
  517. package/skills/wix-replatform/resources/rp-target-wix/domains/stores/entities/promotion.json +84 -0
  518. package/skills/wix-replatform/resources/rp-target-wix/domains/stores/entities/review.json +178 -0
  519. package/skills/wix-replatform/resources/rp-target-wix/domains/stores/entities/subscription-product.json +87 -0
  520. package/skills/wix-replatform/resources/rp-target-wix/domains/tax/docs-survey.json +106 -0
  521. package/skills/wix-replatform/resources/rp-target-wix/domains/tax/domain.json +64 -0
  522. package/skills/wix-replatform/resources/rp-target-wix/domains/tax/entities/manual-tax-mapping.json +119 -0
  523. package/skills/wix-replatform/resources/rp-target-wix/domains/tax/entities/tax-group.json +94 -0
  524. package/skills/wix-replatform/resources/rp-target-wix/domains/tax/entities/tax-region.json +113 -0
  525. package/skills/wix-replatform/resources/rp-target-wix/domains/tax/entities/tax-settings.json +65 -0
  526. package/skills/wix-replatform/resources/rp-target-wix/lib/blog-author-attribution.js +165 -0
  527. package/skills/wix-replatform/resources/rp-target-wix/lib/blog-post-build-client.js +60 -0
  528. package/skills/wix-replatform/resources/rp-target-wix/lib/blog-post-build-duplicates.js +201 -0
  529. package/skills/wix-replatform/resources/rp-target-wix/lib/blog-post-build-ledger.js +306 -0
  530. package/skills/wix-replatform/resources/rp-target-wix/lib/blog-post-build-report.js +229 -0
  531. package/skills/wix-replatform/resources/rp-target-wix/lib/blog-post-build-stage.js +55 -0
  532. package/skills/wix-replatform/resources/rp-target-wix/lib/blog-post-build.js +715 -0
  533. package/skills/wix-replatform/resources/rp-target-wix/lib/blog-post-media.js +567 -0
  534. package/skills/wix-replatform/resources/rp-target-wix/lib/bulk-results.js +73 -0
  535. package/skills/wix-replatform/resources/rp-target-wix/lib/contact-extended-fields.js +194 -0
  536. package/skills/wix-replatform/resources/rp-target-wix/lib/contact-import.js +133 -0
  537. package/skills/wix-replatform/resources/rp-target-wix/lib/contract-ledger.js +13 -4
  538. package/skills/wix-replatform/resources/rp-target-wix/lib/coupon-redemption-drift.js +491 -0
  539. package/skills/wix-replatform/resources/rp-target-wix/lib/customer-member.js +104 -0
  540. package/skills/wix-replatform/resources/rp-target-wix/lib/data-extension-schema.js +673 -0
  541. package/skills/wix-replatform/resources/rp-target-wix/lib/domain-knowledge.js +453 -2
  542. package/skills/wix-replatform/resources/rp-target-wix/lib/gift-card-balance-reconciliation.js +119 -0
  543. package/skills/wix-replatform/resources/rp-target-wix/lib/gift-card-build.js +566 -0
  544. package/skills/wix-replatform/resources/rp-target-wix/lib/gift-card-redemption-build.js +249 -0
  545. package/skills/wix-replatform/resources/rp-target-wix/lib/order-applied-discount-build.js +63 -0
  546. package/skills/wix-replatform/resources/rp-target-wix/lib/order-buyer.js +187 -0
  547. package/skills/wix-replatform/resources/rp-target-wix/lib/order-channel-build.js +64 -0
  548. package/skills/wix-replatform/resources/rp-target-wix/lib/order-history.js +1027 -0
  549. package/skills/wix-replatform/resources/rp-target-wix/lib/order-invoice-contract.js +90 -0
  550. package/skills/wix-replatform/resources/rp-target-wix/lib/order-payment-mapping.js +420 -0
  551. package/skills/wix-replatform/resources/rp-target-wix/lib/pricing-plan-definition.js +177 -0
  552. package/skills/wix-replatform/resources/rp-target-wix/lib/product-import.js +151 -0
  553. package/skills/wix-replatform/resources/rp-target-wix/lib/product-seo.js +723 -0
  554. package/skills/wix-replatform/resources/rp-target-wix/lib/seo-redirects.js +353 -0
  555. package/skills/wix-replatform/resources/rp-target-wix/lib/shipping-build.js +1437 -0
  556. package/skills/wix-replatform/resources/rp-target-wix/lib/shipping-option-stage.js +354 -0
  557. package/skills/wix-replatform/resources/rp-target-wix/lib/store-config-build.js +134 -0
  558. package/skills/wix-replatform/resources/rp-target-wix/lib/stores-category-attach.js +221 -0
  559. package/skills/wix-replatform/resources/rp-target-wix/lib/stores-inventory.js +248 -0
  560. package/skills/wix-replatform/resources/rp-target-wix/lib/stores-verification.js +86 -3
  561. package/skills/wix-replatform/resources/rp-target-wix/lib/tax-build.js +231 -0
  562. package/skills/wix-replatform/resources/rp-target-wix/lib/url-mapper-transport.js +28 -0
  563. package/skills/wix-replatform/resources/rp-target-wix/lib/value-utils.js +14 -0
  564. package/skills/wix-replatform/resources/rp-target-wix/lib/variant-correlation.js +34 -0
  565. package/skills/wix-replatform/resources/rp-target-wix/lib/wix-build.js +166 -15
  566. package/skills/wix-replatform/resources/rp-target-wix/lib/wix-target-spec.js +19 -2
  567. package/skills/wix-replatform/resources/rp-target-wix/lib/wix-writers.js +4079 -257
  568. package/skills/wix-replatform/resources/rp-target-wix/lib/write-verification.js +3 -0
  569. package/skills/wix-replatform/resources/rp-target-wix/scripts/docs-survey-sync.js +150 -0
  570. package/skills/wix-replatform/resources/rp-target-wix/scripts/domain-knowledge-validate.js +40 -2
  571. package/skills/wix-replatform/resources/rp-target-wix/scripts/verify-stores.js +6 -1
  572. package/skills/wix-replatform/resources/rp-telemetry/SKILL.md +148 -8
  573. package/skills/wix-replatform/resources/rp-telemetry/lib/bi-sink.js +83 -15
  574. package/skills/wix-replatform/resources/rp-telemetry/lib/telemetry-recorder.js +1119 -215
  575. package/skills/wix-replatform/resources/rp-telemetry/lib/transcript-digest.js +318 -0
  576. package/skills/wix-replatform/resources/rp-telemetry/scripts/meter-from-audit.js +2 -2
  577. package/skills/wix-replatform/resources/rp-telemetry/scripts/rp-telemetry.js +106 -4
  578. package/skills/wix-replatform/resources/rp-website-continuation/SKILL.md +94 -0
  579. package/skills/wix-replatform/scripts/census-reconciliation.js +25 -0
  580. package/skills/wix-replatform/scripts/cms-fallback.js +89 -0
  581. package/skills/wix-replatform/scripts/discovered-census.js +26 -0
  582. package/skills/wix-replatform/scripts/discovered-set-status.js +33 -0
  583. package/skills/wix-replatform/scripts/entity-qa-attestation.js +130 -0
  584. package/skills/wix-replatform/scripts/execution-health-check.js +415 -0
  585. package/skills/wix-replatform/scripts/execution-manifest-validate.js +1 -1
  586. package/skills/wix-replatform/scripts/execution-state-prepare.js +1 -1
  587. package/skills/wix-replatform/scripts/expectations-ledger.js +44 -0
  588. package/skills/wix-replatform/scripts/import-contract-verify.js +183 -0
  589. package/skills/wix-replatform/scripts/internal-link-audit.js +90 -0
  590. package/skills/wix-replatform/scripts/item-seo-tags-verify.js +205 -0
  591. package/skills/wix-replatform/scripts/migration-completion.js +76 -0
  592. package/skills/wix-replatform/scripts/orchestration-preflight.js +21 -2
  593. package/skills/wix-replatform/scripts/orchestration-route.js +32 -1
  594. package/skills/wix-replatform/scripts/orchestration-state.js +146 -10
  595. package/skills/wix-replatform/scripts/read-back-gate.js +175 -0
  596. package/skills/wix-replatform/scripts/replatform-console.js +146 -0
  597. package/skills/wix-replatform/scripts/replatform.js +436 -0
  598. package/skills/wix-replatform/scripts/source-secrets.js +77 -0
  599. package/skills/wix-replatform/scripts/url-redirects.js +286 -0
  600. package/skills/wix-replatform/scripts/user-action.js +58 -0
  601. package/skills/wix-replatform/scripts/website-handoff-generate.js +64 -0
  602. package/skills/wix-replatform/scripts/wix-dashboard-url.js +54 -0
  603. package/skills/wix-replatform/scripts/wix-destination.js +143 -0
  604. package/skills/wix-replatform/scripts/wix-headless-scaffold.js +762 -0
  605. package/skills/wix-vibe-headless/SKILL.md +7 -3
  606. package/skills/wix-vibe-headless/install/deploy.cjs +61 -34
  607. package/skills/wix-vibe-headless/platforms/base44.md +1 -0
  608. package/skills/wix-vibe-headless/references/donations/INSTRUCTIONS.md +88 -0
  609. package/skills/wix-vibe-headless/references/donations/app/rest/wix-donations.js +112 -0
  610. package/skills/wix-vibe-headless/references/donations/seed/SEED.md +11 -0
  611. package/skills/wix-vibe-headless/references/donations/tests/donations.test.mjs +258 -0
  612. package/skills/wix-vibe-headless/references/restaurants/INSTRUCTIONS.md +5 -2
  613. package/skills/wix-vibe-headless/references/restaurants/app/context/OrderCartContext.jsx +4 -1
  614. package/skills/wix-vibe-headless/references/restaurants/app/rest/wix-restaurants-ordering.js +67 -3
  615. package/skills/wix-vibe-headless/references/shared/app/rest/wix-client.js +4 -3
  616. package/skills/wix-replatform/resources/rp-target-wix/SPEC-product-reviews-and-blog-authorship.md +0 -330
@@ -0,0 +1,71 @@
1
+ // Local contracts only; no Wix requests or financial transactions. Node >=22.12:
2
+ // node --experimental-strip-types --test skills/wix-headless-templates/donations/tests/*.test.mjs
3
+ import test from 'node:test';
4
+ import assert from 'node:assert/strict';
5
+ import * as source from '../app/wix/donations/donations-core.ts';
6
+ import * as project from '../project/src/wix/donations/donations-core.ts';
7
+
8
+ for (const [name, api] of Object.entries({ source, project })) {
9
+ test(`${name}: campaign decimal strings become numeric one-time cart options`, () => {
10
+ const body = api.cartBody('campaign-id', { amount: '25.00', frequency: 'ONE_TIME', coverFee: false, note: '' });
11
+ assert.deepEqual(body, {
12
+ cart: { source: { channelType: 'WEB' } },
13
+ catalogItems: [{ quantity: 1, catalogReference: {
14
+ appId: '333b456e-dd48-4d6b-b32b-9fd48d74e163',
15
+ catalogItemId: 'campaign-id', options: { amount: 25 },
16
+ } }],
17
+ });
18
+ assert.equal(typeof JSON.parse(JSON.stringify(body)).catalogItems[0].catalogReference.options.amount, 'number');
19
+ });
20
+
21
+ for (const frequency of ['WEEK', 'MONTH', 'YEAR']) {
22
+ test(`${name}: ${frequency} and optional fee flag survive without inflating base amount`, () => {
23
+ const body = api.cartBody('campaign-id', { amount: 50, frequency, coverFee: true, note: 'In memory' });
24
+ assert.deepEqual(body.catalogItems[0].catalogReference.options, { amount: 50, frequency, donorCoveringFees: true });
25
+ assert.equal(body.cart.note, 'In memory');
26
+ });
27
+ }
28
+
29
+ test(`${name}: invalid inputs cannot reach cart creation`, () => {
30
+ for (const amount of ['', ' ', 'not-money', 0, -1, NaN, Infinity, null, true, {}]) {
31
+ assert.throws(() => api.donationLineItem('campaign-id', { amount, frequency: 'ONE_TIME' }), /positive donation amount/);
32
+ }
33
+ assert.throws(() => api.donationLineItem('campaign-id', { amount: 25, frequency: 'QUARTER' }), /supported donation frequency/);
34
+ assert.throws(() => api.donationLineItem('', { amount: 25, frequency: 'ONE_TIME' }), /campaign id/);
35
+ });
36
+
37
+ test(`${name}: Cart V2 id is passed directly to hosted checkout, with separate callbacks`, () => {
38
+ const id = api.cartIdOf({ cart: { id: 'cart-id' } });
39
+ assert.equal(api.cartIdOf({ _id: 'cart-id' }), id);
40
+ assert.deepEqual(api.redirectBody(id, 'campaign-id', 'https://donor.example.test'), {
41
+ ecomCheckout: { checkoutId: 'cart-id' },
42
+ callbacks: { postFlowUrl: 'https://donor.example.test/donate/campaign-id', thankYouPageUrl: 'https://donor.example.test/donate/thank-you' },
43
+ });
44
+ assert.throws(() => api.cartIdOf({}), /no cart id/);
45
+ });
46
+
47
+ test(`${name}: payment-related API errors keep their actual cause, status and body`, () => {
48
+ const error = Object.assign(new Error('Unsupported PAYMENT_METHOD'), { status: 400, body: { code: 'PAYMENT_METHOD_UNSUPPORTED' } });
49
+ assert.equal(api.checkoutError(error), error);
50
+ assert.equal(api.checkoutError(error, 'redirect', 'cart-id'), error);
51
+ assert.equal(error.stage, 'redirect');
52
+ assert.equal(error.cartId, 'cart-id');
53
+ assert.deepEqual(error.body, { code: 'PAYMENT_METHOD_UNSUPPORTED' });
54
+ assert.equal(api.checkoutError('network failure').cause, 'network failure');
55
+ });
56
+
57
+ test(`${name}: unavailable goal metrics differ from a verified zero and from an exceeded goal`, () => {
58
+ const goal = { targetAmount: { amount: '100' } };
59
+ assert.equal(api.toGoal(goal, null, 'USD').raised, '');
60
+ assert.notEqual(api.toGoal(goal, [], 'USD').raised, '');
61
+ const known = api.toGoal(goal, [{ currencyCode: 'USD', donationCount: 3, totalAmount: { amount: '125' } }], 'USD');
62
+ assert.equal(known.percent, 125);
63
+ assert.equal(known.donationCount, 3);
64
+ assert.equal(api.toGoal(null, [], 'USD'), null);
65
+ });
66
+ }
67
+
68
+ test('scaffold and deployable donation payloads remain identical', () => {
69
+ const input = { amount: 37.5, frequency: 'MONTH', coverFee: true, note: 'A message' };
70
+ assert.deepEqual(source.cartBody('campaign-id', input), project.cartBody('campaign-id', input));
71
+ });
@@ -0,0 +1,137 @@
1
+ // Component contracts only; hooks and checkout are stubbed, never Wix requests.
2
+ // Run with a project that already has typescript, react, react-dom and jsdom installed:
3
+ // DONATIONS_TEST_PROJECT=/path/to/project node --test <this-file>
4
+ const test = require('node:test');
5
+ const assert = require('node:assert/strict');
6
+ const { readFileSync } = require('node:fs');
7
+ const { resolve, join } = require('node:path');
8
+ const { createRequire } = require('node:module');
9
+ const dependencies = createRequire(join(resolve(process.env.DONATIONS_TEST_PROJECT || process.cwd()), 'package.json'));
10
+ const ts = dependencies('typescript');
11
+ const React = dependencies('react');
12
+ const { renderToStaticMarkup } = dependencies('react-dom/server');
13
+ const { JSDOM } = dependencies('jsdom');
14
+
15
+ const campaign = { id: 'campaign-id', options: {
16
+ currency: 'USD', frequencies: [{ value: 'ONE_TIME', label: 'One-time' }, { value: 'MONTH', label: 'Monthly' }],
17
+ presets: [{ amount: 25, label: '$25', impact: 'Care' }, { amount: 50, label: '$50', impact: 'Supplies' }],
18
+ customAmount: { enabled: true, minLabel: '$5', maxLabel: '$1,000' },
19
+ askCoverFee: true, commentsEnabled: true, commentMaxLength: 100,
20
+ } };
21
+ const state = overrides => ({
22
+ available: true, frequency: 'ONE_TIME', presetAmount: 25, customMode: false, customAmount: '',
23
+ coverFee: false, note: '', messages: {}, showErrors: false, valid: true, submitting: false,
24
+ buttonLabel: 'Donate $25', selectPreset() {}, selectCustom() {}, setCustomAmount() {},
25
+ setFrequency() {}, setCoverFee() {}, setNote() {}, donate: async () => {}, ...overrides,
26
+ });
27
+
28
+ function loadComponent(file, hook, value) {
29
+ const compiled = ts.transpileModule(readFileSync(file, 'utf8'), { compilerOptions: {
30
+ target: ts.ScriptTarget.ES2022, module: ts.ModuleKind.CommonJS, jsx: ts.JsxEmit.ReactJSX,
31
+ } }).outputText;
32
+ const result = { exports: {} };
33
+ const requireStub = name => name.includes('/hooks/donations/') ? { [hook]: () => typeof value === 'function' ? value() : value } : dependencies(name);
34
+ new Function('require', 'module', 'exports', compiled)(requireStub, result, result.exports);
35
+ return result.exports.default;
36
+ }
37
+ function render(file, value, copies = 1) {
38
+ const Form = loadComponent(file, 'useDonation', value);
39
+ const html = renderToStaticMarkup(React.createElement('div', null,
40
+ ...Array.from({ length: copies }, (_, key) => React.createElement(Form, { campaign, key }, 'Campaign closed'))));
41
+ return new JSDOM(html).window.document;
42
+ }
43
+
44
+ for (const [name, path] of [['source', '../app/components/donations/'], ['project', '../project/src/components/donations/']]) {
45
+ const file = resolve(__dirname, path, 'DonateForm.tsx');
46
+
47
+ test(`${name}: choices are labelled native radio groups with separate frequency and amount names`, () => {
48
+ const document = render(file, state());
49
+ const groups = [...document.querySelectorAll('fieldset')];
50
+ assert.deepEqual(groups.map(group => group.querySelector('legend').textContent), ['How often', 'Amount']);
51
+ const frequency = [...groups[0].querySelectorAll('input[type=radio]')];
52
+ const amounts = [...groups[1].querySelectorAll('input[type=radio]')];
53
+ assert.equal(frequency.length, 2); assert.equal(amounts.length, 3);
54
+ assert.ok([...frequency, ...amounts].every(input => input.labels.length === 1));
55
+ assert.equal(new Set(frequency.map(input => input.name)).size, 1);
56
+ assert.equal(new Set(amounts.map(input => input.name)).size, 1);
57
+ assert.notEqual(frequency[0].name, amounts[0].name);
58
+ frequency[1].click();
59
+ assert.equal(frequency[1].checked, true); assert.equal(frequency[0].checked, false);
60
+ assert.equal(amounts[0].checked, true);
61
+ });
62
+
63
+ test(`${name}: two forms for the same campaign do not share ids or radio-group names`, () => {
64
+ const document = render(file, state({ customMode: true }), 2);
65
+ const ids = [...document.querySelectorAll('[id]')].map(el => el.id);
66
+ assert.equal(new Set(ids).size, ids.length);
67
+ const forms = document.querySelectorAll('form');
68
+ assert.notEqual(forms[0].querySelector('input[type=radio]').name, forms[1].querySelector('input[type=radio]').name);
69
+ });
70
+
71
+ test(`${name}: invalid custom amount and note reference their actual error text`, () => {
72
+ const document = render(file, state({ customMode: true, showErrors: true, valid: false,
73
+ messages: { customAmount: 'Enter an amount.', note: 'Keep the note short.' } }));
74
+ const amount = document.querySelector('input[inputmode=decimal]');
75
+ assert.equal(amount.getAttribute('aria-invalid'), 'true');
76
+ assert.equal(document.getElementById(amount.getAttribute('aria-describedby')).textContent, 'Enter an amount.');
77
+ const note = document.querySelector('textarea');
78
+ assert.equal(note.getAttribute('aria-invalid'), 'true');
79
+ assert.ok(note.getAttribute('aria-describedby').split(' ').every(id => document.getElementById(id)));
80
+ });
81
+
82
+ test(`${name}: pending submission disables choices, fields and repeated submits`, () => {
83
+ const document = render(file, state({ customMode: true, submitting: true }));
84
+ assert.ok([...document.querySelectorAll('input,textarea,button')].every(el => el.matches(':disabled')));
85
+ assert.equal(document.querySelector('button[type=submit]').getAttribute('aria-busy'), 'true');
86
+ });
87
+
88
+ test(`${name}: invalid submit focuses the field after rendering, including a repeated attempt`, async () => {
89
+ const dom = new JSDOM('<div id="root"></div>', { pretendToBeVisual: true });
90
+ const globals = { window: dom.window, document: dom.window.document, navigator: dom.window.navigator,
91
+ requestAnimationFrame: dom.window.requestAnimationFrame.bind(dom.window), IS_REACT_ACT_ENVIRONMENT: true };
92
+ const previous = new Map(Object.keys(globals).map(key => [key, Object.getOwnPropertyDescriptor(globalThis, key)]));
93
+ for (const [key, value] of Object.entries(globals)) Object.defineProperty(globalThis, key, { configurable: true, writable: true, value });
94
+ const { createRoot } = dependencies('react-dom/client');
95
+ const act = React.act || dependencies('react-dom/test-utils').act;
96
+ const root = createRoot(dom.window.document.getElementById('root'));
97
+ const Form = loadComponent(file, 'useDonation', () => {
98
+ const [showErrors, setShowErrors] = React.useState(false);
99
+ return state({ customMode: true, valid: false, showErrors, messages: { customAmount: 'Enter an amount.' },
100
+ donate: async () => setShowErrors(true) });
101
+ });
102
+ try {
103
+ await act(async () => root.render(React.createElement(Form, { campaign })));
104
+ for (let attempt = 0; attempt < 2; attempt++) {
105
+ dom.window.document.querySelector('button[type=submit]').focus();
106
+ await act(async () => dom.window.document.querySelector('form').dispatchEvent(new dom.window.Event('submit', { bubbles: true, cancelable: true })));
107
+ await new Promise(resolve => dom.window.requestAnimationFrame(resolve));
108
+ assert.equal(dom.window.document.activeElement, dom.window.document.querySelector('input[inputmode=decimal]'));
109
+ }
110
+ } finally {
111
+ await act(async () => root.unmount());
112
+ dom.window.close();
113
+ for (const [key, descriptor] of previous) {
114
+ if (descriptor) Object.defineProperty(globalThis, key, descriptor);
115
+ else delete globalThis[key];
116
+ }
117
+ }
118
+ });
119
+
120
+ test(`${name}: a closed campaign has no donation controls`, () => {
121
+ const document = render(file, state({ available: false }));
122
+ assert.equal(document.querySelector('form'), null);
123
+ assert.match(document.body.textContent, /Campaign closed/);
124
+ });
125
+
126
+ test(`${name}: direct or unreadable returns have a heading and next step without submission claims`, () => {
127
+ const receiptFile = resolve(__dirname, path, 'DonationReceipt.tsx');
128
+ for (const orderId of ['', 'unverified-order']) {
129
+ const Receipt = loadComponent(receiptFile, 'useDonationReceipt', { orderId, loading: false, receipt: null });
130
+ const document = new JSDOM(renderToStaticMarkup(React.createElement(Receipt))).window.document;
131
+ assert.ok(document.querySelector('h1'));
132
+ assert.ok(document.querySelector('a[href="/donate"]'));
133
+ assert.doesNotMatch(document.body.textContent, /has been received|has been submitted|Thank you for your donation/);
134
+ assert.match(document.body.textContent, /not a payment confirmation|could not be verified/);
135
+ }
136
+ });
137
+ }
@@ -28,7 +28,7 @@ components, plus your home page.
28
28
  | `wix/media.ts` · `wix/money.ts` | `imgAttrs(url, sizes)` — every `<img>` attribute for a DTO image (`src`, `srcSet`, `sizes`, lazy): `<img {...imgAttrs(item.imageUrl, "6rem")} alt={item.name} />`; `imgSrc()` / `imgSrcSet()` / `formatMoney()` underneath, already used by everything shipped |
29
29
  | `wix/restaurants/types.ts` | the DTOs (`MenuData`, `MenuSection`, `MenuItem`, `OrderSelection`, `OrderCart`, `OrderingStatus`, `ReservationLocationInfo`, `ReservationSlot`, …) — contracts below |
30
30
  | `wix/restaurants/menu.ts` | `fetchMenus` — the whole display-ordered menu tree, every price formatted with the site's currency + locale (read once from the eCommerce settings, `fetchSiteMoney`); the transport only — the id-array stitching, the item mapping, the money formatting, and the **modifier rule engine** (`initialSelection`, `toggleModifier`, `validateSelection`, `itemPrice`, `needsSelection`, `ruleLabel`) are in `menu-core.ts` beside it (shared with the REST layer) |
31
- | `wix/restaurants/ordering.ts` · `order-store.ts` | the operation's state (`resolveOrdering`), each menu's ordering settings under it (`fetchMenuOrdering`), the operation's fulfillment methods, dish add-to-cart (Orders-app `catalogReference` with the selection) + eCom Cart V2 + the hosted checkout, and the shared cart state (module store — spans Astro islands); the request shapes, the availability-window check, and the refusal checks are in `ordering-core.ts` |
31
+ | `wix/restaurants/ordering.ts` · `order-store.ts` | the operation's state (`resolveOrdering`), each menu's ordering settings under it (`fetchMenuOrdering`), the operation's fulfillment methods and times, dish add-to-cart (Orders-app `catalogReference` with the selection) + eCom Cart V2, the order's pickup/delivery + time (the cart's delivery method) + the hosted checkout, and the shared cart state (module store — spans Astro islands); the request shapes, the availability-window check, and the refusal checks are in `ordering-core.ts` |
32
32
  | `wix/restaurants/reservations.ts` | locations (enabled for online reservations, with name/address/timezone/approval/form config), AVAILABLE slots in the location's timezone, `holdReservation` → `completeReservation` (automatic approval), `requestReservation` (manual approval, no hold); the mappers, the form validation, and the reservee body are in `reservations-core.ts` |
33
33
  | `wix/restaurants/time-core.ts` | wall-clock arithmetic in an IANA zone with `Intl` only (`zonedIso`, `zonedDayKey`, `zonedTimeLabel`, `zonedDateTimeLabel`) — what the two cores and the stores use for the restaurant's timezone |
34
34
  | `wix/restaurants/menu-store.ts` · `reservation-store.ts` | the menu-browsing and reservation state machines, framework-free (`createMenuStore()`, `createReservationStore()` — `getState`/`subscribe` + actions, one instance per surface); the hooks below bind them to React, every other stack uses them directly |
@@ -100,8 +100,12 @@ else. Look at the seeded menu before designing (how many menus, sections, photos
100
100
  modifiers disabled.
101
101
  - **Cart:** lines with quantity stepper and remove, `descriptionLines` under the name, `subtotal`
102
102
  as given, checkout as a button in the drawer; the order survives a reload (same visitor token) —
103
- nothing to wire. Fulfillment (pickup/delivery, time) is collected on the hosted checkout;
104
- `fulfillment` (the operation's methods, fees formatted) is for a line of copy in the drawer, not a picker.
103
+ nothing to wire. Pickup/delivery and the time are chosen in the drawer, before checkout: a
104
+ Pickup/Delivery switch when `fulfillment` has both types, a time select from `fulfillmentTimes`
105
+ of that type (ASAP first, labelled in `orderingStatus.timeZone`), and for delivery street, city
106
+ and postal code (country and subdivision default to the restaurant's; on blur the drawer reloads the
107
+ times with that address, so delivery times are only those of methods that deliver there) with the
108
+ delivery fee and minimum; the CTA calls `chooseFulfillment(choice)` then `checkout()`.
105
109
  - **Reservations:** only AVAILABLE times offered, labelled in the restaurant's timezone; the query
106
110
  date defaults to today at the restaurant; `approval === "AUTOMATIC"` → hold → details form with
107
111
  the `holdSecondsLeft` countdown → confirm; `approval === "MANUAL"` (or `slot.manualApproval`) →
@@ -151,12 +155,19 @@ else. Look at the seeded menu before designing (how many menus, sections, photos
151
155
  // orderingStatus: { operationId, status: "ENABLED"|"DISABLED"|"PAUSED_UNTIL"|"NONE",
152
156
  // pausedUntilIso, timeZone, fulfillmentIds, defaultFulfillmentType }|null,
153
157
  // menuOrderable(menuId): boolean|null, // false → this menu takes no online orders now (no add control); null = unknown, let the add try
154
- // fulfillment: [{ id, type: "PICKUP"|"DELIVERY", name, fee, minOrderPrice }]|null, // formatted; display only
158
+ // fulfillment: [{ id, type: "PICKUP"|"DELIVERY", name, fee, minOrderPrice }]|null, // formatted; which types the picker offers
159
+ // fulfillmentTimes: [{ type, code, asap, startIso, endIso }]|null, // ASAP first, then today's slots (orderable only)
160
+ // fulfillmentChoice: { type, time?, address? }|null, // what chooseFulfillment last set
161
+ // chooseFulfillment({ type: "PICKUP"|"DELIVERY", time?: FulfillmentTime /* omitted → ASAP */,
162
+ // address?: { addressLine, city, postalCode?, country?, subdivision? } /* delivery; country defaults to the restaurant's */ }),
163
+ // // rejects (and sets .error) on an address outside every delivery area
164
+ // loadFulfillmentTimes(dayKey?, address?), // another day's slots ("YYYY-MM-DD" at the restaurant); with the delivery
165
+ // // address, delivery times are only those of methods that deliver there
155
166
  // busy /* the DRAWER's flag: any cart operation in flight */, pendingItemId /* the item whose add is in
156
167
  // flight, else null — a dish card's add control disables on THIS, never on busy */, error, open,
157
168
  // addToOrder(item, { menuId, sectionId }, quantity?, selection?), // the DTO + ids from the render context — see hard rules
158
169
  // updateQuantity(lineItemId, qty), removeLine(lineItemId),
159
- // checkout(), // browser redirects to the Wix-hosted checkout
170
+ // checkout(), // browser redirects to the Wix-hosted checkout (pickup ASAP if nothing was chosen)
160
171
  // openCart(), closeCart(), refresh() }
161
172
  // OrderLine = { lineItemId, itemName, quantity, unitPrice, linePrice, imageUrl,
162
173
  // descriptionLines /* variant, modifiers, note — as the platform labels them */,
@@ -301,7 +312,8 @@ the stores replace the hooks, and you write the components in your framework to
301
312
  (`start()` when mounted, `stop()` when unmounted), `createReservationStore()` per reservation
302
313
  surface, the order store as-is (module-level: `subscribeOrderCart`/`getOrderCartState`,
303
314
  `isMenuOrderable`, `addOrderLine(item, { menuId, sectionId }, quantity?, selection?)`,
304
- `updateOrderLineQuantity`, `removeLineFromOrder`, `goToOrderCheckout`, `setOrderCartOpen`).
315
+ `updateOrderLineQuantity`, `removeLineFromOrder`, `chooseFulfillment`, `loadFulfillmentTimes`,
316
+ `goToOrderCheckout`, `setOrderCartOpen`).
305
317
  State in, actions out — exactly the hooks' contracts above; the dish sheet's local state is an
306
318
  `OrderSelection` driven by the `menu-core` helpers;
307
319
  - your dish card, sheet, cart drawer, and reservation form to the recommended defaults above — the
@@ -323,14 +335,14 @@ root (config, plan, seed output) is never the upload. Same function names and DT
323
335
  above, so the contracts on this page hold unchanged: `fetchMenus`, `fetchSiteMoney` from
324
336
  `./js/wix/menu.js`; `resolveOrdering`, `resolveOperationId`, `fetchMenuOrdering`,
325
337
  `fetchFulfillmentMethods`, `fetchOrderCart`, `addToOrder(item, { menuId, sectionId }, quantity?,
326
- selection?)`, `updateOrderQuantity`, `removeOrderLine`, `orderCheckoutUrl` from
338
+ selection?)`, `updateOrderQuantity`, `removeOrderLine`, `fetchFulfillmentTimes`, `setOrderFulfillment`, `orderCheckoutUrl` from
327
339
  `./js/wix/ordering.js`; `fetchReservationLocations`, `fetchReservationSlots`, `holdReservation`,
328
340
  `completeReservation`, `requestReservation` from `./js/wix/reservations.js`; the selection helpers
329
341
  from `./js/wix/menu-core.js`. The state machines ship too: `createMenuStore` from
330
342
  `./js/wix/menu-store.js` (`start()` once the page is up; `initialMenus` when you already have
331
343
  them), `./js/wix/order-store.js` (the cart — `subscribeOrderCart`/`getOrderCartState`,
332
344
  `isMenuOrderable`, `addOrderLine`, `updateOrderLineQuantity`, `removeLineFromOrder`,
333
- `goToOrderCheckout`, `setOrderCartOpen`), and `createReservationStore` from
345
+ `chooseFulfillment`, `loadFulfillmentTimes`, `goToOrderCheckout`, `setOrderCartOpen`), and `createReservationStore` from
334
346
  `./js/wix/reservation-store.js` (the whole reservation flow). No components ship — you write the
335
347
  rendering in plain JS: one render function per surface that reads `getState()`, called from
336
348
  `subscribe`, with the surface's controls calling the store's actions. The drawer opens after every
@@ -387,7 +399,7 @@ Routes on Wix hosting: the host serves files only, so a clean route answers 404
387
399
  ## Hard rules
388
400
 
389
401
  - **Data and ordering logic only through the shipped exports** — `useOrderCart`/`addToOrder`
390
- own the restaurant `catalogReference` (the Orders app id + `operationId`/`menuId`/`sectionId`
402
+ own the restaurant `catalogReference` (the Orders app id + `operationId`/`menuId`/`menuSectionId`
391
403
  — all three — plus the visitor's choices as `options.priceVariant`, `options.modifierGroups`,
392
404
  `options.specialRequests`), the line-refusal checks, and the checkout redirect. Never
393
405
  re-derive any of it, never hand-build a checkout URL; extend by adding a function in
@@ -418,13 +430,15 @@ Routes on Wix hosting: the host serves files only, so a clean route answers 404
418
430
  (`orderingStatus.status`, `pausedUntilIso`); `menuOrderable(id) === false` → no add controls and
419
431
  one notice for that menu; `onlineReservationsEnabled === false` → a "call us to book" notice (the
420
432
  toggle is premium-gated). Never mock menus, dishes, prices, slots, or availability.
421
- - **Fulfillment is collected on the hosted checkout** — pickup vs delivery, the time, the address.
422
- The shipped layer does not pre-qualify it (no ASAP/scheduled slot picker, no delivery-address
423
- check before checkout): that is a documented gap, not something to build ad hoc from the
424
- operation's scheduling fields. `fulfillment` is display copy ("Pickup and delivery", fees) only.
433
+ - **Fulfillment is set on the cart before checkout** — the hosted checkout has no pickup/delivery
434
+ or time picker for restaurant orders and refuses one without them ("There was an issue updating
435
+ your fulfillment details…"). Set it with `chooseFulfillment` (times from `fulfillmentTimes`, the
436
+ address for delivery); `checkout()` falls back to pickup ASAP only when nothing was chosen, and
437
+ says "Choose pickup or delivery" when the restaurant has no pickup. Never build the delivery
438
+ method code yourself.
425
439
  - Don't wrap shipped calls in your own API routes — they run client-side by design.
426
440
  - **Cart totals come from `cart`** — never summed or hardcoded in the client; fees, tax, and
427
- delivery resolve on the hosted checkout. The sheet's `itemPrice` is a preview of one line, not a total.
441
+ delivery are shown on the hosted checkout. The sheet's `itemPrice` is a preview of one line, not a total.
428
442
  - **Browsing, ordering and reserving need no login.** They run on the visitor session the
429
443
  shipped client already holds; don't add a members/auth flow unless the brief asks for accounts.
430
444
  - **Call every hook before any conditional return.** Hooks first, branches after.
@@ -1,13 +1,51 @@
1
- // REFERENCE slide-over order cart with quantity stepper, remove, live subtotal, and the
2
- // Wix-hosted checkout. Mount ONCE per page; opens via useOrderCart().openCart(). Correct and
3
- // complete; per the skill's model you design your own chrome on useOrderCart.
1
+ // REFERENCE slide-over order cart with quantity stepper, remove, live subtotal, pickup/delivery
2
+ // with a time (and the address for delivery), and the Wix-hosted checkout. Mount ONCE per page;
3
+ // opens via useOrderCart().openCart(). Correct and complete; per the skill's model you design your
4
+ // own chrome on useOrderCart.
5
+ import { useState } from "react";
4
6
  import { useOrderCart } from "../../hooks/restaurants/useOrderCart";
5
7
  import { imgAttrs } from "../../wix/media";
8
+ import { zonedDateTimeLabel, zonedDayKey, zonedTimeLabel } from "../../wix/restaurants/time-core";
9
+ import type { FulfillmentChoice } from "../../wix/restaurants/types";
6
10
 
7
11
  export default function OrderCartDrawer() {
8
- const { cart, open, closeCart, busy, error, updateQuantity, removeLine, checkout } = useOrderCart();
12
+ const { cart, open, closeCart, busy, error, updateQuantity, removeLine, checkout, fulfillment, fulfillmentTimes, orderingStatus, chooseFulfillment, loadFulfillmentTimes } = useOrderCart();
13
+ const types = [...new Set((fulfillment ?? []).map((m) => m.type))];
14
+ const [type, setType] = useState<"PICKUP" | "DELIVERY" | null>(null);
15
+ const [timeCode, setTimeCode] = useState("");
16
+ const [street, setStreet] = useState("");
17
+ const [city, setCity] = useState("");
18
+ const [postalCode, setPostalCode] = useState("");
9
19
  if (!open) return null;
10
20
  const lines = cart?.lines ?? [];
21
+ const chosenType = type ?? (types.includes("PICKUP") || !types.length ? "PICKUP" : "DELIVERY");
22
+ const times = (fulfillmentTimes ?? []).filter((t) => t.type === chosenType);
23
+ const tz = orderingStatus?.timeZone ?? "";
24
+ const today = zonedDayKey(new Date(), tz);
25
+ // A slot on a later day than today (at the restaurant) carries its date: "Fri, Oct 24, 9:00 AM".
26
+ const timeLabel = (iso: string, asap: boolean) => {
27
+ const d = new Date(iso);
28
+ if (asap) return `As soon as possible (about ${zonedTimeLabel(d, tz)})`;
29
+ return zonedDayKey(d, tz) === today ? zonedTimeLabel(d, tz) : zonedDateTimeLabel(d, tz);
30
+ };
31
+ const deliveryMethod = (fulfillment ?? []).find((m) => m.type === "DELIVERY");
32
+
33
+ // Once street and city are in, delivery times come only from the methods that deliver there.
34
+ function refreshDeliveryTimes() {
35
+ if (street.trim() && city.trim()) void loadFulfillmentTimes(undefined, { addressLine: street, city, postalCode });
36
+ }
37
+
38
+ async function placeOrder() {
39
+ const choice: FulfillmentChoice = {
40
+ type: chosenType,
41
+ time: times.find((t) => t.code === timeCode),
42
+ ...(chosenType === "DELIVERY"
43
+ ? { address: { addressLine: street, city, postalCode } } // country and subdivision: the restaurant's
44
+ : {}),
45
+ };
46
+ await chooseFulfillment(choice); // the hosted checkout refuses an order with no fulfillment
47
+ await checkout();
48
+ }
11
49
 
12
50
  return (
13
51
  <div
@@ -104,11 +142,55 @@ export default function OrderCartDrawer() {
104
142
  <strong className="font-semibold">{cart.subtotal}</strong>
105
143
  </div>
106
144
  )}
145
+ {types.length > 1 && (
146
+ <div role="radiogroup" aria-label="Pickup or delivery" className="mb-3 grid grid-cols-2 gap-2">
147
+ {(["PICKUP", "DELIVERY"] as const).map((t) => (
148
+ <button
149
+ key={t}
150
+ type="button"
151
+ role="radio"
152
+ aria-checked={chosenType === t}
153
+ onClick={() => { setType(t); setTimeCode(""); }}
154
+ className={`rounded-control border py-2 text-sm ${chosenType === t ? "border-primary font-semibold" : "border-border text-muted-foreground"}`}
155
+ >
156
+ {t === "PICKUP" ? "Pickup" : "Delivery"}
157
+ </button>
158
+ ))}
159
+ </div>
160
+ )}
161
+ {chosenType === "DELIVERY" && (
162
+ <div className="mb-3 grid gap-2">
163
+ <input aria-label="Street address" placeholder="Street address" value={street} onChange={(e) => setStreet(e.target.value)} onBlur={refreshDeliveryTimes} className="rounded-control border border-border bg-background px-3 py-2 text-sm" />
164
+ <div className="grid grid-cols-2 gap-2">
165
+ <input aria-label="City" placeholder="City" value={city} onChange={(e) => setCity(e.target.value)} onBlur={refreshDeliveryTimes} className="rounded-control border border-border bg-background px-3 py-2 text-sm" />
166
+ <input aria-label="Postal code" placeholder="Postal code" value={postalCode} onChange={(e) => setPostalCode(e.target.value)} className="rounded-control border border-border bg-background px-3 py-2 text-sm" />
167
+ </div>
168
+ {deliveryMethod && (deliveryMethod.fee || deliveryMethod.minOrderPrice) && (
169
+ <p className="text-xs text-muted-foreground">
170
+ {[deliveryMethod.fee && `Delivery ${deliveryMethod.fee}`, deliveryMethod.minOrderPrice && `minimum order ${deliveryMethod.minOrderPrice}`].filter(Boolean).join(" · ")}
171
+ </p>
172
+ )}
173
+ </div>
174
+ )}
175
+ {times.length > 0 && (
176
+ <select
177
+ aria-label={chosenType === "PICKUP" ? "Pickup time" : "Delivery time"}
178
+ value={timeCode}
179
+ onChange={(e) => setTimeCode(e.target.value)}
180
+ className="mb-4 w-full rounded-control border border-border bg-background px-3 py-2 text-sm"
181
+ >
182
+ {times.map((t) => (
183
+ <option key={t.code} value={t.asap ? "" : t.code}>
184
+ {timeLabel(t.startIso, t.asap)}
185
+ </option>
186
+ ))}
187
+ </select>
188
+ )}
107
189
  {error && <p className="mb-3 text-xs text-destructive">{error}</p>}
108
190
  <button
109
191
  type="button"
110
192
  disabled={busy}
111
- onClick={() => checkout().catch(() => {})}
193
+ onClick={() => placeOrder().catch(() => {})}
112
194
  className="w-full rounded-control bg-primary py-3.5 text-sm font-semibold text-primary-foreground transition-opacity hover:opacity-90 disabled:opacity-50"
113
195
  >
114
196
  {busy ? "One moment…" : "Checkout"}
@@ -3,9 +3,11 @@
3
3
  import { useSyncExternalStore } from "react";
4
4
  import {
5
5
  addOrderLine,
6
+ chooseFulfillment,
6
7
  getOrderCartState,
7
8
  goToOrderCheckout,
8
9
  isMenuOrderable,
10
+ loadFulfillmentTimes,
9
11
  refreshOrderCart,
10
12
  removeLineFromOrder,
11
13
  setOrderCartOpen,
@@ -13,7 +15,7 @@ import {
13
15
  updateOrderLineQuantity,
14
16
  type OrderCartState,
15
17
  } from "../../wix/restaurants/order-store";
16
- import type { MenuItem, OrderSelection } from "../../wix/restaurants/types";
18
+ import type { DeliveryAddress, FulfillmentChoice, MenuItem, OrderSelection } from "../../wix/restaurants/types";
17
19
 
18
20
  const SERVER_STATE = getOrderCartState();
19
21
 
@@ -29,6 +31,10 @@ export interface UseOrderCart extends OrderCartState {
29
31
  menuOrderable: (menuId: string) => boolean | null;
30
32
  updateQuantity: (lineItemId: string, quantity: number) => Promise<void>;
31
33
  removeLine: (lineItemId: string) => Promise<void>;
34
+ /** Set pickup or delivery, the time (a fulfillmentTimes entry; omitted → ASAP), and the delivery address. */
35
+ chooseFulfillment: (choice: FulfillmentChoice) => Promise<void>;
36
+ /** Reload fulfillmentTimes for another day ("YYYY-MM-DD" at the restaurant) and/or a delivery address. */
37
+ loadFulfillmentTimes: (dayKey?: string, address?: DeliveryAddress) => Promise<void>;
32
38
  checkout: () => Promise<void>;
33
39
  openCart: () => void;
34
40
  closeCart: () => void;
@@ -44,6 +50,8 @@ export function useOrderCart(): UseOrderCart {
44
50
  menuOrderable: isMenuOrderable,
45
51
  updateQuantity: updateOrderLineQuantity,
46
52
  removeLine: removeLineFromOrder,
53
+ chooseFulfillment,
54
+ loadFulfillmentTimes,
47
55
  checkout: goToOrderCheckout,
48
56
  openCart: () => setOrderCartOpen(true),
49
57
  closeCart: () => setOrderCartOpen(false),
@@ -4,16 +4,18 @@
4
4
  // Consume it through useOrderCart() (hooks/), or subscribe directly. Besides the cart it holds
5
5
  // the site's ordering gates: the operation's state and each menu's ordering settings, so an add
6
6
  // control can read "accepting orders?" and "is THIS menu orderable now?" without a fetch of its own.
7
- import type { FulfillmentMethodInfo, MenuItem, MenuOrderingInfo, OrderCart, OrderSelection, OrderingStatus } from "./types";
7
+ import type { DeliveryAddress, FulfillmentChoice, FulfillmentMethodInfo, FulfillmentTime, MenuItem, MenuOrderingInfo, OrderCart, OrderSelection, OrderingStatus } from "./types";
8
8
  import { menuOrderable } from "./ordering-core";
9
9
  import {
10
10
  addToOrder as apiAdd,
11
11
  fetchFulfillmentMethods,
12
+ fetchFulfillmentTimes,
12
13
  fetchMenuOrdering,
13
14
  fetchOrderCart,
14
15
  orderCheckoutUrl,
15
16
  removeOrderLine as apiRemove,
16
17
  resolveOrdering,
18
+ setOrderFulfillment,
17
19
  updateOrderQuantity as apiUpdate,
18
20
  } from "./ordering";
19
21
 
@@ -25,8 +27,12 @@ export interface OrderCartState {
25
27
  orderingStatus: OrderingStatus | null;
26
28
  /** Per-menu ordering settings under the operation, keyed by menuId; null while loading or when unreadable. */
27
29
  menuOrdering: Record<string, MenuOrderingInfo> | null;
28
- /** The operation's enabled pickup/delivery methods, for display; null while loading. */
30
+ /** The operation's enabled pickup/delivery methods (names, fees, minimums); null while loading. */
29
31
  fulfillment: FulfillmentMethodInfo[] | null;
32
+ /** When the order can be fulfilled (ASAP first, then today's slots); null while loading or unreadable. */
33
+ fulfillmentTimes: FulfillmentTime[] | null;
34
+ /** The fulfillment last set on the cart through chooseFulfillment; null → none chosen (checkout uses pickup ASAP). */
35
+ fulfillmentChoice: FulfillmentChoice | null;
30
36
  /**
31
37
  * True while any cart operation is in flight — the DRAWER's flag (its steppers, remove and
32
38
  * checkout controls), not a dish card's: a card disables its own add control on `pendingItemId`,
@@ -41,7 +47,7 @@ export interface OrderCartState {
41
47
  open: boolean;
42
48
  }
43
49
 
44
- const EMPTY: OrderCartState = { cart: null, ordering: null, orderingStatus: null, menuOrdering: null, fulfillment: null, busy: false, pendingItemId: null, error: null, open: false };
50
+ const EMPTY: OrderCartState = { cart: null, ordering: null, orderingStatus: null, menuOrdering: null, fulfillment: null, fulfillmentTimes: null, fulfillmentChoice: null, busy: false, pendingItemId: null, error: null, open: false };
45
51
 
46
52
  let state: OrderCartState = EMPTY;
47
53
  const listeners = new Set<() => void>();
@@ -65,6 +71,7 @@ export function subscribeOrderCart(listener: () => void): () => void {
65
71
  void resolveOrdering().then((s) => setState({ ordering: s.status === "ENABLED", orderingStatus: s }));
66
72
  void fetchMenuOrdering().then((m) => setState({ menuOrdering: m })).catch(() => setState({ menuOrdering: null }));
67
73
  void fetchFulfillmentMethods().then((f) => setState({ fulfillment: f }));
74
+ void loadFulfillmentTimes();
68
75
  }
69
76
  return () => listeners.delete(listener);
70
77
  }
@@ -124,7 +131,29 @@ export async function removeLineFromOrder(lineItemId: string): Promise<void> {
124
131
  await run(() => apiRemove(lineItemId));
125
132
  }
126
133
 
127
- /** Navigate to the Wix-hosted checkout. Never hand-build a checkout URL. */
134
+ /**
135
+ * Load the fulfillment times for `dayKey` ("YYYY-MM-DD" at the restaurant; default today). Pass the
136
+ * delivery address once entered: delivery times then come only from methods that deliver there.
137
+ */
138
+ export async function loadFulfillmentTimes(dayKey?: string, address?: DeliveryAddress): Promise<void> {
139
+ try {
140
+ setState({ fulfillmentTimes: await fetchFulfillmentTimes(dayKey, address) });
141
+ } catch {
142
+ setState({ fulfillmentTimes: null }); // unreadable — checkout still works on ASAP
143
+ }
144
+ }
145
+
146
+ /**
147
+ * Set pickup or delivery, the time (a fulfillmentTimes entry; omitted → ASAP) and, for delivery,
148
+ * the address on the order. Throws (and sets .error) when the address isn't delivered to or the
149
+ * time is gone.
150
+ */
151
+ export async function chooseFulfillment(choice: FulfillmentChoice): Promise<void> {
152
+ await run(() => setOrderFulfillment(choice));
153
+ setState({ fulfillmentChoice: choice });
154
+ }
155
+
156
+ /** Navigate to the Wix-hosted checkout (pickup ASAP when no fulfillment was chosen). Never hand-build a checkout URL. */
128
157
  export async function goToOrderCheckout(): Promise<void> {
129
158
  setState({ busy: true, error: null });
130
159
  try {