create-brainerce-store 1.52.4 → 1.53.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/LICENSE +21 -0
- package/dist/index.js +4 -2
- package/messages/en.json +2 -0
- package/messages/he.json +2 -0
- package/package.json +1 -1
- package/templates/nextjs/base/next.config.ts +86 -76
- package/templates/nextjs/base/src/app/layout.tsx.ejs +227 -223
- package/templates/nextjs/base/src/components/checkout/checkout-form.tsx +118 -4
- package/templates/nextjs/base/src/core/providers/store-provider.tsx.ejs +10 -1
- package/templates/nextjs/designs/atelier/app-overlay/layout.tsx.ejs +255 -251
- package/templates/nextjs/designs/atelier/ui/shared/icons.tsx +269 -269
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Brainerce Inc.
|
|
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/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.53.0",
|
|
35
35
|
description: "Scaffold a production-ready e-commerce storefront connected to Brainerce",
|
|
36
36
|
bin: {
|
|
37
37
|
"create-brainerce-store": "dist/index.js"
|
|
@@ -180,7 +180,9 @@ var BRAINERCE_RUNTIME_DEPS = Object.freeze({
|
|
|
180
180
|
// must pin >=1.30 to get the auto-region + tax-estimate methods.
|
|
181
181
|
// 1.44 adds the order-level `notes` field to SetShippingAddressDto /
|
|
182
182
|
// SetCheckoutCustomerDto — the scaffolded checkout form types depend on it.
|
|
183
|
-
|
|
183
|
+
// 1.46 adds getAddressSuggestions/getAddressDetails — the scaffolded
|
|
184
|
+
// checkout form's address-autocomplete typeahead calls these directly.
|
|
185
|
+
brainerce: "^1.46.0",
|
|
184
186
|
"isomorphic-dompurify": "^3.8.0"
|
|
185
187
|
});
|
|
186
188
|
|
package/messages/en.json
CHANGED
|
@@ -258,6 +258,8 @@
|
|
|
258
258
|
"selectRegion": "Select region",
|
|
259
259
|
"address": "Address",
|
|
260
260
|
"streetAddress": "Street address",
|
|
261
|
+
"searchingAddress": "Searching…",
|
|
262
|
+
"outsideDeliveryZone": "This address is outside our regular delivery zones. You can still continue — we'll confirm delivery by phone.",
|
|
261
263
|
"apartmentSuite": "Apartment, suite, etc.",
|
|
262
264
|
"aptPlaceholder": "Apt, suite, unit, etc. (optional)",
|
|
263
265
|
"city": "City",
|
package/messages/he.json
CHANGED
|
@@ -258,6 +258,8 @@
|
|
|
258
258
|
"selectRegion": "בחרו מחוז",
|
|
259
259
|
"address": "כתובת",
|
|
260
260
|
"streetAddress": "רחוב ומספר",
|
|
261
|
+
"searchingAddress": "מחפש…",
|
|
262
|
+
"outsideDeliveryZone": "הכתובת הזו מחוץ לאזורי המשלוח הרגילים שלנו. ניתן להמשיך — ניצור איתך קשר טלפוני לתיאום המשלוח.",
|
|
261
263
|
"apartmentSuite": "דירה, קומה וכו׳",
|
|
262
264
|
"aptPlaceholder": "דירה, קומה, כניסה (אופציונלי)",
|
|
263
265
|
"city": "עיר",
|
package/package.json
CHANGED
|
@@ -1,76 +1,86 @@
|
|
|
1
|
-
import type { NextConfig } from 'next';
|
|
2
|
-
import { OPTIMIZED_IMAGE_HOSTS } from './src/core/lib/image-hosts';
|
|
3
|
-
|
|
4
|
-
// Build-time invariant — fail loud if NEXT_PUBLIC_STORE_CURRENCY is missing
|
|
5
|
-
// for a production build. Next.js inlines NEXT_PUBLIC_* into the client
|
|
6
|
-
// bundle at `next build` time; once inlined, the value cannot be patched at
|
|
7
|
-
// deploy time. A missing env here is the root cause of non-USD stores ending
|
|
8
|
-
// up with `$5,096` baked into their HTML (and indexed by Googlebot).
|
|
9
|
-
//
|
|
10
|
-
// In dev (`next dev`) we only warn, so local-only experiments don't break.
|
|
11
|
-
if (!process.env.NEXT_PUBLIC_STORE_CURRENCY) {
|
|
12
|
-
const msg =
|
|
13
|
-
'NEXT_PUBLIC_STORE_CURRENCY is not set.\n' +
|
|
14
|
-
'Next.js inlines NEXT_PUBLIC_* vars into the client bundle at build time;\n' +
|
|
15
|
-
'a missing value will silently fall back to USD in storefront price displays\n' +
|
|
16
|
-
'and ship that to search-engine crawlers. Set it in .env.local (written by\n' +
|
|
17
|
-
'create-brainerce-store) or in your CI / hosting build env (Coolify / Vercel).';
|
|
18
|
-
if (process.env.NODE_ENV === 'production') {
|
|
19
|
-
throw new Error(`[next.config] ${msg}`);
|
|
20
|
-
} else {
|
|
21
|
-
console.warn(`[next.config] warning: ${msg}`);
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
const nextConfig: NextConfig = {
|
|
26
|
-
// isomorphic-dompurify ships jsdom, which at runtime reads stylesheet files
|
|
27
|
-
// from its own package directory. Webpack bundling breaks those relative
|
|
28
|
-
// lookups — loading it externally from node_modules keeps the paths intact.
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
//
|
|
42
|
-
//
|
|
43
|
-
//
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
{
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
},
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
|
|
1
|
+
import type { NextConfig } from 'next';
|
|
2
|
+
import { OPTIMIZED_IMAGE_HOSTS } from './src/core/lib/image-hosts';
|
|
3
|
+
|
|
4
|
+
// Build-time invariant — fail loud if NEXT_PUBLIC_STORE_CURRENCY is missing
|
|
5
|
+
// for a production build. Next.js inlines NEXT_PUBLIC_* into the client
|
|
6
|
+
// bundle at `next build` time; once inlined, the value cannot be patched at
|
|
7
|
+
// deploy time. A missing env here is the root cause of non-USD stores ending
|
|
8
|
+
// up with `$5,096` baked into their HTML (and indexed by Googlebot).
|
|
9
|
+
//
|
|
10
|
+
// In dev (`next dev`) we only warn, so local-only experiments don't break.
|
|
11
|
+
if (!process.env.NEXT_PUBLIC_STORE_CURRENCY) {
|
|
12
|
+
const msg =
|
|
13
|
+
'NEXT_PUBLIC_STORE_CURRENCY is not set.\n' +
|
|
14
|
+
'Next.js inlines NEXT_PUBLIC_* vars into the client bundle at build time;\n' +
|
|
15
|
+
'a missing value will silently fall back to USD in storefront price displays\n' +
|
|
16
|
+
'and ship that to search-engine crawlers. Set it in .env.local (written by\n' +
|
|
17
|
+
'create-brainerce-store) or in your CI / hosting build env (Coolify / Vercel).';
|
|
18
|
+
if (process.env.NODE_ENV === 'production') {
|
|
19
|
+
throw new Error(`[next.config] ${msg}`);
|
|
20
|
+
} else {
|
|
21
|
+
console.warn(`[next.config] warning: ${msg}`);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const nextConfig: NextConfig = {
|
|
26
|
+
// isomorphic-dompurify ships jsdom, which at runtime reads stylesheet files
|
|
27
|
+
// from its own package directory. Webpack bundling breaks those relative
|
|
28
|
+
// lookups — loading it externally from node_modules keeps the paths intact.
|
|
29
|
+
//
|
|
30
|
+
// brainerce (the SDK) is imported across both the server and client
|
|
31
|
+
// compilation boundaries in ~60 files, including the [locale]/layout.tsx
|
|
32
|
+
// route (see generateStaticParams below) whose static params are resolved
|
|
33
|
+
// by a separate jest-worker child process in `next dev` (webpack). That
|
|
34
|
+
// worker requires the compiled page against the vendor-chunks manifest
|
|
35
|
+
// while the main dev server may still be writing it, which can throw
|
|
36
|
+
// "Cannot find module './vendor-chunks/brainerce.js'". Excluding it from
|
|
37
|
+
// server bundling (loaded externally from node_modules instead) avoids the
|
|
38
|
+
// race.
|
|
39
|
+
serverExternalPackages: ['isomorphic-dompurify', 'brainerce'],
|
|
40
|
+
images: {
|
|
41
|
+
// The storefront is a consumer of the Brainerce API — it has to render
|
|
42
|
+
// whatever image URLs the API returns. In practice those URLs are
|
|
43
|
+
// usually on cdn.brainerce.com, but a product/variant can still carry a
|
|
44
|
+
// raw upstream-merchant URL (WooCommerce, Shopify, self-hosted) while
|
|
45
|
+
// its image-import job is pending or failed. Rather than allowlist every
|
|
46
|
+
// possible merchant host (or hard-fail on them), only cdn.brainerce.com
|
|
47
|
+
// goes through the server-side optimizer; components render product/blog
|
|
48
|
+
// images via `CdnImage` (src/ui/shared/cdn-image.tsx), which
|
|
49
|
+
// detects any other host and renders it `unoptimized` — an unresized
|
|
50
|
+
// direct-from-origin fetch, same as this template's prior behavior —
|
|
51
|
+
// instead of next/image throwing on an unconfigured hostname. No
|
|
52
|
+
// server-side fetching of unknown hosts → no SSRF/DoS surface on this
|
|
53
|
+
// Next server.
|
|
54
|
+
remotePatterns: OPTIMIZED_IMAGE_HOSTS.map((hostname) => ({
|
|
55
|
+
protocol: 'https' as const,
|
|
56
|
+
hostname,
|
|
57
|
+
pathname: '/**',
|
|
58
|
+
})),
|
|
59
|
+
},
|
|
60
|
+
async headers() {
|
|
61
|
+
return [
|
|
62
|
+
{
|
|
63
|
+
source: '/(.*)',
|
|
64
|
+
headers: [
|
|
65
|
+
{
|
|
66
|
+
key: 'Strict-Transport-Security',
|
|
67
|
+
value: 'max-age=63072000; includeSubDomains; preload',
|
|
68
|
+
},
|
|
69
|
+
{ key: 'X-Content-Type-Options', value: 'nosniff' },
|
|
70
|
+
// SAMEORIGIN (not DENY) so iframe-based payment providers (e.g. Cardcom)
|
|
71
|
+
// can redirect the iframe back to /payment-complete on the storefront
|
|
72
|
+
// itself after a successful charge — the postMessage relay needs the
|
|
73
|
+
// parent frame to be able to render our own same-origin page.
|
|
74
|
+
{ key: 'X-Frame-Options', value: 'SAMEORIGIN' },
|
|
75
|
+
{ key: 'Referrer-Policy', value: 'strict-origin-when-cross-origin' },
|
|
76
|
+
{
|
|
77
|
+
key: 'Permissions-Policy',
|
|
78
|
+
value: 'camera=(), microphone=(), geolocation=(), interest-cohort=()',
|
|
79
|
+
},
|
|
80
|
+
],
|
|
81
|
+
},
|
|
82
|
+
];
|
|
83
|
+
},
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
export default nextConfig;
|