@jarwizz/create-jarshop 0.1.1 → 0.1.2

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 (100) hide show
  1. package/README.md +8 -0
  2. package/dist/generator.js +6 -3
  3. package/dist/generator.js.map +1 -1
  4. package/dist/template/CONTEXT.md +10 -0
  5. package/dist/template/README.md +20 -3
  6. package/dist/template/docker-compose.yml +5 -0
  7. package/dist/template/docs/smtp-smoke.md +37 -0
  8. package/dist/template/env.example.template +18 -0
  9. package/dist/template/gitignore.template +2 -0
  10. package/dist/template/package.json +13 -5
  11. package/dist/template/pnpm-lock.yaml +38 -7
  12. package/dist/template/src/dev-storefront.ts +58 -0
  13. package/dist/template/src/dev.ts +67 -4
  14. package/dist/template/src/email-smoke.ts +27 -0
  15. package/dist/template/src/environment.d.ts +6 -0
  16. package/dist/template/src/migrate.ts +16 -0
  17. package/dist/template/src/migrations/1786024108434-jarshop-checkout-attempt.ts +28 -0
  18. package/dist/template/src/migrations/1786024108435-jarshop-legal-and-confirmation.ts +60 -0
  19. package/dist/template/src/migrations/1786024108436-jarshop-order-email-outbox.ts +37 -0
  20. package/dist/template/src/migrations/1786030000000-jarshop-order-email-delivery-lease.ts +27 -0
  21. package/dist/template/src/plugins/jarshop-checkout/checkout-attempt.entity.ts +42 -0
  22. package/dist/template/src/plugins/jarshop-checkout/confirmation-token.entity.ts +31 -0
  23. package/dist/template/src/plugins/jarshop-checkout/confirmation.ts +26 -0
  24. package/dist/template/src/plugins/jarshop-checkout/dashboard/index.tsx +107 -0
  25. package/dist/template/src/plugins/jarshop-checkout/dashboard/order-email-delivery-status.ts +43 -0
  26. package/dist/template/src/plugins/jarshop-checkout/email-smoke-core.ts +56 -0
  27. package/dist/template/src/plugins/jarshop-checkout/index.ts +47 -0
  28. package/dist/template/src/plugins/jarshop-checkout/jarshop-checkout.plugin.ts +813 -0
  29. package/dist/template/src/plugins/jarshop-checkout/legal.entity.ts +39 -0
  30. package/dist/template/src/plugins/jarshop-checkout/order-consent.entity.ts +32 -0
  31. package/dist/template/src/plugins/jarshop-checkout/order-email-delivery-core.ts +337 -0
  32. package/dist/template/src/plugins/jarshop-checkout/order-email-delivery-status.ts +39 -0
  33. package/dist/template/src/plugins/jarshop-checkout/order-email-delivery.entity.ts +66 -0
  34. package/dist/template/src/plugins/jarshop-checkout/order-email-outbox.ts +108 -0
  35. package/dist/template/src/plugins/jarshop-checkout/order-email-transport.ts +35 -0
  36. package/dist/template/src/plugins/jarshop-checkout/order-email-worker.ts +281 -0
  37. package/dist/template/src/plugins/jarshop-checkout/shipping.test.ts +41 -0
  38. package/dist/template/src/plugins/jarshop-checkout/shipping.ts +162 -0
  39. package/dist/template/src/seed.ts +149 -0
  40. package/dist/template/src/vendure-config.ts +68 -5
  41. package/dist/template/static/email/templates/email-verification/body.hbs +4 -4
  42. package/dist/template/storefront/app/[locale]/[slug]/add-to-cart-form.tsx +44 -0
  43. package/dist/template/storefront/app/[locale]/[slug]/page.tsx +35 -26
  44. package/dist/template/storefront/app/[locale]/account/account-mutation-form.tsx +44 -0
  45. package/dist/template/storefront/app/[locale]/account/change-password-form.tsx +65 -0
  46. package/dist/template/storefront/app/[locale]/account/login/login-form.tsx +60 -0
  47. package/dist/template/storefront/app/[locale]/account/login/page.tsx +23 -0
  48. package/dist/template/storefront/app/[locale]/account/page.tsx +215 -0
  49. package/dist/template/storefront/app/[locale]/account/password-reset/callback/route.ts +33 -0
  50. package/dist/template/storefront/app/[locale]/account/password-reset/complete/page.tsx +27 -0
  51. package/dist/template/storefront/app/[locale]/account/password-reset/page.tsx +37 -0
  52. package/dist/template/storefront/app/[locale]/account/password-reset/password-reset-forms.tsx +99 -0
  53. package/dist/template/storefront/app/[locale]/account/register/page.tsx +23 -0
  54. package/dist/template/storefront/app/[locale]/account/register/register-form.tsx +67 -0
  55. package/dist/template/storefront/app/[locale]/account/verify/complete/route.ts +33 -0
  56. package/dist/template/storefront/app/[locale]/account/verify/page.tsx +41 -0
  57. package/dist/template/storefront/app/[locale]/account/verify/refresh-form.tsx +35 -0
  58. package/dist/template/storefront/app/[locale]/cart/page.tsx +78 -0
  59. package/dist/template/storefront/app/[locale]/checkout/checkout-form.tsx +112 -0
  60. package/dist/template/storefront/app/[locale]/checkout/page.tsx +44 -0
  61. package/dist/template/storefront/app/[locale]/checkout/success/page.tsx +23 -0
  62. package/dist/template/storefront/app/[locale]/layout.tsx +48 -0
  63. package/dist/template/storefront/app/[locale]/page.tsx +10 -11
  64. package/dist/template/storefront/app/globals.css +372 -4
  65. package/dist/template/storefront/app/layout.tsx +13 -0
  66. package/dist/template/storefront/eslint.config.mjs +1 -1
  67. package/dist/template/storefront/gitignore.template +1 -0
  68. package/dist/template/storefront/lib/account-security.test.ts +74 -0
  69. package/dist/template/storefront/lib/account-security.ts +81 -0
  70. package/dist/template/storefront/lib/account.ts +366 -0
  71. package/dist/template/storefront/lib/cart-contract.ts +52 -0
  72. package/dist/template/storefront/lib/cart.test.ts +30 -0
  73. package/dist/template/storefront/lib/cart.ts +130 -0
  74. package/dist/template/storefront/lib/checkout-contract.test.ts +20 -0
  75. package/dist/template/storefront/lib/checkout-contract.ts +16 -0
  76. package/dist/template/storefront/lib/checkout.ts +143 -0
  77. package/dist/template/storefront/lib/commerce-session.test.ts +77 -0
  78. package/dist/template/storefront/lib/commerce-session.ts +85 -0
  79. package/dist/template/storefront/lib/commerce.ts +122 -1
  80. package/dist/template/storefront/lib/confirmation-cookie.ts +9 -0
  81. package/dist/template/storefront/lib/confirmation.ts +47 -0
  82. package/dist/template/storefront/lib/form-values.test.ts +14 -0
  83. package/dist/template/storefront/lib/form-values.ts +7 -0
  84. package/dist/template/storefront/lib/i18n.test.ts +50 -0
  85. package/dist/template/storefront/lib/i18n.ts +44 -0
  86. package/dist/template/storefront/lib/password-reset-token.test.ts +31 -0
  87. package/dist/template/storefront/lib/password-reset-token.ts +17 -0
  88. package/dist/template/storefront/lib/valkey-rate-limit.ts +72 -0
  89. package/dist/template/storefront/messages/en.json +89 -0
  90. package/dist/template/storefront/messages/sk.json +89 -0
  91. package/dist/template/storefront/next.config.ts +3 -1
  92. package/dist/template/storefront/package.json +4 -1
  93. package/dist/template/storefront/pnpm-lock.yaml +756 -2
  94. package/dist/template/tsconfig.json +2 -1
  95. package/dist/template/turbo.json +1 -0
  96. package/dist/template/vite.config.mts +4 -1
  97. package/dist/template-manifest.json +1 -1
  98. package/dist/template.js +3 -0
  99. package/dist/template.js.map +1 -1
  100. package/package.json +1 -1
package/README.md CHANGED
@@ -23,3 +23,11 @@ It creates `.env` from the committed development example only when missing,
23
23
  starts PostgreSQL, applies development migrations, runs the idempotent demo
24
24
  seed, and opens the server, worker, Dashboard, and storefront through Turbo.
25
25
  Use `pnpm db:down` to stop PostgreSQL without deleting its volume.
26
+
27
+ # Template build boundary
28
+
29
+ The generated Client Project template is copied from
30
+ `starter/client-project` during this package's build. Turbo treats that source
31
+ tree as a build input while excluding local runtime files such as `.env`,
32
+ `node_modules`, and `dist`; a packed generator therefore always contains the
33
+ template from the commit being verified without hashing secrets or artifacts.
package/dist/generator.js CHANGED
@@ -166,18 +166,21 @@ export async function createProject(options) {
166
166
  recursive: true,
167
167
  filter: (path) => shouldIncludeTemplatePath(relative(templateRoot, path)),
168
168
  });
169
+ // Verify the packed template before materializing npm-safe filenames such
170
+ // as `gitignore.template` into their generated-project counterparts.
171
+ const actualDigest = await sha256Tree(staging);
172
+ if (actualDigest !== expectedDigest)
173
+ fail("Starter template digest verification failed");
169
174
  for (const [packedName, generatedName] of [
170
175
  ["gitignore.template", ".gitignore"],
171
176
  ["env.example.template", ".env.example"],
177
+ ["storefront/gitignore.template", "storefront/.gitignore"],
172
178
  ]) {
173
179
  const packedPath = join(staging, packedName);
174
180
  if (await pathExists(packedPath)) {
175
181
  await rename(packedPath, join(staging, generatedName));
176
182
  }
177
183
  }
178
- const actualDigest = await sha256Tree(staging);
179
- if (actualDigest !== expectedDigest)
180
- fail("Starter template digest verification failed");
181
184
  const templateFiles = await readTemplateFiles(staging);
182
185
  assertSafeTemplate(templateFiles);
183
186
  await writeJarShopManifests(staging, name, packageVersion, actualDigest);
@@ -1 +1 @@
1
- {"version":3,"file":"generator.js","sourceRoot":"","sources":["../src/generator.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"generator.js","sourceRoot":"","sources":["../src/generator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EACL,EAAE,EACF,KAAK,EACL,OAAO,EACP,QAAQ,EACR,MAAM,EACN,EAAE,EACF,IAAI,EACJ,SAAS,GACV,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC7D,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,OAAO,EACL,iBAAiB,EACjB,MAAM,EACN,UAAU,EACV,yBAAyB,GAC1B,MAAM,eAAe,CAAC;AAEvB,MAAM,aAAa,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC;AAC1C,MAAM,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;AAC3E,MAAM,oBAAoB,GAAG,OAAO,CAClC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EACvC,UAAU,CACX,CAAC;AACF,MAAM,mBAAmB,GAAG,IAAI,CAAC,WAAW,EAAE,cAAc,CAAC,CAAC;AAC9D,MAAM,oBAAoB,GAAG,OAAO,CAClC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EACvC,wBAAwB,CACzB,CAAC;AA0BF,SAAS,IAAI,CAAC,OAAe;IAC3B,MAAM,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC;AAC3B,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,IAAc;IACtC,MAAM,CAAC,OAAO,EAAE,IAAI,EAAE,GAAG,KAAK,CAAC,GAAG,IAAI,CAAC;IACvC,IAAI,MAA0B,CAAC;IAC/B,IAAI,SAAS,GAAG,KAAK,CAAC;IAEtB,IAAI,OAAO,KAAK,KAAK,EAAE,CAAC;QACtB,IAAI,CACF,iFAAiF,CAClF,CAAC;IACJ,CAAC;IACD,IAAI,CAAC,IAAI,IAAI,CAAC,iCAAiC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QAC3D,IAAI,CAAC,wCAAwC,CAAC,CAAC;IACjD,CAAC;IACD,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,KAAK,CAAC,MAAM,EAAE,KAAK,IAAI,CAAC,EAAE,CAAC;QACrD,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC;QAC1B,IAAI,IAAI,KAAK,UAAU,EAAE,CAAC;YACxB,IAAI,MAAM,KAAK,SAAS,IAAI,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,SAAS;gBACxD,IAAI,CAAC,iDAAiD,CAAC,CAAC;YAC1D,MAAM,GAAG,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;YAC1B,KAAK,IAAI,CAAC,CAAC;QACb,CAAC;aAAM,IAAI,IAAI,KAAK,cAAc,EAAE,CAAC;YACnC,IAAI,SAAS;gBAAE,IAAI,CAAC,iDAAiD,CAAC,CAAC;YACvE,SAAS,GAAG,IAAI,CAAC;QACnB,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,6BAA6B,IAAI,EAAE,CAAC,CAAC;QAC5C,CAAC;IACH,CAAC;IACD,IAAI,MAAM,KAAK,aAAa;QAC1B,IAAI,CAAC,0CAA0C,CAAC,CAAC;IAEnD,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC;AACrC,CAAC;AAED,KAAK,UAAU,UAAU,CAAC,IAAY;IACpC,IAAI,CAAC;QACH,MAAM,IAAI,CAAC,IAAI,CAAC,CAAC;QACjB,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAK,KAA+B,CAAC,IAAI,KAAK,QAAQ;YAAE,OAAO,KAAK,CAAC;QACrE,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC;AAED,SAAS,sBAAsB,CAAC,OAAe;IAC7C,MAAM,KAAK,GAAG,4CAA4C,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACzE,IAAI,CAAC,KAAK;QAAE,IAAI,CAAC,gCAAgC,OAAO,EAAE,CAAC,CAAC;IAC5D,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IAC/B,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IAC/B,IAAI,KAAK,KAAK,EAAE,IAAI,KAAK,GAAG,EAAE,EAAE,CAAC;QAC/B,IAAI,CAAC,gCAAgC,OAAO,0BAA0B,CAAC,CAAC;IAC1E,CAAC;AACH,CAAC;AAED,SAAS,eAAe;IACtB,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC;IACpD,OAAO,QAAQ;QACb,CAAC,CAAC,CAAC,MAAM,EAAE,sBAAsB,QAAQ,EAAE,EAAE,SAAS,EAAE,mBAAmB,CAAC;QAC5E,CAAC,CAAC,CAAC,MAAM,EAAE,SAAS,EAAE,mBAAmB,CAAC,CAAC;AAC/C,CAAC;AAED,KAAK,UAAU,cAAc,CAAC,GAAW;IACvC,IAAI,CAAC;QACH,MAAM,aAAa,CAAC,UAAU,EAAE,eAAe,EAAE,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC;IAC9D,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,OAAO,GAAG,KAA6C,CAAC;QAC9D,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,OAAO,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC;QAChE,MAAM,IAAI,KAAK,CACb,0BAA0B,GAAG,GAAG,MAAM,CAAC,CAAC,CAAC,KAAK,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAC9D,CAAC;IACJ,CAAC;AACH,CAAC;AAED,KAAK,UAAU,QAAQ,CAAI,IAAY;IACrC,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAM,CAAC;AACvD,CAAC;AAED,SAAS,kBAAkB,CACzB,KAAoD;IAEpD,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IACE,IAAI,CAAC,IAAI,KAAK,MAAM;YACpB,yCAAyC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EACzD,CAAC;YACD,IAAI,CAAC,oDAAoD,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;QACxE,CAAC;QACD,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QAC3C,IAAI,yBAAyB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YACzC,IAAI,CAAC,yCAAyC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;QAC7D,CAAC;QACD,IAAI,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC,EAAE,CAAC;YACvC,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAA4B,CAAC;YAC7D,KAAK,MAAM,OAAO,IAAI;gBACpB,cAAc;gBACd,iBAAiB;gBACjB,kBAAkB;aACV,EAAE,CAAC;gBACX,MAAM,YAAY,GAAG,QAAQ,CAAC,OAAO,CACA,CAAC;gBACtC,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,YAAY,IAAI,EAAE,CAAC,EAAE,CAAC;oBAC/D,IACE,OAAO,KAAK,KAAK,QAAQ;wBACzB,8BAA8B,CAAC,IAAI,CAAC,KAAK,CAAC,EAC1C,CAAC;wBACD,IAAI,CACF,oBAAoB,IAAI,IAAI,KAAK,sBAAsB,IAAI,CAAC,IAAI,EAAE,CACnE,CAAC;oBACJ,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;AACH,CAAC;AAED,SAAS,aAAa,CAAC,IAAY;IACjC,OAAO,IAAI,CAAC,UAAU,CAAC,iBAAiB,CAAC;QACvC,IAAI,CAAC,UAAU,CAAC,oBAAoB,CAAC;QACrC,CAAC,CAAC,cAAc;QAChB,CAAC,CAAC,SAAS,CAAC;AAChB,CAAC;AAED,KAAK,UAAU,qBAAqB,CAClC,OAAe,EACf,IAAY,EACZ,cAAsB,EACtB,cAAsB;IAEtB,MAAM,KAAK,GAAG,MAAM,iBAAiB,CAAC,OAAO,CAAC,CAAC;IAC/C,MAAM,iBAAiB,GAAG,IAAI,CAAC,KAAK,CAClC,CAAC,MAAM,QAAQ,CAAC,IAAI,CAAC,OAAO,EAAE,yBAAyB,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAC/B,CAAC;IAC/C,MAAM,kBAAkB,GACtB,iBAAiB,CAAC,YAAY,EAAE,CAAC,uBAAuB,CAAC,CAAC;IAC5D,IAAI,CAAC,kBAAkB;QACrB,IAAI,CAAC,sDAAsD,CAAC,CAAC;IAE/D,MAAM,eAAe,GAAG;QACtB,aAAa,EAAE,CAAC;QAChB,OAAO,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,aAAa,EAAE;QAC9C,SAAS,EAAE,EAAE,OAAO,EAAE,yBAAyB,EAAE,OAAO,EAAE,cAAc,EAAE;QAC1E,cAAc,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE;QACpD,SAAS,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,SAAS,EAAE;QAC/C,QAAQ,EAAE,EAAE,uBAAuB,EAAE,kBAAkB,EAAE;KAC1D,CAAC;IACF,MAAM,iBAAiB,GAAG;QACxB,aAAa,EAAE,CAAC;QAChB,cAAc;QACd,KAAK,EAAE,MAAM,CAAC,WAAW,CACvB,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC;YAClB,IAAI,CAAC,IAAI;YACT;gBACE,cAAc,EAAE,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC;gBACpC,SAAS,EAAE,EAAE,IAAI,EAAE,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;aAC9C;SACF,CAAC,CACH;KACF,CAAC;IAEF,MAAM,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,UAAU,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC5D,MAAM,SAAS,CACb,IAAI,CAAC,OAAO,EAAE,uBAAuB,CAAC,EACtC,GAAG,IAAI,CAAC,SAAS,CAAC,eAAe,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAChD,CAAC;IACF,MAAM,SAAS,CACb,IAAI,CAAC,OAAO,EAAE,yBAAyB,CAAC,EACxC,GAAG,IAAI,CAAC,SAAS,CAAC,iBAAiB,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAClD,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,OAA6B;IAE7B,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IACpD,sBAAsB,CAAC,OAAO,CAAC,cAAc,IAAI,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IAExE,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IAC1C,IAAI,MAAM,UAAU,CAAC,MAAM,CAAC;QAAE,IAAI,CAAC,0BAA0B,MAAM,EAAE,CAAC,CAAC;IAEvE,MAAM,YAAY,GAAG,OAAO,CAAC,YAAY,IAAI,oBAAoB,CAAC;IAClE,IAAI,CAAC,CAAC,MAAM,UAAU,CAAC,YAAY,CAAC,CAAC;QACnC,IAAI,CAAC,gCAAgC,YAAY,EAAE,CAAC,CAAC;IAEvD,MAAM,cAAc,GAClB,OAAO,CAAC,cAAc;QACtB,CAAC,MAAM,QAAQ,CAAkB,mBAAmB,CAAC,CAAC,CAAC,OAAO,CAAC;IACjE,MAAM,cAAc,GAClB,OAAO,CAAC,cAAc;QACtB,CAAC,MAAM,QAAQ,CAAmB,oBAAoB,CAAC,CAAC,CAAC,MAAM,CAAC;IAElE,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,IAAI,IAAI,WAAW,CAAC,CAAC,CAAC;IAE1E,IAAI,CAAC;QACH,MAAM,KAAK,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC1C,MAAM,EAAE,CAAC,YAAY,EAAE,OAAO,EAAE;YAC9B,SAAS,EAAE,IAAI;YACf,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,yBAAyB,CAAC,QAAQ,CAAC,YAAY,EAAE,IAAI,CAAC,CAAC;SAC1E,CAAC,CAAC;QACH,0EAA0E;QAC1E,qEAAqE;QACrE,MAAM,YAAY,GAAG,MAAM,UAAU,CAAC,OAAO,CAAC,CAAC;QAC/C,IAAI,YAAY,KAAK,cAAc;YACjC,IAAI,CAAC,6CAA6C,CAAC,CAAC;QACtD,KAAK,MAAM,CAAC,UAAU,EAAE,aAAa,CAAC,IAAI;YACxC,CAAC,oBAAoB,EAAE,YAAY,CAAC;YACpC,CAAC,sBAAsB,EAAE,cAAc,CAAC;YACxC,CAAC,+BAA+B,EAAE,uBAAuB,CAAC;SAClD,EAAE,CAAC;YACX,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC;YAC7C,IAAI,MAAM,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;gBACjC,MAAM,MAAM,CAAC,UAAU,EAAE,IAAI,CAAC,OAAO,EAAE,aAAa,CAAC,CAAC,CAAC;YACzD,CAAC;QACH,CAAC;QACD,MAAM,aAAa,GAAG,MAAM,iBAAiB,CAAC,OAAO,CAAC,CAAC;QACvD,kBAAkB,CAAC,aAAa,CAAC,CAAC;QAClC,MAAM,qBAAqB,CAAC,OAAO,EAAE,IAAI,EAAE,cAAc,EAAE,YAAY,CAAC,CAAC;QAEzE,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,cAAc,CAAC;YAClD,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;YACvB,MAAM,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC;QAC7C,CAAC;QAED,MAAM,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QAC9B,OAAO,CAAC,GAAG,CAAC,WAAW,MAAM,EAAE,CAAC,CAAC;QACjC,OAAO,MAAM,CAAC;IAChB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,EAAE,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QACpD,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC"}
@@ -6,9 +6,17 @@
6
6
  - `src/index-worker.ts`: background jobs using the same database.
7
7
  - `src/vendure-config.ts`: runtime composition; no automatic schema sync.
8
8
  - `src/migrations/`: explicit, versioned PostgreSQL schema changes.
9
+ - `src/plugins/jarshop-checkout/`: server-owned checkout boundary and
10
+ `CheckoutAttempt` persistence seam; behavior is added by later checkout
11
+ slices.
9
12
  - `src/seed.ts`: idempotent development-only SK/EN demo catalog seed.
10
13
  - `storefront/`: independent Next.js application on port `3001`.
11
14
  - `storefront/lib/commerce.ts`: typed Commerce Facade used by storefront routes.
15
+ - `storefront/lib/cart.ts`: server-owned cart mutations using an HttpOnly
16
+ `vendure-session` cookie; browser storage is never authoritative.
17
+ - `storefront/lib/checkout.ts`: guest pickup/courier COD checkout boundary
18
+ using the idempotent JarShop Shop API mutation; Vendure remains authoritative
19
+ for shipping eligibility and totals.
12
20
  - `docker-compose.yml`: local PostgreSQL only; production infrastructure is
13
21
  intentionally outside this development contract.
14
22
  - `.jarshop/`: exact generator, Starter Release, package and ownership facts.
@@ -29,6 +37,8 @@
29
37
  - **Commerce SDK**: framework-neutral, typed server-side commerce operations.
30
38
  - **Commerce Facade**: this project's adapter between Next.js and the SDK.
31
39
  - **Dashboard**: Vendure's operator UI; it is not the storefront.
40
+ - **CheckoutAttempt**: a durable idempotency record owned by the JarShop
41
+ checkout plugin; it never stores customer PII.
32
42
 
33
43
  ## Runtime boundary
34
44
 
@@ -13,8 +13,9 @@ pnpm dev
13
13
 
14
14
  `pnpm dev` creates `.env` when needed, starts PostgreSQL, waits for readiness,
15
15
  runs development-only migrations and the idempotent demo seed, then starts the
16
- Vendure server, worker and storefront in Turbo TUI. PostgreSQL remains running
17
- after the dev processes stop; use `pnpm db:down` when you want to stop it.
16
+ Vendure server, worker, Dashboard Vite server and storefront in Turbo TUI.
17
+ PostgreSQL remains running after the dev processes stop; use `pnpm db:down` when
18
+ you want to stop it.
18
19
 
19
20
  Open the generated applications at:
20
21
 
@@ -32,6 +33,19 @@ production, replace every credential and provide secrets through the deployment
32
33
  secret store. Never commit `.env`, production credentials, private keys or
33
34
  Terraform state.
34
35
 
36
+ ## Order-email transport
37
+
38
+ Development uses the deterministic `file` transport from `.env.example`. It is
39
+ valid only for `APP_ENV=dev` or `APP_ENV=test` and writes a sanitized local
40
+ proof instead of delivering a real message.
41
+
42
+ SMTP is explicit: set `JARSHOP_EMAIL_TRANSPORT=smtp` and provide every
43
+ `JARSHOP_EMAIL_SMTP_*` value listed in `.env.example` through an untracked
44
+ environment file or the deployment secret store. The worker validates this
45
+ configuration before it can deliver an order email, but this starter does not
46
+ probe or send to an SMTP provider during application startup. A provider smoke
47
+ test is a separate operational step.
48
+
35
49
  Database schema changes are explicit. The server does not run migrations during
36
50
  startup. Use `pnpm db:migrate` after the database is available.
37
51
 
@@ -55,7 +69,10 @@ generated project. Check `.jarshop/ownership.json` before editing managed files.
55
69
 
56
70
  - **Unsupported Node.js:** install exact Node `24.18.0`, then rerun `pnpm dev`.
57
71
  - **Docker is not available:** start Docker Desktop and rerun the command.
58
- - **Port 3000 or 3001 is occupied:** stop the conflicting local process.
72
+ - **A Vendure or storefront port is occupied:** set free `PORT` and
73
+ `JARSHOP_STOREFRONT_PORT` values in `.env`, then set
74
+ `JARSHOP_COMMERCE_ENDPOINT` and `JARSHOP_STOREFRONT_URL` to the matching
75
+ local URLs before rerunning `pnpm dev`.
59
76
  - **PostgreSQL port 6543 is occupied:** set the same free
60
77
  `JARSHOP_POSTGRES_PORT` and `DB_PORT` values in `.env`.
61
78
  - **Reset only running PostgreSQL:** use `pnpm db:down`. The database volume is
@@ -9,6 +9,11 @@ services:
9
9
  POSTGRES_PASSWORD: change-me-locally
10
10
  volumes:
11
11
  - postgres_db_data:/var/lib/postgresql/data
12
+ valkey:
13
+ image: valkey/valkey:9.1.1-alpine3.24@sha256:de31910896150d5e754a07d57d227cfdde4e258ddd0d1aa4607f2d2f95843715
14
+ ports:
15
+ - "${JARSHOP_VALKEY_PORT:-6380}:6379"
16
+ command: ["valkey-server", "--save", "", "--appendonly", "no"]
12
17
 
13
18
  volumes:
14
19
  postgres_db_data:
@@ -0,0 +1,37 @@
1
+ # Protected SMTP smoke
2
+
3
+ This procedure proves that a staging Client Project can submit one controlled
4
+ message to its configured SMTP transport. It is an operational check, not an
5
+ automated test and not a production deployment procedure.
6
+
7
+ ## Before sending
8
+
9
+ 1. Use a dedicated staging SMTP credential with the least provider access
10
+ possible. Put it only in the staging secret store or an untracked `.env`.
11
+ 2. Set `APP_ENV=staging` and `JARSHOP_EMAIL_TRANSPORT=smtp`.
12
+ 3. Provide every `JARSHOP_EMAIL_SMTP_*` value from `.env.example`.
13
+ 4. Choose a test inbox that the operator can inspect. Do not use a customer
14
+ address.
15
+ 5. Confirm the file transport output directory is not the proof target.
16
+
17
+ ## Send one controlled message
18
+
19
+ ```shell
20
+ pnpm email:smoke -- --to <controlled-test-inbox> --confirm-external-send
21
+ ```
22
+
23
+ The command fails before network activity unless the environment is exactly
24
+ `staging`, SMTP is selected and valid, a valid recipient is supplied, and the
25
+ explicit confirmation flag is present. It sends no order data, confirmation
26
+ token, customer data or database write.
27
+
28
+ ## Evidence and rollback
29
+
30
+ Record the immutable application commit, provider timestamp/message ID if the
31
+ provider exposes one, and receipt in the controlled inbox. Do not record the
32
+ recipient, credentials, SMTP response body or provider secret in GitHub,
33
+ application logs or issue comments.
34
+
35
+ If the smoke fails, rotate or revoke the staging credential if its exposure is
36
+ suspected, correct the environment secret, and retry only after the provider
37
+ configuration is understood. No database rollback is required.
@@ -2,13 +2,31 @@ APP_ENV=dev
2
2
  VENDURE_DISABLE_TELEMETRY=true
3
3
  NEXT_TELEMETRY_DISABLED=1
4
4
  PORT=3000
5
+ JARSHOP_STOREFRONT_PORT=3001
6
+ JARSHOP_COMMERCE_ENDPOINT=http://localhost:3000/shop-api
5
7
  COOKIE_SECRET=replace-with-a-local-development-secret
6
8
  SUPERADMIN_USERNAME=superadmin
7
9
  SUPERADMIN_PASSWORD=change-me-locally
8
10
  DB_HOST=localhost
9
11
  DB_PORT=6543
10
12
  JARSHOP_POSTGRES_PORT=6543
13
+ JARSHOP_VALKEY_PORT=6380
14
+ JARSHOP_ACCOUNT_RATE_LIMIT_URL=redis://localhost:6380
15
+ # Production must replace this local URL with protected Valkey credentials.
11
16
  DB_NAME=vendure
12
17
  DB_USERNAME=vendure
13
18
  DB_PASSWORD=change-me-locally
14
19
  DB_SCHEMA=public
20
+ JARSHOP_ORDER_EMAIL_ENCRYPTION_KEY=MDEyMzQ1Njc4OWFiY2RlZjAxMjM0NTY3ODlhYmNkZWY=
21
+ JARSHOP_EMAIL_TRANSPORT=file
22
+ JARSHOP_EMAIL_FILE_TRANSPORT_PATH=./static/email/jarshop-outbox
23
+ # SMTP is an explicit environment-owned transport. Keep these values in an
24
+ # untracked environment file or deployment secret store; do not commit real credentials.
25
+ # JARSHOP_EMAIL_TRANSPORT=smtp
26
+ # JARSHOP_EMAIL_SMTP_HOST=smtp.example.com
27
+ # JARSHOP_EMAIL_SMTP_PORT=587
28
+ # JARSHOP_EMAIL_SMTP_SECURE=false
29
+ # JARSHOP_EMAIL_SMTP_FROM=orders@example.com
30
+ # JARSHOP_EMAIL_SMTP_USERNAME=orders@example.com
31
+ # JARSHOP_EMAIL_SMTP_PASSWORD=replace-in-secret-store
32
+ JARSHOP_STOREFRONT_URL=http://localhost:3001
@@ -7,4 +7,6 @@ dist/
7
7
  .env
8
8
  static/assets/*
9
9
  static/email/test-emails/*
10
+ static/email/jarshop-outbox/*
11
+ src/gql/
10
12
  !.gitkeep
@@ -7,9 +7,10 @@
7
7
  },
8
8
  "packageManager": "pnpm@11.18.0",
9
9
  "scripts": {
10
- "dev:server": "vendure dev server",
11
- "dev:worker": "vendure dev worker",
12
- "dev:storefront": "pnpm --dir storefront dev --port 3001",
10
+ "dev:server": "tsx ./src/index.ts",
11
+ "dev:worker": "tsx ./src/index-worker.ts",
12
+ "dev:dashboard": "vite --config vite.config.mts",
13
+ "dev:storefront": "tsx ./src/dev-storefront.ts",
13
14
  "dev": "tsx ./src/dev.ts",
14
15
  "build": "vendure build all",
15
16
  "build:server": "vendure build server",
@@ -17,13 +18,16 @@
17
18
  "build:dashboard": "vendure build dashboard",
18
19
  "start:server": "node ./dist/index.js",
19
20
  "start:worker": "node ./dist/index-worker.js",
20
- "db:up": "docker compose up -d postgres_db",
21
- "db:migrate": "vendure migrate --run",
21
+ "db:up": "docker compose up -d postgres_db valkey",
22
+ "db:migrate": "tsx ./src/migrate.ts",
22
23
  "db:seed": "tsx ./src/seed.ts",
24
+ "email:smoke": "tsx ./src/email-smoke.ts",
23
25
  "stack:up": "pnpm db:up",
24
26
  "db:down": "docker compose down"
25
27
  },
26
28
  "dependencies": {
29
+ "@nestjs/common": "11.1.28",
30
+ "@nestjs/graphql": "13.1.0",
27
31
  "@vendure/asset-server-plugin": "3.7.1",
28
32
  "@vendure/common": "3.7.1",
29
33
  "@vendure/core": "3.7.1",
@@ -31,10 +35,14 @@
31
35
  "@vendure/email-plugin": "3.7.1",
32
36
  "@vendure/graphiql-plugin": "3.7.1",
33
37
  "dotenv": "17.4.2",
38
+ "nodemailer": "9.0.4",
34
39
  "pg": "8.22.0",
40
+ "react": "19.2.4",
35
41
  "typeorm": "0.3.31"
36
42
  },
37
43
  "devDependencies": {
44
+ "@types/nodemailer": "8.0.1",
45
+ "@types/react": "19.2.14",
38
46
  "@vendure/cli": "3.7.1",
39
47
  "gql.tada": "1.11.3",
40
48
  "graphql": "16.14.2",
@@ -8,6 +8,12 @@ importers:
8
8
 
9
9
  .:
10
10
  dependencies:
11
+ '@nestjs/common':
12
+ specifier: 11.1.28
13
+ version: 11.1.28(reflect-metadata@0.2.2)(rxjs@7.8.2)(supports-color@7.2.0)
14
+ '@nestjs/graphql':
15
+ specifier: 13.1.0
16
+ version: 13.1.0(@nestjs/common@11.1.28(reflect-metadata@0.2.2)(rxjs@7.8.2)(supports-color@7.2.0))(@nestjs/core@11.1.28)(graphql@16.14.2)(reflect-metadata@0.2.2)(ts-morph@21.0.1)
11
17
  '@vendure/asset-server-plugin':
12
18
  specifier: 3.7.1
13
19
  version: 3.7.1(supports-color@7.2.0)
@@ -29,13 +35,25 @@ importers:
29
35
  dotenv:
30
36
  specifier: 17.4.2
31
37
  version: 17.4.2
38
+ nodemailer:
39
+ specifier: 9.0.4
40
+ version: 9.0.4
32
41
  pg:
33
42
  specifier: 8.22.0
34
43
  version: 8.22.0
44
+ react:
45
+ specifier: 19.2.4
46
+ version: 19.2.4
35
47
  typeorm:
36
48
  specifier: 0.3.31
37
49
  version: 0.3.31(pg@8.22.0)(supports-color@7.2.0)(ts-node@10.9.2(@types/node@26.1.2)(typescript@5.8.2))
38
50
  devDependencies:
51
+ '@types/nodemailer':
52
+ specifier: 8.0.1
53
+ version: 8.0.1
54
+ '@types/react':
55
+ specifier: 19.2.14
56
+ version: 19.2.14
39
57
  '@vendure/cli':
40
58
  specifier: 3.7.1
41
59
  version: 3.7.1(@types/node@26.1.2)(jiti@2.7.0)(lightningcss@1.32.0)(tsx@4.20.3)
@@ -2395,6 +2413,9 @@ packages:
2395
2413
  peerDependencies:
2396
2414
  '@types/react': ^19.2.0
2397
2415
 
2416
+ '@types/react@19.2.14':
2417
+ resolution: {integrity: sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==}
2418
+
2398
2419
  '@types/react@19.2.18':
2399
2420
  resolution: {integrity: sha512-AnzbBERsrLKtk2XSfTbYRLjQPdy116Sty4q+T+Bp3IC4l6jNBvreVPAHmpq9qhXQM7CXZPjLVmGMw9sy+hxQ3w==}
2400
2421
 
@@ -5345,6 +5366,10 @@ packages:
5345
5366
  react: '>=16.6.0'
5346
5367
  react-dom: '>=16.6.0'
5347
5368
 
5369
+ react@19.2.4:
5370
+ resolution: {integrity: sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ==}
5371
+ engines: {node: '>=0.10.0'}
5372
+
5348
5373
  react@19.2.8:
5349
5374
  resolution: {integrity: sha512-PWaYA1L/q9u2u7xYQi+Y3L3Yfnie7XyLeaJICV1MGD6LprsBxcAqGjYyr0eY3p+QdsA+x/Irkt4Qif8D63+Sbw==}
5350
5375
  engines: {node: '>=0.10.0'}
@@ -7012,7 +7037,7 @@ snapshots:
7012
7037
 
7013
7038
  '@graphql-tools/schema@10.0.23(graphql@16.14.2)':
7014
7039
  dependencies:
7015
- '@graphql-tools/merge': 9.0.24(graphql@16.14.2)
7040
+ '@graphql-tools/merge': 9.2.2(graphql@16.14.2)
7016
7041
  '@graphql-tools/utils': 10.8.6(graphql@16.14.2)
7017
7042
  graphql: 16.14.2
7018
7043
  tslib: 2.8.1
@@ -7424,7 +7449,7 @@ snapshots:
7424
7449
  '@apollo/server': 4.13.0(graphql@16.14.2)(supports-color@7.2.0)
7425
7450
  '@apollo/server-plugin-landing-page-graphql-playground': 4.0.1(@apollo/server@4.13.0(graphql@16.14.2)(supports-color@7.2.0))
7426
7451
  '@nestjs/common': 11.1.28(reflect-metadata@0.2.2)(rxjs@7.8.2)(supports-color@7.2.0)
7427
- '@nestjs/core': 11.1.28(@nestjs/common@11.1.28(reflect-metadata@0.2.2)(rxjs@7.8.2)(supports-color@7.2.0))(@nestjs/platform-express@11.1.28)(reflect-metadata@0.2.2)(rxjs@7.8.2)
7452
+ '@nestjs/core': 11.1.28(@nestjs/common@11.1.28(reflect-metadata@0.2.2)(rxjs@7.8.2)(supports-color@7.2.0))(@nestjs/platform-express@11.1.28(@nestjs/common@11.1.28(reflect-metadata@0.2.2)(rxjs@7.8.2)(supports-color@7.2.0))(@nestjs/core@11.1.28)(supports-color@7.2.0))(reflect-metadata@0.2.2)(rxjs@7.8.2)
7428
7453
  '@nestjs/graphql': 13.1.0(@nestjs/common@11.1.28(reflect-metadata@0.2.2)(rxjs@7.8.2)(supports-color@7.2.0))(@nestjs/core@11.1.28)(graphql@16.14.2)(reflect-metadata@0.2.2)(ts-morph@21.0.1)
7429
7454
  graphql: 16.14.2
7430
7455
  iterall: 1.3.0
@@ -7443,7 +7468,7 @@ snapshots:
7443
7468
  transitivePeerDependencies:
7444
7469
  - supports-color
7445
7470
 
7446
- '@nestjs/core@11.1.28(@nestjs/common@11.1.28(reflect-metadata@0.2.2)(rxjs@7.8.2)(supports-color@7.2.0))(@nestjs/platform-express@11.1.28)(reflect-metadata@0.2.2)(rxjs@7.8.2)':
7471
+ '@nestjs/core@11.1.28(@nestjs/common@11.1.28(reflect-metadata@0.2.2)(rxjs@7.8.2)(supports-color@7.2.0))(@nestjs/platform-express@11.1.28(@nestjs/common@11.1.28(reflect-metadata@0.2.2)(rxjs@7.8.2)(supports-color@7.2.0))(@nestjs/core@11.1.28)(supports-color@7.2.0))(reflect-metadata@0.2.2)(rxjs@7.8.2)':
7447
7472
  dependencies:
7448
7473
  '@nestjs/common': 11.1.28(reflect-metadata@0.2.2)(rxjs@7.8.2)(supports-color@7.2.0)
7449
7474
  fast-safe-stringify: 2.1.1
@@ -7462,7 +7487,7 @@ snapshots:
7462
7487
  '@graphql-tools/schema': 10.0.23(graphql@16.14.2)
7463
7488
  '@graphql-tools/utils': 10.8.6(graphql@16.14.2)
7464
7489
  '@nestjs/common': 11.1.28(reflect-metadata@0.2.2)(rxjs@7.8.2)(supports-color@7.2.0)
7465
- '@nestjs/core': 11.1.28(@nestjs/common@11.1.28(reflect-metadata@0.2.2)(rxjs@7.8.2)(supports-color@7.2.0))(@nestjs/platform-express@11.1.28)(reflect-metadata@0.2.2)(rxjs@7.8.2)
7490
+ '@nestjs/core': 11.1.28(@nestjs/common@11.1.28(reflect-metadata@0.2.2)(rxjs@7.8.2)(supports-color@7.2.0))(@nestjs/platform-express@11.1.28(@nestjs/common@11.1.28(reflect-metadata@0.2.2)(rxjs@7.8.2)(supports-color@7.2.0))(@nestjs/core@11.1.28)(supports-color@7.2.0))(reflect-metadata@0.2.2)(rxjs@7.8.2)
7466
7491
  '@nestjs/mapped-types': 2.1.0(@nestjs/common@11.1.28(reflect-metadata@0.2.2)(rxjs@7.8.2)(supports-color@7.2.0))(reflect-metadata@0.2.2)
7467
7492
  chokidar: 4.0.3
7468
7493
  fast-glob: 3.3.3
@@ -7491,7 +7516,7 @@ snapshots:
7491
7516
  '@nestjs/platform-express@11.1.28(@nestjs/common@11.1.28(reflect-metadata@0.2.2)(rxjs@7.8.2)(supports-color@7.2.0))(@nestjs/core@11.1.28)(supports-color@7.2.0)':
7492
7517
  dependencies:
7493
7518
  '@nestjs/common': 11.1.28(reflect-metadata@0.2.2)(rxjs@7.8.2)(supports-color@7.2.0)
7494
- '@nestjs/core': 11.1.28(@nestjs/common@11.1.28(reflect-metadata@0.2.2)(rxjs@7.8.2)(supports-color@7.2.0))(@nestjs/platform-express@11.1.28)(reflect-metadata@0.2.2)(rxjs@7.8.2)
7519
+ '@nestjs/core': 11.1.28(@nestjs/common@11.1.28(reflect-metadata@0.2.2)(rxjs@7.8.2)(supports-color@7.2.0))(@nestjs/platform-express@11.1.28(@nestjs/common@11.1.28(reflect-metadata@0.2.2)(rxjs@7.8.2)(supports-color@7.2.0))(@nestjs/core@11.1.28)(supports-color@7.2.0))(reflect-metadata@0.2.2)(rxjs@7.8.2)
7495
7520
  cors: 2.8.6
7496
7521
  express: 5.2.1(supports-color@7.2.0)
7497
7522
  multer: 2.2.0
@@ -7503,7 +7528,7 @@ snapshots:
7503
7528
  '@nestjs/typeorm@11.0.3(@nestjs/common@11.1.28(reflect-metadata@0.2.2)(rxjs@7.8.2)(supports-color@7.2.0))(@nestjs/core@11.1.28)(reflect-metadata@0.2.2)(rxjs@7.8.2)(typeorm@0.3.31(pg@8.22.0)(supports-color@7.2.0)(ts-node@10.9.2(@types/node@26.1.2)(typescript@5.8.2)))':
7504
7529
  dependencies:
7505
7530
  '@nestjs/common': 11.1.28(reflect-metadata@0.2.2)(rxjs@7.8.2)(supports-color@7.2.0)
7506
- '@nestjs/core': 11.1.28(@nestjs/common@11.1.28(reflect-metadata@0.2.2)(rxjs@7.8.2)(supports-color@7.2.0))(@nestjs/platform-express@11.1.28)(reflect-metadata@0.2.2)(rxjs@7.8.2)
7531
+ '@nestjs/core': 11.1.28(@nestjs/common@11.1.28(reflect-metadata@0.2.2)(rxjs@7.8.2)(supports-color@7.2.0))(@nestjs/platform-express@11.1.28(@nestjs/common@11.1.28(reflect-metadata@0.2.2)(rxjs@7.8.2)(supports-color@7.2.0))(@nestjs/core@11.1.28)(supports-color@7.2.0))(reflect-metadata@0.2.2)(rxjs@7.8.2)
7507
7532
  reflect-metadata: 0.2.2
7508
7533
  rxjs: 7.8.2
7509
7534
  typeorm: 0.3.31(pg@8.22.0)(supports-color@7.2.0)(ts-node@10.9.2(@types/node@26.1.2)(typescript@5.8.2))
@@ -8371,6 +8396,10 @@ snapshots:
8371
8396
  dependencies:
8372
8397
  '@types/react': 19.2.18
8373
8398
 
8399
+ '@types/react@19.2.14':
8400
+ dependencies:
8401
+ csstype: 3.2.3
8402
+
8374
8403
  '@types/react@19.2.18':
8375
8404
  dependencies:
8376
8405
  csstype: 3.2.3
@@ -8567,7 +8596,7 @@ snapshots:
8567
8596
  '@graphql-tools/stitch': 10.2.2(graphql@16.14.2)
8568
8597
  '@nestjs/apollo': 13.1.0(@apollo/server@4.13.0(graphql@16.14.2)(supports-color@7.2.0))(@nestjs/common@11.1.28(reflect-metadata@0.2.2)(rxjs@7.8.2)(supports-color@7.2.0))(@nestjs/core@11.1.28)(@nestjs/graphql@13.1.0(@nestjs/common@11.1.28(reflect-metadata@0.2.2)(rxjs@7.8.2)(supports-color@7.2.0))(@nestjs/core@11.1.28)(graphql@16.14.2)(reflect-metadata@0.2.2)(ts-morph@21.0.1))(graphql@16.14.2)
8569
8598
  '@nestjs/common': 11.1.28(reflect-metadata@0.2.2)(rxjs@7.8.2)(supports-color@7.2.0)
8570
- '@nestjs/core': 11.1.28(@nestjs/common@11.1.28(reflect-metadata@0.2.2)(rxjs@7.8.2)(supports-color@7.2.0))(@nestjs/platform-express@11.1.28)(reflect-metadata@0.2.2)(rxjs@7.8.2)
8599
+ '@nestjs/core': 11.1.28(@nestjs/common@11.1.28(reflect-metadata@0.2.2)(rxjs@7.8.2)(supports-color@7.2.0))(@nestjs/platform-express@11.1.28(@nestjs/common@11.1.28(reflect-metadata@0.2.2)(rxjs@7.8.2)(supports-color@7.2.0))(@nestjs/core@11.1.28)(supports-color@7.2.0))(reflect-metadata@0.2.2)(rxjs@7.8.2)
8571
8600
  '@nestjs/graphql': 13.1.0(@nestjs/common@11.1.28(reflect-metadata@0.2.2)(rxjs@7.8.2)(supports-color@7.2.0))(@nestjs/core@11.1.28)(graphql@16.14.2)(reflect-metadata@0.2.2)(ts-morph@21.0.1)
8572
8601
  '@nestjs/platform-express': 11.1.28(@nestjs/common@11.1.28(reflect-metadata@0.2.2)(rxjs@7.8.2)(supports-color@7.2.0))(@nestjs/core@11.1.28)(supports-color@7.2.0)
8573
8602
  '@nestjs/typeorm': 11.0.3(@nestjs/common@11.1.28(reflect-metadata@0.2.2)(rxjs@7.8.2)(supports-color@7.2.0))(@nestjs/core@11.1.28)(reflect-metadata@0.2.2)(rxjs@7.8.2)(typeorm@0.3.31(pg@8.22.0)(supports-color@7.2.0)(ts-node@10.9.2(@types/node@26.1.2)(typescript@5.8.2)))
@@ -11969,6 +11998,8 @@ snapshots:
11969
11998
  react: 19.2.8
11970
11999
  react-dom: 19.2.8(react@19.2.8)
11971
12000
 
12001
+ react@19.2.4: {}
12002
+
11972
12003
  react@19.2.8: {}
11973
12004
 
11974
12005
  readable-stream@3.6.2:
@@ -0,0 +1,58 @@
1
+ import { spawn } from "node:child_process";
2
+ import { resolve } from "node:path";
3
+ import dotenv from "dotenv";
4
+
5
+ const root = resolve(__dirname, "..");
6
+ const inheritedEnvironment = { ...process.env };
7
+
8
+ function parsePort(value: string): number {
9
+ const port = Number(value);
10
+ if (!Number.isInteger(port) || port < 1 || port > 65_535) {
11
+ throw new Error(
12
+ "JARSHOP_STOREFRONT_PORT must be an integer from 1 to 65535.",
13
+ );
14
+ }
15
+ return port;
16
+ }
17
+
18
+ async function main(): Promise<void> {
19
+ dotenv.config({ path: resolve(root, ".env"), quiet: true });
20
+ const storefrontPort = parsePort(
21
+ process.env.JARSHOP_STOREFRONT_PORT ?? "3001",
22
+ );
23
+ const commerceEndpoint =
24
+ process.env.JARSHOP_COMMERCE_ENDPOINT ??
25
+ `http://localhost:${process.env.PORT ?? "3000"}/shop-api`;
26
+ const child = spawn(
27
+ "pnpm",
28
+ ["--dir", "storefront", "dev", "--port", String(storefrontPort)],
29
+ {
30
+ cwd: root,
31
+ stdio: "inherit",
32
+ // Values from the root .env are intentionally not forwarded to Next.
33
+ // Server, worker and database credentials therefore stay inside their
34
+ // own process; the local storefront receives only the commerce endpoint
35
+ // and its server-only local Valkey URL.
36
+ env: {
37
+ ...inheritedEnvironment,
38
+ JARSHOP_COMMERCE_ENDPOINT: commerceEndpoint,
39
+ JARSHOP_ACCOUNT_RATE_LIMIT_URL:
40
+ process.env.JARSHOP_ACCOUNT_RATE_LIMIT_URL ??
41
+ "redis://localhost:6380",
42
+ NEXT_TELEMETRY_DISABLED: process.env.NEXT_TELEMETRY_DISABLED ?? "1",
43
+ },
44
+ },
45
+ );
46
+ await new Promise<void>((resolvePromise, reject) => {
47
+ child.once("error", reject);
48
+ child.once("exit", (code, signal) => {
49
+ if (code === 0) resolvePromise();
50
+ else reject(new Error(`storefront exited with ${signal ?? code}`));
51
+ });
52
+ });
53
+ }
54
+
55
+ main().catch((error: unknown) => {
56
+ console.error(error instanceof Error ? error.message : error);
57
+ process.exitCode = 1;
58
+ });
@@ -1,6 +1,6 @@
1
- import { copyFile, access } from "node:fs/promises";
1
+ import { access, appendFile, copyFile, readFile } from "node:fs/promises";
2
2
  import { spawn } from "node:child_process";
3
- import { createServer } from "node:net";
3
+ import { createConnection, createServer } from "node:net";
4
4
  import { resolve } from "node:path";
5
5
  import { setTimeout as delay } from "node:timers/promises";
6
6
  import dotenv from "dotenv";
@@ -45,12 +45,59 @@ async function assertPortAvailable(
45
45
  });
46
46
  }
47
47
 
48
+ async function assertServiceReachable(
49
+ port: number,
50
+ service: string,
51
+ ): Promise<void> {
52
+ await new Promise<void>((resolvePromise, reject) => {
53
+ const socket = createConnection({ host: "127.0.0.1", port });
54
+ const cleanup = () => {
55
+ socket.removeAllListeners();
56
+ socket.destroy();
57
+ };
58
+ socket.once("connect", () => {
59
+ cleanup();
60
+ resolvePromise();
61
+ });
62
+ socket.once("error", (error) => {
63
+ cleanup();
64
+ reject(error);
65
+ });
66
+ socket.setTimeout(500, () => {
67
+ cleanup();
68
+ reject(new Error(`${service} is not reachable on localhost:${port}`));
69
+ });
70
+ });
71
+ }
72
+
48
73
  async function ensureEnv() {
49
74
  try {
50
75
  await access(envFile);
51
76
  } catch {
52
77
  await copyFile(envExample, envFile);
53
78
  console.log("Created local .env from .env.example");
79
+ return;
80
+ }
81
+
82
+ const [currentEnvironment, exampleEnvironment] = await Promise.all([
83
+ readFile(envFile, "utf8"),
84
+ readFile(envExample, "utf8"),
85
+ ]);
86
+ const currentKeys = new Set(
87
+ currentEnvironment
88
+ .split(/\r?\n/)
89
+ .flatMap((line) => line.match(/^([A-Z][A-Z0-9_]*)=/)?.[1] ?? []),
90
+ );
91
+ const missingDefaults = exampleEnvironment.split(/\r?\n/).filter((line) => {
92
+ const key = line.match(/^([A-Z][A-Z0-9_]*)=/)?.[1];
93
+ return key !== undefined && !currentKeys.has(key);
94
+ });
95
+
96
+ if (missingDefaults.length > 0) {
97
+ await appendFile(envFile, `\n${missingDefaults.join("\n")}\n`);
98
+ console.log(
99
+ `Added ${missingDefaults.length} missing local default${missingDefaults.length === 1 ? "" : "s"} from .env.example`,
100
+ );
54
101
  }
55
102
  }
56
103
 
@@ -77,6 +124,10 @@ async function dockerReady() {
77
124
  process.env.JARSHOP_POSTGRES_PORT ?? process.env.DB_PORT ?? "6543",
78
125
  "JARSHOP_POSTGRES_PORT",
79
126
  );
127
+ const valkeyPort = parsePort(
128
+ process.env.JARSHOP_VALKEY_PORT ?? "6380",
129
+ "JARSHOP_VALKEY_PORT",
130
+ );
80
131
  try {
81
132
  await run("docker", ["info"], { stdio: "ignore" });
82
133
  } catch {
@@ -86,7 +137,7 @@ async function dockerReady() {
86
137
  }
87
138
 
88
139
  try {
89
- await run("docker", ["compose", "up", "-d", "postgres_db"]);
140
+ await run("docker", ["compose", "up", "-d", "postgres_db", "valkey"]);
90
141
  } catch {
91
142
  throw new Error(
92
143
  `PostgreSQL could not start on port ${dbPort}. Stop the conflicting service or choose another JARSHOP_POSTGRES_PORT.`,
@@ -109,6 +160,13 @@ async function dockerReady() {
109
160
  ],
110
161
  { stdio: "ignore" },
111
162
  );
163
+ // `pg_isready` proves readiness inside Docker. Docker Desktop can expose
164
+ // the container before its host port proxy is available, so also prove
165
+ // the connection that migrations use from the local machine.
166
+ await Promise.all([
167
+ assertServiceReachable(dbPort, "PostgreSQL"),
168
+ assertServiceReachable(valkeyPort, "Valkey"),
169
+ ]);
112
170
  return;
113
171
  } catch {
114
172
  await delay(1000);
@@ -124,9 +182,13 @@ async function main() {
124
182
  dotenv.config({ path: envFile, quiet: true });
125
183
  assertRuntime();
126
184
  const serverPort = parsePort(process.env.PORT ?? "3000", "PORT");
185
+ const storefrontPort = parsePort(
186
+ process.env.JARSHOP_STOREFRONT_PORT ?? "3001",
187
+ "JARSHOP_STOREFRONT_PORT",
188
+ );
127
189
  await Promise.all([
128
190
  assertPortAvailable(serverPort, "Vendure"),
129
- assertPortAvailable(3001, "storefront"),
191
+ assertPortAvailable(storefrontPort, "storefront"),
130
192
  ]);
131
193
  const isDev = (process.env.APP_ENV ?? "dev") === "dev";
132
194
  if (isDev) {
@@ -141,6 +203,7 @@ async function main() {
141
203
  "run",
142
204
  "dev:server",
143
205
  "dev:worker",
206
+ "dev:dashboard",
144
207
  "dev:storefront",
145
208
  `--ui=${turboUi}`,
146
209
  ];
@@ -0,0 +1,27 @@
1
+ import "dotenv/config";
2
+ import { parseSmtpSmokeCommand } from "./plugins/jarshop-checkout/email-smoke-core.js";
3
+ import { createConfiguredOrderEmailTransport } from "./plugins/jarshop-checkout/order-email-transport.js";
4
+
5
+ async function main(): Promise<void> {
6
+ const command = parseSmtpSmokeCommand(process.argv.slice(2), process.env);
7
+ const transport = createConfiguredOrderEmailTransport();
8
+ await transport.deliver({
9
+ deliveryId: 1,
10
+ email: {
11
+ recipient: command.recipient,
12
+ subject: "JarShop SMTP transport smoke",
13
+ text: [
14
+ "This is a controlled JarShop SMTP transport smoke message.",
15
+ "No customer order, bearer token, or checkout data is included.",
16
+ ].join("\n"),
17
+ },
18
+ });
19
+ console.log("SMTP smoke email was accepted by the configured transport.");
20
+ }
21
+
22
+ main().catch(() => {
23
+ console.error(
24
+ "SMTP smoke delivery failed. Check the provider configuration without copying credentials into logs.",
25
+ );
26
+ process.exitCode = 1;
27
+ });