@doswiftly/cli 0.1.17 → 0.1.19

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 (213) hide show
  1. package/README.md +23 -323
  2. package/dist/commands/check.js +1 -1
  3. package/dist/commands/check.js.map +1 -1
  4. package/dist/commands/deploy.d.ts.map +1 -1
  5. package/dist/commands/deploy.js +43 -20
  6. package/dist/commands/deploy.js.map +1 -1
  7. package/dist/commands/doctor.js +3 -3
  8. package/dist/commands/doctor.js.map +1 -1
  9. package/dist/commands/init.js +4 -4
  10. package/dist/commands/sdk.js +5 -5
  11. package/dist/commands/sdk.js.map +1 -1
  12. package/dist/commands/template.js +4 -4
  13. package/dist/commands/template.js.map +1 -1
  14. package/dist/commands/types.js +5 -5
  15. package/dist/commands/types.js.map +1 -1
  16. package/dist/commands/verify.js +2 -2
  17. package/dist/commands/verify.js.map +1 -1
  18. package/dist/lib/package-manager.d.ts +1 -1
  19. package/dist/lib/package-manager.js +1 -1
  20. package/package.json +1 -1
  21. package/templates/storefront-minimal/wrangler.toml +4 -0
  22. package/templates/storefront-nextjs/README.md +16 -12
  23. package/templates/storefront-nextjs/app/account/orders/page.tsx +2 -2
  24. package/templates/storefront-nextjs/app/account/page.tsx +2 -2
  25. package/templates/storefront-nextjs/app/auth/login/page.tsx +1 -1
  26. package/templates/storefront-nextjs/app/auth/register/page.tsx +1 -1
  27. package/templates/storefront-nextjs/app/cart/page.tsx +1 -1
  28. package/templates/storefront-nextjs/app/categories/[slug]/page.tsx +2 -2
  29. package/templates/storefront-nextjs/app/categories/page.tsx +1 -1
  30. package/templates/storefront-nextjs/app/collections/[slug]/page.tsx +1 -1
  31. package/templates/storefront-nextjs/app/collections/page.tsx +1 -1
  32. package/templates/storefront-nextjs/app/page.tsx +1 -1
  33. package/templates/storefront-nextjs/app/products/[slug]/page.tsx +1 -1
  34. package/templates/storefront-nextjs/app/products/page.tsx +2 -2
  35. package/templates/storefront-nextjs/app/search/page.tsx +1 -1
  36. package/templates/storefront-nextjs/components/auth/auth-guard.tsx +1 -1
  37. package/templates/storefront-nextjs/components/commerce/add-to-cart-button.tsx +1 -1
  38. package/templates/storefront-nextjs/components/commerce/cart-icon.tsx +1 -1
  39. package/templates/storefront-nextjs/components/commerce/currency-selector.tsx +2 -2
  40. package/templates/storefront-nextjs/components/commerce/product-filters.tsx +1 -1
  41. package/templates/storefront-nextjs/components/commerce/product-price.tsx +1 -1
  42. package/templates/storefront-nextjs/components/commerce/search-input.tsx +1 -1
  43. package/templates/storefront-nextjs/components/commerce/sort-select.tsx +1 -1
  44. package/templates/storefront-nextjs/components/providers.tsx +1 -1
  45. package/templates/storefront-nextjs/lib/currency.tsx +3 -3
  46. package/templates/storefront-nextjs/lib/format.ts +1 -1
  47. package/templates/storefront-nextjs/lib/graphql-queries.ts +3 -3
  48. package/templates/storefront-nextjs/package.dev.json +1 -1
  49. package/templates/storefront-nextjs/package.json +1 -1
  50. package/templates/storefront-nextjs/package.json.template +1 -1
  51. package/templates/storefront-nextjs/wrangler.toml +4 -0
  52. package/templates/storefront-nextjs-shadcn/.github/workflows/deploy.yml +47 -0
  53. package/templates/storefront-nextjs-shadcn/.github/workflows/preview.yml +47 -0
  54. package/templates/storefront-nextjs-shadcn/CLAUDE.md +148 -35
  55. package/templates/storefront-nextjs-shadcn/README.md +29 -162
  56. package/templates/storefront-nextjs-shadcn/app/account/addresses/page.tsx +98 -91
  57. package/templates/storefront-nextjs-shadcn/app/account/error.tsx +43 -0
  58. package/templates/storefront-nextjs-shadcn/app/account/loading.tsx +19 -0
  59. package/templates/storefront-nextjs-shadcn/app/account/loyalty/page.tsx +53 -162
  60. package/templates/storefront-nextjs-shadcn/app/account/orders/[id]/loading.tsx +60 -0
  61. package/templates/storefront-nextjs-shadcn/app/account/orders/[id]/page.tsx +36 -47
  62. package/templates/storefront-nextjs-shadcn/app/account/orders/page.tsx +46 -29
  63. package/templates/storefront-nextjs-shadcn/app/account/page.tsx +8 -5
  64. package/templates/storefront-nextjs-shadcn/app/account/settings/page.tsx +108 -71
  65. package/templates/storefront-nextjs-shadcn/app/api/auth/clear-token/route.ts +2 -86
  66. package/templates/storefront-nextjs-shadcn/app/api/auth/set-token/route.ts +2 -124
  67. package/templates/storefront-nextjs-shadcn/app/auth/forgot-password/page.tsx +10 -5
  68. package/templates/storefront-nextjs-shadcn/app/blog/[slug]/loading.tsx +17 -0
  69. package/templates/storefront-nextjs-shadcn/app/blog/[slug]/page.tsx +43 -2
  70. package/templates/storefront-nextjs-shadcn/app/blog/loading.tsx +19 -0
  71. package/templates/storefront-nextjs-shadcn/app/brands/page.tsx +2 -1
  72. package/templates/storefront-nextjs-shadcn/app/cart/loading.tsx +26 -0
  73. package/templates/storefront-nextjs-shadcn/app/cart/page.tsx +6 -3
  74. package/templates/storefront-nextjs-shadcn/app/categories/[slug]/category-products-client.tsx +56 -0
  75. package/templates/storefront-nextjs-shadcn/app/categories/[slug]/loading.tsx +32 -0
  76. package/templates/storefront-nextjs-shadcn/app/categories/[slug]/page.tsx +76 -59
  77. package/templates/storefront-nextjs-shadcn/app/categories/page.tsx +8 -4
  78. package/templates/storefront-nextjs-shadcn/app/checkout/error.tsx +43 -0
  79. package/templates/storefront-nextjs-shadcn/app/checkout/loading.tsx +31 -0
  80. package/templates/storefront-nextjs-shadcn/app/checkout/page.tsx +116 -79
  81. package/templates/storefront-nextjs-shadcn/app/collections/[handle]/loading.tsx +19 -0
  82. package/templates/storefront-nextjs-shadcn/app/collections/[handle]/page.tsx +1 -1
  83. package/templates/storefront-nextjs-shadcn/app/collections/loading.tsx +18 -0
  84. package/templates/storefront-nextjs-shadcn/app/collections/page.tsx +7 -4
  85. package/templates/storefront-nextjs-shadcn/app/global-error.tsx +117 -0
  86. package/templates/storefront-nextjs-shadcn/app/globals.css +8 -0
  87. package/templates/storefront-nextjs-shadcn/app/layout.tsx +46 -11
  88. package/templates/storefront-nextjs-shadcn/app/products/[slug]/error.tsx +43 -0
  89. package/templates/storefront-nextjs-shadcn/app/products/[slug]/loading.tsx +29 -0
  90. package/templates/storefront-nextjs-shadcn/app/products/[slug]/page.tsx +6 -6
  91. package/templates/storefront-nextjs-shadcn/app/products/[slug]/product-client.tsx +15 -61
  92. package/templates/storefront-nextjs-shadcn/app/products/loading.tsx +32 -0
  93. package/templates/storefront-nextjs-shadcn/app/products/products-client.tsx +405 -151
  94. package/templates/storefront-nextjs-shadcn/app/search/loading.tsx +18 -0
  95. package/templates/storefront-nextjs-shadcn/app/wishlist/page.tsx +8 -5
  96. package/templates/storefront-nextjs-shadcn/codegen.ts +48 -31
  97. package/templates/storefront-nextjs-shadcn/components/account/customer-info.fragment.graphql +36 -0
  98. package/templates/storefront-nextjs-shadcn/components/account/order-details.tsx +3 -1
  99. package/templates/storefront-nextjs-shadcn/components/account/order-history.tsx +26 -24
  100. package/templates/storefront-nextjs-shadcn/components/account/order-summary.fragment.graphql +36 -0
  101. package/templates/storefront-nextjs-shadcn/components/auth/account-menu.tsx +9 -9
  102. package/templates/storefront-nextjs-shadcn/components/auth/login-form.tsx +11 -37
  103. package/templates/storefront-nextjs-shadcn/components/auth/register-form.tsx +37 -23
  104. package/templates/storefront-nextjs-shadcn/components/cart/cart-drawer.tsx +4 -3
  105. package/templates/storefront-nextjs-shadcn/components/cart/cart-icon.tsx +8 -5
  106. package/templates/storefront-nextjs-shadcn/components/cart/cart-item.tsx +1 -1
  107. package/templates/storefront-nextjs-shadcn/components/cart/cart-line.fragment.graphql +53 -0
  108. package/templates/storefront-nextjs-shadcn/components/cart/cart-summary.tsx +1 -1
  109. package/templates/storefront-nextjs-shadcn/components/cart/shipping-estimator.tsx +22 -7
  110. package/templates/storefront-nextjs-shadcn/components/commerce/currency-selector.tsx +2 -2
  111. package/templates/storefront-nextjs-shadcn/components/commerce/product-actions.tsx +1 -1
  112. package/templates/storefront-nextjs-shadcn/components/commerce/search-input.tsx +2 -2
  113. package/templates/storefront-nextjs-shadcn/components/common/price-display.tsx +35 -11
  114. package/templates/storefront-nextjs-shadcn/components/discount/discount-breakdown.tsx +1 -1
  115. package/templates/storefront-nextjs-shadcn/components/discount/discount-code-input.tsx +3 -3
  116. package/templates/storefront-nextjs-shadcn/components/filters/range-slider-filter.tsx +5 -5
  117. package/templates/storefront-nextjs-shadcn/components/gift-card/gift-card-input.tsx +2 -2
  118. package/templates/storefront-nextjs-shadcn/components/home/category-grid.tsx +2 -1
  119. package/templates/storefront-nextjs-shadcn/components/home/collection-card.fragment.graphql +21 -0
  120. package/templates/storefront-nextjs-shadcn/components/home/featured-collections.tsx +2 -12
  121. package/templates/storefront-nextjs-shadcn/components/home/index.ts +0 -1
  122. package/templates/storefront-nextjs-shadcn/components/hydrated.tsx +24 -0
  123. package/templates/storefront-nextjs-shadcn/components/layout/breadcrumbs.tsx +4 -4
  124. package/templates/storefront-nextjs-shadcn/components/layout/category-node.fragment.graphql +22 -0
  125. package/templates/storefront-nextjs-shadcn/components/layout/currency-selector.tsx +2 -2
  126. package/templates/storefront-nextjs-shadcn/components/layout/header.tsx +33 -23
  127. package/templates/storefront-nextjs-shadcn/components/loyalty/points-balance.tsx +2 -11
  128. package/templates/storefront-nextjs-shadcn/components/loyalty/points-history.tsx +8 -25
  129. package/templates/storefront-nextjs-shadcn/components/loyalty/referral-section.tsx +10 -19
  130. package/templates/storefront-nextjs-shadcn/components/loyalty/rewards-catalog.tsx +17 -41
  131. package/templates/storefront-nextjs-shadcn/components/loyalty/tier-progress.tsx +2 -29
  132. package/templates/storefront-nextjs-shadcn/components/order/index.ts +6 -1
  133. package/templates/storefront-nextjs-shadcn/components/product/b2b-price-display.tsx +3 -1
  134. package/templates/storefront-nextjs-shadcn/components/product/filter-active-pills.tsx +69 -0
  135. package/templates/storefront-nextjs-shadcn/components/product/filter-mobile-sheet.tsx +84 -0
  136. package/templates/storefront-nextjs-shadcn/components/product/filter-price-range.tsx +138 -0
  137. package/templates/storefront-nextjs-shadcn/components/product/index.ts +9 -2
  138. package/templates/storefront-nextjs-shadcn/components/product/product-card.fragment.graphql +49 -0
  139. package/templates/storefront-nextjs-shadcn/components/product/product-card.tsx +3 -31
  140. package/templates/storefront-nextjs-shadcn/components/product/product-detail.fragment.graphql +52 -0
  141. package/templates/storefront-nextjs-shadcn/components/product/product-filters.tsx +176 -123
  142. package/templates/storefront-nextjs-shadcn/components/product/product-grid.tsx +3 -5
  143. package/templates/storefront-nextjs-shadcn/components/product/product-image.tsx +2 -2
  144. package/templates/storefront-nextjs-shadcn/components/product/product-price.tsx +2 -2
  145. package/templates/storefront-nextjs-shadcn/components/product/product-reviews.tsx +5 -4
  146. package/templates/storefront-nextjs-shadcn/components/product/product-sort.tsx +19 -7
  147. package/templates/storefront-nextjs-shadcn/components/product/product-variant-selector.tsx +8 -23
  148. package/templates/storefront-nextjs-shadcn/components/product/product-variant.fragment.graphql +51 -0
  149. package/templates/storefront-nextjs-shadcn/components/product/review-card.tsx +1 -1
  150. package/templates/storefront-nextjs-shadcn/components/product/review-form.tsx +1 -7
  151. package/templates/storefront-nextjs-shadcn/components/product/savings-display.tsx +17 -2
  152. package/templates/storefront-nextjs-shadcn/components/product/similar-products.tsx +3 -2
  153. package/templates/storefront-nextjs-shadcn/components/providers/index.ts +1 -1
  154. package/templates/storefront-nextjs-shadcn/components/providers/stores-provider.tsx +30 -0
  155. package/templates/storefront-nextjs-shadcn/components/providers/theme-provider.tsx +1 -1
  156. package/templates/storefront-nextjs-shadcn/components/returns/index.ts +2 -2
  157. package/templates/storefront-nextjs-shadcn/components/returns/return-request-form.tsx +3 -2
  158. package/templates/storefront-nextjs-shadcn/components/search/search-results.tsx +3 -2
  159. package/templates/storefront-nextjs-shadcn/components/ui/form.tsx +174 -0
  160. package/templates/storefront-nextjs-shadcn/components/ui/index.ts +30 -2
  161. package/templates/storefront-nextjs-shadcn/components/ui/progress.tsx +40 -0
  162. package/templates/storefront-nextjs-shadcn/components/ui/sheet.tsx +107 -0
  163. package/templates/storefront-nextjs-shadcn/components/ui/slider.tsx +33 -0
  164. package/templates/storefront-nextjs-shadcn/components/ui/textarea.tsx +24 -0
  165. package/templates/storefront-nextjs-shadcn/components/wishlist/wishlist-icon.tsx +3 -1
  166. package/templates/storefront-nextjs-shadcn/generated/graphql.ts +12779 -0
  167. package/templates/storefront-nextjs-shadcn/graphql/custom.example.graphql +159 -0
  168. package/templates/storefront-nextjs-shadcn/hooks/index.ts +2 -0
  169. package/templates/storefront-nextjs-shadcn/hooks/use-auth-sync.ts +42 -0
  170. package/templates/storefront-nextjs-shadcn/hooks/use-auth.ts +17 -295
  171. package/templates/storefront-nextjs-shadcn/hooks/use-cart-actions.ts +51 -19
  172. package/templates/storefront-nextjs-shadcn/hooks/use-cart-sync.ts +13 -9
  173. package/templates/storefront-nextjs-shadcn/lib/auth/routes.ts +4 -17
  174. package/templates/storefront-nextjs-shadcn/lib/graphql/client.ts +22 -99
  175. package/templates/storefront-nextjs-shadcn/lib/graphql/config.ts +32 -0
  176. package/templates/storefront-nextjs-shadcn/lib/graphql/fragments.ts +34 -0
  177. package/templates/storefront-nextjs-shadcn/lib/graphql/hooks.ts +687 -632
  178. package/templates/storefront-nextjs-shadcn/lib/graphql/query-keys.ts +86 -0
  179. package/templates/storefront-nextjs-shadcn/lib/graphql/server.ts +131 -182
  180. package/templates/storefront-nextjs-shadcn/lib/graphql/types.ts +62 -0
  181. package/templates/storefront-nextjs-shadcn/lib/theme/theme-config.ts +0 -17
  182. package/templates/storefront-nextjs-shadcn/next-env.d.ts +6 -0
  183. package/templates/storefront-nextjs-shadcn/package.dev.json +1 -3
  184. package/templates/storefront-nextjs-shadcn/package.json +12 -13
  185. package/templates/storefront-nextjs-shadcn/package.json.template +6 -7
  186. package/templates/storefront-nextjs-shadcn/proxy.ts +3 -4
  187. package/templates/storefront-nextjs-shadcn/stores/cart-store.ts +41 -39
  188. package/templates/storefront-nextjs-shadcn/stores/checkout-store.ts +64 -75
  189. package/templates/storefront-nextjs-shadcn/stores/wishlist-store.ts +178 -177
  190. package/templates/storefront-nextjs-shadcn/tsconfig.json +23 -5
  191. package/templates/storefront-nextjs-shadcn/wrangler.toml +4 -0
  192. package/templates/storefront-nextjs-shadcn/CART_INTEGRATION.md +0 -282
  193. package/templates/storefront-nextjs-shadcn/GRAPHQL_DOCUMENT_NAMES.md +0 -190
  194. package/templates/storefront-nextjs-shadcn/GRAPHQL_ERROR_HANDLING.md +0 -263
  195. package/templates/storefront-nextjs-shadcn/GRAPHQL_FIXES_SUMMARY.md +0 -135
  196. package/templates/storefront-nextjs-shadcn/GRAPHQL_INTEGRATION_COMPLETE.md +0 -142
  197. package/templates/storefront-nextjs-shadcn/INTEGRATION_CHECKLIST.md +0 -448
  198. package/templates/storefront-nextjs-shadcn/PRODUCT_DETAIL_PAGE_IMPLEMENTATION.md +0 -307
  199. package/templates/storefront-nextjs-shadcn/THEME_CUSTOMIZATION.md +0 -245
  200. package/templates/storefront-nextjs-shadcn/components/providers/currency-provider.tsx +0 -103
  201. package/templates/storefront-nextjs-shadcn/graphql/collections.example.ts +0 -168
  202. package/templates/storefront-nextjs-shadcn/graphql/products.example.ts +0 -160
  203. package/templates/storefront-nextjs-shadcn/lib/auth/cookies.ts +0 -220
  204. package/templates/storefront-nextjs-shadcn/lib/config.ts +0 -46
  205. package/templates/storefront-nextjs-shadcn/lib/currency/IMPLEMENTATION_SUMMARY.md +0 -254
  206. package/templates/storefront-nextjs-shadcn/lib/currency/README.md +0 -464
  207. package/templates/storefront-nextjs-shadcn/lib/currency/cookie-manager.test.ts +0 -328
  208. package/templates/storefront-nextjs-shadcn/lib/currency/cookie-manager.ts +0 -295
  209. package/templates/storefront-nextjs-shadcn/lib/currency/index.ts +0 -27
  210. package/templates/storefront-nextjs-shadcn/lib/format.ts +0 -226
  211. package/templates/storefront-nextjs-shadcn/lib/hooks.ts +0 -30
  212. package/templates/storefront-nextjs-shadcn/stores/auth-store.ts +0 -66
  213. package/templates/storefront-nextjs-shadcn/stores/currency-store.ts +0 -103
@@ -0,0 +1,47 @@
1
+ name: Preview Deployment
2
+
3
+ on:
4
+ pull_request:
5
+ types: [opened, synchronize]
6
+
7
+ jobs:
8
+ preview:
9
+ runs-on: ubuntu-latest
10
+ env:
11
+ NEXT_PUBLIC_API_URL: ${{ secrets.NEXT_PUBLIC_API_URL }}
12
+ NEXT_PUBLIC_SHOP_SLUG: ${{ secrets.NEXT_PUBLIC_SHOP_SLUG }}
13
+ steps:
14
+ - uses: actions/checkout@v4
15
+
16
+ - name: Detect package manager
17
+ id: pm
18
+ run: |
19
+ if [ -f pnpm-lock.yaml ]; then
20
+ echo "manager=pnpm" >> $GITHUB_OUTPUT
21
+ echo "install=pnpm install --frozen-lockfile" >> $GITHUB_OUTPUT
22
+ elif [ -f yarn.lock ]; then
23
+ echo "manager=yarn" >> $GITHUB_OUTPUT
24
+ echo "install=yarn install --frozen-lockfile" >> $GITHUB_OUTPUT
25
+ else
26
+ echo "manager=npm" >> $GITHUB_OUTPUT
27
+ echo "install=npm ci" >> $GITHUB_OUTPUT
28
+ fi
29
+
30
+ - name: Setup pnpm
31
+ if: steps.pm.outputs.manager == 'pnpm'
32
+ uses: pnpm/action-setup@v4
33
+
34
+ - uses: actions/setup-node@v4
35
+ with:
36
+ node-version: 20
37
+ cache: ${{ steps.pm.outputs.manager }}
38
+
39
+ - name: Install dependencies
40
+ run: ${{ steps.pm.outputs.install }}
41
+
42
+ - name: Deploy preview
43
+ run: |
44
+ npx --yes @doswiftly/cli@latest --version
45
+ npx @doswiftly/cli@latest deploy run --type PREVIEW --branch ${{ github.head_ref }}
46
+ env:
47
+ DOSWIFTLY_DEPLOY_TOKEN: ${{ secrets.DOSWIFTLY_DEPLOY_TOKEN }}
@@ -6,39 +6,87 @@ Ten plik jest synchronizowany do `storefronts/test-shop/` przez `pnpm sync:store
6
6
 
7
7
  ```
8
8
  app/ # Next.js 15 App Router
9
- ├── layout.tsx # Root layout z providers
9
+ ├── layout.tsx # Root layout z StorefrontProvider + QueryProvider
10
10
  ├── page.tsx # Homepage
11
- ├── products/ # Strony produktow
11
+ ├── products/ # Strony produktow (SSR + client hydration)
12
12
  ├── collections/ # Strony kolekcji
13
- ├── cart/ # Koszyk
14
- ├── checkout/ # Checkout
15
- ├── account/ # Panel klienta
16
- └── auth/ # Login/Register
13
+ ├── categories/ # Strony kategorii (SSR metadata + client products)
14
+ ├── cart/ # Koszyk (client-only, Zustand + React Query)
15
+ ├── checkout/ # Checkout (client-only, multi-step mutations)
16
+ ├── account/ # Panel klienta (auth required)
17
+ ├── auth/ # Login/Register
18
+ └── blog/ # Blog (SSR)
17
19
 
18
20
  components/
19
21
  ├── product/ # ProductCard, ProductGrid, AddToCartButton
22
+ │ ├── product-card.fragment.graphql # Colocated fragment
23
+ │ ├── product-detail.fragment.graphql
24
+ │ └── product-variant.fragment.graphql
20
25
  ├── cart/ # CartDrawer, CartItem, CartSummary
21
- ├── auth/ # LoginForm, RegisterForm
26
+ │ └── cart-line.fragment.graphql
27
+ ├── home/ # FeaturedCollections, Hero
28
+ │ └── collection-card.fragment.graphql
29
+ ├── account/ # OrderCard, CustomerInfo
30
+ │ ├── order-summary.fragment.graphql
31
+ │ └── customer-info.fragment.graphql
22
32
  ├── layout/ # Header, Footer, Navigation
33
+ │ └── category-node.fragment.graphql
34
+ ├── auth/ # LoginForm, RegisterForm
23
35
  ├── ui/ # shadcn/ui components
24
- └── providers/ # QueryProvider, CurrencyProvider, ThemeProvider
36
+ └── providers/ # QueryProvider, ThemeProvider
25
37
 
26
38
  lib/
27
39
  ├── graphql/
28
- │ ├── server.ts # SSR helpers z React cache()
29
- │ ├── client.ts # Client-side GraphQL client
30
- └── hooks.ts # React Query hooks
31
- └── currency/ # Currency management
32
-
33
- stores/ # Zustand stores
34
- ├── cart-store.ts # Koszyk (persist localStorage)
35
- ├── currency-store.ts # Waluta (persist cookies)
36
- └── auth-store.ts # Autentykacja
40
+ │ ├── config.ts # Centralized API config (SSOT for apiUrl, shopSlug)
41
+ │ ├── query-keys.ts # Centralized React Query keys
42
+ ├── client.ts # useExecute() hook — uses SDK StorefrontClient from Context
43
+ │ ├── server.ts # SSR helpers z React.cache()
44
+ │ ├── hooks.ts # React Query hooks (useProducts, useCart, etc.)
45
+ │ ├── types.ts # Domain types derived from codegen (query result shapes)
46
+ │ └── fragments.ts # Fragment type re-exports (component data contracts)
47
+ ├── auth/
48
+ └── routes.ts # Route lists + re-exports AUTH_COOKIE_NAME/matchesRoute from SDK
49
+ └── theme/
50
+ └── theme-config.ts # Theme tokens (colors, storage key)
51
+
52
+ graphql/
53
+ └── custom.example.graphql # Example custom operations
54
+
55
+ stores/ # Zustand stores (Context pattern via SDK createStoreContext)
56
+ ├── cart-store.ts # Cart UI state (cartId, isOpen) — items from server
57
+ ├── checkout-store.ts # Checkout form state with persistence
58
+ └── wishlist-store.ts # Wishlist state with persistence
59
+
60
+ hooks/
61
+ ├── use-auth.ts # Thin wrapper over SDK useAuth + httpOnly cookies
62
+ ├── use-auth-sync.ts # Detects auth desync (cookie vs store)
63
+ ├── use-cart-actions.ts # Cart mutations with debounce + race condition protection
64
+ ├── use-cart-sync.ts # Cart data from server (maps GraphQL → CartItemData)
65
+ └── use-filter-params.ts # URL-driven filter state
37
66
 
38
67
  generated/
39
- └── graphql.ts # Auto-generowane typy
68
+ └── graphql.ts # Auto-generated types + TypedDocumentString constants
40
69
  ```
41
70
 
71
+ ## SDK Integration
72
+
73
+ Template importuje z `@doswiftly/storefront-sdk`:
74
+ - **Core (`.`)**: `AUTH_COOKIE_NAME`, `matchesRoute`, `createSetTokenHandler`, `createClearTokenHandler`, `createAuthTokenClient`, `formatPrice`, `formatAmount`, `sanitizeHtml`, `normalizeConnection`
75
+ - **React (`./react`)**: `StorefrontProvider`, `useAuthStore`, `useCurrencyStore`, `useAuthHydrated`, `useStorefrontClient`, `useHydrated`, `useDebouncedValue`, `createStoreContext`
76
+ - **Server (`./react/server`)**: `getStorefrontClient`, `getCurrencyFromCookieAsync`
77
+ - **Auth hooks**: `useAuth` (bazowy, owinięty w `hooks/use-auth.ts`)
78
+
79
+ **Store pattern**: Zustand stores używają `createStore()` (vanilla) + React Context via `createStoreContext()` from SDK.
80
+ Hooki `useAuthStore`/`useCurrencyStore` wymagają owinięcia w `StorefrontProvider`.
81
+ Template stores (cart, checkout, wishlist) wymagają `StoresProvider` (wewnątrz `StorefrontProvider`).
82
+ `useAuthHydrated()` zwraca `true` po rehydracji persist z localStorage.
83
+ `useHydrated()` zwraca `true` po hydration SSR → client.
84
+
85
+ Template NIE importuje z SDK:
86
+ - React Query hooks — są LOCAL w `lib/graphql/hooks.ts`
87
+ - Cart actions — LOCAL w `hooks/use-cart-actions.ts`
88
+ - Data types — LOCAL via codegen (`generated/graphql.ts`)
89
+
42
90
  ## Data Fetching
43
91
 
44
92
  ### Server Components (lib/graphql/server.ts):
@@ -59,38 +107,103 @@ const { data, isLoading } = useProducts({ first: 20 });
59
107
  const addLines = useCartLinesAdd();
60
108
  ```
61
109
 
62
- ## Zustand Stores
110
+ ### SSR → Client Hydration Pattern:
111
+ ```typescript
112
+ // Server Component (page.tsx)
113
+ const { product } = await fetchProduct(slug);
114
+ return <ProductClient product={product} />;
115
+
116
+ // Client Component (product-client.tsx)
117
+ const { data } = useProduct(handle, {
118
+ placeholderData: currencyMatches ? { product: initialProduct } : undefined,
119
+ });
120
+ // placeholderData shows SSR data while React Query refetches with correct currency
121
+ ```
122
+
123
+ ## Fragment-First Architecture (Colocated Fragments)
124
+
125
+ Fragments are **colocated** next to their components (Hydrogen/Relay pattern):
126
+
127
+ ```
128
+ components/product/product-card.fragment.graphql → ProductCardFieldsFragment
129
+ components/cart/cart-line.fragment.graphql → CartLineFieldsFragment
130
+ ```
131
+
132
+ Import fragment types via the stable API layer, not directly from codegen:
63
133
 
64
- ### Cart Store:
65
134
  ```typescript
66
- import { useCartStore } from '@/stores/cart-store';
135
+ // Component uses fragment type for props:
136
+ import type { ProductCardFields } from '@/lib/graphql/fragments';
67
137
 
68
- const { items, addItem, removeItem, getTotalItems, getTotalPrice } = useCartStore();
138
+ interface ProductCardProps {
139
+ product: ProductCardFields;
140
+ }
69
141
  ```
70
142
 
71
- ### Currency Store:
143
+ **Convention**: When a GraphQL fragment exists for data your component receives, use the fragment type — do NOT define a local interface.
144
+
145
+ Codegen picks up colocated fragments via `components/**/*.fragment.graphql` glob.
146
+ Run `pnpm codegen` after adding new `.fragment.graphql` files.
147
+
148
+ ## Why fragmentMasking is disabled
149
+
150
+ `codegen.ts` sets `fragmentMasking: false`. This means:
151
+ - Fragment types are plain TS types (structural typing, no `$fragmentName` branding)
152
+ - Components can accept both fragment types and supertypes from query results
153
+ - Does NOT require `useFragment()` helpers (Relay pattern)
154
+
155
+ Trade-off: a component could technically access fields outside its fragment.
156
+ We accept this intentionally — simplicity and DX > strict data masking.
157
+ If the project scales to multiple teams, consider `fragmentMasking: true`.
158
+
159
+ ## Query Keys
160
+
161
+ All React Query keys are centralized in `lib/graphql/query-keys.ts`:
162
+
72
163
  ```typescript
73
- import { useCurrencyStore } from '@/stores/currency-store';
164
+ import { queryKeys } from '@/lib/graphql/query-keys';
165
+
166
+ // Reading data:
167
+ useQuery({ queryKey: queryKeys.products.detail(slug, currency), ... });
74
168
 
75
- const { currency, setCurrency, supportedCurrencies } = useCurrencyStore();
169
+ // Invalidating:
170
+ queryClient.invalidateQueries({ queryKey: queryKeys.cart.all() });
76
171
  ```
77
172
 
173
+ ## Cart Race Condition Protection
174
+
175
+ Cart mutations use three layers of protection:
176
+ 1. **cancelQueries** — Cancel in-flight cart queries before mutation
177
+ 2. **Debounce** — 500ms debounce on quantity updates
178
+ 3. **onSettled invalidation** — Refetch cart after mutation success OR error
179
+
78
180
  ## Konwencje
79
181
 
80
182
  1. **Client vs Server**: Dodaj `"use client"` tylko gdy potrzebne (hooks, interaktywnosc)
81
- 2. **Typy**: Zawsze definiuj interfejsy dla props
82
- 3. **Styling**: Uzywaj `cn()` dla laczenia klas Tailwind
83
- 4. **Obrazki**: next/image z alt i priority dla LCP
84
- 5. **Formularze**: Zod dla walidacji
183
+ 2. **Fragment types**: Import z `@/lib/graphql/fragments`, NIE z `@/generated/graphql`
184
+ 3. **No local interfaces**: Gdy istnieje fragment type, uzywaj go zamiast local interface
185
+ 4. **Colocated fragments**: `.fragment.graphql` obok komponentu w `components/`
186
+ 5. **Styling**: Uzywaj `cn()` dla laczenia klas Tailwind
187
+ 6. **Obrazki**: next/image z alt i priority dla LCP
188
+ 7. **Formularze**: Zod + react-hook-form
189
+ 8. **Query keys**: Zawsze z `queryKeys.*` (nie hardcoded arrays)
190
+ 9. **Config**: Zawsze z `graphqlConfig` (nie duplikuj env var resolution)
85
191
 
86
192
  ## GraphQL Operations
87
193
 
88
- Operacje sa zdefiniowane w:
194
+ Operacje i schemat sa zdefiniowane w:
195
+ ```
196
+ packages/@doswiftly/storefront-operations/
197
+ ├── schema.graphql # Schemat GraphQL (zsynchronizowany z backendu)
198
+ ├── queries.graphql # Zapytania
199
+ ├── mutations.graphql # Mutacje
200
+ └── fragments.graphql # Fragmenty (backend SSOT)
201
+ ```
202
+
203
+ Colocated component fragments:
89
204
  ```
90
- packages/backend/src/commerce/storefront-graphql/operations/
91
- ├── queries.graphql
92
- ├── mutations.graphql
93
- └── fragments.graphql
205
+ components/**/*.fragment.graphql # UI component fragments (Hydrogen/Relay pattern)
94
206
  ```
95
207
 
96
- Aby poznac dostepne operacje, przeczytaj te pliki.
208
+ Codegen NIE wymaga uruchomionego backendu schemat pochodzi z pliku.
209
+ Aby poznac dostepne operacje, przeczytaj pliki `.graphql` w storefront-operations.
@@ -1,194 +1,61 @@
1
- # DoSwiftly Storefront - shadcn/ui Template
1
+ # DoSwiftly Storefront shadcn/ui Template
2
2
 
3
- This is a Next.js 15+ storefront template with shadcn/ui components, optimized for DoSwiftly Commerce.
3
+ Next.js 15+ storefront template with shadcn/ui, optimized for DoSwiftly Commerce.
4
4
 
5
- ## Features
5
+ ## Tech Stack
6
6
 
7
- - **Next.js 15+** with App Router
8
- - **shadcn/ui** components pre-configured
9
- - **Tailwind CSS v4** for styling
10
- - **TypeScript** for type safety
11
- - ✅ **GraphQL Codegen** for type-safe API calls
12
- - ✅ **React Query** for data fetching
13
- - ✅ **Zustand** for state management
14
- - ✅ **Currency conversion** with client-side switching
7
+ - **Next.js 15+** with App Router and React Server Components
8
+ - **shadcn/ui** + Tailwind CSS v4
9
+ - **@doswiftly/storefront-sdk** type-safe GraphQL hooks and Zustand stores
10
+ - **GraphQL Codegen** auto-generated types from backend schema
15
11
 
16
12
  ## Getting Started
17
13
 
18
- ### 1. Install Dependencies
19
-
20
14
  ```bash
21
15
  pnpm install
16
+ pnpm run codegen # Generate GraphQL types
17
+ pnpm run dev # http://localhost:3000
22
18
  ```
23
19
 
24
- ### 2. Configure Environment
20
+ ### Environment
25
21
 
26
- Copy `.env.example` to `.env.local` and update:
22
+ Copy `.env.example` to `.env.local`:
27
23
 
28
24
  ```env
29
25
  NEXT_PUBLIC_SHOP_SLUG=your-shop-slug
30
26
  NEXT_PUBLIC_API_URL=https://api.doswiftly.pl
31
27
  ```
32
28
 
33
- ### 3. Run GraphQL Codegen
34
-
35
- Generate TypeScript types from your GraphQL schema:
29
+ ## Project Structure
36
30
 
37
- ```bash
38
- pnpm run codegen
39
31
  ```
40
-
41
- ### 4. Start Development Server
42
-
43
- ```bash
44
- pnpm run dev
32
+ app/ # Next.js App Router pages
33
+ components/
34
+ ui/ # shadcn/ui components
35
+ product/ # Product-related components
36
+ cart/ # Cart components
37
+ layout/ # Header, Footer, Navigation
38
+ providers/ # QueryProvider, CurrencyProvider
39
+ lib/
40
+ graphql/ # Server/client GraphQL helpers
41
+ stores/ # Zustand stores (cart, currency, auth)
42
+ generated/ # Auto-generated GraphQL types
45
43
  ```
46
44
 
47
- Open [http://localhost:3000](http://localhost:3000) in your browser.
48
-
49
45
  ## Adding shadcn/ui Components
50
46
 
51
- This template is pre-configured with shadcn/ui. Add components using the shadcn CLI:
52
-
53
47
  ```bash
54
- # Add a button component
55
48
  npx shadcn@latest add button
56
-
57
- # Add a dialog component
58
49
  npx shadcn@latest add dialog
59
-
60
- # Add a dropdown menu
61
- npx shadcn@latest add dropdown-menu
62
-
63
- # See all available components
64
- npx shadcn@latest add
65
- ```
66
-
67
- Components will be added to `components/ui/` directory.
68
-
69
- ## Project Structure
70
-
71
- ```
72
- ├── app/ # Next.js App Router pages
73
- │ ├── layout.tsx # Root layout with providers
74
- │ └── page.tsx # Homepage
75
- ├── components/
76
- │ ├── ui/ # shadcn/ui components (auto-generated)
77
- │ ├── layout/ # Layout components (Header, Footer)
78
- │ └── providers/ # React providers (Query, Currency)
79
- ├── lib/
80
- │ ├── graphql/
81
- │ │ ├── server.ts # Server-side GraphQL client
82
- │ │ ├── client.ts # Client-side GraphQL client
83
- │ │ └── hooks.ts # React Query hooks
84
- │ └── utils.ts # Utility functions (cn helper)
85
- ├── stores/
86
- │ └── currency-store.ts # Zustand currency store
87
- ├── generated/
88
- │ └── graphql.ts # Auto-generated GraphQL types
89
- ├── doswiftly.config.ts # DoSwiftly configuration
90
- ├── components.json # shadcn/ui configuration
91
- └── codegen.ts # GraphQL Codegen configuration
92
- ```
93
-
94
- ## GraphQL Codegen
95
-
96
- This template uses GraphQL Codegen to generate TypeScript types from your GraphQL schema.
97
-
98
- ### Configuration
99
-
100
- See `codegen.ts` for configuration. It reads:
101
- - **Schema**: From your DoSwiftly API
102
- - **Operations**: From `@doswiftly/storefront-operations` package
103
- - **Custom queries**: From `src/graphql/**/*.{ts,tsx}`
104
-
105
- ### Running Codegen
106
-
107
- ```bash
108
- # Generate types
109
- pnpm run codegen
110
-
111
- # Watch mode (auto-regenerate on changes)
112
- pnpm run codegen:watch
113
- ```
114
-
115
- ## Currency Management
116
-
117
- This template includes built-in currency conversion:
118
-
119
- 1. **Server Components**: Render prices in base currency (SSG-compatible)
120
- 2. **Client Components**: Switch to user's preferred currency dynamically
121
- 3. **Currency Store**: Persists user preference in localStorage
122
-
123
- ### Usage
124
-
125
- ```tsx
126
- // Server Component
127
- import { fetchProduct } from '@/lib/graphql/server';
128
-
129
- export default async function ProductPage({ params }) {
130
- const { product } = await fetchProduct(params.handle);
131
- // Prices in base currency
132
- return <div>{product.priceRange.minVariantPrice.amount}</div>;
133
- }
134
-
135
- // Client Component
136
- 'use client';
137
- import { useProduct } from '@/lib/graphql/hooks';
138
- import { useCurrencyStore } from '@/stores/currency-store';
139
-
140
- export function ProductPrice({ handle }) {
141
- const currency = useCurrencyStore((s) => s.currency);
142
- const { data } = useProduct(handle);
143
- // Prices in user's preferred currency
144
- return <div>{data.product.priceRange.minVariantPrice.amount} {currency}</div>;
145
- }
146
- ```
147
-
148
- ## Styling
149
-
150
- This template uses Tailwind CSS v4 with shadcn/ui.
151
-
152
- ### Customizing Theme
153
-
154
- Edit `app/globals.css` to customize colors:
155
-
156
- ```css
157
- @layer base {
158
- :root {
159
- --background: 0 0% 100%;
160
- --foreground: 222.2 84% 4.9%;
161
- /* ... more variables */
162
- }
163
- }
164
- ```
165
-
166
- ### Using cn() Helper
167
-
168
- The `cn()` helper combines Tailwind classes with proper precedence:
169
-
170
- ```tsx
171
- import { cn } from '@/lib/utils';
172
-
173
- <div className={cn('text-base', isActive && 'text-primary')} />
174
- ```
175
-
176
- ## Building for Production
177
-
178
- ```bash
179
- # Build
180
- pnpm run build
181
-
182
- # Start production server
183
- pnpm run start
184
50
  ```
185
51
 
186
- ## Learn More
52
+ ## Documentation
187
53
 
188
- - [DoSwiftly Documentation](https://docs.doswiftly.pl)
189
- - [shadcn/ui Documentation](https://ui.shadcn.com)
190
- - [Next.js Documentation](https://nextjs.org/docs)
191
- - [Tailwind CSS Documentation](https://tailwindcss.com/docs)
54
+ - [SDK Overview](https://docs.doswiftly.pl/storefront-developer/sdk/overview) — hooks, stores, architecture
55
+ - [SDK Products](https://docs.doswiftly.pl/storefront-developer/sdk/products) — product queries and mutations
56
+ - [API Queries](https://docs.doswiftly.pl/storefront-developer/api/queries) — available GraphQL queries
57
+ - [API Mutations](https://docs.doswiftly.pl/storefront-developer/api/mutations) — available GraphQL mutations
58
+ - [CLI Commands](https://docs.doswiftly.pl/storefront-developer/cli-commands) — full CLI reference
192
59
 
193
60
  ## License
194
61