@viu/emporix-sdk 2.22.0 → 2.23.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.
Files changed (105) hide show
  1. package/CHANGELOG.md +122 -0
  2. package/dist/availability.cjs +118 -0
  3. package/dist/availability.cjs.map +1 -1
  4. package/dist/availability.d.cts +178 -2
  5. package/dist/availability.d.ts +178 -2
  6. package/dist/availability.js +1 -1
  7. package/dist/cart.cjs +156 -11
  8. package/dist/cart.cjs.map +1 -1
  9. package/dist/cart.d.cts +176 -3
  10. package/dist/cart.d.ts +176 -3
  11. package/dist/cart.js +1 -1
  12. package/dist/category.cjs +192 -2
  13. package/dist/category.cjs.map +1 -1
  14. package/dist/category.d.cts +398 -1
  15. package/dist/category.d.ts +398 -1
  16. package/dist/category.js +1 -1
  17. package/dist/{chunk-HD5RBCM6.js → chunk-27NLS646.js} +10 -2
  18. package/dist/chunk-27NLS646.js.map +1 -0
  19. package/dist/{chunk-MMX5FGMI.js → chunk-6PJFOX3A.js} +109 -2
  20. package/dist/chunk-6PJFOX3A.js.map +1 -0
  21. package/dist/chunk-HWVFF6B2.js +378 -0
  22. package/dist/chunk-HWVFF6B2.js.map +1 -0
  23. package/dist/chunk-LQFRJSVT.js +224 -0
  24. package/dist/chunk-LQFRJSVT.js.map +1 -0
  25. package/dist/chunk-P7G4LOOV.js +264 -0
  26. package/dist/chunk-P7G4LOOV.js.map +1 -0
  27. package/dist/{chunk-44F52KRE.js → chunk-QQMLN76U.js} +27 -2
  28. package/dist/chunk-QQMLN76U.js.map +1 -0
  29. package/dist/chunk-UNW6SFSB.js +363 -0
  30. package/dist/chunk-UNW6SFSB.js.map +1 -0
  31. package/dist/chunk-V3275BA7.js +181 -0
  32. package/dist/chunk-V3275BA7.js.map +1 -0
  33. package/dist/chunk-W2KBVWJ2.js +323 -0
  34. package/dist/chunk-W2KBVWJ2.js.map +1 -0
  35. package/dist/{chunk-5DWCYDQD.js → chunk-YVZ6GOLE.js} +158 -13
  36. package/dist/chunk-YVZ6GOLE.js.map +1 -0
  37. package/dist/chunk-ZOFGDNSX.js +305 -0
  38. package/dist/chunk-ZOFGDNSX.js.map +1 -0
  39. package/dist/companies.cjs +25 -0
  40. package/dist/companies.cjs.map +1 -1
  41. package/dist/companies.d.cts +14 -0
  42. package/dist/companies.d.ts +14 -0
  43. package/dist/companies.js +1 -1
  44. package/dist/contacts.cjs +8 -0
  45. package/dist/contacts.cjs.map +1 -1
  46. package/dist/contacts.d.cts +2 -0
  47. package/dist/contacts.d.ts +2 -0
  48. package/dist/contacts.js +1 -1
  49. package/dist/customer-groups-BxSNFHq1.d.cts +706 -0
  50. package/dist/customer-groups-GlzWhDsi.d.ts +706 -0
  51. package/dist/customer-groups.cjs +200 -17
  52. package/dist/customer-groups.cjs.map +1 -1
  53. package/dist/customer-groups.d.cts +2 -110
  54. package/dist/customer-groups.d.ts +2 -110
  55. package/dist/customer-groups.js +1 -1
  56. package/dist/index.cjs +2220 -391
  57. package/dist/index.cjs.map +1 -1
  58. package/dist/index.d.cts +433 -11
  59. package/dist/index.d.ts +433 -11
  60. package/dist/index.js +668 -340
  61. package/dist/index.js.map +1 -1
  62. package/dist/orders.cjs +160 -2
  63. package/dist/orders.cjs.map +1 -1
  64. package/dist/orders.d.cts +221 -1
  65. package/dist/orders.d.ts +221 -1
  66. package/dist/orders.js +1 -1
  67. package/dist/payment.cjs +107 -0
  68. package/dist/payment.cjs.map +1 -1
  69. package/dist/payment.d.cts +299 -1
  70. package/dist/payment.d.ts +299 -1
  71. package/dist/payment.js +1 -1
  72. package/dist/price.cjs +197 -0
  73. package/dist/price.cjs.map +1 -1
  74. package/dist/price.d.cts +577 -1
  75. package/dist/price.d.ts +577 -1
  76. package/dist/price.js +1 -1
  77. package/dist/product.cjs +190 -0
  78. package/dist/product.cjs.map +1 -1
  79. package/dist/product.d.cts +503 -1
  80. package/dist/product.d.ts +503 -1
  81. package/dist/product.js +1 -1
  82. package/dist/segment.cjs +179 -0
  83. package/dist/segment.cjs.map +1 -1
  84. package/dist/segment.d.cts +181 -1
  85. package/dist/segment.d.ts +181 -1
  86. package/dist/segment.js +1 -1
  87. package/package.json +1 -1
  88. package/dist/chunk-36T4YPQJ.js +0 -106
  89. package/dist/chunk-36T4YPQJ.js.map +0 -1
  90. package/dist/chunk-3BTPX7IJ.js +0 -41
  91. package/dist/chunk-3BTPX7IJ.js.map +0 -1
  92. package/dist/chunk-44F52KRE.js.map +0 -1
  93. package/dist/chunk-5DWCYDQD.js.map +0 -1
  94. package/dist/chunk-A3LYJUD4.js +0 -108
  95. package/dist/chunk-A3LYJUD4.js.map +0 -1
  96. package/dist/chunk-DXOLWAOY.js +0 -188
  97. package/dist/chunk-DXOLWAOY.js.map +0 -1
  98. package/dist/chunk-FZMP5NQZ.js +0 -173
  99. package/dist/chunk-FZMP5NQZ.js.map +0 -1
  100. package/dist/chunk-HD5RBCM6.js.map +0 -1
  101. package/dist/chunk-IVCCGJN5.js +0 -63
  102. package/dist/chunk-IVCCGJN5.js.map +0 -1
  103. package/dist/chunk-MMX5FGMI.js.map +0 -1
  104. package/dist/chunk-NE7MIZPR.js +0 -144
  105. package/dist/chunk-NE7MIZPR.js.map +0 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,127 @@
1
1
  # @viu/emporix-sdk
2
2
 
3
+ ## 2.23.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#172](https://github.com/viuteam/emporix-sdk/pull/172) [`3761f0f`](https://github.com/viuteam/emporix-sdk/commit/3761f0fd7f0eace3dd0dfa30fb76811c484dd7ee) Thanks [@amnael1](https://github.com/amnael1)! - Add availability admin operations to `client.availability`: `listForSite`
8
+ (paginated per-site listing), per-product `create`/`update`/`delete`, and
9
+ `bulkCreate`/`bulkUpdate`/`bulkDelete` (207 Multi-Status — inspect each entry;
10
+ the bulk delete carries a body). Writes default to service auth. The bulk
11
+ methods accept `{ vendorId }`, sent as the `vendor-id` header — note the OpenAPI
12
+ schema spells it `venodr-id`, an apparent upstream typo, and the corrected name
13
+ is not yet verified against the live API. The deprecated location-management
14
+ endpoints remain unwrapped, and the existing reads are unchanged.
15
+
16
+ - [#176](https://github.com/viuteam/emporix-sdk/pull/176) [`6f3b296`](https://github.com/viuteam/emporix-sdk/commit/6f3b296ca3c4e81a62459fab82fbd33af6feb7a3) Thanks [@amnael1](https://github.com/amnael1)! - Fix `carts.setShippingAddress` and `carts.setBillingAddress`, which called
17
+ `/carts/{id}/shipping-address` and `/carts/{id}/billing-address` — paths that do
18
+ not exist and returned 404 on every call (verified against a live tenant). Cart
19
+ addresses are set through `PUT /carts/{id}` with an `addresses` array. Because
20
+ that array is a full replace — sending one type leaves the other as an empty
21
+ stub — both methods now read the cart, merge in the new address, write, and
22
+ return the re-fetched cart. Their signatures are unchanged.
23
+
24
+ Adds `carts.setAddresses(cartId, { shipping, billing }, auth)` for setting both
25
+ in a single request, skipping the read. Note it **replaces** the address set: an
26
+ omitted type is cleared.
27
+
28
+ - [#167](https://github.com/viuteam/emporix-sdk/pull/167) [`3b7f63a`](https://github.com/viuteam/emporix-sdk/commit/3b7f63afe0264adcf0655694440732fc923b63db) Thanks [@amnael1](https://github.com/amnael1)! - Add the remaining cart operations to `client.carts`: backend `search` (POST
29
+ `/carts/search`), `delete`, and `update` (which take an unguarded auth so a
30
+ service token can manage any cart), plus storefront `getItem`, `listDiscounts`,
31
+ `removeAllDiscounts`, `removeDiscountByIndex`, and `getDeliveryRestrictions`
32
+ (which keep the customer/anonymous guard). Mutating ops re-fetch and return the
33
+ updated `Cart` (`delete` returns void). Existing cart methods are unchanged.
34
+
35
+ - [#166](https://github.com/viuteam/emporix-sdk/pull/166) [`3c058d0`](https://github.com/viuteam/emporix-sdk/commit/3c058d0786132b0ff6281ab39d5f584943c6bf70) Thanks [@amnael1](https://github.com/amnael1)! - Add category admin CRUD to `client.categories`: core writes
36
+ (`create`/`update`/`patch`/`delete`), POST-body search (`searchByQuery`,
37
+ `searchTrees`), and a `categories.assignments` sub-resource — `list`,
38
+ `create`, `bulkCreate`, `remove`, `removeAll`, reference-based
39
+ `upsertByReference`/`removeByReference`/`bulkUpsertByReference`, and
40
+ tenant-wide `listCategoriesByReference`/`removeAllByReference`. Writes default
41
+ to service auth (overridable). The existing storefront reads are unchanged.
42
+
43
+ - [#162](https://github.com/viuteam/emporix-sdk/pull/162) [`7a4b4a5`](https://github.com/viuteam/emporix-sdk/commit/7a4b4a552ad3c49c08b1b3b9dc057f6d57ef7fb2) Thanks [@amnael1](https://github.com/amnael1)! - Add `client.iam` — a CRUD facade for the current IAM admin surface: `iam.users`
44
+ (list/create/get/getMe/update/delete + group/scope/access-control reads),
45
+ `iam.groups` (CRUD + membership + access-controls), `iam.accessControls`
46
+ (list/get/upsert/delete), `iam.scopes` (list/get/upsertCustom/deleteCustom).
47
+ Every method takes a required `auth`. `client.customerGroups` now delegates its
48
+ list/add operations to `iam.groups` (public API unchanged). The deprecated
49
+ legacy-RBAC model (roles/permissions/resources/templates) is not wrapped.
50
+
51
+ - [#168](https://github.com/viuteam/emporix-sdk/pull/168) [`81a9b82`](https://github.com/viuteam/emporix-sdk/commit/81a9b826ffad4bdc1fe2b5a8a008e33d77873df2) Thanks [@amnael1](https://github.com/amnael1)! - Complete the order-v2 admin surface. `client.salesOrders` gains `list`,
52
+ `search`, `create`, `replace` (PUT full-replace, alongside the existing `update`
53
+ PATCH), `delete`, `listTransitions`, `transition`, `listHistoricalTransitions`,
54
+ `calculate`, `updateEntries`, and `split`. `client.orders` gains the B2B reads
55
+ `listForLegalEntity` and `getForLegalEntity`. All sales-order admin methods take
56
+ a required (service-token) auth; the legal-entity reads take a required customer
57
+ auth. Existing order methods are unchanged.
58
+
59
+ - [#171](https://github.com/viuteam/emporix-sdk/pull/171) [`e10181b`](https://github.com/viuteam/emporix-sdk/commit/e10181b9839c4129b6f5ae782de6093e76958772) Thanks [@amnael1](https://github.com/amnael1)! - Add the payment admin surface to `client.payments`. New `payments.modes`
60
+ sub-resource for payment-mode configuration (`list`/`get`/`create`/`update`/`delete`
61
+ against `/paymentmodes/config`), and new `payments.transactions` sub-resource for
62
+ the backend lifecycle: `list`, `get`, `authorize` (backend counterpart of the
63
+ storefront `authorize`), `capture`, `refund`, and `cancel`. All new methods
64
+ default to service auth. Note that these endpoints report business failures in
65
+ the 200 response body (`successful: false`), not as HTTP errors. The existing
66
+ storefront methods are unchanged.
67
+
68
+ - [#164](https://github.com/viuteam/emporix-sdk/pull/164) [`ac816f4`](https://github.com/viuteam/emporix-sdk/commit/ac816f431d33433e2d974325e258ded1078fb4bf) Thanks [@amnael1](https://github.com/amnael1)! - Add price admin CRUD to `client.prices`: flat prices
69
+ (`create`/`list`/`get`/`upsert`/`delete`/`search`/`bulkCreate`/`bulkUpsert`),
70
+ `prices.models` (price models CRUD), and `prices.lists` (price-list CRUD +
71
+ search + nested price-list prices incl. bulk create/upsert/delete). Every admin
72
+ method defaults to `service` auth (override allowed). The existing `match*`
73
+ methods are unchanged.
74
+
75
+ - [#170](https://github.com/viuteam/emporix-sdk/pull/170) [`ea68a89`](https://github.com/viuteam/emporix-sdk/commit/ea68a89e4bff3f7c5cd713b9b7804b1714a548c0) Thanks [@amnael1](https://github.com/amnael1)! - Add product admin writes to `client.products`: `create`, `update` (PATCH),
76
+ `replace` (PUT, with an optional `partial` flag), `delete` (with `force`),
77
+ `bulkCreate`/`bulkUpdate` (207 Multi-Status — inspect each entry), the
78
+ dynamic-variant recalculation group (`recalculate`, `listRecalculationJobs`,
79
+ `getRecalculationJob`), and a `products.templates` sub-resource
80
+ (`list`/`get`/`create`/`update`/`delete`). Writes default to service auth and
81
+ expose the endpoints' query flags (`skipVariantGeneration`, `doIndex`,
82
+ `skipRelatedItemsValidation`); the existing catalog reads are unchanged.
83
+
84
+ - [#175](https://github.com/viuteam/emporix-sdk/pull/175) [`9cb253b`](https://github.com/viuteam/emporix-sdk/commit/9cb253b2ffea1709cfedbc24e749f964f65b9cc3) Thanks [@amnael1](https://github.com/amnael1)! - Close the last API-coverage gaps. `client.companies` gains `search` (POST
85
+ `/legal-entities/search`) and `parentHierarchy`; `client.contacts` gains `get`.
86
+ `client.fees` gains `deleteProductFee` (removing a single fee from a product,
87
+ next to the existing `deleteProductFees` which clears all) plus
88
+ `searchItemFeesByProductId` and `searchItemFeesByProductIds` — note these two
89
+ search bodies are asymmetric upstream (`siteCodes: string[]` vs a single
90
+ `siteCode`, and `productIds` as a comma-separated string), which the SDK mirrors
91
+ verbatim. `client.tenantConfig` gains `listGlobal` and `client.clientConfig`
92
+ gains `listClients`. Every service keeps its existing auth convention.
93
+
94
+ - [#174](https://github.com/viuteam/emporix-sdk/pull/174) [`58243bb`](https://github.com/viuteam/emporix-sdk/commit/58243bb31e4aca4110d57225c91e1b221d6f29bd) Thanks [@amnael1](https://github.com/amnael1)! - Complete the schema-service coverage in `client.schema`. New `schema.references`
95
+ sub-resource (`list`/`get`/`create`/`update`/`delete`) — create and update are
96
+ `multipart/form-data` uploads whose `file` part accepts a `Blob` or a plain
97
+ object (serialized to JSON). New instance bulk methods `bulkCreateInstances`,
98
+ `bulkUpsertInstances` and `bulkDeleteInstances` alongside the existing
99
+ `bulkPatchInstances`, plus `exportCustomEntities` / `importCustomEntities`.
100
+ Note: the OpenAPI schema declares no request body for the bulk delete, but its
101
+ description mandates an array of ids — the SDK follows the description and sends
102
+ one. All methods keep the service's service-token default.
103
+
104
+ - [#165](https://github.com/viuteam/emporix-sdk/pull/165) [`3a3c611`](https://github.com/viuteam/emporix-sdk/commit/3a3c61123674a523f30982b944b1f04b80d2cc58) Thanks [@amnael1](https://github.com/amnael1)! - Add customer-segment admin CRUD to `client.segments`: segment core
105
+ (`create`/`search`/`update`/`patch`/`delete`/`match` + `bulkCreate`/`bulkUpdate`/`bulkDelete`),
106
+ `segments.customers` (list/search + B2C & B2B assign/remove + bulk), and
107
+ `segments.items` (search + assign/remove per PRODUCT/CATEGORY + bulk). Every
108
+ admin method defaults to `service` auth (override allowed). The existing
109
+ storefront read methods are unchanged.
110
+
111
+ - [#173](https://github.com/viuteam/emporix-sdk/pull/173) [`9a2ddfe`](https://github.com/viuteam/emporix-sdk/commit/9a2ddfe7d66b2eabdb056c99b81f4dad412a9082) Thanks [@amnael1](https://github.com/amnael1)! - Add site-settings admin operations to `client.sites`: `create`, `update`
112
+ (PATCH), `replace` (PUT, with an optional `expand` query), `delete`,
113
+ `listCodes` (GET `/siteslist`), and a `sites.mixins` sub-resource
114
+ (`list`/`get`/`create`/`update`/`replace`/`delete`). Writes default to service
115
+ auth. `update`/`replace` return nothing — those endpoints respond 200 without a
116
+ defined body, so re-read with `get(siteCode)` when the updated site is needed.
117
+ The existing reads are unchanged.
118
+
119
+ ### Patch Changes
120
+
121
+ - [#169](https://github.com/viuteam/emporix-sdk/pull/169) [`130811b`](https://github.com/viuteam/emporix-sdk/commit/130811b688bd93525964e680224528548af03644) Thanks [@viu-release-bot](https://github.com/apps/viu-release-bot)! - chore(sdk): sync generated types with upstream Emporix API specs
122
+
123
+ Updated services: schema
124
+
3
125
  ## 2.22.0
4
126
 
5
127
  ### Minor Changes
@@ -43,6 +43,7 @@ var EmporixNotFoundError = class extends EmporixError {
43
43
 
44
44
  // src/services/availability.ts
45
45
  var ANON = { kind: "anonymous" };
46
+ var SERVICE = { kind: "service" };
46
47
  var AvailabilityService = class {
47
48
  constructor(ctx) {
48
49
  this.ctx = ctx;
@@ -97,6 +98,123 @@ var AvailabilityService = class {
97
98
  }
98
99
  );
99
100
  }
101
+ /**
102
+ * Lists every availability record for a site (`GET /availability/site/{site}`),
103
+ * wrapped into `PaginatedItems`. Default auth: anonymous.
104
+ */
105
+ async listForSite(siteCode, params = {}, auth = ANON) {
106
+ const pageNumber = params.pageNumber ?? 1;
107
+ const pageSize = params.pageSize ?? 50;
108
+ const items = await this.ctx.http.request({
109
+ method: "GET",
110
+ path: `/availability/${this.ctx.tenant}/availability/site/${encodeURIComponent(siteCode)}`,
111
+ query: {
112
+ pageNumber,
113
+ pageSize,
114
+ ...params.q === void 0 ? {} : { q: params.q },
115
+ ...params.sort === void 0 ? {} : { sort: params.sort }
116
+ },
117
+ auth
118
+ });
119
+ return { items, pageNumber, pageSize, hasNextPage: items.length === pageSize };
120
+ }
121
+ // --- Admin writes. Default auth: service. ---
122
+ /**
123
+ * Creates an availability record for a product on a site
124
+ * (`POST /availability/{productId}/{site}`). Responds 409 when the record
125
+ * already exists — use {@link update} to upsert. Default auth: service.
126
+ */
127
+ async create(productId, siteCode, input, auth = SERVICE) {
128
+ return this.ctx.http.request({
129
+ method: "POST",
130
+ path: `/availability/${this.ctx.tenant}/availability/${encodeURIComponent(
131
+ productId
132
+ )}/${encodeURIComponent(siteCode)}`,
133
+ body: input,
134
+ auth
135
+ });
136
+ }
137
+ /**
138
+ * Upserts a product's availability on a site
139
+ * (`PUT /availability/{productId}/{site}`). Returns the created record's id
140
+ * on 201 and nothing on 204. This endpoint has no PATCH counterpart.
141
+ * Default auth: service.
142
+ */
143
+ async update(productId, siteCode, input, auth = SERVICE) {
144
+ return this.ctx.http.request({
145
+ method: "PUT",
146
+ path: `/availability/${this.ctx.tenant}/availability/${encodeURIComponent(
147
+ productId
148
+ )}/${encodeURIComponent(siteCode)}`,
149
+ body: input,
150
+ auth
151
+ });
152
+ }
153
+ /**
154
+ * Deletes a product's availability on a site
155
+ * (`DELETE /availability/{productId}/{site}`). Default auth: service.
156
+ */
157
+ async delete(productId, siteCode, auth = SERVICE) {
158
+ await this.ctx.http.request({
159
+ method: "DELETE",
160
+ path: `/availability/${this.ctx.tenant}/availability/${encodeURIComponent(
161
+ productId
162
+ )}/${encodeURIComponent(siteCode)}`,
163
+ auth
164
+ });
165
+ }
166
+ /**
167
+ * Bulk-creates availability records (`POST /availability/bulk`). Responds 207
168
+ * Multi-Status: partial failures do **not** throw — inspect each entry.
169
+ *
170
+ * `options.vendorId` limits the operation to a vendor's products. It is sent
171
+ * as the `vendor-id` header. **Note:** the OpenAPI schema spells this header
172
+ * `venodr-id`, which is an evident upstream typo (the body field is
173
+ * `vendorId`); the SDK sends the corrected name. Unverified against the live
174
+ * API — if the service really expects the misspelling, the filter silently
175
+ * has no effect.
176
+ *
177
+ * Default auth: service.
178
+ */
179
+ async bulkCreate(input, options = {}, auth = SERVICE) {
180
+ return this.ctx.http.request({
181
+ method: "POST",
182
+ path: `/availability/${this.ctx.tenant}/availability/bulk`,
183
+ ...options.vendorId === void 0 ? {} : { headers: { "vendor-id": options.vendorId } },
184
+ body: input,
185
+ auth
186
+ });
187
+ }
188
+ /**
189
+ * Bulk-updates availability records (`PUT /availability/bulk`). Responds 207
190
+ * Multi-Status: partial failures do **not** throw — inspect each entry. See
191
+ * {@link bulkCreate} for the `vendorId` header caveat. Default auth: service.
192
+ */
193
+ async bulkUpdate(input, options = {}, auth = SERVICE) {
194
+ return this.ctx.http.request({
195
+ method: "PUT",
196
+ path: `/availability/${this.ctx.tenant}/availability/bulk`,
197
+ ...options.vendorId === void 0 ? {} : { headers: { "vendor-id": options.vendorId } },
198
+ body: input,
199
+ auth
200
+ });
201
+ }
202
+ /**
203
+ * Bulk-deletes availability records (`DELETE /availability/bulk`). Unusually
204
+ * for a DELETE, this endpoint takes a body listing the records to remove.
205
+ * Responds 207 Multi-Status: partial failures do **not** throw — inspect each
206
+ * entry. See {@link bulkCreate} for the `vendorId` header caveat. Default
207
+ * auth: service.
208
+ */
209
+ async bulkDelete(input, options = {}, auth = SERVICE) {
210
+ return this.ctx.http.request({
211
+ method: "DELETE",
212
+ path: `/availability/${this.ctx.tenant}/availability/bulk`,
213
+ ...options.vendorId === void 0 ? {} : { headers: { "vendor-id": options.vendorId } },
214
+ body: input,
215
+ auth
216
+ });
217
+ }
100
218
  };
101
219
 
102
220
  exports.AvailabilityService = AvailabilityService;
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/core/errors.ts","../src/services/availability.ts"],"names":[],"mappings":"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","file":"availability.cjs","sourcesContent":["/** Keys whose values are stripped from any serialised error body. */\nconst REDACTED_BODY_KEYS = new Set([\n \"access_token\", \"refresh_token\", \"token\", \"customertoken\", \"saastoken\",\n \"secret\", \"client_secret\", \"authorization\", \"password\",\n]);\n\nfunction scrub(body: unknown): unknown {\n if (Array.isArray(body)) return body.map(scrub);\n if (body && typeof body === \"object\") {\n const out: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(body as Record<string, unknown>)) {\n out[k] = REDACTED_BODY_KEYS.has(k.toLowerCase()) ? \"***redacted***\" : scrub(v);\n }\n return out;\n }\n return body;\n}\n\n/** Base class for every error thrown by the SDK. */\nexport class EmporixError extends Error {\n readonly status: number | undefined;\n readonly body: unknown;\n constructor(message: string, status?: number, body?: unknown) {\n super(message);\n this.name = new.target.name;\n this.status = status;\n this.body = body;\n Object.setPrototypeOf(this, new.target.prototype);\n }\n /** Safe serialisation — token-like body fields are redacted. */\n toJSON(): Record<string, unknown> {\n return { name: this.name, message: this.message, status: this.status, body: scrub(this.body) };\n }\n}\n\n/** 401 — authentication failed or token expired. */\nexport class EmporixAuthError extends EmporixError {}\n/** 403 — authenticated but not permitted. */\nexport class EmporixForbiddenError extends EmporixError {}\n/** 404 — resource not found. */\nexport class EmporixNotFoundError extends EmporixError {}\n/** 400/422 — request validation failed. */\nexport class EmporixValidationError extends EmporixError {}\n/** 5xx — server-side failure. */\nexport class EmporixServerError extends EmporixError {}\n/** Request aborted by the configured connect/read timeout. No HTTP status. */\nexport class EmporixTimeoutError extends EmporixError {}\n/** DNS/TLS/connection-level failure before or during the exchange. No HTTP status. */\nexport class EmporixNetworkError extends EmporixError {}\n\n/**\n * 403 with a `missing scope: <name>` hint in the body's `details` array.\n * Subclasses {@link EmporixForbiddenError} so existing 403 catches still work.\n */\nexport class EmporixInsufficientScopeError extends EmporixForbiddenError {\n readonly requiredScope: string | undefined;\n constructor(message: string, status: number, body: unknown, requiredScope?: string) {\n super(message, status, body);\n this.requiredScope = requiredScope;\n }\n}\n\nconst SCOPE_HINT_RE = /missing scope[: ]+([a-z0-9._-]+)/i;\n\nfunction extractRequiredScope(body: unknown): string | undefined {\n if (body && typeof body === \"object\" && \"details\" in body) {\n const details = (body as { details?: unknown }).details;\n if (Array.isArray(details)) {\n for (const d of details) {\n if (typeof d === \"string\") {\n const m = d.match(SCOPE_HINT_RE);\n if (m) return m[1];\n }\n }\n }\n }\n return undefined;\n}\n\n/** Maps an HTTP status to the matching {@link EmporixError} subclass. */\nexport function errorFromResponse(status: number, message: string, body: unknown): EmporixError {\n if (status === 401) return new EmporixAuthError(message, status, body);\n if (status === 403) {\n const scope = extractRequiredScope(body);\n if (scope) return new EmporixInsufficientScopeError(message, status, body, scope);\n return new EmporixForbiddenError(message, status, body);\n }\n if (status === 404) return new EmporixNotFoundError(message, status, body);\n if (status === 400 || status === 422) return new EmporixValidationError(message, status, body);\n if (status >= 500) return new EmporixServerError(message, status, body);\n return new EmporixError(message, status, body);\n}\n","import type { ClientContext } from \"../core/context\";\nimport type { AuthContext } from \"../core/auth\";\nimport { EmporixNotFoundError } from \"../core/errors\";\nimport type { Availability } from \"./availability-types\";\n\nexport type { Availability } from \"./availability-types\";\n\n/** Shared options for {@link AvailabilityService} reads. */\nexport interface AvailabilityOptions {\n /**\n * When `true`, a product with no availability record resolves to a default\n * `{ available: true }` instead of throwing (single `get`) / being marked\n * unavailable (`getMany`). Off by default — opt in for tenants that sell\n * without stock management.\n */\n defaultAvailableOnNotFound?: boolean;\n}\n\nconst ANON: AuthContext = { kind: \"anonymous\" };\n\n/**\n * Reads product availability per site. Default auth is anonymous (like\n * `PriceService.matchByContext`); pass a customer/raw/service context to use a\n * different token. Requires the `availability.availability_view` scope on\n * whichever token is used.\n */\nexport class AvailabilityService {\n static readonly channel = \"availability\" as const;\n constructor(private readonly ctx: ClientContext) {}\n\n /**\n * Single product. Resolves the availability record, or — when\n * `opts.defaultAvailableOnNotFound` is set — a default available record on 404.\n */\n async get(\n productId: string,\n siteCode: string,\n auth: AuthContext = ANON,\n opts: AvailabilityOptions = {},\n ): Promise<Availability> {\n try {\n return await this.ctx.http.request<Availability>({\n method: \"GET\",\n path: `/availability/${this.ctx.tenant}/availability/${encodeURIComponent(\n productId,\n )}/${encodeURIComponent(siteCode)}`,\n auth,\n });\n } catch (err) {\n if (err instanceof EmporixNotFoundError && opts.defaultAvailableOnNotFound) {\n return { productId, site: siteCode, available: true };\n }\n throw err;\n }\n }\n\n /**\n * Batch read via `POST .../availability/search` (one request). Products with\n * no availability record are absent from the response; each is synthesized as\n * `{ available: false }` (or `{ available: true }` when\n * `opts.defaultAvailableOnNotFound` is set). The result preserves input order\n * and length. An empty `productIds` resolves to `[]` without a request.\n */\n async getMany(\n productIds: string[],\n siteCode: string,\n auth: AuthContext = ANON,\n opts: AvailabilityOptions = {},\n ): Promise<Availability[]> {\n if (productIds.length === 0) return [];\n const found = await this.ctx.http.request<Availability[]>({\n method: \"POST\",\n path: `/availability/${this.ctx.tenant}/availability/search`,\n auth,\n query: { site: siteCode, pageSize: productIds.length },\n body: productIds,\n idempotent: true, // pure read over POST — safe to replay on 5xx/429\n });\n const byId = new Map<string, Availability>();\n for (const a of found) if (a.productId) byId.set(a.productId, a);\n return productIds.map(\n (id) =>\n byId.get(id) ?? {\n productId: id,\n site: siteCode,\n available: Boolean(opts.defaultAvailableOnNotFound),\n },\n );\n }\n}\n"]}
1
+ {"version":3,"sources":["../src/core/errors.ts","../src/services/availability.ts"],"names":[],"mappings":"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","file":"availability.cjs","sourcesContent":["/** Keys whose values are stripped from any serialised error body. */\nconst REDACTED_BODY_KEYS = new Set([\n \"access_token\", \"refresh_token\", \"token\", \"customertoken\", \"saastoken\",\n \"secret\", \"client_secret\", \"authorization\", \"password\",\n]);\n\nfunction scrub(body: unknown): unknown {\n if (Array.isArray(body)) return body.map(scrub);\n if (body && typeof body === \"object\") {\n const out: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(body as Record<string, unknown>)) {\n out[k] = REDACTED_BODY_KEYS.has(k.toLowerCase()) ? \"***redacted***\" : scrub(v);\n }\n return out;\n }\n return body;\n}\n\n/** Base class for every error thrown by the SDK. */\nexport class EmporixError extends Error {\n readonly status: number | undefined;\n readonly body: unknown;\n constructor(message: string, status?: number, body?: unknown) {\n super(message);\n this.name = new.target.name;\n this.status = status;\n this.body = body;\n Object.setPrototypeOf(this, new.target.prototype);\n }\n /** Safe serialisation — token-like body fields are redacted. */\n toJSON(): Record<string, unknown> {\n return { name: this.name, message: this.message, status: this.status, body: scrub(this.body) };\n }\n}\n\n/** 401 — authentication failed or token expired. */\nexport class EmporixAuthError extends EmporixError {}\n/** 403 — authenticated but not permitted. */\nexport class EmporixForbiddenError extends EmporixError {}\n/** 404 — resource not found. */\nexport class EmporixNotFoundError extends EmporixError {}\n/** 400/422 — request validation failed. */\nexport class EmporixValidationError extends EmporixError {}\n/** 5xx — server-side failure. */\nexport class EmporixServerError extends EmporixError {}\n/** Request aborted by the configured connect/read timeout. No HTTP status. */\nexport class EmporixTimeoutError extends EmporixError {}\n/** DNS/TLS/connection-level failure before or during the exchange. No HTTP status. */\nexport class EmporixNetworkError extends EmporixError {}\n\n/**\n * 403 with a `missing scope: <name>` hint in the body's `details` array.\n * Subclasses {@link EmporixForbiddenError} so existing 403 catches still work.\n */\nexport class EmporixInsufficientScopeError extends EmporixForbiddenError {\n readonly requiredScope: string | undefined;\n constructor(message: string, status: number, body: unknown, requiredScope?: string) {\n super(message, status, body);\n this.requiredScope = requiredScope;\n }\n}\n\nconst SCOPE_HINT_RE = /missing scope[: ]+([a-z0-9._-]+)/i;\n\nfunction extractRequiredScope(body: unknown): string | undefined {\n if (body && typeof body === \"object\" && \"details\" in body) {\n const details = (body as { details?: unknown }).details;\n if (Array.isArray(details)) {\n for (const d of details) {\n if (typeof d === \"string\") {\n const m = d.match(SCOPE_HINT_RE);\n if (m) return m[1];\n }\n }\n }\n }\n return undefined;\n}\n\n/** Maps an HTTP status to the matching {@link EmporixError} subclass. */\nexport function errorFromResponse(status: number, message: string, body: unknown): EmporixError {\n if (status === 401) return new EmporixAuthError(message, status, body);\n if (status === 403) {\n const scope = extractRequiredScope(body);\n if (scope) return new EmporixInsufficientScopeError(message, status, body, scope);\n return new EmporixForbiddenError(message, status, body);\n }\n if (status === 404) return new EmporixNotFoundError(message, status, body);\n if (status === 400 || status === 422) return new EmporixValidationError(message, status, body);\n if (status >= 500) return new EmporixServerError(message, status, body);\n return new EmporixError(message, status, body);\n}\n","import type { ClientContext, PaginatedItems } from \"../core/context\";\nimport type { AuthContext } from \"../core/auth\";\nimport { EmporixNotFoundError } from \"../core/errors\";\nimport type {\n Availability,\n AvailabilityInput,\n AvailabilityCreated,\n AvailabilityBulkInput,\n AvailabilityBulkDeleteInput,\n AvailabilityBulkResult,\n} from \"./availability-types\";\n\nexport type {\n Availability,\n AvailabilityInput,\n AvailabilityCreated,\n AvailabilityBulkInput,\n AvailabilityBulkDeleteInput,\n AvailabilityBulkResult,\n} from \"./availability-types\";\n\n/** Shared options for {@link AvailabilityService} reads. */\nexport interface AvailabilityOptions {\n /**\n * When `true`, a product with no availability record resolves to a default\n * `{ available: true }` instead of throwing (single `get`) / being marked\n * unavailable (`getMany`). Off by default — opt in for tenants that sell\n * without stock management.\n */\n defaultAvailableOnNotFound?: boolean;\n}\n\nconst ANON: AuthContext = { kind: \"anonymous\" };\nconst SERVICE: AuthContext = { kind: \"service\" };\n\n/**\n * Reads product availability per site. Default auth is anonymous (like\n * `PriceService.matchByContext`); pass a customer/raw/service context to use a\n * different token. Requires the `availability.availability_view` scope on\n * whichever token is used.\n */\nexport class AvailabilityService {\n static readonly channel = \"availability\" as const;\n constructor(private readonly ctx: ClientContext) {}\n\n /**\n * Single product. Resolves the availability record, or — when\n * `opts.defaultAvailableOnNotFound` is set — a default available record on 404.\n */\n async get(\n productId: string,\n siteCode: string,\n auth: AuthContext = ANON,\n opts: AvailabilityOptions = {},\n ): Promise<Availability> {\n try {\n return await this.ctx.http.request<Availability>({\n method: \"GET\",\n path: `/availability/${this.ctx.tenant}/availability/${encodeURIComponent(\n productId,\n )}/${encodeURIComponent(siteCode)}`,\n auth,\n });\n } catch (err) {\n if (err instanceof EmporixNotFoundError && opts.defaultAvailableOnNotFound) {\n return { productId, site: siteCode, available: true };\n }\n throw err;\n }\n }\n\n /**\n * Batch read via `POST .../availability/search` (one request). Products with\n * no availability record are absent from the response; each is synthesized as\n * `{ available: false }` (or `{ available: true }` when\n * `opts.defaultAvailableOnNotFound` is set). The result preserves input order\n * and length. An empty `productIds` resolves to `[]` without a request.\n */\n async getMany(\n productIds: string[],\n siteCode: string,\n auth: AuthContext = ANON,\n opts: AvailabilityOptions = {},\n ): Promise<Availability[]> {\n if (productIds.length === 0) return [];\n const found = await this.ctx.http.request<Availability[]>({\n method: \"POST\",\n path: `/availability/${this.ctx.tenant}/availability/search`,\n auth,\n query: { site: siteCode, pageSize: productIds.length },\n body: productIds,\n idempotent: true, // pure read over POST — safe to replay on 5xx/429\n });\n const byId = new Map<string, Availability>();\n for (const a of found) if (a.productId) byId.set(a.productId, a);\n return productIds.map(\n (id) =>\n byId.get(id) ?? {\n productId: id,\n site: siteCode,\n available: Boolean(opts.defaultAvailableOnNotFound),\n },\n );\n }\n\n /**\n * Lists every availability record for a site (`GET /availability/site/{site}`),\n * wrapped into `PaginatedItems`. Default auth: anonymous.\n */\n async listForSite(\n siteCode: string,\n params: { pageNumber?: number; pageSize?: number; q?: string; sort?: string } = {},\n auth: AuthContext = ANON,\n ): Promise<PaginatedItems<Availability>> {\n const pageNumber = params.pageNumber ?? 1;\n const pageSize = params.pageSize ?? 50;\n const items = await this.ctx.http.request<Availability[]>({\n method: \"GET\",\n path: `/availability/${this.ctx.tenant}/availability/site/${encodeURIComponent(siteCode)}`,\n query: {\n pageNumber,\n pageSize,\n ...(params.q === undefined ? {} : { q: params.q }),\n ...(params.sort === undefined ? {} : { sort: params.sort }),\n },\n auth,\n });\n return { items, pageNumber, pageSize, hasNextPage: items.length === pageSize };\n }\n\n // --- Admin writes. Default auth: service. ---\n\n /**\n * Creates an availability record for a product on a site\n * (`POST /availability/{productId}/{site}`). Responds 409 when the record\n * already exists — use {@link update} to upsert. Default auth: service.\n */\n async create(\n productId: string,\n siteCode: string,\n input: AvailabilityInput,\n auth: AuthContext = SERVICE,\n ): Promise<AvailabilityCreated> {\n return this.ctx.http.request<AvailabilityCreated>({\n method: \"POST\",\n path: `/availability/${this.ctx.tenant}/availability/${encodeURIComponent(\n productId,\n )}/${encodeURIComponent(siteCode)}`,\n body: input,\n auth,\n });\n }\n\n /**\n * Upserts a product's availability on a site\n * (`PUT /availability/{productId}/{site}`). Returns the created record's id\n * on 201 and nothing on 204. This endpoint has no PATCH counterpart.\n * Default auth: service.\n */\n async update(\n productId: string,\n siteCode: string,\n input: AvailabilityInput,\n auth: AuthContext = SERVICE,\n ): Promise<AvailabilityCreated | void> {\n return this.ctx.http.request<AvailabilityCreated | void>({\n method: \"PUT\",\n path: `/availability/${this.ctx.tenant}/availability/${encodeURIComponent(\n productId,\n )}/${encodeURIComponent(siteCode)}`,\n body: input,\n auth,\n });\n }\n\n /**\n * Deletes a product's availability on a site\n * (`DELETE /availability/{productId}/{site}`). Default auth: service.\n */\n async delete(productId: string, siteCode: string, auth: AuthContext = SERVICE): Promise<void> {\n await this.ctx.http.request<void>({\n method: \"DELETE\",\n path: `/availability/${this.ctx.tenant}/availability/${encodeURIComponent(\n productId,\n )}/${encodeURIComponent(siteCode)}`,\n auth,\n });\n }\n\n /**\n * Bulk-creates availability records (`POST /availability/bulk`). Responds 207\n * Multi-Status: partial failures do **not** throw — inspect each entry.\n *\n * `options.vendorId` limits the operation to a vendor's products. It is sent\n * as the `vendor-id` header. **Note:** the OpenAPI schema spells this header\n * `venodr-id`, which is an evident upstream typo (the body field is\n * `vendorId`); the SDK sends the corrected name. Unverified against the live\n * API — if the service really expects the misspelling, the filter silently\n * has no effect.\n *\n * Default auth: service.\n */\n async bulkCreate(\n input: AvailabilityBulkInput[],\n options: { vendorId?: string } = {},\n auth: AuthContext = SERVICE,\n ): Promise<AvailabilityBulkResult[]> {\n return this.ctx.http.request<AvailabilityBulkResult[]>({\n method: \"POST\",\n path: `/availability/${this.ctx.tenant}/availability/bulk`,\n ...(options.vendorId === undefined ? {} : { headers: { \"vendor-id\": options.vendorId } }),\n body: input,\n auth,\n });\n }\n\n /**\n * Bulk-updates availability records (`PUT /availability/bulk`). Responds 207\n * Multi-Status: partial failures do **not** throw — inspect each entry. See\n * {@link bulkCreate} for the `vendorId` header caveat. Default auth: service.\n */\n async bulkUpdate(\n input: AvailabilityBulkInput[],\n options: { vendorId?: string } = {},\n auth: AuthContext = SERVICE,\n ): Promise<AvailabilityBulkResult[]> {\n return this.ctx.http.request<AvailabilityBulkResult[]>({\n method: \"PUT\",\n path: `/availability/${this.ctx.tenant}/availability/bulk`,\n ...(options.vendorId === undefined ? {} : { headers: { \"vendor-id\": options.vendorId } }),\n body: input,\n auth,\n });\n }\n\n /**\n * Bulk-deletes availability records (`DELETE /availability/bulk`). Unusually\n * for a DELETE, this endpoint takes a body listing the records to remove.\n * Responds 207 Multi-Status: partial failures do **not** throw — inspect each\n * entry. See {@link bulkCreate} for the `vendorId` header caveat. Default\n * auth: service.\n */\n async bulkDelete(\n input: AvailabilityBulkDeleteInput[],\n options: { vendorId?: string } = {},\n auth: AuthContext = SERVICE,\n ): Promise<AvailabilityBulkResult[]> {\n return this.ctx.http.request<AvailabilityBulkResult[]>({\n method: \"DELETE\",\n path: `/availability/${this.ctx.tenant}/availability/bulk`,\n ...(options.vendorId === undefined ? {} : { headers: { \"vendor-id\": options.vendorId } }),\n body: input,\n auth,\n });\n }\n}\n"]}
@@ -1,5 +1,81 @@
1
- import { C as ClientContext, b as AuthContext } from './context-CfXJcYKP.cjs';
1
+ import { C as ClientContext, b as AuthContext, P as PaginatedItems } from './context-CfXJcYKP.cjs';
2
2
 
3
+ type AvailabilityDto = {
4
+ /**
5
+ * Stock level of the product, expressed as a number.
6
+ */
7
+ stockLevel?: number;
8
+ /**
9
+ * Flag indicating whether the product is available.
10
+ */
11
+ available?: boolean;
12
+ /**
13
+ * Popularity of the product, expressed as a number.
14
+ */
15
+ popularity?: number;
16
+ distributionChannel?: DistributionChannel;
17
+ /**
18
+ * The field contains mixins values.
19
+ */
20
+ mixins?: {
21
+ [key: string]: unknown;
22
+ };
23
+ metadata?: {
24
+ /**
25
+ * Links to the mixin schemas.
26
+ */
27
+ mixins?: {
28
+ [key: string]: string;
29
+ };
30
+ };
31
+ };
32
+ type AvailabilityBulkDto = {
33
+ /**
34
+ * Unique identifier of the product.
35
+ */
36
+ productId?: string;
37
+ /**
38
+ * Unique identifier of the site.
39
+ */
40
+ site?: string;
41
+ /**
42
+ * Stock level of the product, expressed as a number.
43
+ */
44
+ stockLevel?: number;
45
+ /**
46
+ * Flag indicating whether the product is available.
47
+ */
48
+ available?: boolean;
49
+ /**
50
+ * Popularity of the product, expressed as a number.
51
+ */
52
+ popularity?: number;
53
+ distributionChannel?: DistributionChannel;
54
+ /**
55
+ * The field contains mixins values.
56
+ */
57
+ mixins?: {
58
+ [key: string]: unknown;
59
+ };
60
+ metadata?: {
61
+ /**
62
+ * Links to the mixin schemas.
63
+ */
64
+ mixins?: {
65
+ [key: string]: string;
66
+ };
67
+ };
68
+ };
69
+ type AvailabilityDeleteBulkDto = {
70
+ /**
71
+ * Unique identifier of the product.
72
+ */
73
+ productId?: string;
74
+ /**
75
+ * Unique identifier of the site.
76
+ */
77
+ site?: string;
78
+ };
3
79
  /**
4
80
  * Availability details.
5
81
  */
@@ -118,10 +194,38 @@ type AvailabilityWithBundle = {
118
194
  };
119
195
  };
120
196
  type AvailabilityList = Array<Availability$1>;
197
+ type BulkResponse = {
198
+ /**
199
+ * ID of the affected availability (in the format <site>:&lt;<productId>).
200
+ */
201
+ id?: string;
202
+ /**
203
+ * Index of the processed item, matching the item position in request body.
204
+ */
205
+ index?: number;
206
+ /**
207
+ * HTTP Status Code.
208
+ */
209
+ code?: number;
210
+ /**
211
+ * HTTP Status description.
212
+ */
213
+ status?: string;
214
+ /**
215
+ * Error message. Present only when an error occurs (HTTP status code from groups `4xx` or `5xx`)
216
+ */
217
+ message?: string;
218
+ };
121
219
  /**
122
220
  * Name of the product distribution channel.
123
221
  */
124
222
  type DistributionChannel = 'ASSORTMENT' | 'HOME_DELIVERY' | 'PICKUP';
223
+ type IdResponse = {
224
+ /**
225
+ * ID of the created resource.
226
+ */
227
+ id?: string;
228
+ };
125
229
 
126
230
  /**
127
231
  * Public types for the Availability Service — stable names aliased over the
@@ -135,6 +239,16 @@ type DistributionChannel = 'ASSORTMENT' | 'HOME_DELIVERY' | 'PICKUP';
135
239
 
136
240
  /** A product's availability record (bundle-aware). */
137
241
  type Availability = AvailabilityWithBundle;
242
+ /** Body for creating or updating a single product's availability. */
243
+ type AvailabilityInput = AvailabilityDto;
244
+ /** Id envelope returned when an availability record is created. */
245
+ type AvailabilityCreated = IdResponse;
246
+ /** One entry of a bulk create/update request. */
247
+ type AvailabilityBulkInput = AvailabilityBulkDto;
248
+ /** One entry of a bulk delete request. */
249
+ type AvailabilityBulkDeleteInput = AvailabilityDeleteBulkDto;
250
+ /** Per-entry result of a bulk availability operation (207 Multi-Status). */
251
+ type AvailabilityBulkResult = BulkResponse;
138
252
 
139
253
  /** Shared options for {@link AvailabilityService} reads. */
140
254
  interface AvailabilityOptions {
@@ -169,6 +283,68 @@ declare class AvailabilityService {
169
283
  * and length. An empty `productIds` resolves to `[]` without a request.
170
284
  */
171
285
  getMany(productIds: string[], siteCode: string, auth?: AuthContext, opts?: AvailabilityOptions): Promise<Availability[]>;
286
+ /**
287
+ * Lists every availability record for a site (`GET /availability/site/{site}`),
288
+ * wrapped into `PaginatedItems`. Default auth: anonymous.
289
+ */
290
+ listForSite(siteCode: string, params?: {
291
+ pageNumber?: number;
292
+ pageSize?: number;
293
+ q?: string;
294
+ sort?: string;
295
+ }, auth?: AuthContext): Promise<PaginatedItems<Availability>>;
296
+ /**
297
+ * Creates an availability record for a product on a site
298
+ * (`POST /availability/{productId}/{site}`). Responds 409 when the record
299
+ * already exists — use {@link update} to upsert. Default auth: service.
300
+ */
301
+ create(productId: string, siteCode: string, input: AvailabilityInput, auth?: AuthContext): Promise<AvailabilityCreated>;
302
+ /**
303
+ * Upserts a product's availability on a site
304
+ * (`PUT /availability/{productId}/{site}`). Returns the created record's id
305
+ * on 201 and nothing on 204. This endpoint has no PATCH counterpart.
306
+ * Default auth: service.
307
+ */
308
+ update(productId: string, siteCode: string, input: AvailabilityInput, auth?: AuthContext): Promise<AvailabilityCreated | void>;
309
+ /**
310
+ * Deletes a product's availability on a site
311
+ * (`DELETE /availability/{productId}/{site}`). Default auth: service.
312
+ */
313
+ delete(productId: string, siteCode: string, auth?: AuthContext): Promise<void>;
314
+ /**
315
+ * Bulk-creates availability records (`POST /availability/bulk`). Responds 207
316
+ * Multi-Status: partial failures do **not** throw — inspect each entry.
317
+ *
318
+ * `options.vendorId` limits the operation to a vendor's products. It is sent
319
+ * as the `vendor-id` header. **Note:** the OpenAPI schema spells this header
320
+ * `venodr-id`, which is an evident upstream typo (the body field is
321
+ * `vendorId`); the SDK sends the corrected name. Unverified against the live
322
+ * API — if the service really expects the misspelling, the filter silently
323
+ * has no effect.
324
+ *
325
+ * Default auth: service.
326
+ */
327
+ bulkCreate(input: AvailabilityBulkInput[], options?: {
328
+ vendorId?: string;
329
+ }, auth?: AuthContext): Promise<AvailabilityBulkResult[]>;
330
+ /**
331
+ * Bulk-updates availability records (`PUT /availability/bulk`). Responds 207
332
+ * Multi-Status: partial failures do **not** throw — inspect each entry. See
333
+ * {@link bulkCreate} for the `vendorId` header caveat. Default auth: service.
334
+ */
335
+ bulkUpdate(input: AvailabilityBulkInput[], options?: {
336
+ vendorId?: string;
337
+ }, auth?: AuthContext): Promise<AvailabilityBulkResult[]>;
338
+ /**
339
+ * Bulk-deletes availability records (`DELETE /availability/bulk`). Unusually
340
+ * for a DELETE, this endpoint takes a body listing the records to remove.
341
+ * Responds 207 Multi-Status: partial failures do **not** throw — inspect each
342
+ * entry. See {@link bulkCreate} for the `vendorId` header caveat. Default
343
+ * auth: service.
344
+ */
345
+ bulkDelete(input: AvailabilityBulkDeleteInput[], options?: {
346
+ vendorId?: string;
347
+ }, auth?: AuthContext): Promise<AvailabilityBulkResult[]>;
172
348
  }
173
349
 
174
- export { type Availability, type AvailabilityOptions, AvailabilityService };
350
+ export { type Availability, type AvailabilityBulkDeleteInput, type AvailabilityBulkInput, type AvailabilityBulkResult, type AvailabilityCreated, type AvailabilityInput, type AvailabilityOptions, AvailabilityService };