create-brainerce-store 1.83.0 → 1.85.0
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.
- package/README.md +130 -92
- package/dist/index.js +39 -17
- package/messages/en.json +3 -0
- package/messages/he.json +3 -0
- package/package.json +1 -1
- package/templates/nextjs/base/.env.local.ejs +10 -1
- package/templates/nextjs/base/AGENTS.md.ejs +229 -207
- package/templates/nextjs/base/AI-GUIDE.md +4 -0
- package/templates/nextjs/base/CLAUDE.md.ejs +240 -218
- package/templates/nextjs/base/scripts/connect.mjs +115 -18
- package/templates/nextjs/base/scripts/env-file.mjs +93 -0
- package/templates/nextjs/base/scripts/fetch-store-info.mjs +109 -83
- package/templates/nextjs/base/src/app/api/auth/reset-callback/route.ts +2 -1
- package/templates/nextjs/base/src/app/forgot-password/page.tsx +3 -2
- package/templates/nextjs/base/src/app/layout.tsx.ejs +50 -21
- package/templates/nextjs/base/src/app/opengraph-image.tsx +5 -1
- package/templates/nextjs/base/src/app/reset-password/page.tsx +25 -138
- package/templates/nextjs/base/src/app/reset-password/reset-password-form.tsx +138 -0
- package/templates/nextjs/base/src/components/auth/oauth-buttons.tsx +174 -137
- package/templates/nextjs/base/src/components/checkout/payment-step.tsx +847 -761
- package/templates/nextjs/base/src/core/lib/render-mode.ts +49 -0
- package/templates/nextjs/base/src/core/lib/store-name.ts.ejs +56 -0
- package/templates/nextjs/base/src/core/lib/use-store-name.ts +18 -0
- package/templates/nextjs/base/src/ui/home/hero-section.tsx +27 -27
- package/templates/nextjs/base/src/ui/layout/header-search.tsx +2 -2
- package/templates/nextjs/base/src/ui/layout/site-footer.tsx.ejs +160 -160
- package/templates/nextjs/base/src/ui/layout/site-header.tsx.ejs +2 -2
- package/templates/nextjs/designs/atelier/app-overlay/layout.tsx.ejs +374 -345
- package/templates/nextjs/designs/atelier/globals.css +408 -402
- package/templates/nextjs/designs/atelier/messages-patch/en.json +91 -96
- package/templates/nextjs/designs/atelier/messages-patch/he.json +91 -96
- package/templates/nextjs/designs/atelier/ui/cart/cart-bundle-offer.tsx +131 -128
- package/templates/nextjs/designs/atelier/ui/cart/cart-item.tsx +2 -1
- package/templates/nextjs/designs/atelier/ui/cart/cart-upgrade-banner.tsx +222 -219
- package/templates/nextjs/designs/atelier/ui/home/category-tiles.tsx +178 -151
- package/templates/nextjs/designs/atelier/ui/home/hero-section.tsx +61 -31
- package/templates/nextjs/designs/atelier/ui/layout/header-search.tsx +2 -2
- package/templates/nextjs/designs/atelier/ui/layout/site-footer.tsx.ejs +161 -155
- package/templates/nextjs/designs/atelier/ui/product/frequently-bought-together.tsx +232 -227
- package/templates/nextjs/designs/atelier/ui/product/product-card.tsx +271 -268
- package/templates/nextjs/designs/atelier/ui/product/product-client-section.tsx +558 -553
- package/templates/nextjs/designs/atelier/ui/product/recommendation-section.tsx +113 -110
- package/templates/nextjs/designs/atelier/ui/shared/no-photo-tile.tsx +73 -0
package/README.md
CHANGED
|
@@ -1,92 +1,130 @@
|
|
|
1
|
-
# create-brainerce-store
|
|
2
|
-
|
|
3
|
-
Scaffold a production-ready e-commerce storefront connected to [Brainerce](https://brainerce.com) — cart, checkout, variants, coupons, auth, SEO, and i18n wired out of the box.
|
|
4
|
-
|
|
5
|
-
```bash
|
|
6
|
-
npm create brainerce-store@latest my-store -- --connection-id vc_xxxxxxxx
|
|
7
|
-
# or
|
|
8
|
-
pnpm create brainerce-store my-store --connection-id vc_xxxxxxxx
|
|
9
|
-
```
|
|
10
|
-
|
|
11
|
-
Run it with no flags for a fully interactive setup. The CLI fetches your store's name, currency, language, and locales from the connection ID (`vc_*`, from your Brainerce dashboard), so the generated store matches the real channel from the first `dev` run.
|
|
12
|
-
|
|
13
|
-
## The design
|
|
14
|
-
|
|
15
|
-
Every scaffold ships **Atelier** — a complete, AI-built storefront look (not just a color theme): warm editorial gallery with soft washes + glass surfaces, a floating hero collage, near-full-bleed product grid, styled popover dropdowns, a mini-cart drawer that opens on add-to-cart, and an RTL-safe fly-to-cart micro-interaction. Fully de-branded — driven by your store's name, catalog and dashboard content.
|
|
16
|
-
|
|
17
|
-
It's a starting point, not a lock-in: the entire look lives in `src/ui/` + `globals.css` and is designed to be rewritten (see below). The shipped texts are **
|
|
18
|
-
|
|
19
|
-
## Blank-canvas mode
|
|
20
|
-
|
|
21
|
-
```bash
|
|
22
|
-
npm create brainerce-store@latest my-store -- --connection-id vc_xxx --canvas
|
|
23
|
-
```
|
|
24
|
-
|
|
25
|
-
`--canvas` ships `src/ui/` as bare, semantic, essentially-unstyled skeletons (`DESIGN ME` markers included) with zero aesthetic opinion — commerce stays fully wired. It's the starting point for designing a storefront from scratch with an AI session, and the authoring substrate for new gallery designs. Canvas mode skips the design pack entirely.
|
|
26
|
-
|
|
27
|
-
## AI-first by default
|
|
28
|
-
|
|
29
|
-
Every scaffolded store is ready to be redesigned by an AI coding session:
|
|
30
|
-
|
|
31
|
-
- **`CLAUDE.md`** — auto-loaded by Claude Code; teaches the session the one rule (`core/` is the platform's, `ui/` is yours) before it touches anything.
|
|
32
|
-
- **`AGENTS.md`** — the same context for other agentic tools.
|
|
33
|
-
- **`/design <your art-direction brief>`** — a ready-made slash command that walks the full redesign: concept → implementation in `ui/` → verification (tsc, real browser, screenshots, RTL checks).
|
|
34
|
-
- **`AI-GUIDE.md`** — the design contract: file map, per-page hook contracts, verification loop, and hard-won RTL/i18n gotchas from real agency builds.
|
|
35
|
-
|
|
36
|
-
## Architecture (core/ui)
|
|
37
|
-
|
|
38
|
-
- `src/core/` — platform-owned commerce: client, auth, providers, and data/behavior hooks that return state + handlers, never JSX. Don't modify.
|
|
39
|
-
- `src/ui/` — 100% replaceable presentation. Delete-and-rebuild is encouraged; the store keeps working.
|
|
40
|
-
- `src/app/` — thin routes composing the two (~10 lines each).
|
|
41
|
-
- An ESLint boundary rule enforces the split in both directions.
|
|
42
|
-
|
|
43
|
-
Full details: [TEMPLATE-ARCHITECTURE.md](./TEMPLATE-ARCHITECTURE.md).
|
|
44
|
-
|
|
45
|
-
## Flags
|
|
46
|
-
|
|
47
|
-
| Flag | Description | Default |
|
|
48
|
-
| ---------------------- | ------------------------------------------------------ | ------------------ |
|
|
49
|
-
| `--connection-id <id>` | Brainerce vibe-coded connection ID (`vc_*`) | prompted |
|
|
50
|
-
| `--
|
|
51
|
-
| `--
|
|
52
|
-
| `--
|
|
53
|
-
| `--
|
|
54
|
-
| `--
|
|
55
|
-
| `--
|
|
56
|
-
| `--no-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
1
|
+
# create-brainerce-store
|
|
2
|
+
|
|
3
|
+
Scaffold a production-ready e-commerce storefront connected to [Brainerce](https://brainerce.com) — cart, checkout, variants, coupons, auth, SEO, and i18n wired out of the box.
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
npm create brainerce-store@latest my-store -- --connection-id vc_xxxxxxxx
|
|
7
|
+
# or
|
|
8
|
+
pnpm create brainerce-store my-store --connection-id vc_xxxxxxxx
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Run it with no flags for a fully interactive setup. The CLI fetches your store's name, currency, language, and locales from the connection ID (`vc_*`, from your Brainerce dashboard), so the generated store matches the real channel from the first `dev` run.
|
|
12
|
+
|
|
13
|
+
## The design
|
|
14
|
+
|
|
15
|
+
Every scaffold ships **Atelier** — a complete, AI-built storefront look (not just a color theme): warm editorial gallery with soft washes + glass surfaces, a floating hero collage, near-full-bleed product grid, styled popover dropdowns, a mini-cart drawer that opens on add-to-cart, and an RTL-safe fly-to-cart micro-interaction. Fully de-branded — driven by your store's name, catalog and dashboard content.
|
|
16
|
+
|
|
17
|
+
It's a starting point, not a lock-in: the entire look lives in `src/ui/` + `globals.css` and is designed to be rewritten (see below). The shipped texts are **vertical-neutral placeholder content** (like any template's sample copy: they name no product category) — your catalog replaces the imagery automatically, and the copy (hero, story, footer tagline) lives in `messages/` ready to be rewritten in your own voice by you or an AI session. On a brand-new store with no products yet, the homepage hero shows a designed placeholder that swaps for your first published products.
|
|
18
|
+
|
|
19
|
+
## Blank-canvas mode
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
npm create brainerce-store@latest my-store -- --connection-id vc_xxx --canvas
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
`--canvas` ships `src/ui/` as bare, semantic, essentially-unstyled skeletons (`DESIGN ME` markers included) with zero aesthetic opinion — commerce stays fully wired. It's the starting point for designing a storefront from scratch with an AI session, and the authoring substrate for new gallery designs. Canvas mode skips the design pack entirely.
|
|
26
|
+
|
|
27
|
+
## AI-first by default
|
|
28
|
+
|
|
29
|
+
Every scaffolded store is ready to be redesigned by an AI coding session:
|
|
30
|
+
|
|
31
|
+
- **`CLAUDE.md`** — auto-loaded by Claude Code; teaches the session the one rule (`core/` is the platform's, `ui/` is yours) before it touches anything.
|
|
32
|
+
- **`AGENTS.md`** — the same context for other agentic tools.
|
|
33
|
+
- **`/design <your art-direction brief>`** — a ready-made slash command that walks the full redesign: concept → implementation in `ui/` → verification (tsc, real browser, screenshots, RTL checks).
|
|
34
|
+
- **`AI-GUIDE.md`** — the design contract: file map, per-page hook contracts, verification loop, and hard-won RTL/i18n gotchas from real agency builds.
|
|
35
|
+
|
|
36
|
+
## Architecture (core/ui)
|
|
37
|
+
|
|
38
|
+
- `src/core/` — platform-owned commerce: client, auth, providers, and data/behavior hooks that return state + handlers, never JSX. Don't modify.
|
|
39
|
+
- `src/ui/` — 100% replaceable presentation. Delete-and-rebuild is encouraged; the store keeps working.
|
|
40
|
+
- `src/app/` — thin routes composing the two (~10 lines each).
|
|
41
|
+
- An ESLint boundary rule enforces the split in both directions.
|
|
42
|
+
|
|
43
|
+
Full details: [TEMPLATE-ARCHITECTURE.md](./TEMPLATE-ARCHITECTURE.md).
|
|
44
|
+
|
|
45
|
+
## Flags
|
|
46
|
+
|
|
47
|
+
| Flag | Description | Default |
|
|
48
|
+
| ---------------------- | ------------------------------------------------------ | ------------------ |
|
|
49
|
+
| `--connection-id <id>` | Brainerce vibe-coded connection ID (`vc_*`) | prompted |
|
|
50
|
+
| `--defer-connection` | Scaffold now, connect later with `npm run connect` | off |
|
|
51
|
+
| `--canvas` | Bare unstyled `src/ui/` skeletons for AI-driven design | off |
|
|
52
|
+
| `--language <lang>` | Store language (`en`, `he`). **One-way** — see below | fetched from store |
|
|
53
|
+
| `--pkg-manager <pm>` | `npm`, `pnpm`, `yarn`, `bun` | auto-detected |
|
|
54
|
+
| `--framework <fw>` | `nextjs` (Vite/Remix coming) | `nextjs` |
|
|
55
|
+
| `--api-url <url>` | Brainerce API base URL (or `BRAINERCE_API_URL` env) | auto-discovered |
|
|
56
|
+
| `--no-git` | Skip git initialization | git on |
|
|
57
|
+
| `--no-install` | Skip dependency installation | install on |
|
|
58
|
+
|
|
59
|
+
Pass `.` as the project name to scaffold into the current directory.
|
|
60
|
+
|
|
61
|
+
`--language` is the one decision that cannot be changed after scaffolding: it
|
|
62
|
+
picks which `messages/` ship and the `<html lang>` / `dir` of every page.
|
|
63
|
+
`npm run connect` and `npm run setup` refresh the store name and currency from
|
|
64
|
+
the live channel, never the language — a store in the wrong language is
|
|
65
|
+
re-scaffolded, not adjusted. Pass it explicitly when you know it (for example
|
|
66
|
+
`--language he` for a Hebrew merchant); without a channel to read, a deferred
|
|
67
|
+
scaffold assumes `en`.
|
|
68
|
+
|
|
69
|
+
## Building first, connecting later
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
npm create brainerce-store@latest my-store -- --defer-connection --language he
|
|
73
|
+
cd my-store
|
|
74
|
+
npm run connect # one browser approval; creates a store + channel if needed
|
|
75
|
+
npm run build # NEXT_PUBLIC_* values are baked at build time
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
`--defer-connection` writes a placeholder channel id and skips the approval,
|
|
79
|
+
so an AI builder can construct the whole storefront without stopping. The
|
|
80
|
+
scaffold then knows no store: the name it bakes is the project directory name
|
|
81
|
+
and the currency is `USD`. `npm run connect` writes the real channel id and
|
|
82
|
+
runs `npm run setup`, which fetches the real name and currency into
|
|
83
|
+
`.env.local`. At runtime the storefront prefers the live store name and
|
|
84
|
+
currency from the API (server components, `<title>`, JSON-LD, the Open Graph
|
|
85
|
+
card) and falls back to those `.env.local` values, then to the scaffold
|
|
86
|
+
literal, so a connected store is branded correctly on the first request
|
|
87
|
+
without a rebuild. The `NEXT_PUBLIC_*` fallbacks the client bundle carries are
|
|
88
|
+
inlined at build time, though, so **rebuild before deploying and restart a
|
|
89
|
+
running dev server** after connecting — `connect` says so when it finishes.
|
|
90
|
+
|
|
91
|
+
`npm run connect -- --seed-products '[{"name":"Burr Grinder","basePrice":389}]'`
|
|
92
|
+
seeds a starter catalog in the same approval and reports, per product, whether
|
|
93
|
+
it was created and whether it is published to this channel; a product that
|
|
94
|
+
exists but is not published is named so you can publish it from the dashboard
|
|
95
|
+
rather than add it twice. On PowerShell put the JSON in
|
|
96
|
+
`BRAINERCE_SEED_PRODUCTS` instead of the flag.
|
|
97
|
+
|
|
98
|
+
## Reading the connection
|
|
99
|
+
|
|
100
|
+
Before scaffolding, the CLI reads the channel from `/api/vc/<id>/info` so the
|
|
101
|
+
generated project gets the real store name, currency and language rather than
|
|
102
|
+
guesses. It walks production first, then staging, and stops at the first
|
|
103
|
+
environment that answers. When it has to fall back, it says so and names the
|
|
104
|
+
URL the project will be wired to.
|
|
105
|
+
|
|
106
|
+
That endpoint checks the request's `Origin` against the channel's **Domain**
|
|
107
|
+
and **Allowed Origins**, and the match counts the **port**. A Test channel with
|
|
108
|
+
an empty Domain box accepts anything; one with `localhost:3000` recorded will
|
|
109
|
+
refuse a bare `http://localhost`. The CLI therefore presents
|
|
110
|
+
`http://localhost:3000` first and plain `http://localhost` second, and reports
|
|
111
|
+
what every environment said rather than only the last one. A `403` from
|
|
112
|
+
production must never surface as "not found on staging".
|
|
113
|
+
|
|
114
|
+
A channel it cannot read is a hard stop, not a warning. Build-time
|
|
115
|
+
`NEXT_PUBLIC_*` values are inlined into the client bundle and cannot be
|
|
116
|
+
corrected at deploy time, so guessing `USD` / `en` here would ship a storefront
|
|
117
|
+
quoting the wrong currency.
|
|
118
|
+
|
|
119
|
+
## Requirements
|
|
120
|
+
|
|
121
|
+
Node `^20.19.0 || ^22.13.0 || >=24.0.0`.
|
|
122
|
+
|
|
123
|
+
## After scaffolding
|
|
124
|
+
|
|
125
|
+
```bash
|
|
126
|
+
cd my-store
|
|
127
|
+
pnpm dev # store at http://localhost:3000
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
Want a unique look? Open the folder in Claude Code and run `/design <your art-direction brief>`.
|
package/dist/index.js
CHANGED
|
@@ -31,7 +31,7 @@ var require_package = __commonJS({
|
|
|
31
31
|
"package.json"(exports2, module2) {
|
|
32
32
|
module2.exports = {
|
|
33
33
|
name: "create-brainerce-store",
|
|
34
|
-
version: "1.
|
|
34
|
+
version: "1.85.0",
|
|
35
35
|
description: "Scaffold a production-ready e-commerce storefront connected to Brainerce",
|
|
36
36
|
homepage: "https://brainerce.com",
|
|
37
37
|
repository: {
|
|
@@ -629,8 +629,10 @@ function toJsStringLiteral(value) {
|
|
|
629
629
|
return JSON.stringify(value);
|
|
630
630
|
}
|
|
631
631
|
function toEnvLiteral(value) {
|
|
632
|
-
const clean = stripControlChars(value).replace(
|
|
633
|
-
return `"${clean}"`;
|
|
632
|
+
const clean = stripControlChars(value).replace(/\$/g, "\\$");
|
|
633
|
+
if (!clean.includes('"') && !/\\[nr]/.test(clean)) return `"${clean}"`;
|
|
634
|
+
if (!clean.includes("'")) return `'${clean}'`;
|
|
635
|
+
return `\`${clean.replace(/`/g, "")}\``;
|
|
634
636
|
}
|
|
635
637
|
function isValidLocale(locale) {
|
|
636
638
|
return typeof locale === "string" && /^[a-zA-Z]{2,3}(-[a-zA-Z0-9]{2,8})?$/.test(locale);
|
|
@@ -682,15 +684,19 @@ async function scaffold(options) {
|
|
|
682
684
|
/** Raw store name for prose contexts (markdown docs) — JS/env contexts
|
|
683
685
|
* must keep using the escaped storeNameJs / storeNameEnv variants. */
|
|
684
686
|
storeName: cleanStoreName,
|
|
687
|
+
/** The scaffold-time name as a JS literal. In the base template it lands
|
|
688
|
+
* in ONE place, `src/core/lib/store-name.ts.ejs`, as the LAST fallback
|
|
689
|
+
* behind live `storeInfo.name` and `NEXT_PUBLIC_STORE_NAME` — under
|
|
690
|
+
* `--defer-connection` it is only the project directory name, so
|
|
691
|
+
* nothing else may bake it. The atelier `app-overlay/layout.tsx.ejs`
|
|
692
|
+
* resolves the name the same way and splices nothing. */
|
|
685
693
|
storeNameJs: toJsStringLiteral(cleanStoreName),
|
|
686
|
-
/** Pre-escaped for splicing into a JSON string value (no wrapping
|
|
687
|
-
* quotes) — used by the `{{storeName}}` token in messages-patch files. */
|
|
688
|
-
storeNameJsonEscaped: JSON.stringify(cleanStoreName).slice(1, -1),
|
|
689
694
|
titleTemplateJs: toJsStringLiteral(`%s | ${cleanStoreName}`),
|
|
690
695
|
storeNameEnv: toEnvLiteral(cleanStoreName),
|
|
691
696
|
currencyEnv: toEnvLiteral(cleanCurrency),
|
|
692
697
|
apiBaseUrlEnv: toEnvLiteral(cleanApiBaseUrl),
|
|
693
698
|
language: options.language,
|
|
699
|
+
deferred: options.deferred === true,
|
|
694
700
|
direction,
|
|
695
701
|
fontImport: fontConfig.fontImport,
|
|
696
702
|
fontVariable: fontConfig.fontVariable,
|
|
@@ -767,11 +773,7 @@ async function scaffold(options) {
|
|
|
767
773
|
if (!await import_fs_extra.default.pathExists(patchFile)) continue;
|
|
768
774
|
const targetFile = import_path.default.join(targetMessages, file);
|
|
769
775
|
const base = await import_fs_extra.default.readJson(targetFile);
|
|
770
|
-
const
|
|
771
|
-
/\{\{storeName\}\}/g,
|
|
772
|
-
templateVars.storeNameJsonEscaped
|
|
773
|
-
);
|
|
774
|
-
const patch = JSON.parse(patchText);
|
|
776
|
+
const patch = await import_fs_extra.default.readJson(patchFile);
|
|
775
777
|
await import_fs_extra.default.writeJson(targetFile, deepMerge(base, patch), { spaces: 2 });
|
|
776
778
|
}
|
|
777
779
|
}
|
|
@@ -1127,10 +1129,25 @@ async function runSeed(apiBaseUrl, deviceCode, products) {
|
|
|
1127
1129
|
}
|
|
1128
1130
|
const created = Array.isArray(body.created) ? body.created : [];
|
|
1129
1131
|
const failed = Array.isArray(body.failed) ? body.failed : [];
|
|
1130
|
-
|
|
1132
|
+
const reportsPublish = created.some((p) => typeof p.published === "boolean");
|
|
1133
|
+
const live = reportsPublish ? created.filter((p) => p.published !== false) : created;
|
|
1134
|
+
const unpublished = reportsPublish ? created.filter((p) => p.published === false) : [];
|
|
1135
|
+
if (live.length > 0) {
|
|
1131
1136
|
logger.success(
|
|
1132
|
-
` Seeded ${
|
|
1137
|
+
` Seeded${reportsPublish ? " and published" : ""} ${live.length} product(s): ${live.map((p) => p.name).join(", ")}`
|
|
1138
|
+
);
|
|
1139
|
+
}
|
|
1140
|
+
for (const p of unpublished) {
|
|
1141
|
+
logger.info(
|
|
1142
|
+
` Created but NOT published to this sales channel: ${p.name} \u2014 ${p.publishError || "the publish did not land"}`
|
|
1143
|
+
);
|
|
1144
|
+
}
|
|
1145
|
+
if (unpublished.length > 0) {
|
|
1146
|
+
logger.info(
|
|
1147
|
+
` ${unpublished.length} product(s) exist in the store but will not show on the storefront.`
|
|
1133
1148
|
);
|
|
1149
|
+
logger.info(" Do NOT re-add them. Publish them from the dashboard: Products > the product >");
|
|
1150
|
+
logger.info(" sales channels > toggle this channel on.");
|
|
1134
1151
|
}
|
|
1135
1152
|
for (const f of failed) {
|
|
1136
1153
|
logger.info(` Not created: ${f.name} \u2014 ${f.reason}`);
|
|
@@ -1475,6 +1492,7 @@ program.name("create-brainerce-store").description("Scaffold a production-ready
|
|
|
1475
1492
|
language: language || storeInfo.language,
|
|
1476
1493
|
i18n: storeInfo.i18n,
|
|
1477
1494
|
scaffoldInPlace,
|
|
1495
|
+
deferred: connectionId === DEFERRED_CONNECTION_ID,
|
|
1478
1496
|
canvas,
|
|
1479
1497
|
design: canvas ? void 0 : design || "atelier"
|
|
1480
1498
|
});
|
|
@@ -1560,7 +1578,10 @@ Your store will be running at http://localhost:3000
|
|
|
1560
1578
|
`
|
|
1561
1579
|
This store is not connected yet. \`connect\` opens one browser approval,
|
|
1562
1580
|
writes the sales channel id into .env.local, and creates a store and a
|
|
1563
|
-
channel for you if you have neither.
|
|
1581
|
+
channel for you if you have neither. It then fetches the store's real name
|
|
1582
|
+
and currency into .env.local \u2014 until it runs, the storefront calls itself
|
|
1583
|
+
"${projectName}". Those values are baked in at build time, so build (or
|
|
1584
|
+
restart \`dev\`) AFTER connecting.
|
|
1564
1585
|
|
|
1565
1586
|
Know what this store sells? Seed the catalog in that same command \u2014 the
|
|
1566
1587
|
approval opens a short window that needs no admin key, and it is the only
|
|
@@ -1576,9 +1597,10 @@ instead.) Without it the store starts empty and products come from the dashboard
|
|
|
1576
1597
|
Your store will be running at http://localhost:3000`);
|
|
1577
1598
|
logger.info(
|
|
1578
1599
|
`
|
|
1579
|
-
The storefront ships with
|
|
1580
|
-
|
|
1581
|
-
|
|
1600
|
+
The storefront ships with vertical-neutral placeholder copy (hero, story,
|
|
1601
|
+
footer tagline) \u2014 a starting point, not the merchant's voice. Your real
|
|
1602
|
+
products replace the imagery automatically; the texts live in messages/
|
|
1603
|
+
and should be rewritten in the store's own words (or let an AI session do it).`
|
|
1582
1604
|
);
|
|
1583
1605
|
logger.info(
|
|
1584
1606
|
`
|
package/messages/en.json
CHANGED
|
@@ -247,6 +247,8 @@
|
|
|
247
247
|
"payment": "Payment",
|
|
248
248
|
"securePayment": "Secure payment",
|
|
249
249
|
"preparingPayment": "Preparing payment...",
|
|
250
|
+
"paymentModalClosed": "The payment page was closed. Open it again when you are ready, or go back a step.",
|
|
251
|
+
"openPaymentModal": "Continue to payment",
|
|
250
252
|
"loadingPaymentOptions": "Loading payment options...",
|
|
251
253
|
"paymentNotConfigured": "Payment Not Configured",
|
|
252
254
|
"paymentNotConfiguredDesc": "Payment has not been set up for this store yet. Please contact the store owner.",
|
|
@@ -371,6 +373,7 @@
|
|
|
371
373
|
"lastNamePlaceholder": "Doe",
|
|
372
374
|
"atLeastChars": "At least 8 characters",
|
|
373
375
|
"orContinueWith": "or continue with",
|
|
376
|
+
"socialLoginUnavailable": "Sign-in with {provider} is not available right now. Please use your email and password.",
|
|
374
377
|
"tooShort": "Too short",
|
|
375
378
|
"weak": "Weak",
|
|
376
379
|
"fair": "Fair",
|
package/messages/he.json
CHANGED
|
@@ -247,6 +247,8 @@
|
|
|
247
247
|
"payment": "תשלום",
|
|
248
248
|
"securePayment": "תשלום מאובטח",
|
|
249
249
|
"preparingPayment": "מכין תשלום...",
|
|
250
|
+
"paymentModalClosed": "דף התשלום נסגר. כשתהיו מוכנים, פתחו אותו שוב או חזרו לשלב הקודם.",
|
|
251
|
+
"openPaymentModal": "המשך לתשלום",
|
|
250
252
|
"loadingPaymentOptions": "טוען אפשרויות תשלום...",
|
|
251
253
|
"paymentNotConfigured": "תשלום לא מוגדר",
|
|
252
254
|
"paymentNotConfiguredDesc": "התשלום עדיין לא הוגדר לחנות זו. אנא פנו לבעל החנות.",
|
|
@@ -371,6 +373,7 @@
|
|
|
371
373
|
"lastNamePlaceholder": "ישראלי",
|
|
372
374
|
"atLeastChars": "לפחות 8 תווים",
|
|
373
375
|
"orContinueWith": "או המשיכו עם",
|
|
376
|
+
"socialLoginUnavailable": "ההתחברות דרך {provider} אינה זמינה כרגע. אפשר להתחבר עם אימייל וסיסמה.",
|
|
374
377
|
"tooShort": "קצרה מדי",
|
|
375
378
|
"weak": "חלשה",
|
|
376
379
|
"fair": "סבירה",
|
package/package.json
CHANGED
|
@@ -4,7 +4,16 @@ NEXT_PUBLIC_BRAINERCE_SALES_CHANNEL_ID=<%= connectionId %>
|
|
|
4
4
|
# @deprecated will be removed when SDK 2.0 ships.
|
|
5
5
|
NEXT_PUBLIC_BRAINERCE_CONNECTION_ID=<%= connectionId %>
|
|
6
6
|
|
|
7
|
-
# Store
|
|
7
|
+
# Store name and currency. The storefront prefers the LIVE values from the
|
|
8
|
+
# Brainerce API wherever it can (server components, <title>, JSON-LD, the OG
|
|
9
|
+
# card); these are the fallback the client bundle carries for the moments
|
|
10
|
+
# before that data arrives, and what renders if the API is unreachable.
|
|
11
|
+
# Refresh them with `npm run setup` (`npm run connect` runs it for you).
|
|
12
|
+
#
|
|
13
|
+
# ⛔ NEXT_PUBLIC_* values are inlined at BUILD time. Editing this file changes
|
|
14
|
+
# nothing already built: run `npm run build` before deploying, and restart a
|
|
15
|
+
# running dev server. Values are quoted the way Next.js's env loader reads
|
|
16
|
+
# them; `setup` and `connect` write the same form (see scripts/env-file.mjs).
|
|
8
17
|
NEXT_PUBLIC_STORE_NAME=<%- storeNameEnv %>
|
|
9
18
|
NEXT_PUBLIC_STORE_CURRENCY=<%- currencyEnv %>
|
|
10
19
|
|