brainerce 2.1.0 → 2.2.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 +367 -65
- package/dist/index.d.mts +305 -13
- package/dist/index.d.ts +305 -13
- package/dist/index.js +249 -71
- package/dist/index.mjs +249 -71
- package/package.json +85 -84
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.0
|
|
207
|
+
var SDK_VERSION = "2.2.0";
|
|
208
208
|
|
|
209
209
|
// src/client.ts
|
|
210
210
|
var DEFAULT_BASE_URL = "https://api.brainerce.com";
|
|
@@ -450,7 +450,7 @@ var _BrainerceClient = class _BrainerceClient {
|
|
|
450
450
|
* Works in all three SDK modes (vibe-coded, storefront, admin):
|
|
451
451
|
* - **Public reads** (`get`, `list`, `getBySlug`): work in any mode.
|
|
452
452
|
* - **Write operations** (`create`, `update`, `publish`, `unpublish`,
|
|
453
|
-
* `remove`): admin mode only — they call `/api/
|
|
453
|
+
* `remove`): admin mode only — they call `/api/content/...` with
|
|
454
454
|
* the API key. Calling from storefront / vibe-coded mode throws.
|
|
455
455
|
*
|
|
456
456
|
* **Default key:** every type has `'main'` as its universal default key.
|
|
@@ -487,7 +487,7 @@ var _BrainerceClient = class _BrainerceClient {
|
|
|
487
487
|
this.content = (() => {
|
|
488
488
|
const DEFAULT_KEY = "main";
|
|
489
489
|
const publicGetPath = (type, key) => `/content/${encodeURIComponent(type)}/${encodeURIComponent(key)}`;
|
|
490
|
-
const adminBase = () => "/api/
|
|
490
|
+
const adminBase = () => "/api/content";
|
|
491
491
|
const publicGet = async (type, key, locale) => {
|
|
492
492
|
const query = locale ? { locale } : void 0;
|
|
493
493
|
const path = publicGetPath(type, key);
|
|
@@ -2107,11 +2107,9 @@ var _BrainerceClient = class _BrainerceClient {
|
|
|
2107
2107
|
queryParams
|
|
2108
2108
|
);
|
|
2109
2109
|
}
|
|
2110
|
-
|
|
2111
|
-
"
|
|
2112
|
-
|
|
2113
|
-
void 0,
|
|
2114
|
-
queryParams
|
|
2110
|
+
throw new BrainerceError(
|
|
2111
|
+
"getSearchSuggestions is a storefront API. There is no admin suggestions endpoint \u2014 construct the client with `salesChannelId` or `storeId` to use it, or call getProducts({ search }) in admin mode.",
|
|
2112
|
+
400
|
|
2115
2113
|
);
|
|
2116
2114
|
}
|
|
2117
2115
|
/**
|
|
@@ -5812,6 +5810,166 @@ var _BrainerceClient = class _BrainerceClient {
|
|
|
5812
5810
|
return this.adminRequest("POST", "/api/v1/gift-cards/balance", { code });
|
|
5813
5811
|
}
|
|
5814
5812
|
// ==========================================================================
|
|
5813
|
+
// Gift cards — administration (API key only)
|
|
5814
|
+
//
|
|
5815
|
+
// Full programmatic management, unlike Shopify, which requires you to ask
|
|
5816
|
+
// their support for the equivalent scope. The gate here is the SCOPE the
|
|
5817
|
+
// merchant granted your key, so the separation matters: `gift_cards:issue`
|
|
5818
|
+
// mints stored value and `gift_cards:adjust` rewrites a balance, and neither
|
|
5819
|
+
// is implied by `gift_cards:read`. Ask for the least your integration needs.
|
|
5820
|
+
//
|
|
5821
|
+
// Every call reaches the same service the dashboard uses, so the rules hold
|
|
5822
|
+
// identically: a note is mandatory on anything that moves value, a debit
|
|
5823
|
+
// cannot cross what live checkout holds have reserved, and there is no delete
|
|
5824
|
+
// anywhere — the ledger is append-only.
|
|
5825
|
+
// ==========================================================================
|
|
5826
|
+
/**
|
|
5827
|
+
* List gift cards.
|
|
5828
|
+
*
|
|
5829
|
+
* `search` matches the LAST FOUR of a code or part of a recipient email. It
|
|
5830
|
+
* cannot match a full code: only an HMAC is stored, so there is nothing to
|
|
5831
|
+
* search against.
|
|
5832
|
+
*
|
|
5833
|
+
* Requires `gift_cards:read`.
|
|
5834
|
+
*/
|
|
5835
|
+
async listGiftCards(params) {
|
|
5836
|
+
const q = new URLSearchParams();
|
|
5837
|
+
if (params?.page) q.set("page", String(params.page));
|
|
5838
|
+
if (params?.limit) q.set("limit", String(params.limit));
|
|
5839
|
+
if (params?.filter) q.set("filter", params.filter);
|
|
5840
|
+
if (params?.search) q.set("search", params.search);
|
|
5841
|
+
const qs = q.toString();
|
|
5842
|
+
return this.adminRequest(
|
|
5843
|
+
"GET",
|
|
5844
|
+
`/api/v1/gift-cards${qs ? `?${qs}` : ""}`
|
|
5845
|
+
);
|
|
5846
|
+
}
|
|
5847
|
+
/**
|
|
5848
|
+
* Outstanding gift card liability, per currency.
|
|
5849
|
+
*
|
|
5850
|
+
* This is the month-end number. Read `byCurrency` if the store sells in more
|
|
5851
|
+
* than one — currencies are never summed together.
|
|
5852
|
+
*
|
|
5853
|
+
* Requires `gift_cards:read`.
|
|
5854
|
+
*/
|
|
5855
|
+
async getGiftCardLiability() {
|
|
5856
|
+
return this.adminRequest("GET", "/api/v1/gift-cards/liability");
|
|
5857
|
+
}
|
|
5858
|
+
/**
|
|
5859
|
+
* One gift card with its full ledger.
|
|
5860
|
+
*
|
|
5861
|
+
* Requires `gift_cards:read`.
|
|
5862
|
+
*/
|
|
5863
|
+
async getGiftCard(giftCardId) {
|
|
5864
|
+
return this.adminRequest(
|
|
5865
|
+
"GET",
|
|
5866
|
+
`/api/v1/gift-cards/${encodePathSegment(giftCardId)}`
|
|
5867
|
+
);
|
|
5868
|
+
}
|
|
5869
|
+
/**
|
|
5870
|
+
* Issue a gift card.
|
|
5871
|
+
*
|
|
5872
|
+
* ⚠️ **The code comes back exactly once.** It is stored only as an HMAC, so
|
|
5873
|
+
* this response is the only time it exists in readable form anywhere. Persist
|
|
5874
|
+
* it or deliver it before you discard the response — no later call, dashboard
|
|
5875
|
+
* screen or database query can recover it.
|
|
5876
|
+
*
|
|
5877
|
+
* A `note` is required. Refused when gift cards are switched off for the
|
|
5878
|
+
* store. Pass an `Idempotency-Key` header to make a retry safe.
|
|
5879
|
+
*
|
|
5880
|
+
* Requires `gift_cards:issue`.
|
|
5881
|
+
*
|
|
5882
|
+
* @example
|
|
5883
|
+
* ```typescript
|
|
5884
|
+
* const card = await client.issueGiftCard({
|
|
5885
|
+
* amount: '200.00',
|
|
5886
|
+
* note: 'Compensation for order #1042',
|
|
5887
|
+
* recipientEmail: 'dana@example.com',
|
|
5888
|
+
* });
|
|
5889
|
+
* await sendToCustomer(card.plaintextCode); // your only chance
|
|
5890
|
+
* ```
|
|
5891
|
+
*/
|
|
5892
|
+
async issueGiftCard(data) {
|
|
5893
|
+
return this.adminRequest("POST", "/api/v1/gift-cards", data);
|
|
5894
|
+
}
|
|
5895
|
+
/**
|
|
5896
|
+
* Re-issue a gift card onto a new code.
|
|
5897
|
+
*
|
|
5898
|
+
* The answer to a customer losing their code. Mints a new code, moves the
|
|
5899
|
+
* WHOLE balance to it, and REVOKES the old card.
|
|
5900
|
+
*
|
|
5901
|
+
* **This is not a resend.** The old code stops working the moment this
|
|
5902
|
+
* returns — if the customer still holds a printed card, it dies. Refused
|
|
5903
|
+
* while a checkout holds value on the card. The original expiry carries
|
|
5904
|
+
* forward, so this cannot be used to restart an expiry clock.
|
|
5905
|
+
*
|
|
5906
|
+
* The new code is returned exactly once, under the same rules as issuance.
|
|
5907
|
+
*
|
|
5908
|
+
* Requires `gift_cards:issue`.
|
|
5909
|
+
*/
|
|
5910
|
+
async reissueGiftCard(giftCardId, note) {
|
|
5911
|
+
return this.adminRequest(
|
|
5912
|
+
"POST",
|
|
5913
|
+
`/api/v1/gift-cards/${encodePathSegment(giftCardId)}/reissue`,
|
|
5914
|
+
{ note }
|
|
5915
|
+
);
|
|
5916
|
+
}
|
|
5917
|
+
/**
|
|
5918
|
+
* Adjust a gift card balance.
|
|
5919
|
+
*
|
|
5920
|
+
* `delta` is a SIGNED decimal string: `"25.00"` adds, `"-25.00"` takes away.
|
|
5921
|
+
* The `note` is required and is written to the ledger permanently — it is the
|
|
5922
|
+
* row a finance review reads a year from now.
|
|
5923
|
+
*
|
|
5924
|
+
* A debit cannot take the balance below what live checkout holds have already
|
|
5925
|
+
* reserved; that refusal names the held amount so you can act on it.
|
|
5926
|
+
*
|
|
5927
|
+
* Requires `gift_cards:adjust`.
|
|
5928
|
+
*/
|
|
5929
|
+
async adjustGiftCardBalance(giftCardId, delta, note) {
|
|
5930
|
+
return this.adminRequest(
|
|
5931
|
+
"PATCH",
|
|
5932
|
+
`/api/v1/gift-cards/${encodePathSegment(giftCardId)}/adjust`,
|
|
5933
|
+
{ delta, note }
|
|
5934
|
+
);
|
|
5935
|
+
}
|
|
5936
|
+
/**
|
|
5937
|
+
* Enable, disable or revoke one gift card.
|
|
5938
|
+
*
|
|
5939
|
+
* Deliberately does NOT touch live holds: a checkout that already reserved
|
|
5940
|
+
* value settles normally, because pulling it out from under a shopper
|
|
5941
|
+
* mid-payment would strand a provider charge already in flight. Disabling
|
|
5942
|
+
* stops NEW holds, which is what "off" actually means.
|
|
5943
|
+
*
|
|
5944
|
+
* Requires `gift_cards:write`.
|
|
5945
|
+
*/
|
|
5946
|
+
async setGiftCardStatus(giftCardId, status) {
|
|
5947
|
+
return this.adminRequest(
|
|
5948
|
+
"PATCH",
|
|
5949
|
+
`/api/v1/gift-cards/${encodePathSegment(giftCardId)}/status`,
|
|
5950
|
+
{ status }
|
|
5951
|
+
);
|
|
5952
|
+
}
|
|
5953
|
+
/**
|
|
5954
|
+
* Disable or reactivate many gift cards at once.
|
|
5955
|
+
*
|
|
5956
|
+
* `REVOKED` is not accepted here — it belongs to re-issue, which moves the
|
|
5957
|
+
* balance to a replacement first. Revoking in bulk would strand balances with
|
|
5958
|
+
* nowhere to go. Cards already revoked are skipped, so the returned count is
|
|
5959
|
+
* the honest one and may be lower than the ids you sent.
|
|
5960
|
+
*
|
|
5961
|
+
* There is no bulk delete, here or anywhere: the ledger is append-only and a
|
|
5962
|
+
* card may carry a statutory retention life.
|
|
5963
|
+
*
|
|
5964
|
+
* Requires `gift_cards:write`.
|
|
5965
|
+
*/
|
|
5966
|
+
async bulkSetGiftCardStatus(giftCardIds, status) {
|
|
5967
|
+
return this.adminRequest("PATCH", "/api/v1/gift-cards/bulk/status", {
|
|
5968
|
+
giftCardIds,
|
|
5969
|
+
status
|
|
5970
|
+
});
|
|
5971
|
+
}
|
|
5972
|
+
// ==========================================================================
|
|
5815
5973
|
// Donations
|
|
5816
5974
|
// ==========================================================================
|
|
5817
5975
|
/**
|
|
@@ -5954,10 +6112,7 @@ var _BrainerceClient = class _BrainerceClient {
|
|
|
5954
6112
|
"/checkouts/shipping-destinations"
|
|
5955
6113
|
);
|
|
5956
6114
|
}
|
|
5957
|
-
return this.adminRequest(
|
|
5958
|
-
"GET",
|
|
5959
|
-
"/api/v1/checkouts/shipping-destinations"
|
|
5960
|
-
);
|
|
6115
|
+
return this.adminRequest("GET", "/api/checkouts/shipping-destinations");
|
|
5961
6116
|
}
|
|
5962
6117
|
/**
|
|
5963
6118
|
* Set shipping address on checkout (includes customer email).
|
|
@@ -6216,7 +6371,7 @@ var _BrainerceClient = class _BrainerceClient {
|
|
|
6216
6371
|
if (this.storeId && !this.apiKey) {
|
|
6217
6372
|
return this.storefrontRequest("GET", "/pickup-locations");
|
|
6218
6373
|
}
|
|
6219
|
-
return this.adminRequest("GET", "/api/
|
|
6374
|
+
return this.adminRequest("GET", "/api/checkouts/pickup-locations");
|
|
6220
6375
|
}
|
|
6221
6376
|
/**
|
|
6222
6377
|
* Set delivery type on checkout (shipping or pickup).
|
|
@@ -9190,10 +9345,7 @@ var _BrainerceClient = class _BrainerceClient {
|
|
|
9190
9345
|
* ```
|
|
9191
9346
|
*/
|
|
9192
9347
|
async applyTaxPreset(presetKey) {
|
|
9193
|
-
return this.adminRequest(
|
|
9194
|
-
"POST",
|
|
9195
|
-
`/api/v1/tax/presets/${encodePathSegment(presetKey)}/apply`
|
|
9196
|
-
);
|
|
9348
|
+
return this.adminRequest("POST", `/api/v1/tax/presets/${encodePathSegment(presetKey)}/apply`);
|
|
9197
9349
|
}
|
|
9198
9350
|
/**
|
|
9199
9351
|
* Get a single tax rate by ID
|
|
@@ -9823,6 +9975,27 @@ var _BrainerceClient = class _BrainerceClient {
|
|
|
9823
9975
|
}
|
|
9824
9976
|
// -------------------- Store Team Management (Admin) --------------------
|
|
9825
9977
|
// Store-level team management. Each store has its own team with roles and permissions.
|
|
9978
|
+
/**
|
|
9979
|
+
* Every store-level team operation is dashboard-only.
|
|
9980
|
+
*
|
|
9981
|
+
* `store-team.controller.ts:53` carries `DashboardOnlyGuard`, which rejects
|
|
9982
|
+
* `api_key` and `app_installation` principals outright, so no SDK caller can
|
|
9983
|
+
* reach these however the URL is spelled. They additionally pointed at
|
|
9984
|
+
* `/api/v1/stores/:storeId/team*`, and `@Controller('v1')`
|
|
9985
|
+
* (external-api.controller.ts:181) has no `stores` root — so what they
|
|
9986
|
+
* actually returned was a 404, not the 403 you would expect from the guard.
|
|
9987
|
+
*
|
|
9988
|
+
* Throwing beats either status code: a 404 reads as "wrong id" and a 403 as
|
|
9989
|
+
* "missing permission", and both send the caller looking for a fix that does
|
|
9990
|
+
* not exist. Use the account-level `getTeamMembers()` family, or the
|
|
9991
|
+
* dashboard.
|
|
9992
|
+
*/
|
|
9993
|
+
dashboardOnlyTeamOperation(operation) {
|
|
9994
|
+
throw new BrainerceError(
|
|
9995
|
+
`${operation} is a dashboard-only operation. Store-level team management sits behind DashboardOnlyGuard, which rejects API-key principals, so there is no SDK path to it in any mode. Use the account-level team methods (getTeamMembers, inviteTeamMember, ...) or the Brainerce dashboard.`,
|
|
9996
|
+
403
|
|
9997
|
+
);
|
|
9998
|
+
}
|
|
9826
9999
|
/**
|
|
9827
10000
|
* Get the team for a specific store (members + pending invitations)
|
|
9828
10001
|
* Requires Admin mode (apiKey) and MANAGE_TEAM permission
|
|
@@ -9832,11 +10005,8 @@ var _BrainerceClient = class _BrainerceClient {
|
|
|
9832
10005
|
* const { members, invitations } = await client.getStoreTeam('store_id');
|
|
9833
10006
|
* ```
|
|
9834
10007
|
*/
|
|
9835
|
-
async getStoreTeam(
|
|
9836
|
-
return this.
|
|
9837
|
-
"GET",
|
|
9838
|
-
`/api/v1/stores/${encodePathSegment(storeId)}/team`
|
|
9839
|
-
);
|
|
10008
|
+
async getStoreTeam(_storeId) {
|
|
10009
|
+
return this.dashboardOnlyTeamOperation("getStoreTeam");
|
|
9840
10010
|
}
|
|
9841
10011
|
/**
|
|
9842
10012
|
* Invite a new member to a store
|
|
@@ -9853,12 +10023,8 @@ var _BrainerceClient = class _BrainerceClient {
|
|
|
9853
10023
|
* });
|
|
9854
10024
|
* ```
|
|
9855
10025
|
*/
|
|
9856
|
-
async inviteStoreMember(
|
|
9857
|
-
return this.
|
|
9858
|
-
"POST",
|
|
9859
|
-
`/api/v1/stores/${encodePathSegment(storeId)}/team/invite`,
|
|
9860
|
-
data
|
|
9861
|
-
);
|
|
10026
|
+
async inviteStoreMember(_storeId, _data) {
|
|
10027
|
+
return this.dashboardOnlyTeamOperation("inviteStoreMember");
|
|
9862
10028
|
}
|
|
9863
10029
|
/**
|
|
9864
10030
|
* Update a store team member's role and/or permissions
|
|
@@ -9875,12 +10041,8 @@ var _BrainerceClient = class _BrainerceClient {
|
|
|
9875
10041
|
* });
|
|
9876
10042
|
* ```
|
|
9877
10043
|
*/
|
|
9878
|
-
async updateStoreMember(
|
|
9879
|
-
return this.
|
|
9880
|
-
"PATCH",
|
|
9881
|
-
`/api/v1/stores/${encodePathSegment(storeId)}/team/${encodePathSegment(memberId)}`,
|
|
9882
|
-
data
|
|
9883
|
-
);
|
|
10044
|
+
async updateStoreMember(_storeId, _memberId, _data) {
|
|
10045
|
+
return this.dashboardOnlyTeamOperation("updateStoreMember");
|
|
9884
10046
|
}
|
|
9885
10047
|
/**
|
|
9886
10048
|
* Replace the set of vibe-coded sales channels a store member is restricted to.
|
|
@@ -9901,42 +10063,29 @@ var _BrainerceClient = class _BrainerceClient {
|
|
|
9901
10063
|
* });
|
|
9902
10064
|
* ```
|
|
9903
10065
|
*/
|
|
9904
|
-
async updateStoreMemberSalesChannels(
|
|
9905
|
-
return this.
|
|
9906
|
-
"PATCH",
|
|
9907
|
-
`/api/v1/stores/${encodePathSegment(storeId)}/team/${encodePathSegment(memberId)}/sales-channels`,
|
|
9908
|
-
data
|
|
9909
|
-
);
|
|
10066
|
+
async updateStoreMemberSalesChannels(_storeId, _memberId, _data) {
|
|
10067
|
+
return this.dashboardOnlyTeamOperation("updateStoreMemberSalesChannels");
|
|
9910
10068
|
}
|
|
9911
10069
|
/**
|
|
9912
10070
|
* Remove a member from a store team
|
|
9913
10071
|
* Requires Admin mode (apiKey) and MANAGE_TEAM permission
|
|
9914
10072
|
*/
|
|
9915
|
-
async removeStoreMember(
|
|
9916
|
-
|
|
9917
|
-
"DELETE",
|
|
9918
|
-
`/api/v1/stores/${encodePathSegment(storeId)}/team/${encodePathSegment(memberId)}`
|
|
9919
|
-
);
|
|
10073
|
+
async removeStoreMember(_storeId, _memberId) {
|
|
10074
|
+
return this.dashboardOnlyTeamOperation("removeStoreMember");
|
|
9920
10075
|
}
|
|
9921
10076
|
/**
|
|
9922
10077
|
* Resend a store invitation email
|
|
9923
10078
|
* Requires Admin mode (apiKey) and MANAGE_TEAM permission
|
|
9924
10079
|
*/
|
|
9925
|
-
async resendStoreInvitation(
|
|
9926
|
-
return this.
|
|
9927
|
-
"POST",
|
|
9928
|
-
`/api/v1/stores/${encodePathSegment(storeId)}/team/invitations/${encodePathSegment(invitationId)}/resend`
|
|
9929
|
-
);
|
|
10080
|
+
async resendStoreInvitation(_storeId, _invitationId) {
|
|
10081
|
+
return this.dashboardOnlyTeamOperation("resendStoreInvitation");
|
|
9930
10082
|
}
|
|
9931
10083
|
/**
|
|
9932
10084
|
* Revoke a store invitation
|
|
9933
10085
|
* Requires Admin mode (apiKey) and MANAGE_TEAM permission
|
|
9934
10086
|
*/
|
|
9935
|
-
async revokeStoreInvitation(
|
|
9936
|
-
|
|
9937
|
-
"DELETE",
|
|
9938
|
-
`/api/v1/stores/${encodePathSegment(storeId)}/team/invitations/${encodePathSegment(invitationId)}`
|
|
9939
|
-
);
|
|
10087
|
+
async revokeStoreInvitation(_storeId, _invitationId) {
|
|
10088
|
+
return this.dashboardOnlyTeamOperation("revokeStoreInvitation");
|
|
9940
10089
|
}
|
|
9941
10090
|
/**
|
|
9942
10091
|
* Get public invitation details by token (no auth required)
|
|
@@ -9945,7 +10094,7 @@ var _BrainerceClient = class _BrainerceClient {
|
|
|
9945
10094
|
async getStoreInvitationByToken(token) {
|
|
9946
10095
|
return this.request(
|
|
9947
10096
|
"GET",
|
|
9948
|
-
`/api/
|
|
10097
|
+
`/api/store-invitations/${encodePathSegment(token)}`
|
|
9949
10098
|
);
|
|
9950
10099
|
}
|
|
9951
10100
|
/**
|
|
@@ -9953,9 +10102,9 @@ var _BrainerceClient = class _BrainerceClient {
|
|
|
9953
10102
|
* Requires Admin mode (apiKey)
|
|
9954
10103
|
*/
|
|
9955
10104
|
async acceptStoreInvitation(token) {
|
|
9956
|
-
|
|
9957
|
-
"
|
|
9958
|
-
|
|
10105
|
+
throw new BrainerceError(
|
|
10106
|
+
"acceptStoreInvitation requires a dashboard session belonging to the invited user: the invitation is matched against the email address of that user, which an API key does not have. Send the invitee to the invitation link instead.",
|
|
10107
|
+
403
|
|
9959
10108
|
);
|
|
9960
10109
|
}
|
|
9961
10110
|
/**
|
|
@@ -9972,7 +10121,7 @@ var _BrainerceClient = class _BrainerceClient {
|
|
|
9972
10121
|
* ```
|
|
9973
10122
|
*/
|
|
9974
10123
|
async getMyStores() {
|
|
9975
|
-
return this.
|
|
10124
|
+
return this.dashboardOnlyUserContext("getMyStores");
|
|
9976
10125
|
}
|
|
9977
10126
|
/**
|
|
9978
10127
|
* Get the current user's resolved permissions for a specific store
|
|
@@ -9986,10 +10135,23 @@ var _BrainerceClient = class _BrainerceClient {
|
|
|
9986
10135
|
* }
|
|
9987
10136
|
* ```
|
|
9988
10137
|
*/
|
|
9989
|
-
async getMyStorePermissions(
|
|
9990
|
-
return this.
|
|
9991
|
-
|
|
9992
|
-
|
|
10138
|
+
async getMyStorePermissions(_storeId) {
|
|
10139
|
+
return this.dashboardOnlyUserContext("getMyStorePermissions");
|
|
10140
|
+
}
|
|
10141
|
+
/**
|
|
10142
|
+
* `/me/*` answers "who am I and what can I reach", which only a real user can
|
|
10143
|
+
* ask. `UserContextController` (store-team.controller.ts:246) is guarded by
|
|
10144
|
+
* `DashboardOnlyGuard` for a load-bearing reason its own G16 comment spells
|
|
10145
|
+
* out: both routes resolve access purely from `@CurrentUserId()`, which is
|
|
10146
|
+
* `undefined` for an api_key principal, so the store filter would be stripped
|
|
10147
|
+
* and every store on the platform returned. The guard is the control. These
|
|
10148
|
+
* also pointed at `/api/v1/me/*`, which no controller serves, so the observed
|
|
10149
|
+
* failure was a 404 rather than the guard's 403.
|
|
10150
|
+
*/
|
|
10151
|
+
dashboardOnlyUserContext(operation) {
|
|
10152
|
+
throw new BrainerceError(
|
|
10153
|
+
`${operation} resolves the CURRENT USER, so it requires a dashboard session and is rejected for API-key principals by design. An API key is already scoped to one store: read it with getStore(), and read the permissions of a member from getStoreTeam() in the dashboard.`,
|
|
10154
|
+
403
|
|
9993
10155
|
);
|
|
9994
10156
|
}
|
|
9995
10157
|
// -------------------- Email Settings & Templates (Admin) --------------------
|
|
@@ -10132,7 +10294,7 @@ var _BrainerceClient = class _BrainerceClient {
|
|
|
10132
10294
|
* Requires Admin mode (apiKey)
|
|
10133
10295
|
*/
|
|
10134
10296
|
async getSyncConflicts() {
|
|
10135
|
-
return this.
|
|
10297
|
+
return this.syncConflictsNotImplemented("getSyncConflicts");
|
|
10136
10298
|
}
|
|
10137
10299
|
/**
|
|
10138
10300
|
* Resolve a sync conflict
|
|
@@ -10142,12 +10304,28 @@ var _BrainerceClient = class _BrainerceClient {
|
|
|
10142
10304
|
* @param resolution - 'MERGE' to link to existing product, 'CREATE_NEW' to create new product
|
|
10143
10305
|
*/
|
|
10144
10306
|
async resolveSyncConflict(conflictId, resolution) {
|
|
10145
|
-
|
|
10146
|
-
|
|
10147
|
-
|
|
10148
|
-
|
|
10149
|
-
|
|
10150
|
-
|
|
10307
|
+
void conflictId;
|
|
10308
|
+
void resolution;
|
|
10309
|
+
return this.syncConflictsNotImplemented("resolveSyncConflict");
|
|
10310
|
+
}
|
|
10311
|
+
/**
|
|
10312
|
+
* Sync conflicts were never implemented on the server.
|
|
10313
|
+
*
|
|
10314
|
+
* There is no `sync-conflict` route anywhere in the backend — not under
|
|
10315
|
+
* `@Controller('v1')`, not on any other controller. These two methods have
|
|
10316
|
+
* called a URL that has never existed, and `SyncConflict` /
|
|
10317
|
+
* `SyncConflictResolution` / `ResolveSyncConflictDto` are exported types with
|
|
10318
|
+
* no producer. The METAFIELD conflict siblings below are real
|
|
10319
|
+
* (external-api.controller.ts:4788, :4802) and are easy to mistake for these.
|
|
10320
|
+
*
|
|
10321
|
+
* Kept as throwing stubs rather than deleted: removing exported methods from a
|
|
10322
|
+
* published package is a breaking change, and a caller who has been swallowing
|
|
10323
|
+
* a 404 deserves to be told why.
|
|
10324
|
+
*/
|
|
10325
|
+
syncConflictsNotImplemented(operation) {
|
|
10326
|
+
throw new BrainerceError(
|
|
10327
|
+
`${operation} is not implemented: the platform exposes no sync-conflict endpoint. If you are looking for metafield sync conflicts, use getMetafieldConflicts() / resolveMetafieldConflict().`,
|
|
10328
|
+
501
|
|
10151
10329
|
);
|
|
10152
10330
|
}
|
|
10153
10331
|
// -------------------- Metafield Conflicts (Admin) --------------------
|