@doswiftly/cli 0.1.1

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 (453) hide show
  1. package/README.md +357 -0
  2. package/bin/doswiftly.js +2 -0
  3. package/dist/commands/auth-github.d.ts +6 -0
  4. package/dist/commands/auth-github.d.ts.map +1 -0
  5. package/dist/commands/auth-github.js +89 -0
  6. package/dist/commands/auth-github.js.map +1 -0
  7. package/dist/commands/auth-token.d.ts +12 -0
  8. package/dist/commands/auth-token.d.ts.map +1 -0
  9. package/dist/commands/auth-token.js +43 -0
  10. package/dist/commands/auth-token.js.map +1 -0
  11. package/dist/commands/auth.d.ts +22 -0
  12. package/dist/commands/auth.d.ts.map +1 -0
  13. package/dist/commands/auth.js +348 -0
  14. package/dist/commands/auth.js.map +1 -0
  15. package/dist/commands/check.d.ts +5 -0
  16. package/dist/commands/check.d.ts.map +1 -0
  17. package/dist/commands/check.js +234 -0
  18. package/dist/commands/check.js.map +1 -0
  19. package/dist/commands/config.d.ts +3 -0
  20. package/dist/commands/config.d.ts.map +1 -0
  21. package/dist/commands/config.js +104 -0
  22. package/dist/commands/config.js.map +1 -0
  23. package/dist/commands/deploy.d.ts +37 -0
  24. package/dist/commands/deploy.d.ts.map +1 -0
  25. package/dist/commands/deploy.js +580 -0
  26. package/dist/commands/deploy.js.map +1 -0
  27. package/dist/commands/dev.d.ts +8 -0
  28. package/dist/commands/dev.d.ts.map +1 -0
  29. package/dist/commands/dev.js +83 -0
  30. package/dist/commands/dev.js.map +1 -0
  31. package/dist/commands/doctor.d.ts +5 -0
  32. package/dist/commands/doctor.d.ts.map +1 -0
  33. package/dist/commands/doctor.js +363 -0
  34. package/dist/commands/doctor.js.map +1 -0
  35. package/dist/commands/domain.d.ts +13 -0
  36. package/dist/commands/domain.d.ts.map +1 -0
  37. package/dist/commands/domain.js +128 -0
  38. package/dist/commands/domain.js.map +1 -0
  39. package/dist/commands/env.d.ts +25 -0
  40. package/dist/commands/env.d.ts.map +1 -0
  41. package/dist/commands/env.js +228 -0
  42. package/dist/commands/env.js.map +1 -0
  43. package/dist/commands/init.d.ts +11 -0
  44. package/dist/commands/init.d.ts.map +1 -0
  45. package/dist/commands/init.js +1028 -0
  46. package/dist/commands/init.js.map +1 -0
  47. package/dist/commands/inspect.d.ts +12 -0
  48. package/dist/commands/inspect.d.ts.map +1 -0
  49. package/dist/commands/inspect.js +162 -0
  50. package/dist/commands/inspect.js.map +1 -0
  51. package/dist/commands/migrate.d.ts +18 -0
  52. package/dist/commands/migrate.d.ts.map +1 -0
  53. package/dist/commands/migrate.js +355 -0
  54. package/dist/commands/migrate.js.map +1 -0
  55. package/dist/commands/preview.d.ts +29 -0
  56. package/dist/commands/preview.d.ts.map +1 -0
  57. package/dist/commands/preview.js +199 -0
  58. package/dist/commands/preview.js.map +1 -0
  59. package/dist/commands/proxy.d.ts +9 -0
  60. package/dist/commands/proxy.d.ts.map +1 -0
  61. package/dist/commands/proxy.js +37 -0
  62. package/dist/commands/proxy.js.map +1 -0
  63. package/dist/commands/sdk.d.ts +5 -0
  64. package/dist/commands/sdk.d.ts.map +1 -0
  65. package/dist/commands/sdk.js +82 -0
  66. package/dist/commands/sdk.js.map +1 -0
  67. package/dist/commands/template.d.ts +107 -0
  68. package/dist/commands/template.d.ts.map +1 -0
  69. package/dist/commands/template.js +1309 -0
  70. package/dist/commands/template.js.map +1 -0
  71. package/dist/commands/types.d.ts +5 -0
  72. package/dist/commands/types.d.ts.map +1 -0
  73. package/dist/commands/types.js +82 -0
  74. package/dist/commands/types.js.map +1 -0
  75. package/dist/commands/update.d.ts +2 -0
  76. package/dist/commands/update.d.ts.map +1 -0
  77. package/dist/commands/update.js +103 -0
  78. package/dist/commands/update.js.map +1 -0
  79. package/dist/commands/upgrade.d.ts +18 -0
  80. package/dist/commands/upgrade.d.ts.map +1 -0
  81. package/dist/commands/upgrade.js +55 -0
  82. package/dist/commands/upgrade.js.map +1 -0
  83. package/dist/commands/verify.d.ts +5 -0
  84. package/dist/commands/verify.d.ts.map +1 -0
  85. package/dist/commands/verify.js +232 -0
  86. package/dist/commands/verify.js.map +1 -0
  87. package/dist/commands/whoami.d.ts +5 -0
  88. package/dist/commands/whoami.d.ts.map +1 -0
  89. package/dist/commands/whoami.js +60 -0
  90. package/dist/commands/whoami.js.map +1 -0
  91. package/dist/config/types.d.ts +173 -0
  92. package/dist/config/types.d.ts.map +1 -0
  93. package/dist/config/types.js +48 -0
  94. package/dist/config/types.js.map +1 -0
  95. package/dist/index.d.ts +3 -0
  96. package/dist/index.d.ts.map +1 -0
  97. package/dist/index.js +416 -0
  98. package/dist/index.js.map +1 -0
  99. package/dist/lib/api-url.d.ts +14 -0
  100. package/dist/lib/api-url.d.ts.map +1 -0
  101. package/dist/lib/api-url.js +24 -0
  102. package/dist/lib/api-url.js.map +1 -0
  103. package/dist/lib/api.d.ts +67 -0
  104. package/dist/lib/api.d.ts.map +1 -0
  105. package/dist/lib/api.js +36 -0
  106. package/dist/lib/api.js.map +1 -0
  107. package/dist/lib/config.d.ts +39 -0
  108. package/dist/lib/config.d.ts.map +1 -0
  109. package/dist/lib/config.js +195 -0
  110. package/dist/lib/config.js.map +1 -0
  111. package/dist/lib/env-storage.d.ts +140 -0
  112. package/dist/lib/env-storage.d.ts.map +1 -0
  113. package/dist/lib/env-storage.js +464 -0
  114. package/dist/lib/env-storage.js.map +1 -0
  115. package/dist/lib/errors.d.ts +61 -0
  116. package/dist/lib/errors.d.ts.map +1 -0
  117. package/dist/lib/errors.js +204 -0
  118. package/dist/lib/errors.js.map +1 -0
  119. package/dist/lib/i18n.d.ts +99 -0
  120. package/dist/lib/i18n.d.ts.map +1 -0
  121. package/dist/lib/i18n.js +184 -0
  122. package/dist/lib/i18n.js.map +1 -0
  123. package/dist/lib/logger.d.ts +95 -0
  124. package/dist/lib/logger.d.ts.map +1 -0
  125. package/dist/lib/logger.js +168 -0
  126. package/dist/lib/logger.js.map +1 -0
  127. package/dist/lib/package-manager.d.ts +91 -0
  128. package/dist/lib/package-manager.d.ts.map +1 -0
  129. package/dist/lib/package-manager.js +205 -0
  130. package/dist/lib/package-manager.js.map +1 -0
  131. package/dist/lib/proxy-server.d.ts +24 -0
  132. package/dist/lib/proxy-server.d.ts.map +1 -0
  133. package/dist/lib/proxy-server.js +173 -0
  134. package/dist/lib/proxy-server.js.map +1 -0
  135. package/dist/lib/select-with-back.d.ts +34 -0
  136. package/dist/lib/select-with-back.d.ts.map +1 -0
  137. package/dist/lib/select-with-back.js +94 -0
  138. package/dist/lib/select-with-back.js.map +1 -0
  139. package/dist/lib/shared-api-client.d.ts +40 -0
  140. package/dist/lib/shared-api-client.d.ts.map +1 -0
  141. package/dist/lib/shared-api-client.js +92 -0
  142. package/dist/lib/shared-api-client.js.map +1 -0
  143. package/dist/lib/wizard-engine.d.ts +128 -0
  144. package/dist/lib/wizard-engine.d.ts.map +1 -0
  145. package/dist/lib/wizard-engine.js +168 -0
  146. package/dist/lib/wizard-engine.js.map +1 -0
  147. package/package.json +85 -0
  148. package/templates/storefront-minimal/.env.example +10 -0
  149. package/templates/storefront-minimal/.github/workflows/build-template.yml +109 -0
  150. package/templates/storefront-minimal/app/globals.css +18 -0
  151. package/templates/storefront-minimal/app/layout.tsx +26 -0
  152. package/templates/storefront-minimal/app/page.tsx +93 -0
  153. package/templates/storefront-minimal/lib/graphql-client.ts +23 -0
  154. package/templates/storefront-minimal/next.config.ts +15 -0
  155. package/templates/storefront-minimal/open-next.config.ts +3 -0
  156. package/templates/storefront-minimal/package.json +30 -0
  157. package/templates/storefront-minimal/postcss.config.mjs +5 -0
  158. package/templates/storefront-minimal/tailwind.config.ts +14 -0
  159. package/templates/storefront-minimal/tsconfig.json +27 -0
  160. package/templates/storefront-minimal/wrangler.toml +9 -0
  161. package/templates/storefront-nextjs/.env.example +68 -0
  162. package/templates/storefront-nextjs/.github/workflows/build-template.yml +109 -0
  163. package/templates/storefront-nextjs/.github/workflows/deploy.yml +25 -0
  164. package/templates/storefront-nextjs/.github/workflows/preview.yml +22 -0
  165. package/templates/storefront-nextjs/README.md +520 -0
  166. package/templates/storefront-nextjs/app/account/orders/page.tsx +216 -0
  167. package/templates/storefront-nextjs/app/account/page.tsx +167 -0
  168. package/templates/storefront-nextjs/app/auth/login/page.tsx +135 -0
  169. package/templates/storefront-nextjs/app/auth/register/page.tsx +228 -0
  170. package/templates/storefront-nextjs/app/cart/page.tsx +263 -0
  171. package/templates/storefront-nextjs/app/categories/[slug]/page.tsx +200 -0
  172. package/templates/storefront-nextjs/app/categories/page.tsx +58 -0
  173. package/templates/storefront-nextjs/app/checkout/page.tsx +351 -0
  174. package/templates/storefront-nextjs/app/collections/[slug]/page.tsx +158 -0
  175. package/templates/storefront-nextjs/app/collections/page.tsx +61 -0
  176. package/templates/storefront-nextjs/app/globals.css +98 -0
  177. package/templates/storefront-nextjs/app/layout.tsx +39 -0
  178. package/templates/storefront-nextjs/app/page.tsx +136 -0
  179. package/templates/storefront-nextjs/app/products/[slug]/page.tsx +119 -0
  180. package/templates/storefront-nextjs/app/products/page.tsx +107 -0
  181. package/templates/storefront-nextjs/app/search/page.tsx +127 -0
  182. package/templates/storefront-nextjs/components/auth/auth-guard.tsx +94 -0
  183. package/templates/storefront-nextjs/components/commerce/add-to-cart-button.tsx +77 -0
  184. package/templates/storefront-nextjs/components/commerce/cart-icon.tsx +29 -0
  185. package/templates/storefront-nextjs/components/commerce/currency-selector.tsx +217 -0
  186. package/templates/storefront-nextjs/components/commerce/pagination.tsx +62 -0
  187. package/templates/storefront-nextjs/components/commerce/product-actions.tsx +135 -0
  188. package/templates/storefront-nextjs/components/commerce/product-filters.tsx +109 -0
  189. package/templates/storefront-nextjs/components/commerce/product-price.tsx +375 -0
  190. package/templates/storefront-nextjs/components/commerce/search-input.tsx +178 -0
  191. package/templates/storefront-nextjs/components/commerce/sort-select.tsx +64 -0
  192. package/templates/storefront-nextjs/components/commerce/variant-selector.tsx +210 -0
  193. package/templates/storefront-nextjs/components/layout/footer.tsx +107 -0
  194. package/templates/storefront-nextjs/components/layout/header.tsx +104 -0
  195. package/templates/storefront-nextjs/components/providers.tsx +62 -0
  196. package/templates/storefront-nextjs/lib/auth/routes.ts +52 -0
  197. package/templates/storefront-nextjs/lib/currency.tsx +140 -0
  198. package/templates/storefront-nextjs/lib/format.ts +159 -0
  199. package/templates/storefront-nextjs/lib/graphql-queries.ts +629 -0
  200. package/templates/storefront-nextjs/lib/hooks.ts +30 -0
  201. package/templates/storefront-nextjs/middleware.ts +80 -0
  202. package/templates/storefront-nextjs/next.config.ts +37 -0
  203. package/templates/storefront-nextjs/open-next.config.ts +3 -0
  204. package/templates/storefront-nextjs/package.dev.json +30 -0
  205. package/templates/storefront-nextjs/package.json +32 -0
  206. package/templates/storefront-nextjs/package.json.template +32 -0
  207. package/templates/storefront-nextjs/postcss.config.mjs +8 -0
  208. package/templates/storefront-nextjs/tailwind.config.ts +111 -0
  209. package/templates/storefront-nextjs/tsconfig.json +27 -0
  210. package/templates/storefront-nextjs/wrangler.toml +9 -0
  211. package/templates/storefront-nextjs-shadcn/.env.example +68 -0
  212. package/templates/storefront-nextjs-shadcn/.github/workflows/build-template.yml +109 -0
  213. package/templates/storefront-nextjs-shadcn/.github/workflows/deploy.yml +25 -0
  214. package/templates/storefront-nextjs-shadcn/.github/workflows/preview.yml +22 -0
  215. package/templates/storefront-nextjs-shadcn/CART_INTEGRATION.md +282 -0
  216. package/templates/storefront-nextjs-shadcn/CLAUDE.md +96 -0
  217. package/templates/storefront-nextjs-shadcn/GRAPHQL_DOCUMENT_NAMES.md +190 -0
  218. package/templates/storefront-nextjs-shadcn/GRAPHQL_ERROR_HANDLING.md +263 -0
  219. package/templates/storefront-nextjs-shadcn/GRAPHQL_FIXES_SUMMARY.md +135 -0
  220. package/templates/storefront-nextjs-shadcn/GRAPHQL_INTEGRATION_COMPLETE.md +142 -0
  221. package/templates/storefront-nextjs-shadcn/INTEGRATION_CHECKLIST.md +448 -0
  222. package/templates/storefront-nextjs-shadcn/PRODUCT_DETAIL_PAGE_IMPLEMENTATION.md +307 -0
  223. package/templates/storefront-nextjs-shadcn/README.md +195 -0
  224. package/templates/storefront-nextjs-shadcn/THEME_CUSTOMIZATION.md +245 -0
  225. package/templates/storefront-nextjs-shadcn/app/about/page.tsx +34 -0
  226. package/templates/storefront-nextjs-shadcn/app/account/addresses/page.tsx +215 -0
  227. package/templates/storefront-nextjs-shadcn/app/account/loyalty/page.tsx +484 -0
  228. package/templates/storefront-nextjs-shadcn/app/account/orders/[id]/page.tsx +128 -0
  229. package/templates/storefront-nextjs-shadcn/app/account/orders/[id]/tracking/page.tsx +206 -0
  230. package/templates/storefront-nextjs-shadcn/app/account/orders/page.tsx +80 -0
  231. package/templates/storefront-nextjs-shadcn/app/account/page.tsx +107 -0
  232. package/templates/storefront-nextjs-shadcn/app/account/settings/page.tsx +195 -0
  233. package/templates/storefront-nextjs-shadcn/app/api/auth/clear-token/route.ts +87 -0
  234. package/templates/storefront-nextjs-shadcn/app/api/auth/set-token/route.ts +125 -0
  235. package/templates/storefront-nextjs-shadcn/app/auth/forgot-password/page.tsx +131 -0
  236. package/templates/storefront-nextjs-shadcn/app/auth/login/page.tsx +24 -0
  237. package/templates/storefront-nextjs-shadcn/app/auth/register/page.tsx +20 -0
  238. package/templates/storefront-nextjs-shadcn/app/blog/[slug]/page.tsx +323 -0
  239. package/templates/storefront-nextjs-shadcn/app/blog/page.tsx +159 -0
  240. package/templates/storefront-nextjs-shadcn/app/brands/[slug]/page.tsx +170 -0
  241. package/templates/storefront-nextjs-shadcn/app/brands/page.tsx +73 -0
  242. package/templates/storefront-nextjs-shadcn/app/cart/page.tsx +165 -0
  243. package/templates/storefront-nextjs-shadcn/app/categories/[slug]/page.tsx +78 -0
  244. package/templates/storefront-nextjs-shadcn/app/categories/page.tsx +75 -0
  245. package/templates/storefront-nextjs-shadcn/app/checkout/page.tsx +1752 -0
  246. package/templates/storefront-nextjs-shadcn/app/checkout/success/[orderId]/page.tsx +256 -0
  247. package/templates/storefront-nextjs-shadcn/app/collections/[handle]/page.tsx +74 -0
  248. package/templates/storefront-nextjs-shadcn/app/collections/page.tsx +75 -0
  249. package/templates/storefront-nextjs-shadcn/app/contact/page.tsx +114 -0
  250. package/templates/storefront-nextjs-shadcn/app/error.tsx +90 -0
  251. package/templates/storefront-nextjs-shadcn/app/globals.css +125 -0
  252. package/templates/storefront-nextjs-shadcn/app/layout.tsx +57 -0
  253. package/templates/storefront-nextjs-shadcn/app/not-found.tsx +68 -0
  254. package/templates/storefront-nextjs-shadcn/app/page.tsx +21 -0
  255. package/templates/storefront-nextjs-shadcn/app/products/[slug]/page.tsx +246 -0
  256. package/templates/storefront-nextjs-shadcn/app/products/[slug]/product-client.tsx +343 -0
  257. package/templates/storefront-nextjs-shadcn/app/products/page.tsx +25 -0
  258. package/templates/storefront-nextjs-shadcn/app/products/products-client.tsx +192 -0
  259. package/templates/storefront-nextjs-shadcn/app/returns/page.tsx +77 -0
  260. package/templates/storefront-nextjs-shadcn/app/robots.ts +53 -0
  261. package/templates/storefront-nextjs-shadcn/app/search/page.tsx +16 -0
  262. package/templates/storefront-nextjs-shadcn/app/search/search-client.tsx +47 -0
  263. package/templates/storefront-nextjs-shadcn/app/shipping/page.tsx +62 -0
  264. package/templates/storefront-nextjs-shadcn/app/sitemap.ts +144 -0
  265. package/templates/storefront-nextjs-shadcn/app/wishlist/page.tsx +179 -0
  266. package/templates/storefront-nextjs-shadcn/codegen.ts +51 -0
  267. package/templates/storefront-nextjs-shadcn/components/account/address-form.tsx +348 -0
  268. package/templates/storefront-nextjs-shadcn/components/account/address-list.tsx +144 -0
  269. package/templates/storefront-nextjs-shadcn/components/account/order-details.tsx +258 -0
  270. package/templates/storefront-nextjs-shadcn/components/account/order-history.tsx +107 -0
  271. package/templates/storefront-nextjs-shadcn/components/auth/account-menu.tsx +132 -0
  272. package/templates/storefront-nextjs-shadcn/components/auth/login-form.tsx +188 -0
  273. package/templates/storefront-nextjs-shadcn/components/auth/register-form.tsx +305 -0
  274. package/templates/storefront-nextjs-shadcn/components/blog/blog-card.tsx +240 -0
  275. package/templates/storefront-nextjs-shadcn/components/blog/blog-sidebar.tsx +177 -0
  276. package/templates/storefront-nextjs-shadcn/components/blog/index.ts +8 -0
  277. package/templates/storefront-nextjs-shadcn/components/brand/brand-card.tsx +119 -0
  278. package/templates/storefront-nextjs-shadcn/components/brand/brand-grid.tsx +64 -0
  279. package/templates/storefront-nextjs-shadcn/components/cart/cart-drawer.tsx +140 -0
  280. package/templates/storefront-nextjs-shadcn/components/cart/cart-icon.tsx +48 -0
  281. package/templates/storefront-nextjs-shadcn/components/cart/cart-item.tsx +112 -0
  282. package/templates/storefront-nextjs-shadcn/components/cart/cart-summary.tsx +84 -0
  283. package/templates/storefront-nextjs-shadcn/components/cart/index.ts +17 -0
  284. package/templates/storefront-nextjs-shadcn/components/cart/promo-code-input.tsx +121 -0
  285. package/templates/storefront-nextjs-shadcn/components/cart/shipping-estimator.tsx +162 -0
  286. package/templates/storefront-nextjs-shadcn/components/checkout/index.ts +25 -0
  287. package/templates/storefront-nextjs-shadcn/components/checkout/payment-method-card.tsx +187 -0
  288. package/templates/storefront-nextjs-shadcn/components/checkout/payment-step.tsx +160 -0
  289. package/templates/storefront-nextjs-shadcn/components/checkout/tax-breakdown.tsx +154 -0
  290. package/templates/storefront-nextjs-shadcn/components/commerce/currency-selector.tsx +225 -0
  291. package/templates/storefront-nextjs-shadcn/components/commerce/pagination.tsx +62 -0
  292. package/templates/storefront-nextjs-shadcn/components/commerce/product-actions.tsx +158 -0
  293. package/templates/storefront-nextjs-shadcn/components/commerce/search-input.tsx +174 -0
  294. package/templates/storefront-nextjs-shadcn/components/commerce/variant-selector.tsx +210 -0
  295. package/templates/storefront-nextjs-shadcn/components/common/category-card.tsx +97 -0
  296. package/templates/storefront-nextjs-shadcn/components/common/collection-card.tsx +187 -0
  297. package/templates/storefront-nextjs-shadcn/components/common/price-display.tsx +151 -0
  298. package/templates/storefront-nextjs-shadcn/components/common/social-share.tsx +166 -0
  299. package/templates/storefront-nextjs-shadcn/components/discount/discount-breakdown.tsx +245 -0
  300. package/templates/storefront-nextjs-shadcn/components/discount/discount-code-input.tsx +246 -0
  301. package/templates/storefront-nextjs-shadcn/components/discount/index.ts +19 -0
  302. package/templates/storefront-nextjs-shadcn/components/error/error-boundary.tsx +113 -0
  303. package/templates/storefront-nextjs-shadcn/components/error/index.ts +7 -0
  304. package/templates/storefront-nextjs-shadcn/components/filters/attribute-filter.tsx +153 -0
  305. package/templates/storefront-nextjs-shadcn/components/filters/checkbox-group-filter.tsx +167 -0
  306. package/templates/storefront-nextjs-shadcn/components/filters/color-swatch-filter.tsx +176 -0
  307. package/templates/storefront-nextjs-shadcn/components/filters/dynamic-attribute-filters.tsx +220 -0
  308. package/templates/storefront-nextjs-shadcn/components/filters/index.ts +36 -0
  309. package/templates/storefront-nextjs-shadcn/components/filters/range-slider-filter.tsx +193 -0
  310. package/templates/storefront-nextjs-shadcn/components/filters/toggle-filter.tsx +132 -0
  311. package/templates/storefront-nextjs-shadcn/components/gift-card/gift-card-balance.tsx +321 -0
  312. package/templates/storefront-nextjs-shadcn/components/gift-card/gift-card-input.tsx +309 -0
  313. package/templates/storefront-nextjs-shadcn/components/gift-card/index.ts +24 -0
  314. package/templates/storefront-nextjs-shadcn/components/home/category-grid.tsx +72 -0
  315. package/templates/storefront-nextjs-shadcn/components/home/featured-collections.tsx +107 -0
  316. package/templates/storefront-nextjs-shadcn/components/home/featured-products.tsx +85 -0
  317. package/templates/storefront-nextjs-shadcn/components/home/hero-section.tsx +34 -0
  318. package/templates/storefront-nextjs-shadcn/components/home/index.ts +8 -0
  319. package/templates/storefront-nextjs-shadcn/components/home/newsletter-signup.tsx +108 -0
  320. package/templates/storefront-nextjs-shadcn/components/layout/breadcrumbs.tsx +133 -0
  321. package/templates/storefront-nextjs-shadcn/components/layout/currency-selector.tsx +341 -0
  322. package/templates/storefront-nextjs-shadcn/components/layout/footer.tsx +128 -0
  323. package/templates/storefront-nextjs-shadcn/components/layout/header.tsx +147 -0
  324. package/templates/storefront-nextjs-shadcn/components/layout/index.ts +9 -0
  325. package/templates/storefront-nextjs-shadcn/components/layout/mobile-menu.tsx +211 -0
  326. package/templates/storefront-nextjs-shadcn/components/layout/navigation.tsx +95 -0
  327. package/templates/storefront-nextjs-shadcn/components/layout/theme-switcher.tsx +192 -0
  328. package/templates/storefront-nextjs-shadcn/components/loyalty/index.ts +11 -0
  329. package/templates/storefront-nextjs-shadcn/components/loyalty/points-balance.tsx +93 -0
  330. package/templates/storefront-nextjs-shadcn/components/loyalty/points-history.tsx +177 -0
  331. package/templates/storefront-nextjs-shadcn/components/loyalty/referral-section.tsx +250 -0
  332. package/templates/storefront-nextjs-shadcn/components/loyalty/rewards-catalog.tsx +217 -0
  333. package/templates/storefront-nextjs-shadcn/components/loyalty/tier-badge.tsx +106 -0
  334. package/templates/storefront-nextjs-shadcn/components/loyalty/tier-progress.tsx +131 -0
  335. package/templates/storefront-nextjs-shadcn/components/order/delivery-estimate.tsx +196 -0
  336. package/templates/storefront-nextjs-shadcn/components/order/index.ts +11 -0
  337. package/templates/storefront-nextjs-shadcn/components/order/order-tracking.tsx +200 -0
  338. package/templates/storefront-nextjs-shadcn/components/order/shipment-card.tsx +407 -0
  339. package/templates/storefront-nextjs-shadcn/components/order/tracking-status.tsx +222 -0
  340. package/templates/storefront-nextjs-shadcn/components/order/tracking-timeline.tsx +205 -0
  341. package/templates/storefront-nextjs-shadcn/components/product/add-to-cart-button.tsx +161 -0
  342. package/templates/storefront-nextjs-shadcn/components/product/b2b-price-display.tsx +250 -0
  343. package/templates/storefront-nextjs-shadcn/components/product/discount-badge.tsx +196 -0
  344. package/templates/storefront-nextjs-shadcn/components/product/index.ts +41 -0
  345. package/templates/storefront-nextjs-shadcn/components/product/product-card.tsx +147 -0
  346. package/templates/storefront-nextjs-shadcn/components/product/product-filters.tsx +217 -0
  347. package/templates/storefront-nextjs-shadcn/components/product/product-gallery.tsx +143 -0
  348. package/templates/storefront-nextjs-shadcn/components/product/product-grid.tsx +83 -0
  349. package/templates/storefront-nextjs-shadcn/components/product/product-image.tsx +155 -0
  350. package/templates/storefront-nextjs-shadcn/components/product/product-price.tsx +158 -0
  351. package/templates/storefront-nextjs-shadcn/components/product/product-quantity-selector.tsx +111 -0
  352. package/templates/storefront-nextjs-shadcn/components/product/product-reviews.tsx +238 -0
  353. package/templates/storefront-nextjs-shadcn/components/product/product-sort.tsx +58 -0
  354. package/templates/storefront-nextjs-shadcn/components/product/product-variant-selector.tsx +169 -0
  355. package/templates/storefront-nextjs-shadcn/components/product/review-card.tsx +220 -0
  356. package/templates/storefront-nextjs-shadcn/components/product/review-form.tsx +338 -0
  357. package/templates/storefront-nextjs-shadcn/components/product/review-summary.tsx +143 -0
  358. package/templates/storefront-nextjs-shadcn/components/product/sale-countdown.tsx +166 -0
  359. package/templates/storefront-nextjs-shadcn/components/product/savings-display.tsx +213 -0
  360. package/templates/storefront-nextjs-shadcn/components/product/similar-products.tsx +57 -0
  361. package/templates/storefront-nextjs-shadcn/components/product/stock-indicator.tsx +91 -0
  362. package/templates/storefront-nextjs-shadcn/components/providers/currency-provider.tsx +103 -0
  363. package/templates/storefront-nextjs-shadcn/components/providers/index.ts +8 -0
  364. package/templates/storefront-nextjs-shadcn/components/providers/query-provider.tsx +260 -0
  365. package/templates/storefront-nextjs-shadcn/components/providers/theme-provider.tsx +13 -0
  366. package/templates/storefront-nextjs-shadcn/components/returns/index.ts +26 -0
  367. package/templates/storefront-nextjs-shadcn/components/returns/return-request-form.tsx +608 -0
  368. package/templates/storefront-nextjs-shadcn/components/returns/return-status-card.tsx +554 -0
  369. package/templates/storefront-nextjs-shadcn/components/search/index.ts +8 -0
  370. package/templates/storefront-nextjs-shadcn/components/search/search-bar.tsx +140 -0
  371. package/templates/storefront-nextjs-shadcn/components/search/search-results.tsx +58 -0
  372. package/templates/storefront-nextjs-shadcn/components/search/search-suggestions.tsx +43 -0
  373. package/templates/storefront-nextjs-shadcn/components/seo/index.ts +12 -0
  374. package/templates/storefront-nextjs-shadcn/components/seo/json-ld.tsx +56 -0
  375. package/templates/storefront-nextjs-shadcn/components/seo/product-json-ld.ts +167 -0
  376. package/templates/storefront-nextjs-shadcn/components/shipping/index.ts +16 -0
  377. package/templates/storefront-nextjs-shadcn/components/shipping/shipping-method-selector.tsx +337 -0
  378. package/templates/storefront-nextjs-shadcn/components/ui/accordion.tsx +153 -0
  379. package/templates/storefront-nextjs-shadcn/components/ui/alert.tsx +59 -0
  380. package/templates/storefront-nextjs-shadcn/components/ui/badge.tsx +34 -0
  381. package/templates/storefront-nextjs-shadcn/components/ui/button.tsx +51 -0
  382. package/templates/storefront-nextjs-shadcn/components/ui/card.tsx +77 -0
  383. package/templates/storefront-nextjs-shadcn/components/ui/checkbox.tsx +30 -0
  384. package/templates/storefront-nextjs-shadcn/components/ui/dialog.tsx +137 -0
  385. package/templates/storefront-nextjs-shadcn/components/ui/empty-state.tsx +207 -0
  386. package/templates/storefront-nextjs-shadcn/components/ui/index.ts +67 -0
  387. package/templates/storefront-nextjs-shadcn/components/ui/input.tsx +65 -0
  388. package/templates/storefront-nextjs-shadcn/components/ui/label.tsx +26 -0
  389. package/templates/storefront-nextjs-shadcn/components/ui/pagination.tsx +205 -0
  390. package/templates/storefront-nextjs-shadcn/components/ui/radio-group.tsx +44 -0
  391. package/templates/storefront-nextjs-shadcn/components/ui/select.tsx +160 -0
  392. package/templates/storefront-nextjs-shadcn/components/ui/separator.tsx +28 -0
  393. package/templates/storefront-nextjs-shadcn/components/ui/skeleton.tsx +20 -0
  394. package/templates/storefront-nextjs-shadcn/components/ui/spinner.tsx +82 -0
  395. package/templates/storefront-nextjs-shadcn/components/ui/tabs.tsx +119 -0
  396. package/templates/storefront-nextjs-shadcn/components/ui/toast.tsx +96 -0
  397. package/templates/storefront-nextjs-shadcn/components/wishlist/index.ts +9 -0
  398. package/templates/storefront-nextjs-shadcn/components/wishlist/wishlist-button.tsx +148 -0
  399. package/templates/storefront-nextjs-shadcn/components/wishlist/wishlist-icon.tsx +47 -0
  400. package/templates/storefront-nextjs-shadcn/components/wishlist/wishlist-item.tsx +165 -0
  401. package/templates/storefront-nextjs-shadcn/components.json +19 -0
  402. package/templates/storefront-nextjs-shadcn/generated/.gitkeep +2 -0
  403. package/templates/storefront-nextjs-shadcn/graphql/.gitkeep +31 -0
  404. package/templates/storefront-nextjs-shadcn/graphql/collections.example.ts +168 -0
  405. package/templates/storefront-nextjs-shadcn/graphql/products.example.ts +160 -0
  406. package/templates/storefront-nextjs-shadcn/hooks/index.ts +9 -0
  407. package/templates/storefront-nextjs-shadcn/hooks/use-auth.ts +310 -0
  408. package/templates/storefront-nextjs-shadcn/hooks/use-cart-actions.ts +286 -0
  409. package/templates/storefront-nextjs-shadcn/hooks/use-cart-sync.ts +110 -0
  410. package/templates/storefront-nextjs-shadcn/hooks/use-filter-params.test.ts +173 -0
  411. package/templates/storefront-nextjs-shadcn/hooks/use-filter-params.ts +298 -0
  412. package/templates/storefront-nextjs-shadcn/lib/auth/cookies.ts +220 -0
  413. package/templates/storefront-nextjs-shadcn/lib/auth/routes.ts +57 -0
  414. package/templates/storefront-nextjs-shadcn/lib/config.ts +46 -0
  415. package/templates/storefront-nextjs-shadcn/lib/currency/IMPLEMENTATION_SUMMARY.md +254 -0
  416. package/templates/storefront-nextjs-shadcn/lib/currency/README.md +464 -0
  417. package/templates/storefront-nextjs-shadcn/lib/currency/cookie-manager.test.ts +328 -0
  418. package/templates/storefront-nextjs-shadcn/lib/currency/cookie-manager.ts +295 -0
  419. package/templates/storefront-nextjs-shadcn/lib/currency/index.ts +27 -0
  420. package/templates/storefront-nextjs-shadcn/lib/format.test.ts +397 -0
  421. package/templates/storefront-nextjs-shadcn/lib/format.ts +226 -0
  422. package/templates/storefront-nextjs-shadcn/lib/graphql/client.ts +109 -0
  423. package/templates/storefront-nextjs-shadcn/lib/graphql/hooks.ts +1183 -0
  424. package/templates/storefront-nextjs-shadcn/lib/graphql/server.ts +267 -0
  425. package/templates/storefront-nextjs-shadcn/lib/hooks.ts +30 -0
  426. package/templates/storefront-nextjs-shadcn/lib/theme/theme-config.ts +89 -0
  427. package/templates/storefront-nextjs-shadcn/lib/utils.ts +6 -0
  428. package/templates/storefront-nextjs-shadcn/next.config.ts +47 -0
  429. package/templates/storefront-nextjs-shadcn/open-next.config.ts +3 -0
  430. package/templates/storefront-nextjs-shadcn/package.dev.json +30 -0
  431. package/templates/storefront-nextjs-shadcn/package.json +60 -0
  432. package/templates/storefront-nextjs-shadcn/package.json.template +46 -0
  433. package/templates/storefront-nextjs-shadcn/postcss.config.mjs +8 -0
  434. package/templates/storefront-nextjs-shadcn/proxy.ts +80 -0
  435. package/templates/storefront-nextjs-shadcn/public/icons/payment/apple-pay.svg +8 -0
  436. package/templates/storefront-nextjs-shadcn/public/icons/payment/bank-transfer.svg +10 -0
  437. package/templates/storefront-nextjs-shadcn/public/icons/payment/blik.svg +6 -0
  438. package/templates/storefront-nextjs-shadcn/public/icons/payment/cash-on-delivery.svg +11 -0
  439. package/templates/storefront-nextjs-shadcn/public/icons/payment/google-pay.svg +11 -0
  440. package/templates/storefront-nextjs-shadcn/public/icons/payment/mastercard.svg +7 -0
  441. package/templates/storefront-nextjs-shadcn/public/icons/payment/paypal.svg +7 -0
  442. package/templates/storefront-nextjs-shadcn/public/icons/payment/payu.svg +7 -0
  443. package/templates/storefront-nextjs-shadcn/public/icons/payment/przelewy24.svg +7 -0
  444. package/templates/storefront-nextjs-shadcn/public/icons/payment/stripe.svg +4 -0
  445. package/templates/storefront-nextjs-shadcn/public/icons/payment/visa.svg +5 -0
  446. package/templates/storefront-nextjs-shadcn/stores/auth-store.ts +66 -0
  447. package/templates/storefront-nextjs-shadcn/stores/cart-store.ts +56 -0
  448. package/templates/storefront-nextjs-shadcn/stores/checkout-store.ts +184 -0
  449. package/templates/storefront-nextjs-shadcn/stores/currency-store.ts +103 -0
  450. package/templates/storefront-nextjs-shadcn/stores/wishlist-store.ts +291 -0
  451. package/templates/storefront-nextjs-shadcn/tailwind.config.ts +111 -0
  452. package/templates/storefront-nextjs-shadcn/tsconfig.json +27 -0
  453. package/templates/storefront-nextjs-shadcn/wrangler.toml +9 -0
@@ -0,0 +1,267 @@
1
+ import { cache } from 'react';
2
+ import { GraphQLClient } from 'graphql-request';
3
+ import type { TypedDocumentNode } from '@graphql-typed-document-node/core';
4
+ import { getCurrencyFromCookieAsync } from '@/lib/currency/';
5
+
6
+ // Import config - will be injected by CLI during template generation
7
+ let config: {
8
+ shop: { slug: string };
9
+ api: { url: string };
10
+ } | null = null;
11
+
12
+ try {
13
+ // Dynamic import to handle cases where config doesn't exist yet
14
+ const configModule = require('@/doswiftly.config');
15
+ config = configModule.default || configModule;
16
+ } catch (error) {
17
+ // Fallback to environment variables if config file doesn't exist
18
+ config = {
19
+ shop: {
20
+ slug: process.env.NEXT_PUBLIC_SHOP_SLUG || 'demo-shop',
21
+ },
22
+ api: {
23
+ url: process.env.NEXT_PUBLIC_API_URL || 'http://localhost:8000',
24
+ },
25
+ };
26
+ }
27
+
28
+ /**
29
+ * Cached GraphQL client factory for Server Components
30
+ *
31
+ * Uses React cache() to deduplicate requests within a single render pass.
32
+ * Server-side requests now include X-Preferred-Currency header from cookie
33
+ * for SSR currency consistency.
34
+ *
35
+ * Note: This is an async function in Next.js 15+ because cookies() is async.
36
+ *
37
+ * @returns GraphQL client configured for server-side usage with currency support
38
+ */
39
+ export const getClient = cache(async () => {
40
+ // Read currency from cookie (SSR-safe, async in Next.js 15+)
41
+ const currency = await getCurrencyFromCookieAsync();
42
+
43
+ return new GraphQLClient(`${config!.api.url}/storefront/graphql`, {
44
+ headers: {
45
+ 'X-Shop-Slug': config!.shop.slug,
46
+ // Include X-Preferred-Currency from cookie for SSR consistency
47
+ ...(currency && { 'X-Preferred-Currency': currency }),
48
+ },
49
+ });
50
+ });
51
+
52
+ /**
53
+ * Generic request helper with React cache
54
+ *
55
+ * @param document - TypedDocumentNode from codegen
56
+ * @param variables - Query variables
57
+ * @returns Query result
58
+ */
59
+ export const request = cache(async <TResult, TVariables>(
60
+ document: TypedDocumentNode<TResult, TVariables>,
61
+ variables?: TVariables
62
+ ): Promise<TResult> => {
63
+ const client = await getClient();
64
+ return client.request(document, variables as any);
65
+ });
66
+
67
+ // ============================================================================
68
+ // HELPER FUNCTIONS
69
+ // ============================================================================
70
+
71
+ /**
72
+ * Fetch shop data with currency configuration
73
+ *
74
+ * Used in root layout to initialize currency store.
75
+ * Cached per render to avoid duplicate requests.
76
+ *
77
+ * @returns Shop query result
78
+ *
79
+ * @example
80
+ * ```typescript
81
+ * // app/layout.tsx
82
+ * import { fetchShop } from '@/lib/graphql/server';
83
+ *
84
+ * export default async function RootLayout() {
85
+ * const data = await fetchShop();
86
+ * return <CurrencyProvider shopData={data.shop}>...</CurrencyProvider>;
87
+ * }
88
+ * ```
89
+ */
90
+ export const fetchShop = cache(async () => {
91
+ // Import generated types dynamically to avoid circular dependencies
92
+ const { ShopDocument } = await import('@/generated/graphql');
93
+ return request(ShopDocument, {});
94
+ });
95
+
96
+ /**
97
+ * Fetch single product by handle or ID
98
+ *
99
+ * Returns product in base currency for SSG compatibility.
100
+ * Client components should refetch with preferred currency if needed.
101
+ *
102
+ * @param handleOrId - Product handle (string) or ID
103
+ * @returns Product query result
104
+ *
105
+ * @example
106
+ * ```typescript
107
+ * // app/products/[handle]/page.tsx
108
+ * import { fetchProduct } from '@/lib/graphql/server';
109
+ *
110
+ * export default async function ProductPage({ params }) {
111
+ * const data = await fetchProduct(params.handle);
112
+ * return <ProductClient initialProduct={data.product} />;
113
+ * }
114
+ * ```
115
+ */
116
+ export const fetchProduct = cache(async (handleOrId: string) => {
117
+ if (!handleOrId) {
118
+ throw new Error('Product handle or ID is required');
119
+ }
120
+
121
+ const { ProductDocument } = await import('@/generated/graphql');
122
+
123
+ // Determine if it's an ID or handle
124
+ const isId = handleOrId.startsWith('gid://');
125
+
126
+ return request(ProductDocument, {
127
+ ...(isId ? { id: handleOrId } : { handle: handleOrId }),
128
+ });
129
+ });
130
+
131
+ /**
132
+ * Fetch products with pagination and normalization
133
+ *
134
+ * Automatically normalizes GraphQL edges/nodes structure to flat arrays
135
+ * for easier consumption in components.
136
+ *
137
+ * @param variables - Query variables (first, after, query, sortKey, reverse)
138
+ * @returns Normalized products response
139
+ *
140
+ * @example
141
+ * ```typescript
142
+ * // app/products/page.tsx
143
+ * import { fetchProducts } from '@/lib/graphql/server';
144
+ *
145
+ * export default async function ProductsPage() {
146
+ * const { products, pageInfo } = await fetchProducts({ first: 20 });
147
+ * return products.map(product => <ProductCard key={product.id} product={product} />);
148
+ * }
149
+ * ```
150
+ */
151
+ export const fetchProducts = cache(async (variables?: {
152
+ first?: number;
153
+ after?: string;
154
+ query?: string;
155
+ sortKey?: string;
156
+ reverse?: boolean;
157
+ }) => {
158
+ const { ProductsDocument } = await import('@/generated/graphql');
159
+
160
+ const data = await request(ProductsDocument, {
161
+ first: variables?.first ?? 20,
162
+ after: variables?.after,
163
+ query: variables?.query,
164
+ sortKey: variables?.sortKey as any,
165
+ reverse: variables?.reverse,
166
+ });
167
+
168
+ // Normalize: edges/nodes → flat array
169
+ return {
170
+ products: data.products.edges.map((edge: any) => edge.node),
171
+ pageInfo: data.products.pageInfo,
172
+ totalCount: data.products.totalCount,
173
+ };
174
+ });
175
+
176
+ /**
177
+ * Fetch collections with pagination and normalization
178
+ *
179
+ * @param variables - Query variables
180
+ * @returns Normalized collections response
181
+ *
182
+ * @example
183
+ * ```typescript
184
+ * import { fetchCollections } from '@/lib/graphql/server';
185
+ *
186
+ * const { collections } = await fetchCollections({ first: 10 });
187
+ * ```
188
+ */
189
+ export const fetchCollections = cache(async (variables?: {
190
+ first?: number;
191
+ after?: string;
192
+ query?: string;
193
+ sortKey?: string;
194
+ reverse?: boolean;
195
+ }) => {
196
+ const { CollectionsDocument } = await import('@/generated/graphql');
197
+
198
+ const data = await request(CollectionsDocument, {
199
+ first: variables?.first ?? 20,
200
+ after: variables?.after,
201
+ query: variables?.query,
202
+ sortKey: variables?.sortKey as any,
203
+ reverse: variables?.reverse,
204
+ });
205
+
206
+ // Normalize: edges/nodes → flat array
207
+ return {
208
+ collections: data.collections.edges.map((edge: any) => edge.node),
209
+ pageInfo: data.collections.pageInfo,
210
+ totalCount: data.collections.totalCount,
211
+ };
212
+ });
213
+
214
+ /**
215
+ * Fetch single collection by handle or ID
216
+ *
217
+ * @param handleOrId - Collection handle or ID
218
+ * @returns Collection query result
219
+ *
220
+ * @example
221
+ * ```typescript
222
+ * import { fetchCollection } from '@/lib/graphql/server';
223
+ *
224
+ * const data = await fetchCollection('featured-products');
225
+ * ```
226
+ */
227
+ export const fetchCollection = cache(async (handleOrId: string) => {
228
+ const { CollectionDocument } = await import('@/generated/graphql');
229
+
230
+ const isId = handleOrId.startsWith('gid://');
231
+
232
+ return request(CollectionDocument, {
233
+ ...(isId ? { id: handleOrId } : { handle: handleOrId }),
234
+ });
235
+ });
236
+
237
+ /**
238
+ * Fetch categories from GraphQL API
239
+ *
240
+ * @returns Categories query result with tree structure
241
+ */
242
+ export const fetchCategories = cache(async () => {
243
+ const { CategoriesDocument } = await import('@/generated/graphql');
244
+ return request(CategoriesDocument, {});
245
+ });
246
+
247
+ /**
248
+ * Fetch customer data (requires access token)
249
+ *
250
+ * @param accessToken - Customer access token
251
+ * @returns Customer query result with addresses and orders
252
+ */
253
+ export const fetchCustomer = cache(async (accessToken: string) => {
254
+ const { CustomerDocument } = await import('@/generated/graphql');
255
+ return request(CustomerDocument, { customerAccessToken: accessToken });
256
+ });
257
+
258
+ // ============================================================================
259
+ // TYPE EXPORTS
260
+ // ============================================================================
261
+
262
+ /**
263
+ * Normalized response types for helper functions
264
+ * These types will be inferred from generated GraphQL types
265
+ */
266
+ export type NormalizedProductsResponse = Awaited<ReturnType<typeof fetchProducts>>;
267
+ export type NormalizedCollectionsResponse = Awaited<ReturnType<typeof fetchCollections>>;
@@ -0,0 +1,30 @@
1
+ import { useState, useEffect } from "react";
2
+
3
+ /**
4
+ * useDebouncedValue - Debounce a value
5
+ *
6
+ * @param value - Value to debounce
7
+ * @param delay - Delay in ms (default: 300)
8
+ * @returns Debounced value
9
+ *
10
+ * @example
11
+ * ```tsx
12
+ * const [query, setQuery] = useState("");
13
+ * const debouncedQuery = useDebouncedValue(query, 300);
14
+ *
15
+ * // debouncedQuery updates 300ms after query stops changing
16
+ * ```
17
+ */
18
+ export function useDebouncedValue<T>(value: T, delay = 300): T {
19
+ const [debouncedValue, setDebouncedValue] = useState(value);
20
+
21
+ useEffect(() => {
22
+ const timer = setTimeout(() => {
23
+ setDebouncedValue(value);
24
+ }, delay);
25
+
26
+ return () => clearTimeout(timer);
27
+ }, [value, delay]);
28
+
29
+ return debouncedValue;
30
+ }
@@ -0,0 +1,89 @@
1
+ /**
2
+ * Theme Configuration
3
+ * Design tokens and theme settings for the storefront
4
+ */
5
+
6
+ export const themeConfig = {
7
+ // Default theme
8
+ defaultTheme: "system" as const,
9
+
10
+ // Available themes
11
+ themes: ["light", "dark", "system"] as const,
12
+
13
+ // Enable system theme detection
14
+ enableSystem: true,
15
+
16
+ // Disable theme transition on page load
17
+ disableTransitionOnChange: false,
18
+
19
+ // Storage key for theme preference
20
+ storageKey: "doswiftly-theme",
21
+
22
+ // Attribute to set on document element
23
+ attribute: "class",
24
+
25
+ // CSS variables for theme colors
26
+ colors: {
27
+ light: {
28
+ background: "0 0% 100%",
29
+ foreground: "222.2 84% 4.9%",
30
+ card: "0 0% 100%",
31
+ "card-foreground": "222.2 84% 4.9%",
32
+ popover: "0 0% 100%",
33
+ "popover-foreground": "222.2 84% 4.9%",
34
+ primary: "222.2 47.4% 11.2%",
35
+ "primary-foreground": "210 40% 98%",
36
+ secondary: "210 40% 96.1%",
37
+ "secondary-foreground": "222.2 47.4% 11.2%",
38
+ muted: "210 40% 96.1%",
39
+ "muted-foreground": "215.4 16.3% 46.9%",
40
+ accent: "210 40% 96.1%",
41
+ "accent-foreground": "222.2 47.4% 11.2%",
42
+ destructive: "0 84.2% 60.2%",
43
+ "destructive-foreground": "210 40% 98%",
44
+ border: "214.3 31.8% 91.4%",
45
+ input: "214.3 31.8% 91.4%",
46
+ ring: "222.2 84% 4.9%",
47
+ },
48
+ dark: {
49
+ background: "222.2 84% 4.9%",
50
+ foreground: "210 40% 98%",
51
+ card: "222.2 84% 4.9%",
52
+ "card-foreground": "210 40% 98%",
53
+ popover: "222.2 84% 4.9%",
54
+ "popover-foreground": "210 40% 98%",
55
+ primary: "210 40% 98%",
56
+ "primary-foreground": "222.2 47.4% 11.2%",
57
+ secondary: "217.2 32.6% 17.5%",
58
+ "secondary-foreground": "210 40% 98%",
59
+ muted: "217.2 32.6% 17.5%",
60
+ "muted-foreground": "215 20.2% 65.1%",
61
+ accent: "217.2 32.6% 17.5%",
62
+ "accent-foreground": "210 40% 98%",
63
+ destructive: "0 62.8% 30.6%",
64
+ "destructive-foreground": "210 40% 98%",
65
+ border: "217.2 32.6% 17.5%",
66
+ input: "217.2 32.6% 17.5%",
67
+ ring: "212.7 26.8% 83.9%",
68
+ },
69
+ },
70
+ } as const;
71
+
72
+ export type Theme = (typeof themeConfig.themes)[number];
73
+
74
+ /**
75
+ * Get theme colors for a specific theme
76
+ */
77
+ export function getThemeColors(theme: "light" | "dark") {
78
+ return themeConfig.colors[theme];
79
+ }
80
+
81
+ /**
82
+ * Generate CSS variables for theme
83
+ */
84
+ export function generateThemeVariables(theme: "light" | "dark") {
85
+ const colors = getThemeColors(theme);
86
+ return Object.entries(colors)
87
+ .map(([key, value]) => `--${key}: ${value};`)
88
+ .join("\n ");
89
+ }
@@ -0,0 +1,6 @@
1
+ import { clsx, type ClassValue } from "clsx";
2
+ import { twMerge } from "tailwind-merge";
3
+
4
+ export function cn(...inputs: ClassValue[]) {
5
+ return twMerge(clsx(inputs));
6
+ }
@@ -0,0 +1,47 @@
1
+ import type { NextConfig } from 'next';
2
+
3
+ const nextConfig: NextConfig = {
4
+ // Enable React strict mode for better development experience
5
+ reactStrictMode: true,
6
+
7
+ // Image optimization configuration
8
+ images: {
9
+ remotePatterns: [
10
+ {
11
+ protocol: 'https',
12
+ hostname: '**.doswiftly.pl',
13
+ },
14
+ {
15
+ protocol: 'https',
16
+ hostname: 'images.unsplash.com',
17
+ },
18
+ {
19
+ protocol: 'http',
20
+ hostname: 'app.localhost',
21
+ port: '8000',
22
+ },
23
+ ],
24
+ // Allow dangerous URLs for local development
25
+ dangerouslyAllowSVG: true,
26
+ contentDispositionType: 'attachment',
27
+ // Disable image optimization for local development if needed
28
+ unoptimized: process.env.NODE_ENV === 'development',
29
+ },
30
+
31
+ // Experimental features
32
+ experimental: {
33
+ // Enable server actions
34
+ serverActions: {
35
+ bodySizeLimit: '2mb',
36
+ },
37
+ },
38
+
39
+ // Environment variables validation
40
+ env: {
41
+ NEXT_PUBLIC_API_URL: process.env.NEXT_PUBLIC_API_URL,
42
+ NEXT_PUBLIC_PROJECT_ID: process.env.NEXT_PUBLIC_PROJECT_ID,
43
+ NEXT_PUBLIC_SHOP_SLUG: process.env.NEXT_PUBLIC_SHOP_SLUG,
44
+ },
45
+ };
46
+
47
+ export default nextConfig;
@@ -0,0 +1,3 @@
1
+ import { defineCloudflareConfig } from "@opennextjs/cloudflare";
2
+
3
+ export default defineCloudflareConfig({});
@@ -0,0 +1,30 @@
1
+ {
2
+ "name": "test-storefront",
3
+ "version": "0.1.0",
4
+ "private": true,
5
+ "scripts": {
6
+ "dev": "next dev",
7
+ "build": "next build",
8
+ "start": "next start",
9
+ "lint": "next lint"
10
+ },
11
+ "dependencies": {
12
+ "@doswiftly/commerce-sdk": "file:../../../commerce-sdk",
13
+ "graphql-request": "^7.1.2",
14
+ "graphql": "^16.10.0",
15
+ "next": "latest",
16
+ "react": "^19",
17
+ "react-dom": "^19",
18
+ "lucide-react": "latest"
19
+ },
20
+ "devDependencies": {
21
+ "@types/node": "latest",
22
+ "@types/react": "latest",
23
+ "@types/react-dom": "latest",
24
+ "typescript": "latest",
25
+ "@tailwindcss/postcss": "latest",
26
+ "tailwindcss": "latest",
27
+ "eslint": "latest",
28
+ "eslint-config-next": "latest"
29
+ }
30
+ }
@@ -0,0 +1,60 @@
1
+ {
2
+ "name": "{{PROJECT_NAME}}",
3
+ "version": "0.1.0",
4
+ "private": true,
5
+ "scripts": {
6
+ "dev": "next dev",
7
+ "build": "next build",
8
+ "build:cf": "opennextjs-cloudflare build",
9
+ "start": "next start",
10
+ "lint": "next lint",
11
+ "codegen": "graphql-codegen --config codegen.ts",
12
+ "codegen:watch": "graphql-codegen --config codegen.ts --watch"
13
+ },
14
+ "dependencies": {
15
+ "@doswiftly/storefront-operations": "{{STOREFRONT_OPS_VERSION}}",
16
+ "@graphql-typed-document-node/core": "^3.2.0",
17
+ "@tanstack/react-query": "^5.62.0",
18
+ "graphql-request": "^7.1.2",
19
+ "graphql": "^16.10.0",
20
+ "graphql-tag": "^2.12.6",
21
+ "js-cookie": "^3.0.5",
22
+ "next": "^15.1.9",
23
+ "react": "^19",
24
+ "react-dom": "^19",
25
+ "lucide-react": "latest",
26
+ "@radix-ui/react-accordion": "^1.2.0",
27
+ "@radix-ui/react-checkbox": "^1.1.0",
28
+ "@radix-ui/react-dialog": "^1.1.0",
29
+ "@radix-ui/react-label": "^2.1.0",
30
+ "@radix-ui/react-radio-group": "^1.2.0",
31
+ "@radix-ui/react-select": "^2.1.0",
32
+ "@radix-ui/react-slot": "^1.1.0",
33
+ "@radix-ui/react-tabs": "^1.1.0",
34
+ "class-variance-authority": "^0.7.0",
35
+ "clsx": "^2.1.0",
36
+ "tailwind-merge": "^2.5.0",
37
+ "zustand": "^5.0.2",
38
+ "zod": "^3.23.8",
39
+ "sonner": "^1.7.1",
40
+ "next-themes": "^0.4.4"
41
+ },
42
+ "devDependencies": {
43
+ "@graphql-codegen/cli": "^5.0.3",
44
+ "@graphql-codegen/typescript": "^4.1.2",
45
+ "@graphql-codegen/typescript-operations": "^4.4.2",
46
+ "@graphql-codegen/typed-document-node": "^5.0.12",
47
+ "@next/env": "^15.1.9",
48
+ "@opennextjs/cloudflare": "^1.0.0",
49
+ "@types/js-cookie": "^3.0.6",
50
+ "@types/node": "latest",
51
+ "@types/react": "latest",
52
+ "@types/react-dom": "latest",
53
+ "fast-check": "^3.15.0",
54
+ "typescript": "latest",
55
+ "@tailwindcss/postcss": "latest",
56
+ "tailwindcss": "latest",
57
+ "eslint": "latest",
58
+ "eslint-config-next": "^15.1.9"
59
+ }
60
+ }
@@ -0,0 +1,46 @@
1
+ {
2
+ "name": "{{PROJECT_NAME}}",
3
+ "version": "0.1.0",
4
+ "private": true,
5
+ "scripts": {
6
+ "dev": "next dev",
7
+ "build": "next build",
8
+ "start": "next start",
9
+ "lint": "next lint",
10
+ "codegen": "graphql-codegen --config codegen.ts",
11
+ "codegen:watch": "graphql-codegen --config codegen.ts --watch"
12
+ },
13
+ "dependencies": {
14
+ "@doswiftly/storefront-operations": "{{STOREFRONT_OPS_VERSION}}",
15
+ "@graphql-typed-document-node/core": "^3.2.0",
16
+ "@tanstack/react-query": "^5.62.0",
17
+ "graphql-request": "^7.1.2",
18
+ "graphql": "^16.10.0",
19
+ "graphql-tag": "^2.12.6",
20
+ "next": "latest",
21
+ "react": "^19",
22
+ "react-dom": "^19",
23
+ "lucide-react": "latest",
24
+ "@radix-ui/react-slot": "^1.1.0",
25
+ "class-variance-authority": "^0.7.0",
26
+ "clsx": "^2.1.0",
27
+ "tailwind-merge": "^2.5.0",
28
+ "zustand": "^5.0.2",
29
+ "zod": "^3.23.8"
30
+ },
31
+ "devDependencies": {
32
+ "@graphql-codegen/cli": "^5.0.3",
33
+ "@graphql-codegen/typescript": "^4.1.2",
34
+ "@graphql-codegen/typescript-operations": "^4.4.2",
35
+ "@graphql-codegen/typed-document-node": "^5.0.12",
36
+ "@next/env": "latest",
37
+ "@types/node": "latest",
38
+ "@types/react": "latest",
39
+ "@types/react-dom": "latest",
40
+ "typescript": "latest",
41
+ "@tailwindcss/postcss": "latest",
42
+ "tailwindcss": "latest",
43
+ "eslint": "latest",
44
+ "eslint-config-next": "latest"
45
+ }
46
+ }
@@ -0,0 +1,8 @@
1
+ /** @type {import('postcss-load-config').Config} */
2
+ const config = {
3
+ plugins: {
4
+ "@tailwindcss/postcss": {},
5
+ },
6
+ };
7
+
8
+ export default config;
@@ -0,0 +1,80 @@
1
+ import { NextResponse } from "next/server";
2
+ import type { NextRequest } from "next/server";
3
+ import {
4
+ protectedRoutes,
5
+ guestOnlyRoutes,
6
+ AUTH_COOKIE_NAME,
7
+ redirects,
8
+ matchesRoute,
9
+ } from "@/lib/auth/routes";
10
+
11
+ /**
12
+ * Authentication Proxy Function (Next.js 15+)
13
+ *
14
+ * Security Model (3 layers):
15
+ * 1. Proxy function (this file) - Fast redirect based on cookie existence (UX layer)
16
+ * 2. AuthGuard component - Client-side validation via useAuth hook
17
+ * 3. GraphQL Backend - Ultimate security (validates token on every request)
18
+ *
19
+ * IMPORTANT: This proxy checks cookie EXISTENCE, not VALIDITY.
20
+ * Token validation happens in:
21
+ * - AuthGuard (client-side via useAuth hook)
22
+ * - GraphQL API (server-side, ultimate security)
23
+ *
24
+ * Why this approach?
25
+ * - Proxy runs on Edge Runtime (fast, but limited capabilities)
26
+ * - Cannot make GraphQL requests to validate token
27
+ * - Provides instant redirect without waiting for client hydration
28
+ * - Prevents flash of protected content for unauthenticated users
29
+ *
30
+ * @see lib/auth/routes.ts - SSOT for route configuration
31
+ * @see components/auth/auth-guard.tsx - Client-side auth protection
32
+ */
33
+ export function proxy(request: NextRequest) {
34
+ const { pathname } = request.nextUrl;
35
+ const token = request.cookies.get(AUTH_COOKIE_NAME)?.value;
36
+ const hasToken = Boolean(token);
37
+
38
+ // Protected routes - redirect to login if no token
39
+ if (matchesRoute(pathname, protectedRoutes)) {
40
+ if (!hasToken) {
41
+ const loginUrl = new URL(redirects.unauthenticated, request.url);
42
+ // Preserve the original URL for redirect after login
43
+ loginUrl.searchParams.set("redirect", pathname);
44
+ return NextResponse.redirect(loginUrl);
45
+ }
46
+ }
47
+
48
+ // Guest-only routes - redirect to account if has token
49
+ if (matchesRoute(pathname, guestOnlyRoutes)) {
50
+ if (hasToken) {
51
+ return NextResponse.redirect(
52
+ new URL(redirects.authenticated, request.url)
53
+ );
54
+ }
55
+ }
56
+
57
+ return NextResponse.next();
58
+ }
59
+
60
+ /**
61
+ * Matcher configuration
62
+ *
63
+ * Only run proxy on routes that need auth checks.
64
+ * This improves performance by skipping static assets, API routes, etc.
65
+ *
66
+ * Update this when adding new protected or guest-only route groups.
67
+ */
68
+ export const config = {
69
+ matcher: [
70
+ /*
71
+ * Match all request paths except:
72
+ * - _next/static (static files)
73
+ * - _next/image (image optimization files)
74
+ * - favicon.ico (favicon file)
75
+ * - public folder files (images, etc.)
76
+ * - API routes (handled separately)
77
+ */
78
+ "/((?!_next/static|_next/image|favicon.ico|.*\\.(?:svg|png|jpg|jpeg|gif|webp)$).*)",
79
+ ],
80
+ };
@@ -0,0 +1,8 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 32" fill="none">
2
+ <rect width="48" height="32" rx="4" fill="#000"/>
3
+ <path d="M14.5 11.5c.5-.7.9-1.6.8-2.5-.8 0-1.8.5-2.3 1.2-.5.6-.9 1.5-.8 2.4.9.1 1.8-.4 2.3-1.1z" fill="#fff"/>
4
+ <path d="M15.3 12.8c-1.3-.1-2.4.7-3 .7-.6 0-1.6-.7-2.6-.7-1.3 0-2.6.8-3.3 2-.7 1.2-.9 3.2.1 5 .5.9 1.1 1.8 1.9 1.8s1.2-.5 2.3-.5c1.1 0 1.4.5 2.4.5s1.4-.9 1.9-1.8c.3-.5.5-.9.6-1.2-1.4-.5-2-2.2-1.4-3.5.3-.7.8-1.2 1.4-1.5-.5-.8-1.3-1.3-2.3-1.3v.5z" fill="#fff"/>
5
+ <path d="M22 21.5V11h2.9c2 0 3.4 1.4 3.4 3.4s-1.4 3.4-3.4 3.4h-1.5v3.7H22zm1.4-4.9h1.2c1.4 0 2.1-.7 2.1-2s-.7-2-2.1-2h-1.2v4z" fill="#fff"/>
6
+ <path d="M29 18.3c0-2 1.3-3.2 3.2-3.2 2 0 3.2 1.2 3.2 3.2v.3h-5.1c.1 1.2.8 1.9 2 1.9.8 0 1.4-.3 1.6-.9h1.4c-.2 1.2-1.4 2-3 2-2 0-3.3-1.3-3.3-3.3zm1.3-.4h3.8c-.1-1.1-.8-1.8-1.9-1.8s-1.8.7-1.9 1.8z" fill="#fff"/>
7
+ <path d="M36.5 24v-1.2c.1 0 .3.1.5.1.6 0 1-.3 1.2-.9l.1-.4-2.6-6.4h1.5l1.9 5.2 1.9-5.2H42l-2.7 6.9c-.6 1.5-1.3 2-2.5 2-.1 0-.2 0-.3-.1z" fill="#fff"/>
8
+ </svg>