@jarwizz/create-jarshop 0.1.1 → 0.1.3

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 (107) hide show
  1. package/README.md +10 -2
  2. package/dist/generator.js +10 -4
  3. package/dist/generator.js.map +1 -1
  4. package/dist/template/AGENTS.md +3 -3
  5. package/dist/template/CONTEXT.md +14 -0
  6. package/dist/template/README.md +25 -3
  7. package/dist/template/docker-compose.yml +5 -0
  8. package/dist/template/docs/smtp-smoke.md +37 -0
  9. package/dist/template/env.example.template +18 -0
  10. package/dist/template/gitignore.template +2 -0
  11. package/dist/template/package.json +19 -6
  12. package/dist/template/pnpm-lock.yaml +2389 -98
  13. package/dist/template/pnpm-workspace.yaml +12 -1
  14. package/dist/template/src/dev-storefront.ts +58 -0
  15. package/dist/template/src/dev.ts +67 -4
  16. package/dist/template/src/email-smoke.ts +27 -0
  17. package/dist/template/src/environment.d.ts +6 -0
  18. package/dist/template/src/migrate.ts +16 -0
  19. package/dist/template/src/migrations/1786024108434-jarshop-checkout-attempt.ts +28 -0
  20. package/dist/template/src/migrations/1786024108435-jarshop-legal-and-confirmation.ts +60 -0
  21. package/dist/template/src/migrations/1786024108436-jarshop-order-email-outbox.ts +37 -0
  22. package/dist/template/src/migrations/1786030000000-jarshop-order-email-delivery-lease.ts +27 -0
  23. package/dist/template/src/plugins/jarshop-checkout/checkout-attempt.entity.ts +42 -0
  24. package/dist/template/src/plugins/jarshop-checkout/cod-payment.test.ts +44 -0
  25. package/dist/template/src/plugins/jarshop-checkout/cod-payment.ts +28 -0
  26. package/dist/template/src/plugins/jarshop-checkout/confirmation-token.entity.ts +31 -0
  27. package/dist/template/src/plugins/jarshop-checkout/confirmation.ts +59 -0
  28. package/dist/template/src/plugins/jarshop-checkout/dashboard/index.tsx +107 -0
  29. package/dist/template/src/plugins/jarshop-checkout/dashboard/order-email-delivery-status.ts +43 -0
  30. package/dist/template/src/plugins/jarshop-checkout/email-smoke-core.ts +56 -0
  31. package/dist/template/src/plugins/jarshop-checkout/index.ts +51 -0
  32. package/dist/template/src/plugins/jarshop-checkout/jarshop-checkout.plugin.ts +870 -0
  33. package/dist/template/src/plugins/jarshop-checkout/legal.entity.ts +39 -0
  34. package/dist/template/src/plugins/jarshop-checkout/order-consent.entity.ts +32 -0
  35. package/dist/template/src/plugins/jarshop-checkout/order-email-delivery-core.ts +337 -0
  36. package/dist/template/src/plugins/jarshop-checkout/order-email-delivery-status.ts +39 -0
  37. package/dist/template/src/plugins/jarshop-checkout/order-email-delivery.entity.ts +66 -0
  38. package/dist/template/src/plugins/jarshop-checkout/order-email-outbox.ts +108 -0
  39. package/dist/template/src/plugins/jarshop-checkout/order-email-transport.ts +35 -0
  40. package/dist/template/src/plugins/jarshop-checkout/order-email-worker.ts +281 -0
  41. package/dist/template/src/plugins/jarshop-checkout/shipping.test.ts +41 -0
  42. package/dist/template/src/plugins/jarshop-checkout/shipping.ts +162 -0
  43. package/dist/template/src/seed.ts +171 -0
  44. package/dist/template/src/vendure-config.ts +72 -7
  45. package/dist/template/static/email/templates/email-verification/body.hbs +4 -4
  46. package/dist/template/storefront/app/[locale]/[slug]/add-to-cart-form.tsx +44 -0
  47. package/dist/template/storefront/app/[locale]/[slug]/page.tsx +35 -26
  48. package/dist/template/storefront/app/[locale]/account/account-mutation-form.tsx +44 -0
  49. package/dist/template/storefront/app/[locale]/account/change-password-form.tsx +65 -0
  50. package/dist/template/storefront/app/[locale]/account/login/login-form.tsx +60 -0
  51. package/dist/template/storefront/app/[locale]/account/login/page.tsx +23 -0
  52. package/dist/template/storefront/app/[locale]/account/page.tsx +215 -0
  53. package/dist/template/storefront/app/[locale]/account/password-reset/callback/route.ts +33 -0
  54. package/dist/template/storefront/app/[locale]/account/password-reset/complete/page.tsx +27 -0
  55. package/dist/template/storefront/app/[locale]/account/password-reset/page.tsx +37 -0
  56. package/dist/template/storefront/app/[locale]/account/password-reset/password-reset-forms.tsx +99 -0
  57. package/dist/template/storefront/app/[locale]/account/register/page.tsx +23 -0
  58. package/dist/template/storefront/app/[locale]/account/register/register-form.tsx +67 -0
  59. package/dist/template/storefront/app/[locale]/account/verify/complete/route.ts +33 -0
  60. package/dist/template/storefront/app/[locale]/account/verify/page.tsx +41 -0
  61. package/dist/template/storefront/app/[locale]/account/verify/refresh-form.tsx +35 -0
  62. package/dist/template/storefront/app/[locale]/cart/page.tsx +78 -0
  63. package/dist/template/storefront/app/[locale]/checkout/checkout-form.tsx +112 -0
  64. package/dist/template/storefront/app/[locale]/checkout/confirmation/route.ts +21 -0
  65. package/dist/template/storefront/app/[locale]/checkout/page.tsx +44 -0
  66. package/dist/template/storefront/app/[locale]/checkout/success/page.tsx +28 -0
  67. package/dist/template/storefront/app/[locale]/layout.tsx +48 -0
  68. package/dist/template/storefront/app/[locale]/page.tsx +12 -13
  69. package/dist/template/storefront/app/globals.css +372 -4
  70. package/dist/template/storefront/app/layout.tsx +13 -0
  71. package/dist/template/storefront/eslint.config.mjs +8 -1
  72. package/dist/template/storefront/gitignore.template +1 -0
  73. package/dist/template/storefront/lib/account-security.test.ts +74 -0
  74. package/dist/template/storefront/lib/account-security.ts +81 -0
  75. package/dist/template/storefront/lib/account.ts +366 -0
  76. package/dist/template/storefront/lib/cart-contract.ts +52 -0
  77. package/dist/template/storefront/lib/cart.test.ts +30 -0
  78. package/dist/template/storefront/lib/cart.ts +130 -0
  79. package/dist/template/storefront/lib/checkout-contract.test.ts +20 -0
  80. package/dist/template/storefront/lib/checkout-contract.ts +16 -0
  81. package/dist/template/storefront/lib/checkout.ts +149 -0
  82. package/dist/template/storefront/lib/commerce-session.test.ts +77 -0
  83. package/dist/template/storefront/lib/commerce-session.ts +85 -0
  84. package/dist/template/storefront/lib/commerce.ts +129 -4
  85. package/dist/template/storefront/lib/confirmation-cookie.ts +9 -0
  86. package/dist/template/storefront/lib/confirmation.ts +95 -0
  87. package/dist/template/storefront/lib/form-values.test.ts +14 -0
  88. package/dist/template/storefront/lib/form-values.ts +7 -0
  89. package/dist/template/storefront/lib/i18n.test.ts +50 -0
  90. package/dist/template/storefront/lib/i18n.ts +44 -0
  91. package/dist/template/storefront/lib/password-reset-token.test.ts +31 -0
  92. package/dist/template/storefront/lib/password-reset-token.ts +17 -0
  93. package/dist/template/storefront/lib/valkey-rate-limit.ts +72 -0
  94. package/dist/template/storefront/messages/en.json +89 -0
  95. package/dist/template/storefront/messages/sk.json +89 -0
  96. package/dist/template/storefront/next.config.ts +3 -1
  97. package/dist/template/storefront/package.json +11 -4
  98. package/dist/template/storefront/vitest.config.ts +8 -0
  99. package/dist/template/tsconfig.json +2 -1
  100. package/dist/template/turbo.json +8 -0
  101. package/dist/template/vite.config.mts +4 -1
  102. package/dist/template-manifest.json +1 -1
  103. package/dist/template.js +3 -0
  104. package/dist/template.js.map +1 -1
  105. package/package.json +1 -1
  106. package/dist/template/storefront/pnpm-lock.yaml +0 -3562
  107. package/dist/template/storefront/pnpm-workspace.yaml +0 -26
@@ -0,0 +1,31 @@
1
+ import { describe, expect, it } from "vitest";
2
+
3
+ import {
4
+ PASSWORD_RESET_TOKEN_COOKIE,
5
+ passwordResetToken,
6
+ passwordResetTokenCookieOptions,
7
+ } from "./password-reset-token";
8
+
9
+ describe("password-reset token bridge", () => {
10
+ it("uses one short-lived HttpOnly cookie that browser JavaScript cannot read", () => {
11
+ expect(PASSWORD_RESET_TOKEN_COOKIE).toBe("jarshop-password-reset-token");
12
+ expect(passwordResetTokenCookieOptions).toMatchObject({
13
+ httpOnly: true,
14
+ maxAge: 15 * 60,
15
+ path: "/",
16
+ sameSite: "lax",
17
+ });
18
+ });
19
+
20
+ it("reads only the reset-token cookie from the server cookie store", () => {
21
+ const store = {
22
+ get(name: string) {
23
+ return name === PASSWORD_RESET_TOKEN_COOKIE
24
+ ? { value: "opaque-reset-token" }
25
+ : undefined;
26
+ },
27
+ };
28
+
29
+ expect(passwordResetToken(store)).toBe("opaque-reset-token");
30
+ });
31
+ });
@@ -0,0 +1,17 @@
1
+ import type { CommerceSessionStore } from "./commerce-session";
2
+
3
+ export const PASSWORD_RESET_TOKEN_COOKIE = "jarshop-password-reset-token";
4
+
5
+ export const passwordResetTokenCookieOptions = {
6
+ httpOnly: true,
7
+ maxAge: 15 * 60,
8
+ path: "/",
9
+ sameSite: "lax" as const,
10
+ secure: process.env.NODE_ENV === "production",
11
+ };
12
+
13
+ export function passwordResetToken(
14
+ store: Pick<CommerceSessionStore, "get">,
15
+ ): string | undefined {
16
+ return store.get(PASSWORD_RESET_TOKEN_COOKIE)?.value;
17
+ }
@@ -0,0 +1,72 @@
1
+ import { GlideClient } from "@valkey/valkey-glide";
2
+
3
+ import type {
4
+ AccountRateLimitBucket,
5
+ AccountRateLimitStore,
6
+ } from "./account-security";
7
+
8
+ const CONSUME_SCRIPT = `
9
+ local allowed = 1
10
+ for i = 1, #KEYS do
11
+ local count = redis.call("INCR", KEYS[i])
12
+ if count == 1 then redis.call("PEXPIRE", KEYS[i], ARGV[1]) end
13
+ if count > tonumber(ARGV[i + 1]) then allowed = 0 end
14
+ end
15
+ return allowed
16
+ `;
17
+
18
+ let clientPromise: Promise<GlideClient> | undefined;
19
+
20
+ function rateLimitUrl(): URL {
21
+ const value = process.env.JARSHOP_ACCOUNT_RATE_LIMIT_URL;
22
+ if (!value) throw new Error("JARSHOP_ACCOUNT_RATE_LIMIT_URL is required");
23
+ const url = new URL(value);
24
+ if (url.protocol !== "redis:" && url.protocol !== "rediss:") {
25
+ throw new Error("JARSHOP_ACCOUNT_RATE_LIMIT_URL must use redis or rediss");
26
+ }
27
+ return url;
28
+ }
29
+
30
+ async function client(): Promise<GlideClient> {
31
+ if (!clientPromise) {
32
+ const url = rateLimitUrl();
33
+ const databaseId = url.pathname === "/" ? 0 : Number(url.pathname.slice(1));
34
+ if (!Number.isInteger(databaseId) || databaseId < 0) {
35
+ throw new Error("JARSHOP_ACCOUNT_RATE_LIMIT_URL has an invalid database");
36
+ }
37
+ clientPromise = GlideClient.createClient({
38
+ addresses: [{ host: url.hostname, port: Number(url.port || 6379) }],
39
+ ...(url.username || url.password
40
+ ? {
41
+ credentials: {
42
+ username: decodeURIComponent(url.username || "default"),
43
+ password: decodeURIComponent(url.password),
44
+ },
45
+ }
46
+ : {}),
47
+ databaseId,
48
+ useTLS: url.protocol === "rediss:",
49
+ requestTimeout: 500,
50
+ clientName: "jarshop-storefront-account-rate-limit",
51
+ });
52
+ }
53
+ return clientPromise;
54
+ }
55
+
56
+ export const valkeyAccountRateLimitStore: AccountRateLimitStore = {
57
+ async consume(
58
+ buckets: readonly AccountRateLimitBucket[],
59
+ windowMs: number,
60
+ ): Promise<boolean> {
61
+ const connection = await client();
62
+ const result = await connection.customCommand([
63
+ "EVAL",
64
+ CONSUME_SCRIPT,
65
+ String(buckets.length),
66
+ ...buckets.map((bucket) => bucket.key),
67
+ String(windowMs),
68
+ ...buckets.map((bucket) => String(bucket.maxAttempts)),
69
+ ]);
70
+ return Number(result) === 1;
71
+ },
72
+ };
@@ -0,0 +1,89 @@
1
+ {
2
+ "catalog.title": "Products",
3
+ "catalog.empty": "Products are not available.",
4
+ "nav.catalog": "Products",
5
+ "nav.cart": "Cart",
6
+ "nav.cartItems": "{count} items",
7
+ "nav.account": "Account",
8
+ "product.back": "Back",
9
+ "product.notFound": "Product not found.",
10
+ "product.inStock": "In stock",
11
+ "product.outOfStock": "Out of stock",
12
+ "product.addToCart": "Add to cart",
13
+ "product.addedToCart": "Product added to your cart.",
14
+ "product.viewCart": "View cart",
15
+ "cart.title": "Cart",
16
+ "cart.empty": "Your cart is empty.",
17
+ "cart.quantity": "Quantity",
18
+ "cart.update": "Update",
19
+ "cart.remove": "Remove",
20
+ "cart.subtotal": "Subtotal",
21
+ "cart.shipping": "Shipping",
22
+ "cart.total": "Total",
23
+ "cart.checkout": "Continue to checkout",
24
+ "checkout.title": "Checkout",
25
+ "checkout.email": "Email",
26
+ "checkout.firstName": "First name",
27
+ "checkout.lastName": "Last name",
28
+ "checkout.phone": "Phone",
29
+ "checkout.terms": "I accept the terms and conditions",
30
+ "checkout.shippingMethod": "Shipping method",
31
+ "checkout.pickup": "Personal pickup — free",
32
+ "checkout.courier": "Courier — 4.90 EUR",
33
+ "checkout.street": "Street and number",
34
+ "checkout.city": "City",
35
+ "checkout.postalCode": "Postal code",
36
+ "checkout.country": "Country",
37
+ "checkout.slovakia": "Slovakia",
38
+ "checkout.pickupSummary": "Personal pickup: 0 EUR. Payment: cash on delivery.",
39
+ "checkout.courierSummary": "Courier: 4.90 EUR. Payment: cash on delivery.",
40
+ "checkout.submitPickup": "Place pickup COD order",
41
+ "checkout.submitCourier": "Place courier COD order",
42
+ "checkout.priceChanged": "The cart price changed. Review the refreshed totals and try again.",
43
+ "checkout.insufficientStock": "Some items are no longer available in that quantity. Adjust the cart and try again.",
44
+ "success.title": "Order placed",
45
+ "success.orderCode": "Order code",
46
+ "account.title": "My account",
47
+ "account.name": "Name",
48
+ "account.email": "Email",
49
+ "account.password": "Password",
50
+ "account.phone": "Phone",
51
+ "account.signIn": "Sign in",
52
+ "account.signOut": "Sign out",
53
+ "account.register": "Create account",
54
+ "account.registrationSent": "If this address can complete account setup, check its inbox for the next step. If you already have an account, use password reset to recover access.",
55
+ "account.verify": "Verify account",
56
+ "account.resetPassword": "Reset password",
57
+ "account.requestPasswordReset": "Forgot password?",
58
+ "account.resetSent": "If an account exists for this address, we sent password-reset instructions.",
59
+ "account.currentPassword": "Current password",
60
+ "account.newPassword": "New password",
61
+ "account.confirmNewPassword": "Confirm new password",
62
+ "account.passwordMismatch": "The passwords do not match.",
63
+ "account.passwordChanged": "Password changed.",
64
+ "account.profile": "Profile",
65
+ "account.saveProfile": "Save profile",
66
+ "account.addresses": "Addresses",
67
+ "account.addAddress": "Add address",
68
+ "account.removeAddress": "Remove address",
69
+ "account.fullName": "Full name",
70
+ "account.street": "Street and number",
71
+ "account.city": "City",
72
+ "account.postalCode": "Postal code",
73
+ "account.country": "Country",
74
+ "account.defaultShippingAddress": "Default shipping address",
75
+ "account.defaultBillingAddress": "Default billing address",
76
+ "account.orders": "Orders",
77
+ "account.noOrders": "You do not have any orders yet.",
78
+ "account.invalidCredentials": "The email address or password is incorrect.",
79
+ "account.passwordInvalid": "Choose a stronger password and try again.",
80
+ "account.invalidToken": "This token is invalid or has expired.",
81
+ "account.signInFailed": "We could not complete the request. Please try again.",
82
+ "account.saved": "Changes saved.",
83
+ "account.saveFailed": "Changes could not be saved. Try again.",
84
+ "account.addressAdded": "Address added.",
85
+ "account.addressRemoved": "Address removed.",
86
+ "account.loadMoreOrders": "Load more orders",
87
+ "account.resendVerification": "Send a new verification link",
88
+ "account.verificationSent": "If this address is waiting for verification, a new link was sent."
89
+ }
@@ -0,0 +1,89 @@
1
+ {
2
+ "catalog.title": "Produkty",
3
+ "catalog.empty": "Produkty sa nepodarilo načítať.",
4
+ "nav.catalog": "Produkty",
5
+ "nav.cart": "Košík",
6
+ "nav.cartItems": "{count} ks",
7
+ "nav.account": "Účet",
8
+ "product.back": "Späť",
9
+ "product.notFound": "Produkt sa nenašiel.",
10
+ "product.inStock": "Skladom",
11
+ "product.outOfStock": "Vypredané",
12
+ "product.addToCart": "Pridať do košíka",
13
+ "product.addedToCart": "Produkt bol pridaný do košíka.",
14
+ "product.viewCart": "Zobraziť košík",
15
+ "cart.title": "Košík",
16
+ "cart.empty": "Košík je prázdny.",
17
+ "cart.quantity": "Množstvo",
18
+ "cart.update": "Aktualizovať",
19
+ "cart.remove": "Odstrániť",
20
+ "cart.subtotal": "Medzisúčet",
21
+ "cart.shipping": "Doprava",
22
+ "cart.total": "Spolu",
23
+ "cart.checkout": "Pokračovať k objednávke",
24
+ "checkout.title": "Objednávka",
25
+ "checkout.email": "E-mail",
26
+ "checkout.firstName": "Meno",
27
+ "checkout.lastName": "Priezvisko",
28
+ "checkout.phone": "Telefón",
29
+ "checkout.terms": "Súhlasím s obchodnými podmienkami",
30
+ "checkout.shippingMethod": "Spôsob dopravy",
31
+ "checkout.pickup": "Osobný odber — zdarma",
32
+ "checkout.courier": "Kuriér — 4,90 EUR",
33
+ "checkout.street": "Ulica a číslo",
34
+ "checkout.city": "Mesto",
35
+ "checkout.postalCode": "PSČ",
36
+ "checkout.country": "Krajina",
37
+ "checkout.slovakia": "Slovensko",
38
+ "checkout.pickupSummary": "Osobný odber: 0 EUR. Platba: dobierka.",
39
+ "checkout.courierSummary": "Kuriér: 4,90 EUR. Platba: dobierka.",
40
+ "checkout.submitPickup": "Objednať osobný odber na dobierku",
41
+ "checkout.submitCourier": "Objednať doručenie kuriérom na dobierku",
42
+ "checkout.priceChanged": "Cena v košíku sa zmenila. Skontroluj aktualizované sumy a skús to znova.",
43
+ "checkout.insufficientStock": "Niektoré položky už nemajú požadované množstvo. Uprav košík a skús to znova.",
44
+ "success.title": "Objednávka odoslaná",
45
+ "success.orderCode": "Kód objednávky",
46
+ "account.title": "Môj účet",
47
+ "account.name": "Meno",
48
+ "account.email": "E-mail",
49
+ "account.password": "Heslo",
50
+ "account.phone": "Telefón",
51
+ "account.signIn": "Prihlásiť sa",
52
+ "account.signOut": "Odhlásiť sa",
53
+ "account.register": "Vytvoriť účet",
54
+ "account.registrationSent": "Ak je možné účet pre túto adresu dokončiť, ďalší krok nájdeš v jej schránke. Ak už účet máš, obnov prístup cez zmenu hesla.",
55
+ "account.verify": "Overiť účet",
56
+ "account.resetPassword": "Obnoviť heslo",
57
+ "account.requestPasswordReset": "Zabudnuté heslo?",
58
+ "account.resetSent": "Ak účet s touto adresou existuje, poslali sme pokyny na obnovu hesla.",
59
+ "account.currentPassword": "Aktuálne heslo",
60
+ "account.newPassword": "Nové heslo",
61
+ "account.confirmNewPassword": "Potvrď nové heslo",
62
+ "account.passwordMismatch": "Heslá sa nezhodujú.",
63
+ "account.passwordChanged": "Heslo bolo zmenené.",
64
+ "account.profile": "Profil",
65
+ "account.saveProfile": "Uložiť profil",
66
+ "account.addresses": "Adresy",
67
+ "account.addAddress": "Pridať adresu",
68
+ "account.removeAddress": "Odstrániť adresu",
69
+ "account.fullName": "Celé meno",
70
+ "account.street": "Ulica a číslo",
71
+ "account.city": "Mesto",
72
+ "account.postalCode": "PSČ",
73
+ "account.country": "Krajina",
74
+ "account.defaultShippingAddress": "Predvolená doručovacia adresa",
75
+ "account.defaultBillingAddress": "Predvolená fakturačná adresa",
76
+ "account.orders": "Objednávky",
77
+ "account.noOrders": "Zatiaľ nemáš žiadne objednávky.",
78
+ "account.invalidCredentials": "E-mail alebo heslo nie je správne.",
79
+ "account.passwordInvalid": "Zvoľ silnejšie heslo a skús to znova.",
80
+ "account.invalidToken": "Tento token nie je platný alebo mu vypršala platnosť.",
81
+ "account.signInFailed": "Požiadavku sa nepodarilo dokončiť. Skús to znova.",
82
+ "account.saved": "Zmeny boli uložené.",
83
+ "account.saveFailed": "Zmeny sa nepodarilo uložiť. Skús to znova.",
84
+ "account.addressAdded": "Adresa bola pridaná.",
85
+ "account.addressRemoved": "Adresa bola odstránená.",
86
+ "account.loadMoreOrders": "Načítať ďalšie objednávky",
87
+ "account.resendVerification": "Poslať nový overovací odkaz",
88
+ "account.verificationSent": "Ak táto adresa čaká na overenie, poslali sme nový odkaz."
89
+ }
@@ -1,4 +1,5 @@
1
1
  import type { NextConfig } from "next";
2
+ import { resolve } from "node:path";
2
3
 
3
4
  const nextConfig: NextConfig = {
4
5
  // Vendure's development watcher ignores dist directories. Keeping Next's
@@ -6,8 +7,9 @@ const nextConfig: NextConfig = {
6
7
  // server and worker.
7
8
  distDir: "dist",
8
9
  output: "standalone",
10
+ serverExternalPackages: ["@valkey/valkey-glide"],
9
11
  turbopack: {
10
- root: import.meta.dirname,
12
+ root: resolve(import.meta.dirname, "../../.."),
11
13
  },
12
14
  };
13
15
 
@@ -6,16 +6,22 @@
6
6
  "engines": {
7
7
  "node": ">=24.18.0 <25"
8
8
  },
9
- "packageManager": "pnpm@11.18.0",
10
9
  "scripts": {
11
10
  "dev": "next dev",
12
11
  "build": "next build",
12
+ "build:storefront": "next build",
13
13
  "start": "next start",
14
14
  "lint": "eslint .",
15
- "typecheck": "tsc --noEmit"
15
+ "lint:storefront": "eslint .",
16
+ "typecheck": "tsc --noEmit",
17
+ "typecheck:storefront": "tsc --noEmit",
18
+ "test": "vitest run --config vitest.config.ts",
19
+ "test:storefront": "vitest run --config vitest.config.ts"
16
20
  },
17
21
  "dependencies": {
18
- "@jarwizz/commerce-sdk": "0.1.0",
22
+ "@jarwizz/commerce-sdk": "0.3.0",
23
+ "@swc/helpers": "0.5.15",
24
+ "@valkey/valkey-glide": "2.5.1",
19
25
  "next": "16.2.12",
20
26
  "react": "19.2.8",
21
27
  "react-dom": "19.2.8"
@@ -26,7 +32,8 @@
26
32
  "@types/react-dom": "19.2.3",
27
33
  "eslint": "9.39.5",
28
34
  "eslint-config-next": "16.2.12",
35
+ "typescript": "6.0.3",
29
36
  "typescript-eslint": "8.65.0",
30
- "typescript": "6.0.3"
37
+ "vitest": "4.1.10"
31
38
  }
32
39
  }
@@ -0,0 +1,8 @@
1
+ import { defineConfig } from "vitest/config";
2
+
3
+ export default defineConfig({
4
+ test: {
5
+ environment: "node",
6
+ include: ["lib/**/*.test.ts"],
7
+ },
8
+ });
@@ -11,5 +11,6 @@
11
11
  "emitDecoratorMetadata": true,
12
12
  "useDefineForClassFields": false
13
13
  },
14
- "include": ["src/**/*.ts"]
14
+ "include": ["src/**/*.ts"],
15
+ "exclude": ["src/**/*.test.ts"]
15
16
  }
@@ -1,8 +1,16 @@
1
1
  {
2
2
  "$schema": "https://turbo.build/schema.json",
3
3
  "tasks": {
4
+ "build:vendure": { "outputs": ["dist/**"] },
5
+ "build:storefront": {
6
+ "outputs": [".next/**", "!.next/cache/**"]
7
+ },
8
+ "lint:storefront": {},
9
+ "typecheck:storefront": {},
10
+ "test:storefront": {},
4
11
  "dev:server": { "cache": false, "persistent": true },
5
12
  "dev:worker": { "cache": false, "persistent": true },
13
+ "dev:dashboard": { "cache": false, "persistent": true },
6
14
  "dev:storefront": { "cache": false, "persistent": true }
7
15
  }
8
16
  }
@@ -16,7 +16,10 @@ export default defineConfig({
16
16
  api:
17
17
  process.env.NODE_ENV === "production"
18
18
  ? { host: "auto", port: "auto" }
19
- : { host: "http://localhost", port: 3000 },
19
+ : {
20
+ host: "http://localhost",
21
+ port: Number(process.env.PORT ?? 3000),
22
+ },
20
23
  gqlOutputPath: "./src/gql",
21
24
  }),
22
25
  ],
@@ -1,3 +1,3 @@
1
1
  {
2
- "digest": "sha256:2dd337148e2dbc5ddd9446290d16788f0635954f8454d39bba0d2bc79bcc3cf8"
2
+ "digest": "sha256:16e696efe1452c2aeac287d87541d38e5254828686eae16084e1562c0e5a6bd1"
3
3
  }
package/dist/template.js CHANGED
@@ -6,8 +6,11 @@ const ignoredNames = new Set([
6
6
  ".next",
7
7
  ".turbo",
8
8
  ".vendure",
9
+ "assets",
9
10
  "dist",
10
11
  "node_modules",
12
+ "test-emails",
13
+ "jarshop-outbox",
11
14
  ]);
12
15
  export function shouldIncludeTemplatePath(path) {
13
16
  return !path
@@ -1 +1 @@
1
- {"version":3,"file":"template.js","sourceRoot":"","sources":["../src/template.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,MAAM,YAAY,GAAG,IAAI,GAAG,CAAC;IAC3B,MAAM;IACN,OAAO;IACP,QAAQ;IACR,UAAU;IACV,MAAM;IACN,cAAc;CACf,CAAC,CAAC;AAEH,MAAM,UAAU,yBAAyB,CAAC,IAAY;IACpD,OAAO,CAAC,IAAI;SACT,KAAK,CAAC,QAAQ,CAAC;SACf,IAAI,CACH,CAAC,OAAO,EAAE,EAAE,CACV,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAC,CAChE,CAAC;AACN,CAAC;AAOD,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,IAAY;IAClD,MAAM,KAAK,GAAmB,EAAE,CAAC;IAEjC,KAAK,UAAU,IAAI,CAAC,OAAe,EAAE,MAAc;QACjD,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,OAAO,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;QAChE,OAAO,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;QAEnE,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;YAC5B,MAAM,YAAY,GAAG,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC;YACrE,IAAI,CAAC,yBAAyB,CAAC,YAAY,CAAC;gBAAE,SAAS;YACvD,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;YAC/C,IAAI,KAAK,CAAC,WAAW,EAAE;gBAAE,MAAM,IAAI,CAAC,YAAY,EAAE,YAAY,CAAC,CAAC;iBAC3D,IAAI,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC;gBACxB,KAAK,CAAC,IAAI,CAAC;oBACT,OAAO,EAAE,MAAM,QAAQ,CAAC,YAAY,CAAC;oBACrC,IAAI,EAAE,YAAY;iBACnB,CAAC,CAAC;YACL,CAAC;QACH,CAAC;IACH,CAAC;IAED,MAAM,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;IACrB,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,MAAM,CAAC,OAAwB;IAC7C,OAAO,UAAU,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;AACxE,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,IAAY;IAC3C,MAAM,KAAK,GAAG,MAAM,iBAAiB,CAAC,IAAI,CAAC,CAAC;IAC5C,MAAM,IAAI,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC;IAClC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACvB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAClB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC1B,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IACpB,CAAC;IACD,OAAO,UAAU,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;AACxC,CAAC"}
1
+ {"version":3,"file":"template.js","sourceRoot":"","sources":["../src/template.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,MAAM,YAAY,GAAG,IAAI,GAAG,CAAC;IAC3B,MAAM;IACN,OAAO;IACP,QAAQ;IACR,UAAU;IACV,QAAQ;IACR,MAAM;IACN,cAAc;IACd,aAAa;IACb,gBAAgB;CACjB,CAAC,CAAC;AAEH,MAAM,UAAU,yBAAyB,CAAC,IAAY;IACpD,OAAO,CAAC,IAAI;SACT,KAAK,CAAC,QAAQ,CAAC;SACf,IAAI,CACH,CAAC,OAAO,EAAE,EAAE,CACV,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAC,CAChE,CAAC;AACN,CAAC;AAOD,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,IAAY;IAClD,MAAM,KAAK,GAAmB,EAAE,CAAC;IAEjC,KAAK,UAAU,IAAI,CAAC,OAAe,EAAE,MAAc;QACjD,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,OAAO,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;QAChE,OAAO,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;QAEnE,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;YAC5B,MAAM,YAAY,GAAG,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC;YACrE,IAAI,CAAC,yBAAyB,CAAC,YAAY,CAAC;gBAAE,SAAS;YACvD,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;YAC/C,IAAI,KAAK,CAAC,WAAW,EAAE;gBAAE,MAAM,IAAI,CAAC,YAAY,EAAE,YAAY,CAAC,CAAC;iBAC3D,IAAI,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC;gBACxB,KAAK,CAAC,IAAI,CAAC;oBACT,OAAO,EAAE,MAAM,QAAQ,CAAC,YAAY,CAAC;oBACrC,IAAI,EAAE,YAAY;iBACnB,CAAC,CAAC;YACL,CAAC;QACH,CAAC;IACH,CAAC;IAED,MAAM,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;IACrB,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,MAAM,CAAC,OAAwB;IAC7C,OAAO,UAAU,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;AACxE,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,IAAY;IAC3C,MAAM,KAAK,GAAG,MAAM,iBAAiB,CAAC,IAAI,CAAC,CAAC;IAC5C,MAAM,IAAI,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC;IAClC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACvB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAClB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC1B,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IACpB,CAAC;IACD,OAAO,UAAU,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;AACxC,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jarwizz/create-jarshop",
3
- "version": "0.1.1",
3
+ "version": "0.1.3",
4
4
  "private": false,
5
5
  "description": "Generate an independent JarShop Client Project.",
6
6
  "license": "MIT",