@jarwizz/create-jarshop 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +25 -0
  3. package/dist/cli.d.ts +2 -0
  4. package/dist/cli.js +14 -0
  5. package/dist/cli.js.map +1 -0
  6. package/dist/generator.d.ts +16 -0
  7. package/dist/generator.js +198 -0
  8. package/dist/generator.js.map +1 -0
  9. package/dist/template/AGENTS.md +41 -0
  10. package/dist/template/CONTEXT.md +37 -0
  11. package/dist/template/MEMORY.md +16 -0
  12. package/dist/template/README.md +63 -0
  13. package/dist/template/docker-compose.yml +14 -0
  14. package/dist/template/env.example.template +14 -0
  15. package/dist/template/gitignore.template +10 -0
  16. package/dist/template/package.json +46 -0
  17. package/dist/template/pnpm-lock.yaml +12852 -0
  18. package/dist/template/pnpm-workspace.yaml +24 -0
  19. package/dist/template/src/dev.ts +154 -0
  20. package/dist/template/src/environment.d.ts +19 -0
  21. package/dist/template/src/index-worker.ts +9 -0
  22. package/dist/template/src/index.ts +7 -0
  23. package/dist/template/src/migrations/1786024108433-initial.ts +2677 -0
  24. package/dist/template/src/seed.ts +138 -0
  25. package/dist/template/src/vendure-config.ts +75 -0
  26. package/dist/template/static/email/templates/email-address-change/body.hbs +20 -0
  27. package/dist/template/static/email/templates/email-verification/body.hbs +20 -0
  28. package/dist/template/static/email/templates/order-confirmation/body.hbs +133 -0
  29. package/dist/template/static/email/templates/partials/footer.hbs +10 -0
  30. package/dist/template/static/email/templates/partials/header.hbs +18 -0
  31. package/dist/template/static/email/templates/password-reset/body.hbs +24 -0
  32. package/dist/template/storefront/README.md +8 -0
  33. package/dist/template/storefront/app/[locale]/[slug]/page.tsx +52 -0
  34. package/dist/template/storefront/app/[locale]/page.tsx +35 -0
  35. package/dist/template/storefront/app/globals.css +16 -0
  36. package/dist/template/storefront/eslint.config.mjs +9 -0
  37. package/dist/template/storefront/lib/commerce.ts +35 -0
  38. package/dist/template/storefront/next-env.d.ts +6 -0
  39. package/dist/template/storefront/next.config.ts +14 -0
  40. package/dist/template/storefront/package.json +32 -0
  41. package/dist/template/storefront/pnpm-lock.yaml +3562 -0
  42. package/dist/template/storefront/pnpm-workspace.yaml +26 -0
  43. package/dist/template/storefront/tsconfig.json +30 -0
  44. package/dist/template/tsconfig.dashboard.json +4 -0
  45. package/dist/template/tsconfig.json +15 -0
  46. package/dist/template/turbo.json +8 -0
  47. package/dist/template/vite.config.mts +26 -0
  48. package/dist/template-manifest.json +3 -0
  49. package/dist/template.d.ts +8 -0
  50. package/dist/template.js +54 -0
  51. package/dist/template.js.map +1 -0
  52. package/package.json +50 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Jarwizz
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,25 @@
1
+ # @jarwizz/create-jarshop
2
+
3
+ Pre-release generator for independent JarShop Client Projects.
4
+
5
+ ```shell
6
+ pnpm dlx @jarwizz/create-jarshop@0.1.1 new demo-shop --preset sk-standard
7
+ ```
8
+
9
+ The default path performs frozen installs for the generated Vendure project and
10
+ storefront. `--no-install` is an explicit offline/CI escape hatch. The
11
+ generator never uses telemetry. In restricted local runners, set
12
+ `JARSHOP_PNPM_STORE_DIR` to an allowed pnpm store directory; normal developer
13
+ installs do not need this environment variable.
14
+
15
+ After generation, the normal local workflow is one command:
16
+
17
+ ```shell
18
+ cd demo-shop
19
+ pnpm dev
20
+ ```
21
+
22
+ It creates `.env` from the committed development example only when missing,
23
+ starts PostgreSQL, applies development migrations, runs the idempotent demo
24
+ seed, and opens the server, worker, Dashboard, and storefront through Turbo.
25
+ Use `pnpm db:down` to stop PostgreSQL without deleting its volume.
package/dist/cli.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export { createProject, parseArgs } from "./generator.js";
package/dist/cli.js ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env node
2
+ import { resolve } from "node:path";
3
+ import { fileURLToPath } from "node:url";
4
+ import { createProject } from "./generator.js";
5
+ export { createProject, parseArgs } from "./generator.js";
6
+ const isEntrypoint = process.argv[1] !== undefined &&
7
+ resolve(process.argv[1]) === fileURLToPath(import.meta.url);
8
+ if (isEntrypoint) {
9
+ createProject({ argv: process.argv.slice(2), cwd: process.cwd() }).catch((error) => {
10
+ console.error(error instanceof Error ? error.message : error);
11
+ process.exitCode = 1;
12
+ });
13
+ }
14
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAE/C,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAE1D,MAAM,YAAY,GAChB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,SAAS;IAC7B,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAE9D,IAAI,YAAY,EAAE,CAAC;IACjB,aAAa,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,KAAK,CACtE,CAAC,KAAc,EAAE,EAAE;QACjB,OAAO,CAAC,KAAK,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;QAC9D,OAAO,CAAC,QAAQ,GAAG,CAAC,CAAC;IACvB,CAAC,CACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,16 @@
1
+ export interface GeneratorArguments {
2
+ readonly name: string;
3
+ readonly noInstall: boolean;
4
+ readonly preset: "sk-standard";
5
+ }
6
+ export interface CreateProjectOptions {
7
+ readonly argv: string[];
8
+ readonly cwd: string;
9
+ readonly install?: (cwd: string) => Promise<void>;
10
+ readonly packageVersion?: string;
11
+ readonly runtimeVersion?: string;
12
+ readonly templateDigest?: string;
13
+ readonly templateRoot?: string;
14
+ }
15
+ export declare function parseArgs(argv: string[]): GeneratorArguments;
16
+ export declare function createProject(options: CreateProjectOptions): Promise<string>;
@@ -0,0 +1,198 @@
1
+ import { execFile } from "node:child_process";
2
+ import { cp, mkdir, mkdtemp, readFile, rename, rm, stat, writeFile, } from "node:fs/promises";
3
+ import { dirname, join, relative, resolve } from "node:path";
4
+ import { promisify } from "node:util";
5
+ import { fileURLToPath } from "node:url";
6
+ import { readTemplateFiles, sha256, sha256Tree, shouldIncludeTemplatePath, } from "./template.js";
7
+ const execFileAsync = promisify(execFile);
8
+ const packageRoot = resolve(dirname(fileURLToPath(import.meta.url)), "..");
9
+ const packagedTemplateRoot = resolve(dirname(fileURLToPath(import.meta.url)), "template");
10
+ const packageManifestPath = join(packageRoot, "package.json");
11
+ const templateManifestPath = resolve(dirname(fileURLToPath(import.meta.url)), "template-manifest.json");
12
+ function fail(message) {
13
+ throw new Error(message);
14
+ }
15
+ export function parseArgs(argv) {
16
+ const [command, name, ...flags] = argv;
17
+ let preset;
18
+ let noInstall = false;
19
+ if (command !== "new") {
20
+ fail("Usage: create-jarshop new <kebab-case-name> --preset sk-standard [--no-install]");
21
+ }
22
+ if (!name || !/^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/.test(name)) {
23
+ fail("Project name must be a kebab-case slug");
24
+ }
25
+ for (let index = 0; index < flags.length; index += 1) {
26
+ const flag = flags[index];
27
+ if (flag === "--preset") {
28
+ if (preset !== undefined || flags[index + 1] === undefined)
29
+ fail("The preset option must be provided exactly once");
30
+ preset = flags[index + 1];
31
+ index += 1;
32
+ }
33
+ else if (flag === "--no-install") {
34
+ if (noInstall)
35
+ fail("The no-install option may be provided only once");
36
+ noInstall = true;
37
+ }
38
+ else {
39
+ fail(`Unknown generator option: ${flag}`);
40
+ }
41
+ }
42
+ if (preset !== "sk-standard")
43
+ fail("Only the sk-standard preset is supported");
44
+ return { name, noInstall, preset };
45
+ }
46
+ async function pathExists(path) {
47
+ try {
48
+ await stat(path);
49
+ return true;
50
+ }
51
+ catch (error) {
52
+ if (error.code === "ENOENT")
53
+ return false;
54
+ throw error;
55
+ }
56
+ }
57
+ function assertSupportedRuntime(version) {
58
+ const match = /^(\d+)\.(\d+)\.(\d+)(?:-[0-9A-Za-z.-]+)?$/u.exec(version);
59
+ if (!match)
60
+ fail(`Unsupported Node.js runtime: ${version}`);
61
+ const major = Number(match[1]);
62
+ const minor = Number(match[2]);
63
+ if (major !== 24 || minor < 18) {
64
+ fail(`Unsupported Node.js runtime: ${version}; expected >=24.18.0 <25`);
65
+ }
66
+ }
67
+ function pnpmInstallArgs() {
68
+ const storeDir = process.env.JARSHOP_PNPM_STORE_DIR;
69
+ return storeDir
70
+ ? ["pnpm", `--config.store-dir=${storeDir}`, "install", "--frozen-lockfile"]
71
+ : ["pnpm", "install", "--frozen-lockfile"];
72
+ }
73
+ async function runPnpmInstall(cwd) {
74
+ try {
75
+ await execFileAsync("corepack", pnpmInstallArgs(), { cwd });
76
+ }
77
+ catch (error) {
78
+ const details = error;
79
+ const output = details.stderr?.trim() || details.stdout?.trim();
80
+ throw new Error(`pnpm install failed in ${cwd}${output ? `: ${output}` : ""}`);
81
+ }
82
+ }
83
+ async function readJson(path) {
84
+ return JSON.parse(await readFile(path, "utf8"));
85
+ }
86
+ function assertSafeTemplate(files) {
87
+ for (const file of files) {
88
+ if (file.path === ".env" ||
89
+ /(?:^|\/)(?:id_rsa|id_ed25519|.*\.pem)$/u.test(file.path)) {
90
+ fail(`Secret-like file is not allowed in the template: ${file.path}`);
91
+ }
92
+ const text = file.content.toString("utf8");
93
+ if (/__JARSHOP_[A-Z0-9_]+__/u.test(text)) {
94
+ fail(`Unresolved JarShop token in template: ${file.path}`);
95
+ }
96
+ if (file.path.endsWith("package.json")) {
97
+ const manifest = JSON.parse(text);
98
+ for (const section of [
99
+ "dependencies",
100
+ "devDependencies",
101
+ "peerDependencies",
102
+ ]) {
103
+ const dependencies = manifest[section];
104
+ for (const [name, value] of Object.entries(dependencies ?? {})) {
105
+ if (typeof value === "string" &&
106
+ /^(?:file:|link:|workspace:)/u.test(value)) {
107
+ fail(`Local dependency ${name}@${value} is not allowed in ${file.path}`);
108
+ }
109
+ }
110
+ }
111
+ }
112
+ }
113
+ }
114
+ function ownershipKind(path) {
115
+ return path.startsWith("storefront/app/") ||
116
+ path.startsWith("storefront/public/")
117
+ ? "client-owned"
118
+ : "managed";
119
+ }
120
+ async function writeJarShopManifests(staging, name, packageVersion, templateDigest) {
121
+ const files = await readTemplateFiles(staging);
122
+ const storefrontPackage = JSON.parse((await readFile(join(staging, "storefront/package.json"))).toString("utf8"));
123
+ const commerceSdkVersion = storefrontPackage.dependencies?.["@jarwizz/commerce-sdk"];
124
+ if (!commerceSdkVersion)
125
+ fail("Template is missing an exact Commerce SDK dependency");
126
+ const projectManifest = {
127
+ schemaVersion: 1,
128
+ project: { slug: name, preset: "sk-standard" },
129
+ generator: { package: "@jarwizz/create-jarshop", version: packageVersion },
130
+ starterRelease: { version: "0.1.0", templateDigest },
131
+ toolchain: { node: "24.18.0", pnpm: "11.18.0" },
132
+ packages: { "@jarwizz/commerce-sdk": commerceSdkVersion },
133
+ };
134
+ const ownershipManifest = {
135
+ schemaVersion: 1,
136
+ templateDigest,
137
+ files: Object.fromEntries(files.map((file) => [
138
+ file.path,
139
+ {
140
+ baselineDigest: sha256(file.content),
141
+ ownership: { kind: ownershipKind(file.path) },
142
+ },
143
+ ])),
144
+ };
145
+ await mkdir(join(staging, ".jarshop"), { recursive: true });
146
+ await writeFile(join(staging, ".jarshop/project.json"), `${JSON.stringify(projectManifest, null, 2)}\n`);
147
+ await writeFile(join(staging, ".jarshop/ownership.json"), `${JSON.stringify(ownershipManifest, null, 2)}\n`);
148
+ }
149
+ export async function createProject(options) {
150
+ const { name, noInstall } = parseArgs(options.argv);
151
+ assertSupportedRuntime(options.runtimeVersion ?? process.versions.node);
152
+ const target = resolve(options.cwd, name);
153
+ if (await pathExists(target))
154
+ fail(`Target already exists: ${target}`);
155
+ const templateRoot = options.templateRoot ?? packagedTemplateRoot;
156
+ if (!(await pathExists(templateRoot)))
157
+ fail(`Starter template is missing: ${templateRoot}`);
158
+ const packageVersion = options.packageVersion ??
159
+ (await readJson(packageManifestPath)).version;
160
+ const expectedDigest = options.templateDigest ??
161
+ (await readJson(templateManifestPath)).digest;
162
+ const staging = await mkdtemp(join(dirname(target), `.${name}.jarshop-`));
163
+ try {
164
+ await mkdir(staging, { recursive: true });
165
+ await cp(templateRoot, staging, {
166
+ recursive: true,
167
+ filter: (path) => shouldIncludeTemplatePath(relative(templateRoot, path)),
168
+ });
169
+ for (const [packedName, generatedName] of [
170
+ ["gitignore.template", ".gitignore"],
171
+ ["env.example.template", ".env.example"],
172
+ ]) {
173
+ const packedPath = join(staging, packedName);
174
+ if (await pathExists(packedPath)) {
175
+ await rename(packedPath, join(staging, generatedName));
176
+ }
177
+ }
178
+ const actualDigest = await sha256Tree(staging);
179
+ if (actualDigest !== expectedDigest)
180
+ fail("Starter template digest verification failed");
181
+ const templateFiles = await readTemplateFiles(staging);
182
+ assertSafeTemplate(templateFiles);
183
+ await writeJarShopManifests(staging, name, packageVersion, actualDigest);
184
+ if (!noInstall) {
185
+ const install = options.install ?? runPnpmInstall;
186
+ await install(staging);
187
+ await install(join(staging, "storefront"));
188
+ }
189
+ await rename(staging, target);
190
+ console.log(`Created ${target}`);
191
+ return target;
192
+ }
193
+ catch (error) {
194
+ await rm(staging, { recursive: true, force: true });
195
+ throw error;
196
+ }
197
+ }
198
+ //# sourceMappingURL=generator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generator.js","sourceRoot":"","sources":["../src/generator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,41 @@
1
+ # JarShop Client Project Rules
2
+
3
+ ## Read order
4
+
5
+ 1. Read the current approved issue and inspect `git status --short --branch`.
6
+ 2. Read this file and the affected section of `CONTEXT.md`.
7
+ 3. Read the nearest subtree rules, affected code, tests and manifests.
8
+ 4. Check `.jarshop/ownership.json` before changing generated managed content.
9
+
10
+ ## Invariants
11
+
12
+ - This Client Project is independent: it owns its repository, database,
13
+ configuration, secrets, deployment and infrastructure state.
14
+ - Storefront UI code accesses commerce only through `storefront/lib/commerce.ts`.
15
+ Do not import raw Vendure GraphQL contracts into UI components.
16
+ - Never silently overwrite client-owned files or a modified managed baseline.
17
+ - Migrations and seeds are explicit operations. Application startup never runs
18
+ them; the local `pnpm dev` orchestrator invokes them only in `APP_ENV=dev`.
19
+ - Never commit `.env`, credentials, private keys, production data or state.
20
+
21
+ ## Change workflow
22
+
23
+ - Work on one approved issue and one cohesive diff at a time.
24
+ - Preserve unrelated and client-owned changes.
25
+ - Run focused checks first and relevant build/runtime proof before review.
26
+ - Keep source presence, local checks, CI, staging and production evidence
27
+ clearly separated.
28
+ - Update the technical documentation in the same change as its contract.
29
+
30
+ ## Useful commands
31
+
32
+ ```shell
33
+ pnpm dev
34
+ pnpm db:migrate
35
+ pnpm db:seed
36
+ pnpm db:down
37
+ pnpm build
38
+ pnpm --dir storefront lint
39
+ pnpm --dir storefront typecheck
40
+ pnpm --dir storefront build
41
+ ```
@@ -0,0 +1,37 @@
1
+ # JarShop Client Project Context
2
+
3
+ ## System map
4
+
5
+ - `src/index.ts`: Vendure Shop/Admin APIs and Dashboard on port `3000`.
6
+ - `src/index-worker.ts`: background jobs using the same database.
7
+ - `src/vendure-config.ts`: runtime composition; no automatic schema sync.
8
+ - `src/migrations/`: explicit, versioned PostgreSQL schema changes.
9
+ - `src/seed.ts`: idempotent development-only SK/EN demo catalog seed.
10
+ - `storefront/`: independent Next.js application on port `3001`.
11
+ - `storefront/lib/commerce.ts`: typed Commerce Facade used by storefront routes.
12
+ - `docker-compose.yml`: local PostgreSQL only; production infrastructure is
13
+ intentionally outside this development contract.
14
+ - `.jarshop/`: exact generator, Starter Release, package and ownership facts.
15
+
16
+ ## Ownership
17
+
18
+ - `storefront/app/**` and `storefront/public/**` are client-owned.
19
+ - Other generated files are managed baselines unless the Ownership Manifest
20
+ records a structured exception.
21
+ - A future upgrade must stop atomically when managed content changed or an
22
+ ownership conflict cannot be resolved.
23
+
24
+ ## Vocabulary
25
+
26
+ - **Client Project**: this independently deployable generated shop.
27
+ - **Starter Release**: the immutable template baseline recorded in the Project
28
+ Manifest.
29
+ - **Commerce SDK**: framework-neutral, typed server-side commerce operations.
30
+ - **Commerce Facade**: this project's adapter between Next.js and the SDK.
31
+ - **Dashboard**: Vendure's operator UI; it is not the storefront.
32
+
33
+ ## Runtime boundary
34
+
35
+ `pnpm dev` is a local convenience flow. It may create `.env`, start Docker,
36
+ apply development migrations and seed demo data. Staging and production use
37
+ separate secrets and explicit migration/deployment procedures.
@@ -0,0 +1,16 @@
1
+ # JarShop Client Project Memory Index
2
+
3
+ This file is navigation, not a work log.
4
+
5
+ - Operating rules: `AGENTS.md`
6
+ - Architecture and vocabulary: `CONTEXT.md`
7
+ - Developer onboarding and troubleshooting: `README.md`
8
+ - Generator and package facts: `.jarshop/project.json`
9
+ - File ownership and baseline digests: `.jarshop/ownership.json`
10
+ - Vendure composition: `src/vendure-config.ts`
11
+ - Database changes: `src/migrations/`
12
+ - Commerce boundary: `storefront/lib/commerce.ts`
13
+
14
+ Use code, tests, manifests and CI as behavior evidence. Keep live handoff notes
15
+ in the issue or pull request, never in this index. Do not store secrets,
16
+ credentials, speculative claims or copied chat history here.
@@ -0,0 +1,63 @@
1
+ # JarShop Client Project Starter
2
+
3
+ This is the Vendure-based runtime starter generated for a JarShop Client Project.
4
+ It is intentionally neutral: client branding, commerce features and deployment
5
+ configuration are added by later feature slices.
6
+
7
+ ## Local setup
8
+
9
+ ```shell
10
+ pnpm install --frozen-lockfile
11
+ pnpm dev
12
+ ```
13
+
14
+ `pnpm dev` creates `.env` when needed, starts PostgreSQL, waits for readiness,
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.
18
+
19
+ Open the generated applications at:
20
+
21
+ - Storefront SK: <http://localhost:3001/sk>
22
+ - Storefront EN: <http://localhost:3001/en>
23
+ - Vendure Dashboard: <http://localhost:3000/dashboard>
24
+ - Health check: <http://localhost:3000/health>
25
+
26
+ Sign in to the local Dashboard with `SUPERADMIN_USERNAME` and
27
+ `SUPERADMIN_PASSWORD` from your untracked `.env`. The committed values are
28
+ development placeholders, not reusable staging or production credentials.
29
+
30
+ The `.env.example` values are development placeholders only. Before staging or
31
+ production, replace every credential and provide secrets through the deployment
32
+ secret store. Never commit `.env`, production credentials, private keys or
33
+ Terraform state.
34
+
35
+ Database schema changes are explicit. The server does not run migrations during
36
+ startup. Use `pnpm db:migrate` after the database is available.
37
+
38
+ ## Generated tree
39
+
40
+ ```text
41
+ .jarshop/ Generator, release and ownership facts
42
+ src/ Vendure server, worker, migration and seed source
43
+ storefront/app/ Client-owned SK/EN routes and UI
44
+ storefront/lib/commerce.ts Typed Commerce Facade
45
+ docker-compose.yml Local PostgreSQL
46
+ AGENTS.md Human and agent operating rules
47
+ CONTEXT.md Stable architecture and vocabulary
48
+ MEMORY.md Short navigation index
49
+ ```
50
+
51
+ Read `AGENTS.md`, then only the affected part of `CONTEXT.md`, before changing a
52
+ generated project. Check `.jarshop/ownership.json` before editing managed files.
53
+
54
+ ## Troubleshooting
55
+
56
+ - **Unsupported Node.js:** install exact Node `24.18.0`, then rerun `pnpm dev`.
57
+ - **Docker is not available:** start Docker Desktop and rerun the command.
58
+ - **Port 3000 or 3001 is occupied:** stop the conflicting local process.
59
+ - **PostgreSQL port 6543 is occupied:** set the same free
60
+ `JARSHOP_POSTGRES_PORT` and `DB_PORT` values in `.env`.
61
+ - **Reset only running PostgreSQL:** use `pnpm db:down`. The database volume is
62
+ retained intentionally; never delete production data as a troubleshooting
63
+ shortcut.
@@ -0,0 +1,14 @@
1
+ services:
2
+ postgres_db:
3
+ image: postgres:16.14-alpine3.24@sha256:57c72fd2a128e416c7fcc499958864df5301e940bca0a56f58fddf30ffc07777
4
+ ports:
5
+ - "${JARSHOP_POSTGRES_PORT:-6543}:5432"
6
+ environment:
7
+ POSTGRES_DB: vendure
8
+ POSTGRES_USER: vendure
9
+ POSTGRES_PASSWORD: change-me-locally
10
+ volumes:
11
+ - postgres_db_data:/var/lib/postgresql/data
12
+
13
+ volumes:
14
+ postgres_db_data:
@@ -0,0 +1,14 @@
1
+ APP_ENV=dev
2
+ VENDURE_DISABLE_TELEMETRY=true
3
+ NEXT_TELEMETRY_DISABLED=1
4
+ PORT=3000
5
+ COOKIE_SECRET=replace-with-a-local-development-secret
6
+ SUPERADMIN_USERNAME=superadmin
7
+ SUPERADMIN_PASSWORD=change-me-locally
8
+ DB_HOST=localhost
9
+ DB_PORT=6543
10
+ JARSHOP_POSTGRES_PORT=6543
11
+ DB_NAME=vendure
12
+ DB_USERNAME=vendure
13
+ DB_PASSWORD=change-me-locally
14
+ DB_SCHEMA=public
@@ -0,0 +1,10 @@
1
+ node_modules/
2
+ dist/
3
+ .next/
4
+ .turbo/
5
+ *.tsbuildinfo
6
+ .vendure/
7
+ .env
8
+ static/assets/*
9
+ static/email/test-emails/*
10
+ !.gitkeep
@@ -0,0 +1,46 @@
1
+ {
2
+ "name": "@jarwizz/jarshop-client-project",
3
+ "version": "0.1.0",
4
+ "private": true,
5
+ "engines": {
6
+ "node": ">=24.18.0"
7
+ },
8
+ "packageManager": "pnpm@11.18.0",
9
+ "scripts": {
10
+ "dev:server": "vendure dev server",
11
+ "dev:worker": "vendure dev worker",
12
+ "dev:storefront": "pnpm --dir storefront dev --port 3001",
13
+ "dev": "tsx ./src/dev.ts",
14
+ "build": "vendure build all",
15
+ "build:server": "vendure build server",
16
+ "build:worker": "vendure build worker",
17
+ "build:dashboard": "vendure build dashboard",
18
+ "start:server": "node ./dist/index.js",
19
+ "start:worker": "node ./dist/index-worker.js",
20
+ "db:up": "docker compose up -d postgres_db",
21
+ "db:migrate": "vendure migrate --run",
22
+ "db:seed": "tsx ./src/seed.ts",
23
+ "stack:up": "pnpm db:up",
24
+ "db:down": "docker compose down"
25
+ },
26
+ "dependencies": {
27
+ "@vendure/asset-server-plugin": "3.7.1",
28
+ "@vendure/common": "3.7.1",
29
+ "@vendure/core": "3.7.1",
30
+ "@vendure/dashboard": "3.7.1",
31
+ "@vendure/email-plugin": "3.7.1",
32
+ "@vendure/graphiql-plugin": "3.7.1",
33
+ "dotenv": "17.4.2",
34
+ "pg": "8.22.0",
35
+ "typeorm": "0.3.31"
36
+ },
37
+ "devDependencies": {
38
+ "@vendure/cli": "3.7.1",
39
+ "gql.tada": "1.11.3",
40
+ "graphql": "16.14.2",
41
+ "tsx": "4.20.3",
42
+ "turbo": "2.10.6",
43
+ "typescript": "5.8.2",
44
+ "vite": "7.3.6"
45
+ }
46
+ }