brainerce 2.2.0 → 2.3.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/README.md +8090 -7920
- package/dist/index.d.mts +210 -43
- package/dist/index.d.ts +210 -43
- package/dist/index.js +236 -97
- package/dist/index.mjs +236 -97
- package/package.json +4 -3
package/dist/index.js
CHANGED
|
@@ -204,7 +204,7 @@ function isDevGuardsEnabled() {
|
|
|
204
204
|
}
|
|
205
205
|
|
|
206
206
|
// src/version.ts
|
|
207
|
-
var SDK_VERSION = "2.
|
|
207
|
+
var SDK_VERSION = "2.3.0";
|
|
208
208
|
|
|
209
209
|
// src/client.ts
|
|
210
210
|
var DEFAULT_BASE_URL = "https://api.brainerce.com";
|
|
@@ -926,10 +926,19 @@ var _BrainerceClient = class _BrainerceClient {
|
|
|
926
926
|
this.customerToken = null;
|
|
927
927
|
}
|
|
928
928
|
// -------------------- Private Methods --------------------
|
|
929
|
+
/**
|
|
930
|
+
* Turn an `idempotencyKey` option into the header the backend reads.
|
|
931
|
+
*
|
|
932
|
+
* Returns `undefined` when there is no key, so the header is absent rather
|
|
933
|
+
* than empty — the interceptor rejects a present-but-blank key with a 400.
|
|
934
|
+
*/
|
|
935
|
+
idempotencyHeaders(options) {
|
|
936
|
+
return options?.idempotencyKey ? { "Idempotency-Key": options.idempotencyKey } : void 0;
|
|
937
|
+
}
|
|
929
938
|
/**
|
|
930
939
|
* Make a request to the Admin API (requires apiKey)
|
|
931
940
|
*/
|
|
932
|
-
async adminRequest(method, path, body, queryParams, responseType = "json") {
|
|
941
|
+
async adminRequest(method, path, body, queryParams, responseType = "json", extraHeaders) {
|
|
933
942
|
if (!this.apiKey) {
|
|
934
943
|
throw new BrainerceError(
|
|
935
944
|
"This operation requires an API key. Initialize with apiKey instead of storeId.",
|
|
@@ -959,6 +968,11 @@ var _BrainerceClient = class _BrainerceClient {
|
|
|
959
968
|
if (this.locale) {
|
|
960
969
|
headers["Accept-Language"] = this.locale;
|
|
961
970
|
}
|
|
971
|
+
if (extraHeaders) {
|
|
972
|
+
for (const [key, value] of Object.entries(extraHeaders)) {
|
|
973
|
+
if (value) headers[key] = value;
|
|
974
|
+
}
|
|
975
|
+
}
|
|
962
976
|
for (let attempt = 0; attempt < 2; attempt++) {
|
|
963
977
|
const controller = new AbortController();
|
|
964
978
|
const timeoutId = setTimeout(() => controller.abort(), this.timeout);
|
|
@@ -2283,21 +2297,25 @@ var _BrainerceClient = class _BrainerceClient {
|
|
|
2283
2297
|
);
|
|
2284
2298
|
}
|
|
2285
2299
|
/**
|
|
2286
|
-
* Publish a product to specific platforms
|
|
2300
|
+
* Publish a product to specific platforms.
|
|
2287
2301
|
*
|
|
2288
|
-
*
|
|
2289
|
-
*
|
|
2290
|
-
*
|
|
2291
|
-
*
|
|
2292
|
-
*
|
|
2302
|
+
* **Not callable.** The API-key `/v1` surface has no `products/:id/publish`
|
|
2303
|
+
* route. Platform publishing for products exists only on the dashboard
|
|
2304
|
+
* surface (`POST /api/products/:id/publish?storeId=`,
|
|
2305
|
+
* `products.controller.ts:556`), which resolves the acting user from a
|
|
2306
|
+
* dashboard session an API key does not carry. The generic trigger
|
|
2307
|
+
* `POST /v1/sync` answers `501 Not Implemented` and points at per-resource
|
|
2308
|
+
* publish endpoints — and products have none.
|
|
2309
|
+
*
|
|
2310
|
+
* {@link publishProductToSalesChannel} is a DIFFERENT operation: it controls
|
|
2311
|
+
* visibility on a vibe-coded storefront, not a push to an external platform.
|
|
2293
2312
|
*/
|
|
2294
2313
|
async publishProduct(productId, platforms) {
|
|
2295
|
-
|
|
2296
|
-
|
|
2297
|
-
|
|
2298
|
-
|
|
2299
|
-
|
|
2300
|
-
}
|
|
2314
|
+
void productId;
|
|
2315
|
+
void platforms;
|
|
2316
|
+
throw new BrainerceError(
|
|
2317
|
+
"publishProduct is not a route on the API-key /v1 surface. There is no products/:id/publish endpoint to call, so nothing was published; publish the product to a platform from the Brainerce dashboard. Note that publishProductToSalesChannel is a different operation \u2014 it controls vibe-coded storefront visibility, not an external-platform push.",
|
|
2318
|
+
400
|
|
2301
2319
|
);
|
|
2302
2320
|
}
|
|
2303
2321
|
// -------------------- Variants --------------------
|
|
@@ -4292,6 +4310,9 @@ var _BrainerceClient = class _BrainerceClient {
|
|
|
4292
4310
|
* flags reflect the live state. Call this on cart load if you want to
|
|
4293
4311
|
* surface drift to the customer before they reach checkout.
|
|
4294
4312
|
*
|
|
4313
|
+
* **Storefront and vibe-coded modes only.** There is no admin (`apiKey`)
|
|
4314
|
+
* route for this, so an admin-mode client throws instead of 404ing.
|
|
4315
|
+
*
|
|
4295
4316
|
* @example
|
|
4296
4317
|
* ```typescript
|
|
4297
4318
|
* const cart = await client.recalculateCart('cart_123');
|
|
@@ -4316,9 +4337,9 @@ var _BrainerceClient = class _BrainerceClient {
|
|
|
4316
4337
|
"cart"
|
|
4317
4338
|
);
|
|
4318
4339
|
}
|
|
4319
|
-
|
|
4320
|
-
|
|
4321
|
-
|
|
4340
|
+
throw new BrainerceError(
|
|
4341
|
+
"recalculateCart is not a route on the API-key /v1 surface. There is no cart/:cartId/recalculate endpoint to call, so nothing was recalculated. Cart recalculation is a storefront operation \u2014 call it from a client constructed with `salesChannelId` (vibe-coded) or `storeId` (public storefront), where the route exists.",
|
|
4342
|
+
400
|
|
4322
4343
|
);
|
|
4323
4344
|
}
|
|
4324
4345
|
/**
|
|
@@ -4327,6 +4348,9 @@ var _BrainerceClient = class _BrainerceClient {
|
|
|
4327
4348
|
* subsequent `createCheckout` call will then succeed (it would otherwise
|
|
4328
4349
|
* throw `PRICE_DRIFT`).
|
|
4329
4350
|
*
|
|
4351
|
+
* **Storefront and vibe-coded modes only.** There is no admin (`apiKey`)
|
|
4352
|
+
* route for this, so an admin-mode client throws instead of 404ing.
|
|
4353
|
+
*
|
|
4330
4354
|
* @example
|
|
4331
4355
|
* ```typescript
|
|
4332
4356
|
* try {
|
|
@@ -4361,12 +4385,9 @@ var _BrainerceClient = class _BrainerceClient {
|
|
|
4361
4385
|
"cart"
|
|
4362
4386
|
);
|
|
4363
4387
|
}
|
|
4364
|
-
|
|
4365
|
-
|
|
4366
|
-
|
|
4367
|
-
`/api/v1/cart/${encodePathSegment(cartId)}/refresh-snapshots`
|
|
4368
|
-
),
|
|
4369
|
-
"cart"
|
|
4388
|
+
throw new BrainerceError(
|
|
4389
|
+
"refreshCartSnapshots is not a route on the API-key /v1 surface. There is no cart/:cartId/refresh-snapshots endpoint to call, so no price snapshots were refreshed. Snapshot refresh is a storefront operation \u2014 call it from a client constructed with `salesChannelId` (vibe-coded) or `storeId` (public storefront), where the route exists.",
|
|
4390
|
+
400
|
|
4370
4391
|
);
|
|
4371
4392
|
}
|
|
4372
4393
|
/**
|
|
@@ -5875,22 +5896,39 @@ var _BrainerceClient = class _BrainerceClient {
|
|
|
5875
5896
|
* screen or database query can recover it.
|
|
5876
5897
|
*
|
|
5877
5898
|
* A `note` is required. Refused when gift cards are switched off for the
|
|
5878
|
-
* store.
|
|
5899
|
+
* store.
|
|
5900
|
+
*
|
|
5901
|
+
* ⚠️ **Pass an `idempotencyKey`.** It is the ONLY recovery that exists here:
|
|
5902
|
+
* re-sending the identical request with the same key inside 24 hours replays
|
|
5903
|
+
* the cached response, code included. Without one, a retried timeout mints a
|
|
5904
|
+
* SECOND card and a second real liability. The key is sent as the
|
|
5905
|
+
* `Idempotency-Key` header; reuse the same value across retries of the same
|
|
5906
|
+
* logical issue, never a fresh random one.
|
|
5879
5907
|
*
|
|
5880
5908
|
* Requires `gift_cards:issue`.
|
|
5881
5909
|
*
|
|
5882
5910
|
* @example
|
|
5883
5911
|
* ```typescript
|
|
5884
|
-
* const card = await client.issueGiftCard(
|
|
5885
|
-
*
|
|
5886
|
-
*
|
|
5887
|
-
*
|
|
5888
|
-
*
|
|
5912
|
+
* const card = await client.issueGiftCard(
|
|
5913
|
+
* {
|
|
5914
|
+
* amount: '200.00',
|
|
5915
|
+
* note: 'Compensation for order #1042',
|
|
5916
|
+
* recipientEmail: 'dana@example.com',
|
|
5917
|
+
* },
|
|
5918
|
+
* { idempotencyKey: 'compensation-order-1042' }
|
|
5919
|
+
* );
|
|
5889
5920
|
* await sendToCustomer(card.plaintextCode); // your only chance
|
|
5890
5921
|
* ```
|
|
5891
5922
|
*/
|
|
5892
|
-
async issueGiftCard(data) {
|
|
5893
|
-
return this.adminRequest(
|
|
5923
|
+
async issueGiftCard(data, options) {
|
|
5924
|
+
return this.adminRequest(
|
|
5925
|
+
"POST",
|
|
5926
|
+
"/api/v1/gift-cards",
|
|
5927
|
+
data,
|
|
5928
|
+
void 0,
|
|
5929
|
+
"json",
|
|
5930
|
+
this.idempotencyHeaders(options)
|
|
5931
|
+
);
|
|
5894
5932
|
}
|
|
5895
5933
|
/**
|
|
5896
5934
|
* Re-issue a gift card onto a new code.
|
|
@@ -5903,15 +5941,21 @@ var _BrainerceClient = class _BrainerceClient {
|
|
|
5903
5941
|
* while a checkout holds value on the card. The original expiry carries
|
|
5904
5942
|
* forward, so this cannot be used to restart an expiry clock.
|
|
5905
5943
|
*
|
|
5906
|
-
* The new code is returned exactly once, under the same rules as issuance
|
|
5944
|
+
* The new code is returned exactly once, under the same rules as issuance —
|
|
5945
|
+
* so pass an `idempotencyKey` here for the same reason, and with the same
|
|
5946
|
+
* force: a retried timeout without one revokes the replacement it just made
|
|
5947
|
+
* and mints another.
|
|
5907
5948
|
*
|
|
5908
5949
|
* Requires `gift_cards:issue`.
|
|
5909
5950
|
*/
|
|
5910
|
-
async reissueGiftCard(giftCardId, note) {
|
|
5951
|
+
async reissueGiftCard(giftCardId, note, options) {
|
|
5911
5952
|
return this.adminRequest(
|
|
5912
5953
|
"POST",
|
|
5913
5954
|
`/api/v1/gift-cards/${encodePathSegment(giftCardId)}/reissue`,
|
|
5914
|
-
{ note }
|
|
5955
|
+
{ note },
|
|
5956
|
+
void 0,
|
|
5957
|
+
"json",
|
|
5958
|
+
this.idempotencyHeaders(options)
|
|
5915
5959
|
);
|
|
5916
5960
|
}
|
|
5917
5961
|
/**
|
|
@@ -5924,13 +5968,19 @@ var _BrainerceClient = class _BrainerceClient {
|
|
|
5924
5968
|
* A debit cannot take the balance below what live checkout holds have already
|
|
5925
5969
|
* reserved; that refusal names the held amount so you can act on it.
|
|
5926
5970
|
*
|
|
5971
|
+
* Pass an `idempotencyKey`: an adjustment is a relative move, so a retried
|
|
5972
|
+
* timeout without one applies the delta twice.
|
|
5973
|
+
*
|
|
5927
5974
|
* Requires `gift_cards:adjust`.
|
|
5928
5975
|
*/
|
|
5929
|
-
async adjustGiftCardBalance(giftCardId, delta, note) {
|
|
5976
|
+
async adjustGiftCardBalance(giftCardId, delta, note, options) {
|
|
5930
5977
|
return this.adminRequest(
|
|
5931
5978
|
"PATCH",
|
|
5932
5979
|
`/api/v1/gift-cards/${encodePathSegment(giftCardId)}/adjust`,
|
|
5933
|
-
{ delta, note }
|
|
5980
|
+
{ delta, note },
|
|
5981
|
+
void 0,
|
|
5982
|
+
"json",
|
|
5983
|
+
this.idempotencyHeaders(options)
|
|
5934
5984
|
);
|
|
5935
5985
|
}
|
|
5936
5986
|
/**
|
|
@@ -5943,11 +5993,14 @@ var _BrainerceClient = class _BrainerceClient {
|
|
|
5943
5993
|
*
|
|
5944
5994
|
* Requires `gift_cards:write`.
|
|
5945
5995
|
*/
|
|
5946
|
-
async setGiftCardStatus(giftCardId, status) {
|
|
5996
|
+
async setGiftCardStatus(giftCardId, status, options) {
|
|
5947
5997
|
return this.adminRequest(
|
|
5948
5998
|
"PATCH",
|
|
5949
5999
|
`/api/v1/gift-cards/${encodePathSegment(giftCardId)}/status`,
|
|
5950
|
-
{ status }
|
|
6000
|
+
{ status },
|
|
6001
|
+
void 0,
|
|
6002
|
+
"json",
|
|
6003
|
+
this.idempotencyHeaders(options)
|
|
5951
6004
|
);
|
|
5952
6005
|
}
|
|
5953
6006
|
/**
|
|
@@ -5963,11 +6016,15 @@ var _BrainerceClient = class _BrainerceClient {
|
|
|
5963
6016
|
*
|
|
5964
6017
|
* Requires `gift_cards:write`.
|
|
5965
6018
|
*/
|
|
5966
|
-
async bulkSetGiftCardStatus(giftCardIds, status) {
|
|
5967
|
-
return this.adminRequest(
|
|
5968
|
-
|
|
5969
|
-
status
|
|
5970
|
-
|
|
6019
|
+
async bulkSetGiftCardStatus(giftCardIds, status, options) {
|
|
6020
|
+
return this.adminRequest(
|
|
6021
|
+
"PATCH",
|
|
6022
|
+
"/api/v1/gift-cards/bulk/status",
|
|
6023
|
+
{ giftCardIds, status },
|
|
6024
|
+
void 0,
|
|
6025
|
+
"json",
|
|
6026
|
+
this.idempotencyHeaders(options)
|
|
6027
|
+
);
|
|
5971
6028
|
}
|
|
5972
6029
|
// ==========================================================================
|
|
5973
6030
|
// Donations
|
|
@@ -6376,6 +6433,9 @@ var _BrainerceClient = class _BrainerceClient {
|
|
|
6376
6433
|
/**
|
|
6377
6434
|
* Set delivery type on checkout (shipping or pickup).
|
|
6378
6435
|
*
|
|
6436
|
+
* **Storefront and vibe-coded modes only.** There is no admin (`apiKey`)
|
|
6437
|
+
* route for this, so an admin-mode client throws instead of 404ing.
|
|
6438
|
+
*
|
|
6379
6439
|
* @example
|
|
6380
6440
|
* ```typescript
|
|
6381
6441
|
* const checkout = await client.setDeliveryType('checkout_123', 'pickup');
|
|
@@ -6400,12 +6460,9 @@ var _BrainerceClient = class _BrainerceClient {
|
|
|
6400
6460
|
}
|
|
6401
6461
|
);
|
|
6402
6462
|
}
|
|
6403
|
-
|
|
6404
|
-
"
|
|
6405
|
-
|
|
6406
|
-
{
|
|
6407
|
-
deliveryType
|
|
6408
|
-
}
|
|
6463
|
+
throw new BrainerceError(
|
|
6464
|
+
"setDeliveryType is not a route on the API-key /v1 surface. There is no checkout/:checkoutId/delivery-type endpoint to call, so the delivery type was not changed. Set it from the storefront session that owns the checkout \u2014 a client constructed with `salesChannelId` (vibe-coded) or `storeId` (public storefront) \u2014 or from the Brainerce dashboard.",
|
|
6465
|
+
400
|
|
6409
6466
|
);
|
|
6410
6467
|
}
|
|
6411
6468
|
/**
|
|
@@ -6413,6 +6470,9 @@ var _BrainerceClient = class _BrainerceClient {
|
|
|
6413
6470
|
* This sets the delivery type to "pickup", records customer info, and prepares for payment.
|
|
6414
6471
|
* Equivalent to setShippingAddress + selectShippingMethod for delivery orders.
|
|
6415
6472
|
*
|
|
6473
|
+
* **Storefront and vibe-coded modes only.** There is no admin (`apiKey`)
|
|
6474
|
+
* route for this, so an admin-mode client throws instead of 404ing.
|
|
6475
|
+
*
|
|
6416
6476
|
* @example
|
|
6417
6477
|
* ```typescript
|
|
6418
6478
|
* const checkout = await client.selectPickupLocation('checkout_123', {
|
|
@@ -6439,10 +6499,9 @@ var _BrainerceClient = class _BrainerceClient {
|
|
|
6439
6499
|
data
|
|
6440
6500
|
);
|
|
6441
6501
|
}
|
|
6442
|
-
|
|
6443
|
-
"
|
|
6444
|
-
|
|
6445
|
-
data
|
|
6502
|
+
throw new BrainerceError(
|
|
6503
|
+
"selectPickupLocation is not a route on the API-key /v1 surface. There is no checkout/:checkoutId/pickup-location endpoint to call, so no pickup location was selected. Select it from the storefront session that owns the checkout \u2014 a client constructed with `salesChannelId` (vibe-coded) or `storeId` (public storefront) \u2014 or from the Brainerce dashboard.",
|
|
6504
|
+
400
|
|
6446
6505
|
);
|
|
6447
6506
|
}
|
|
6448
6507
|
/**
|
|
@@ -7767,13 +7826,17 @@ var _BrainerceClient = class _BrainerceClient {
|
|
|
7767
7826
|
* lifetime earned, the program's display config, earned milestone `badges`,
|
|
7768
7827
|
* and the `paidMembership` subscription state (null for free members).
|
|
7769
7828
|
* Requires customerToken. Only available in storefront mode. `program` is
|
|
7770
|
-
* null when the store has no loyalty program.
|
|
7829
|
+
* null when the store has no loyalty program. `pointsBalance` excludes points
|
|
7830
|
+
* still inside the return window - those are in `pendingPoints`, and a panel
|
|
7831
|
+
* that ignores them shows a shopper 0 the day they order.
|
|
7771
7832
|
*
|
|
7772
7833
|
* @example
|
|
7773
7834
|
* ```typescript
|
|
7774
7835
|
* client.setCustomerToken(auth.token);
|
|
7775
7836
|
* const status = await client.getLoyaltyStatus();
|
|
7776
7837
|
* if (status.enrolled) console.log(`${status.pointsBalance} ${status.program?.pointsName}`);
|
|
7838
|
+
* // Points from an order just placed are in pendingPoints, NOT pointsBalance.
|
|
7839
|
+
* if (status.pendingPoints > 0) console.log(`+${status.pendingPoints} on ${status.pendingPointsConfirmAt}`);
|
|
7777
7840
|
* status.badges?.forEach((b) => console.log(`🏅 ${b.name}`));
|
|
7778
7841
|
* if (status.paidMembership?.status === 'ACTIVE') showPremiumPerks(status.paidMembership.plan);
|
|
7779
7842
|
* ```
|
|
@@ -8620,11 +8683,28 @@ var _BrainerceClient = class _BrainerceClient {
|
|
|
8620
8683
|
return this.adminRequest("POST", "/api/v1/tags", data);
|
|
8621
8684
|
}
|
|
8622
8685
|
/**
|
|
8623
|
-
* Update an existing tag
|
|
8624
|
-
*
|
|
8686
|
+
* Update an existing tag.
|
|
8687
|
+
*
|
|
8688
|
+
* **Not callable.** The API-key `/v1` surface serves `GET`, `POST` and
|
|
8689
|
+
* `DELETE` on tags (`external-api.controller.ts:3276`, `:3310`, `:3331`) but
|
|
8690
|
+
* no update verb — `PATCH /api/v1/tags/:id` 404'd silently. Tag editing lives
|
|
8691
|
+
* only on the dashboard surface (`PATCH /api/stores/:storeId/tags/:id`,
|
|
8692
|
+
* `tags.controller.ts:127`), which needs a `storeId` in the path that this
|
|
8693
|
+
* signature does not carry, and resolves the acting user from a dashboard
|
|
8694
|
+
* session an API key does not have.
|
|
8695
|
+
*
|
|
8696
|
+
* Edit the tag in the Brainerce dashboard. {@link deleteTag} +
|
|
8697
|
+
* {@link createTag} is NOT an equivalent workaround: it drops the tag's
|
|
8698
|
+
* product assignments, and `CreateTagDto` has no `translations` field, so any
|
|
8699
|
+
* per-locale names are lost too.
|
|
8625
8700
|
*/
|
|
8626
8701
|
async updateTag(tagId, data) {
|
|
8627
|
-
|
|
8702
|
+
void tagId;
|
|
8703
|
+
void data;
|
|
8704
|
+
throw new BrainerceError(
|
|
8705
|
+
"updateTag is not a route on the API-key /v1 surface. Tags are served there for read, create and delete only, so the tag was not changed; edit it in the Brainerce dashboard. Deleting and recreating the tag is not equivalent \u2014 it drops the product assignments and the translations.",
|
|
8706
|
+
400
|
|
8707
|
+
);
|
|
8628
8708
|
}
|
|
8629
8709
|
/**
|
|
8630
8710
|
* Delete a tag
|
|
@@ -8722,24 +8802,41 @@ var _BrainerceClient = class _BrainerceClient {
|
|
|
8722
8802
|
);
|
|
8723
8803
|
}
|
|
8724
8804
|
/**
|
|
8725
|
-
* Update an attribute option
|
|
8726
|
-
*
|
|
8805
|
+
* Update an attribute option.
|
|
8806
|
+
*
|
|
8807
|
+
* **Not callable.** The API-key `/v1` surface serves attribute options for
|
|
8808
|
+
* list and create only (`external-api.controller.ts:3517`, `:3543`); there is
|
|
8809
|
+
* no per-option route, so this 404'd silently. Editing an option lives on the
|
|
8810
|
+
* dashboard surface (`PUT /api/stores/:storeId/attributes/:id/options/:optionId`,
|
|
8811
|
+
* `attributes.controller.ts:132` — note it is `PUT` there, not `PATCH`), which
|
|
8812
|
+
* needs a path `storeId` this signature does not carry.
|
|
8813
|
+
*
|
|
8814
|
+
* Edit the option in the Brainerce dashboard.
|
|
8727
8815
|
*/
|
|
8728
8816
|
async updateAttributeOption(attributeId, optionId, data) {
|
|
8729
|
-
|
|
8730
|
-
|
|
8731
|
-
|
|
8732
|
-
|
|
8817
|
+
void attributeId;
|
|
8818
|
+
void optionId;
|
|
8819
|
+
void data;
|
|
8820
|
+
throw new BrainerceError(
|
|
8821
|
+
"updateAttributeOption is not a route on the API-key /v1 surface. Attribute options are served there for list and create only, so the option was not changed; edit it in the Brainerce dashboard.",
|
|
8822
|
+
400
|
|
8733
8823
|
);
|
|
8734
8824
|
}
|
|
8735
8825
|
/**
|
|
8736
|
-
* Delete an attribute option
|
|
8737
|
-
*
|
|
8826
|
+
* Delete an attribute option.
|
|
8827
|
+
*
|
|
8828
|
+
* **Not callable.** Same gap as {@link updateAttributeOption}: the `/v1`
|
|
8829
|
+
* surface has no per-option route. Deleting an option lives on the dashboard
|
|
8830
|
+
* surface (`DELETE /api/stores/:storeId/attributes/:id/options/:optionId`,
|
|
8831
|
+
* `attributes.controller.ts:145`), which needs a path `storeId` this signature
|
|
8832
|
+
* does not carry.
|
|
8738
8833
|
*/
|
|
8739
8834
|
async deleteAttributeOption(attributeId, optionId) {
|
|
8740
|
-
|
|
8741
|
-
|
|
8742
|
-
|
|
8835
|
+
void attributeId;
|
|
8836
|
+
void optionId;
|
|
8837
|
+
throw new BrainerceError(
|
|
8838
|
+
"deleteAttributeOption is not a route on the API-key /v1 surface. Attribute options are served there for list and create only, so nothing was deleted; delete the option in the Brainerce dashboard.",
|
|
8839
|
+
400
|
|
8743
8840
|
);
|
|
8744
8841
|
}
|
|
8745
8842
|
// -------------------- Modifier Groups (Admin) --------------------
|
|
@@ -9562,25 +9659,48 @@ var _BrainerceClient = class _BrainerceClient {
|
|
|
9562
9659
|
// Products/Coupons. When no publishes exist for an entity, it remains
|
|
9563
9660
|
// visible to all vibe-coded sites of the store (legacy default).
|
|
9564
9661
|
/**
|
|
9565
|
-
* Publish a metafield definition to a
|
|
9566
|
-
*
|
|
9567
|
-
*
|
|
9568
|
-
*
|
|
9569
|
-
*
|
|
9662
|
+
* Publish a metafield definition to a sales channel (admin mode).
|
|
9663
|
+
*
|
|
9664
|
+
* **Not callable.** This asked for `publish-vibe-coded`, which is a
|
|
9665
|
+
* deprecated backend alias, not the canonical route. The canonical spelling
|
|
9666
|
+
* is `publish-sales-channel`, and the `/v1` surface serves it for products
|
|
9667
|
+
* (`external-api.controller.ts:862`), coupons (`:947`), customers (`:1548`),
|
|
9668
|
+
* categories (`:3039`), brands (`:3211`) and tags (`:3349`) — but NOT for
|
|
9669
|
+
* metafield definitions. Both spellings 404 there.
|
|
9670
|
+
*
|
|
9671
|
+
* The operation exists only on the dashboard surface
|
|
9672
|
+
* (`POST /api/stores/:storeId/metafield-definitions/:id/publish-sales-channel`,
|
|
9673
|
+
* `metafields.controller.ts:190`), which needs a path `storeId` this signature
|
|
9674
|
+
* does not carry.
|
|
9675
|
+
*
|
|
9676
|
+
* Publish the definition to a sales channel from the Brainerce dashboard. A
|
|
9677
|
+
* definition with no publishes stays visible to every sales channel of the
|
|
9678
|
+
* store, so leaving it unpublished is the permissive default, not a lockout.
|
|
9570
9679
|
*/
|
|
9571
9680
|
async publishMetafieldDefinitionToVibeCodedSite(definitionId, vibeCodedConnectionId) {
|
|
9572
|
-
|
|
9573
|
-
|
|
9574
|
-
|
|
9575
|
-
|
|
9681
|
+
void definitionId;
|
|
9682
|
+
void vibeCodedConnectionId;
|
|
9683
|
+
throw new BrainerceError(
|
|
9684
|
+
"publishMetafieldDefinitionToVibeCodedSite is not a route on the API-key /v1 surface. Per-sales-channel publishing is served there for products, coupons, customers, categories, brands and tags, but not for metafield definitions, so nothing was published; publish it in the Brainerce dashboard. A definition with no publishes remains visible to every sales channel of the store.",
|
|
9685
|
+
400
|
|
9576
9686
|
);
|
|
9577
9687
|
}
|
|
9578
|
-
/**
|
|
9688
|
+
/**
|
|
9689
|
+
* Unpublish a metafield definition from a sales channel (admin mode).
|
|
9690
|
+
*
|
|
9691
|
+
* **Not callable.** Same gap as
|
|
9692
|
+
* {@link publishMetafieldDefinitionToVibeCodedSite} — the `/v1` surface
|
|
9693
|
+
* carries no per-sales-channel routes for metafield definitions under either
|
|
9694
|
+
* the canonical `unpublish-sales-channel` spelling or the deprecated
|
|
9695
|
+
* `unpublish-vibe-coded` alias. The dashboard route is
|
|
9696
|
+
* `metafields.controller.ts:217`.
|
|
9697
|
+
*/
|
|
9579
9698
|
async unpublishMetafieldDefinitionFromVibeCodedSite(definitionId, vibeCodedConnectionId) {
|
|
9580
|
-
|
|
9581
|
-
|
|
9582
|
-
|
|
9583
|
-
|
|
9699
|
+
void definitionId;
|
|
9700
|
+
void vibeCodedConnectionId;
|
|
9701
|
+
throw new BrainerceError(
|
|
9702
|
+
"unpublishMetafieldDefinitionFromVibeCodedSite is not a route on the API-key /v1 surface. Per-sales-channel publishing is served there for products, coupons, customers, categories, brands and tags, but not for metafield definitions, so nothing was unpublished; unpublish it in the Brainerce dashboard.",
|
|
9703
|
+
400
|
|
9584
9704
|
);
|
|
9585
9705
|
}
|
|
9586
9706
|
/**
|
|
@@ -9726,10 +9846,11 @@ var _BrainerceClient = class _BrainerceClient {
|
|
|
9726
9846
|
* ```
|
|
9727
9847
|
*/
|
|
9728
9848
|
async setDefinitionProducts(definitionId, data) {
|
|
9729
|
-
|
|
9730
|
-
|
|
9731
|
-
|
|
9732
|
-
|
|
9849
|
+
void definitionId;
|
|
9850
|
+
void data;
|
|
9851
|
+
throw new BrainerceError(
|
|
9852
|
+
"setDefinitionProducts is not a route on the API-key /v1 surface. There is no metafield-definitions/:id/products endpoint to call, so the definition's product list was not changed; set it in the Brainerce dashboard.",
|
|
9853
|
+
400
|
|
9733
9854
|
);
|
|
9734
9855
|
}
|
|
9735
9856
|
// -------------------- Metafields: Product Values --------------------
|
|
@@ -9775,24 +9896,41 @@ var _BrainerceClient = class _BrainerceClient {
|
|
|
9775
9896
|
// -------------------- Product Customization Fields (Admin) --------------------
|
|
9776
9897
|
/**
|
|
9777
9898
|
* Get customization fields assigned to a product.
|
|
9778
|
-
*
|
|
9899
|
+
*
|
|
9900
|
+
* **Not callable.** The API-key `/v1` surface has no
|
|
9901
|
+
* `metafield-definitions/products/:productId/customization-fields` route, so
|
|
9902
|
+
* this 404'd silently. It exists only on the dashboard surface
|
|
9903
|
+
* (`GET /api/stores/:storeId/metafield-definitions/products/:productId/customization-fields`,
|
|
9904
|
+
* `metafields.controller.ts:277`), which needs a path `storeId` this signature
|
|
9905
|
+
* does not carry.
|
|
9906
|
+
*
|
|
9907
|
+
* {@link getProductMetafields} is the closest working call — it returns the
|
|
9908
|
+
* metafield VALUES stored on a product over
|
|
9909
|
+
* `GET /api/v1/products/:productId/metafields`, not the customer-input field
|
|
9910
|
+
* definitions attached to it.
|
|
9779
9911
|
*/
|
|
9780
9912
|
async getProductCustomizationFields(productId) {
|
|
9781
|
-
|
|
9782
|
-
|
|
9783
|
-
|
|
9913
|
+
void productId;
|
|
9914
|
+
throw new BrainerceError(
|
|
9915
|
+
"getProductCustomizationFields is not a route on the API-key /v1 surface. There is no metafield-definitions/products/:productId/customization-fields endpoint to call; read the assignments in the Brainerce dashboard. getProductMetafields returns the product's stored metafield values, which is a different thing.",
|
|
9916
|
+
400
|
|
9784
9917
|
);
|
|
9785
9918
|
}
|
|
9786
9919
|
/**
|
|
9787
9920
|
* Set customization fields for a product (replaces all existing assignments).
|
|
9788
|
-
*
|
|
9789
|
-
*
|
|
9921
|
+
*
|
|
9922
|
+
* **Not callable.** Same gap as {@link getProductCustomizationFields}: the
|
|
9923
|
+
* `/v1` surface carries no customization-field routes. The dashboard route is
|
|
9924
|
+
* `PATCH /api/stores/:storeId/metafield-definitions/products/:productId/customization-fields`
|
|
9925
|
+
* (`metafields.controller.ts:298`), which needs a path `storeId` this
|
|
9926
|
+
* signature does not carry.
|
|
9790
9927
|
*/
|
|
9791
9928
|
async setProductCustomizationFields(productId, definitionIds) {
|
|
9792
|
-
|
|
9793
|
-
|
|
9794
|
-
|
|
9795
|
-
|
|
9929
|
+
void productId;
|
|
9930
|
+
void definitionIds;
|
|
9931
|
+
throw new BrainerceError(
|
|
9932
|
+
"setProductCustomizationFields is not a route on the API-key /v1 surface. There is no metafield-definitions/products/:productId/customization-fields endpoint to call, so the assignments were not changed; set them in the Brainerce dashboard.",
|
|
9933
|
+
400
|
|
9796
9934
|
);
|
|
9797
9935
|
}
|
|
9798
9936
|
/**
|
|
@@ -11187,6 +11325,7 @@ function buildProductJsonLd(product, opts) {
|
|
|
11187
11325
|
const inv = product.inventory;
|
|
11188
11326
|
const availability = !inv ? "https://schema.org/InStock" : inv.inStock ?? (inv.available ?? 0) > 0 ? "https://schema.org/InStock" : inv.canPurchase ? "https://schema.org/BackOrder" : "https://schema.org/OutOfStock";
|
|
11189
11327
|
const isVariable = product.type === "VARIABLE" && product.priceMin && product.priceMax;
|
|
11328
|
+
const omitOffer = product.type === "KIT";
|
|
11190
11329
|
const itemCondition = "https://schema.org/NewCondition";
|
|
11191
11330
|
const shippingDetails = (opts.shipping ?? []).filter((z) => z.amount !== null).map((z) => ({
|
|
11192
11331
|
"@type": "OfferShippingDetails",
|
|
@@ -11249,7 +11388,7 @@ function buildProductJsonLd(product, opts) {
|
|
|
11249
11388
|
...product.gtin ? { gtin: product.gtin } : {},
|
|
11250
11389
|
...product.mpn ? { mpn: product.mpn } : {},
|
|
11251
11390
|
...brand ? { brand: { "@type": "Brand", name: brand } } : {},
|
|
11252
|
-
offers: offer,
|
|
11391
|
+
...omitOffer ? {} : { offers: offer },
|
|
11253
11392
|
// Google policy: never emit an empty/zero rating block. bestRating /
|
|
11254
11393
|
// worstRating make the 1-5 scale explicit so aggregators can't misread
|
|
11255
11394
|
// a 4.8 on an assumed 0-10 scale.
|