brainerce 1.26.0 → 1.27.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 +6 -6
- package/dist/index.d.mts +0 -6
- package/dist/index.d.ts +0 -6
- package/dist/index.js +43 -50
- package/dist/index.mjs +43 -50
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -50,9 +50,9 @@ Every Brainerce storefront must include **all mandatory features** below. Featur
|
|
|
50
50
|
| Discount banners + product badges | `client.getDiscountBanners()`, `client.getProductDiscountBadge(productId)` | ✅ |
|
|
51
51
|
| Product reviews on PDP + JSON-LD aggregateRating | `client.listProductReviews(id)`, `client.submitProductReview(id, …)` | ✅ |
|
|
52
52
|
| Site chrome (header + footer + announcement bar) | `client.content.header.get()`, `client.content.footer.get()`, `client.content.announcement.list()` | ✅ |
|
|
53
|
-
| FAQ page | `client.content.faq.get('main', locale)`
|
|
54
|
-
| Static pages catch-all (`/pages/[slug]`) | `client.content.page.getBySlug(slug, locale)`
|
|
55
|
-
| Multi-language + RTL (when i18n enabled) | `client.setLocale()`, `client.getStoreDirection(locale)`
|
|
53
|
+
| FAQ page | `client.content.faq.get('main', locale)` | conditional |
|
|
54
|
+
| Static pages catch-all (`/pages/[slug]`) | `client.content.page.getBySlug(slug, locale)` | conditional |
|
|
55
|
+
| Multi-language + RTL (when i18n enabled) | `client.setLocale()`, `client.getStoreDirection(locale)` | conditional |
|
|
56
56
|
|
|
57
57
|
---
|
|
58
58
|
|
|
@@ -349,7 +349,7 @@ await client.addToCart(cart.id, {
|
|
|
349
349
|
});
|
|
350
350
|
```
|
|
351
351
|
|
|
352
|
-
Full rendering guide + per-type validation rules: [
|
|
352
|
+
Full rendering guide + per-type validation rules: [Core Integration §2.8](https://brainerce.com/docs/integration/core) and [Rules & Reference](https://brainerce.com/docs/integration/rules).
|
|
353
353
|
|
|
354
354
|
### Modifier groups (restaurant / build-your-own products)
|
|
355
355
|
|
|
@@ -369,7 +369,7 @@ await client.addToCart(cart.id, {
|
|
|
369
369
|
|
|
370
370
|
Money on the wire is **always strings** (`priceDelta: "5.00"`). Validation failures arrive as a structured 400 envelope on `BrainerceError.details` with `code: 'MODIFIER_VALIDATION_FAILED'` and `errors[]` — see INTEGRATION-RULES.md "Modifier validation errors" for the full code list.
|
|
371
371
|
|
|
372
|
-
Full rendering guide: [
|
|
372
|
+
Full rendering guide: [Core Integration §2.9](https://brainerce.com/docs/integration/core). Restaurant features (allergens, scheduled availability, nested combos to depth 3, downsell modifiers): [Optional Features "Restaurant / build-your-own products"](https://brainerce.com/docs/integration/optional).
|
|
373
373
|
|
|
374
374
|
### Content (FAQ / Footer / Header / Announcements / Pages)
|
|
375
375
|
|
|
@@ -402,7 +402,7 @@ import DOMPurify from 'isomorphic-dompurify';
|
|
|
402
402
|
|
|
403
403
|
The `create-brainerce-store` scaffold ships ready-made components (`<AnnouncementBar>`, `<SiteHeader>`, `<SiteFooter>`, `<FaqSection>`, `<RichTextBlock>`) + a `/pages/[slug]` catch-all route — use them rather than rolling your own renderers.
|
|
404
404
|
|
|
405
|
-
Full guide: [
|
|
405
|
+
Full guide: [Core Integration "Content"](https://brainerce.com/docs/integration/core#content). Advanced patterns (channel scoping, custom fields, translations, admin writes): [Optional Features "Content"](https://brainerce.com/docs/integration/optional). Validation + sanitize rules: [Rules & Reference "Content"](https://brainerce.com/docs/integration/rules).
|
|
406
406
|
|
|
407
407
|
---
|
|
408
408
|
|
package/dist/index.d.mts
CHANGED
|
@@ -3793,12 +3793,6 @@ interface CreateMetafieldDefinitionDto {
|
|
|
3793
3793
|
enumValues?: string[];
|
|
3794
3794
|
defaultValue?: string;
|
|
3795
3795
|
position?: number;
|
|
3796
|
-
/**
|
|
3797
|
-
* When `true`, create the definition account-wide (`storeId = null`).
|
|
3798
|
-
* Defaults to false — the definition belongs to the store named in the
|
|
3799
|
-
* route's `:storeId` parameter.
|
|
3800
|
-
*/
|
|
3801
|
-
accountWide?: boolean;
|
|
3802
3796
|
/** Sales channels / platforms where this field is published. */
|
|
3803
3797
|
publishedOn?: string[];
|
|
3804
3798
|
/**
|
package/dist/index.d.ts
CHANGED
|
@@ -3793,12 +3793,6 @@ interface CreateMetafieldDefinitionDto {
|
|
|
3793
3793
|
enumValues?: string[];
|
|
3794
3794
|
defaultValue?: string;
|
|
3795
3795
|
position?: number;
|
|
3796
|
-
/**
|
|
3797
|
-
* When `true`, create the definition account-wide (`storeId = null`).
|
|
3798
|
-
* Defaults to false — the definition belongs to the store named in the
|
|
3799
|
-
* route's `:storeId` parameter.
|
|
3800
|
-
*/
|
|
3801
|
-
accountWide?: boolean;
|
|
3802
3796
|
/** Sales channels / platforms where this field is published. */
|
|
3803
3797
|
publishedOn?: string[];
|
|
3804
3798
|
/**
|
package/dist/index.js
CHANGED
|
@@ -309,87 +309,76 @@ var BrainerceClient = class {
|
|
|
309
309
|
* ```
|
|
310
310
|
*/
|
|
311
311
|
this.content = (() => {
|
|
312
|
-
const self = this;
|
|
313
312
|
const DEFAULT_KEY = "main";
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
function publicGetPath(type, key) {
|
|
318
|
-
return `/content/${encodeURIComponent(type)}/${encodeURIComponent(key)}`;
|
|
319
|
-
}
|
|
320
|
-
function adminBase() {
|
|
321
|
-
return "/api/v1/content";
|
|
322
|
-
}
|
|
323
|
-
async function publicGet(type, key, locale) {
|
|
313
|
+
const publicGetPath = (type, key) => `/content/${encodeURIComponent(type)}/${encodeURIComponent(key)}`;
|
|
314
|
+
const adminBase = () => "/api/v1/content";
|
|
315
|
+
const publicGet = async (type, key, locale) => {
|
|
324
316
|
const query = locale ? { locale } : void 0;
|
|
325
317
|
const path = publicGetPath(type, key);
|
|
326
318
|
const onNotFound = (err) => {
|
|
327
319
|
if (err instanceof BrainerceError && err.statusCode === 404) return null;
|
|
328
320
|
throw err;
|
|
329
321
|
};
|
|
330
|
-
if (
|
|
331
|
-
return
|
|
322
|
+
if (this.isVibeCodedMode()) {
|
|
323
|
+
return this.vibeCodedRequest("GET", path, void 0, query).catch(onNotFound);
|
|
332
324
|
}
|
|
333
|
-
if (
|
|
334
|
-
return
|
|
325
|
+
if (this.storeId && !this.apiKey) {
|
|
326
|
+
return this.storefrontRequest("GET", path, void 0, query).catch(onNotFound);
|
|
335
327
|
}
|
|
336
328
|
throw new BrainerceError(
|
|
337
329
|
"content.<type>.get(key) is a public-read API. In admin mode, call client.content.list({ type }) and filter by key, or use client.content.findById(id).",
|
|
338
330
|
400
|
|
339
331
|
);
|
|
340
|
-
}
|
|
341
|
-
async
|
|
332
|
+
};
|
|
333
|
+
const publicList = async (type, locale) => {
|
|
342
334
|
const query = { type };
|
|
343
335
|
if (locale) query.locale = locale;
|
|
344
|
-
if (
|
|
345
|
-
return
|
|
336
|
+
if (this.isVibeCodedMode()) {
|
|
337
|
+
return this.vibeCodedRequest("GET", "/content", void 0, query);
|
|
346
338
|
}
|
|
347
|
-
if (
|
|
348
|
-
return
|
|
339
|
+
if (this.storeId && !this.apiKey) {
|
|
340
|
+
return this.storefrontRequest("GET", "/content", void 0, query);
|
|
349
341
|
}
|
|
350
|
-
return
|
|
342
|
+
return this.adminRequest(
|
|
351
343
|
"GET",
|
|
352
344
|
`${adminBase()}?type=${encodeURIComponent(type)}`
|
|
353
345
|
);
|
|
354
|
-
}
|
|
355
|
-
|
|
356
|
-
if (
|
|
346
|
+
};
|
|
347
|
+
const requireAdmin = (action) => {
|
|
348
|
+
if (this.isVibeCodedMode() || this.storeId && !this.apiKey) {
|
|
357
349
|
throw new BrainerceError(
|
|
358
350
|
`client.content.${action}() requires admin mode (apiKey). Vibe-coded and storefront modes are read-only.`,
|
|
359
351
|
403
|
|
360
352
|
);
|
|
361
353
|
}
|
|
362
|
-
}
|
|
363
|
-
async
|
|
354
|
+
};
|
|
355
|
+
const createByType = async (type, input) => {
|
|
364
356
|
requireAdmin("create");
|
|
365
|
-
return
|
|
366
|
-
}
|
|
367
|
-
async
|
|
357
|
+
return this.adminRequest("POST", adminBase(), { ...input, type });
|
|
358
|
+
};
|
|
359
|
+
const updateById = async (id, input) => {
|
|
368
360
|
requireAdmin("update");
|
|
369
|
-
return
|
|
361
|
+
return this.adminRequest(
|
|
370
362
|
"PATCH",
|
|
371
363
|
`${adminBase()}/${encodeURIComponent(id)}`,
|
|
372
364
|
input
|
|
373
365
|
);
|
|
374
|
-
}
|
|
375
|
-
async
|
|
366
|
+
};
|
|
367
|
+
const publishById = async (id) => {
|
|
376
368
|
requireAdmin("publish");
|
|
377
|
-
return
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
);
|
|
381
|
-
}
|
|
382
|
-
async function unpublishById(id) {
|
|
369
|
+
return this.adminRequest("POST", `${adminBase()}/${encodeURIComponent(id)}/publish`);
|
|
370
|
+
};
|
|
371
|
+
const unpublishById = async (id) => {
|
|
383
372
|
requireAdmin("unpublish");
|
|
384
|
-
return
|
|
373
|
+
return this.adminRequest(
|
|
385
374
|
"POST",
|
|
386
375
|
`${adminBase()}/${encodeURIComponent(id)}/unpublish`
|
|
387
376
|
);
|
|
388
|
-
}
|
|
389
|
-
async
|
|
377
|
+
};
|
|
378
|
+
const removeById = async (id) => {
|
|
390
379
|
requireAdmin("remove");
|
|
391
|
-
await
|
|
392
|
-
}
|
|
380
|
+
await this.adminRequest("DELETE", `${adminBase()}/${encodeURIComponent(id)}`);
|
|
381
|
+
};
|
|
393
382
|
function makeNamespace(type) {
|
|
394
383
|
return {
|
|
395
384
|
/**
|
|
@@ -424,11 +413,15 @@ var BrainerceClient = class {
|
|
|
424
413
|
if (err instanceof BrainerceError && err.statusCode === 404) return null;
|
|
425
414
|
throw err;
|
|
426
415
|
};
|
|
427
|
-
if (
|
|
428
|
-
return
|
|
416
|
+
if (this.isVibeCodedMode()) {
|
|
417
|
+
return this.vibeCodedRequest("GET", path, void 0, query).catch(
|
|
418
|
+
onNotFound
|
|
419
|
+
);
|
|
429
420
|
}
|
|
430
|
-
if (
|
|
431
|
-
return
|
|
421
|
+
if (this.storeId && !this.apiKey) {
|
|
422
|
+
return this.storefrontRequest("GET", path, void 0, query).catch(
|
|
423
|
+
onNotFound
|
|
424
|
+
);
|
|
432
425
|
}
|
|
433
426
|
throw new BrainerceError(
|
|
434
427
|
"content.page.getBySlug() is a public-read API; not available in admin mode.",
|
|
@@ -440,7 +433,7 @@ var BrainerceClient = class {
|
|
|
440
433
|
/** Find a single row by its admin id (admin mode). */
|
|
441
434
|
findById: async (id) => {
|
|
442
435
|
requireAdmin("findById");
|
|
443
|
-
return
|
|
436
|
+
return this.adminRequest("GET", `${adminBase()}/${encodeURIComponent(id)}`);
|
|
444
437
|
},
|
|
445
438
|
/** List rows in admin mode with optional filters. */
|
|
446
439
|
listAdmin: async (filters) => {
|
|
@@ -449,7 +442,7 @@ var BrainerceClient = class {
|
|
|
449
442
|
if (filters?.type) params.set("type", filters.type);
|
|
450
443
|
if (filters?.status) params.set("status", filters.status);
|
|
451
444
|
const qs = params.toString();
|
|
452
|
-
return
|
|
445
|
+
return this.adminRequest(
|
|
453
446
|
"GET",
|
|
454
447
|
qs ? `${adminBase()}?${qs}` : adminBase()
|
|
455
448
|
);
|
package/dist/index.mjs
CHANGED
|
@@ -242,87 +242,76 @@ var BrainerceClient = class {
|
|
|
242
242
|
* ```
|
|
243
243
|
*/
|
|
244
244
|
this.content = (() => {
|
|
245
|
-
const self = this;
|
|
246
245
|
const DEFAULT_KEY = "main";
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
function publicGetPath(type, key) {
|
|
251
|
-
return `/content/${encodeURIComponent(type)}/${encodeURIComponent(key)}`;
|
|
252
|
-
}
|
|
253
|
-
function adminBase() {
|
|
254
|
-
return "/api/v1/content";
|
|
255
|
-
}
|
|
256
|
-
async function publicGet(type, key, locale) {
|
|
246
|
+
const publicGetPath = (type, key) => `/content/${encodeURIComponent(type)}/${encodeURIComponent(key)}`;
|
|
247
|
+
const adminBase = () => "/api/v1/content";
|
|
248
|
+
const publicGet = async (type, key, locale) => {
|
|
257
249
|
const query = locale ? { locale } : void 0;
|
|
258
250
|
const path = publicGetPath(type, key);
|
|
259
251
|
const onNotFound = (err) => {
|
|
260
252
|
if (err instanceof BrainerceError && err.statusCode === 404) return null;
|
|
261
253
|
throw err;
|
|
262
254
|
};
|
|
263
|
-
if (
|
|
264
|
-
return
|
|
255
|
+
if (this.isVibeCodedMode()) {
|
|
256
|
+
return this.vibeCodedRequest("GET", path, void 0, query).catch(onNotFound);
|
|
265
257
|
}
|
|
266
|
-
if (
|
|
267
|
-
return
|
|
258
|
+
if (this.storeId && !this.apiKey) {
|
|
259
|
+
return this.storefrontRequest("GET", path, void 0, query).catch(onNotFound);
|
|
268
260
|
}
|
|
269
261
|
throw new BrainerceError(
|
|
270
262
|
"content.<type>.get(key) is a public-read API. In admin mode, call client.content.list({ type }) and filter by key, or use client.content.findById(id).",
|
|
271
263
|
400
|
|
272
264
|
);
|
|
273
|
-
}
|
|
274
|
-
async
|
|
265
|
+
};
|
|
266
|
+
const publicList = async (type, locale) => {
|
|
275
267
|
const query = { type };
|
|
276
268
|
if (locale) query.locale = locale;
|
|
277
|
-
if (
|
|
278
|
-
return
|
|
269
|
+
if (this.isVibeCodedMode()) {
|
|
270
|
+
return this.vibeCodedRequest("GET", "/content", void 0, query);
|
|
279
271
|
}
|
|
280
|
-
if (
|
|
281
|
-
return
|
|
272
|
+
if (this.storeId && !this.apiKey) {
|
|
273
|
+
return this.storefrontRequest("GET", "/content", void 0, query);
|
|
282
274
|
}
|
|
283
|
-
return
|
|
275
|
+
return this.adminRequest(
|
|
284
276
|
"GET",
|
|
285
277
|
`${adminBase()}?type=${encodeURIComponent(type)}`
|
|
286
278
|
);
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
if (
|
|
279
|
+
};
|
|
280
|
+
const requireAdmin = (action) => {
|
|
281
|
+
if (this.isVibeCodedMode() || this.storeId && !this.apiKey) {
|
|
290
282
|
throw new BrainerceError(
|
|
291
283
|
`client.content.${action}() requires admin mode (apiKey). Vibe-coded and storefront modes are read-only.`,
|
|
292
284
|
403
|
|
293
285
|
);
|
|
294
286
|
}
|
|
295
|
-
}
|
|
296
|
-
async
|
|
287
|
+
};
|
|
288
|
+
const createByType = async (type, input) => {
|
|
297
289
|
requireAdmin("create");
|
|
298
|
-
return
|
|
299
|
-
}
|
|
300
|
-
async
|
|
290
|
+
return this.adminRequest("POST", adminBase(), { ...input, type });
|
|
291
|
+
};
|
|
292
|
+
const updateById = async (id, input) => {
|
|
301
293
|
requireAdmin("update");
|
|
302
|
-
return
|
|
294
|
+
return this.adminRequest(
|
|
303
295
|
"PATCH",
|
|
304
296
|
`${adminBase()}/${encodeURIComponent(id)}`,
|
|
305
297
|
input
|
|
306
298
|
);
|
|
307
|
-
}
|
|
308
|
-
async
|
|
299
|
+
};
|
|
300
|
+
const publishById = async (id) => {
|
|
309
301
|
requireAdmin("publish");
|
|
310
|
-
return
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
);
|
|
314
|
-
}
|
|
315
|
-
async function unpublishById(id) {
|
|
302
|
+
return this.adminRequest("POST", `${adminBase()}/${encodeURIComponent(id)}/publish`);
|
|
303
|
+
};
|
|
304
|
+
const unpublishById = async (id) => {
|
|
316
305
|
requireAdmin("unpublish");
|
|
317
|
-
return
|
|
306
|
+
return this.adminRequest(
|
|
318
307
|
"POST",
|
|
319
308
|
`${adminBase()}/${encodeURIComponent(id)}/unpublish`
|
|
320
309
|
);
|
|
321
|
-
}
|
|
322
|
-
async
|
|
310
|
+
};
|
|
311
|
+
const removeById = async (id) => {
|
|
323
312
|
requireAdmin("remove");
|
|
324
|
-
await
|
|
325
|
-
}
|
|
313
|
+
await this.adminRequest("DELETE", `${adminBase()}/${encodeURIComponent(id)}`);
|
|
314
|
+
};
|
|
326
315
|
function makeNamespace(type) {
|
|
327
316
|
return {
|
|
328
317
|
/**
|
|
@@ -357,11 +346,15 @@ var BrainerceClient = class {
|
|
|
357
346
|
if (err instanceof BrainerceError && err.statusCode === 404) return null;
|
|
358
347
|
throw err;
|
|
359
348
|
};
|
|
360
|
-
if (
|
|
361
|
-
return
|
|
349
|
+
if (this.isVibeCodedMode()) {
|
|
350
|
+
return this.vibeCodedRequest("GET", path, void 0, query).catch(
|
|
351
|
+
onNotFound
|
|
352
|
+
);
|
|
362
353
|
}
|
|
363
|
-
if (
|
|
364
|
-
return
|
|
354
|
+
if (this.storeId && !this.apiKey) {
|
|
355
|
+
return this.storefrontRequest("GET", path, void 0, query).catch(
|
|
356
|
+
onNotFound
|
|
357
|
+
);
|
|
365
358
|
}
|
|
366
359
|
throw new BrainerceError(
|
|
367
360
|
"content.page.getBySlug() is a public-read API; not available in admin mode.",
|
|
@@ -373,7 +366,7 @@ var BrainerceClient = class {
|
|
|
373
366
|
/** Find a single row by its admin id (admin mode). */
|
|
374
367
|
findById: async (id) => {
|
|
375
368
|
requireAdmin("findById");
|
|
376
|
-
return
|
|
369
|
+
return this.adminRequest("GET", `${adminBase()}/${encodeURIComponent(id)}`);
|
|
377
370
|
},
|
|
378
371
|
/** List rows in admin mode with optional filters. */
|
|
379
372
|
listAdmin: async (filters) => {
|
|
@@ -382,7 +375,7 @@ var BrainerceClient = class {
|
|
|
382
375
|
if (filters?.type) params.set("type", filters.type);
|
|
383
376
|
if (filters?.status) params.set("status", filters.status);
|
|
384
377
|
const qs = params.toString();
|
|
385
|
-
return
|
|
378
|
+
return this.adminRequest(
|
|
386
379
|
"GET",
|
|
387
380
|
qs ? `${adminBase()}?${qs}` : adminBase()
|
|
388
381
|
);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "brainerce",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.27.0",
|
|
4
4
|
"description": "Official SDK for building e-commerce storefronts with Brainerce Platform. Perfect for vibe-coded sites, AI-built stores (Cursor, Lovable, v0), and custom storefronts.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|