@sixtyninecommerce/admin 0.7.0 → 0.9.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 (161) hide show
  1. package/README.md +2445 -17
  2. package/dist/api-tokens/index.d.ts +15 -5
  3. package/dist/api-tokens/index.js +1 -0
  4. package/dist/apps/event-subscription.d.ts +59 -0
  5. package/dist/apps/event-subscription.js +32 -0
  6. package/dist/apps/hook-secret.d.ts +22 -0
  7. package/dist/apps/hook-secret.js +36 -0
  8. package/dist/apps/index.d.ts +54 -3
  9. package/dist/apps/index.js +17 -0
  10. package/dist/audit/index.d.ts +7 -0
  11. package/dist/auth/queries.d.ts +5 -1
  12. package/dist/auth/queries.js +6 -0
  13. package/dist/bulk/index.d.ts +323 -0
  14. package/dist/bulk/index.js +162 -0
  15. package/dist/catalog/assets.d.ts +147 -0
  16. package/dist/catalog/assets.js +164 -0
  17. package/dist/catalog/collections.d.ts +109 -0
  18. package/dist/catalog/collections.js +91 -0
  19. package/dist/catalog/facets.d.ts +103 -0
  20. package/dist/catalog/facets.js +100 -0
  21. package/dist/catalog/index.d.ts +115 -0
  22. package/dist/catalog/index.js +21 -0
  23. package/dist/catalog/options.d.ts +89 -0
  24. package/dist/catalog/options.js +88 -0
  25. package/dist/catalog/products-bulk.d.ts +21 -0
  26. package/dist/catalog/products-bulk.js +58 -0
  27. package/dist/catalog/products.d.ts +489 -0
  28. package/dist/catalog/products.js +365 -0
  29. package/dist/catalog/properties.d.ts +234 -0
  30. package/dist/catalog/properties.js +158 -0
  31. package/dist/catalog/types.d.ts +174 -0
  32. package/dist/catalog/types.js +141 -0
  33. package/dist/catalog/variants.d.ts +274 -0
  34. package/dist/catalog/variants.js +258 -0
  35. package/dist/catalog/visibility.d.ts +57 -0
  36. package/dist/catalog/visibility.js +59 -0
  37. package/dist/client.d.ts +171 -3
  38. package/dist/client.js +81 -12
  39. package/dist/compliance/index.d.ts +88 -0
  40. package/dist/compliance/index.js +88 -0
  41. package/dist/customer-data-redaction.d.ts +14 -0
  42. package/dist/customer-data-redaction.js +22 -0
  43. package/dist/customers/index.d.ts +428 -17
  44. package/dist/customers/index.js +322 -15
  45. package/dist/documents/index.d.ts +513 -16
  46. package/dist/documents/index.js +229 -3
  47. package/dist/events/index.d.ts +259 -0
  48. package/dist/events/index.js +147 -0
  49. package/dist/feeds/ai.d.ts +46 -0
  50. package/dist/feeds/ai.js +43 -0
  51. package/dist/feeds/categories.d.ts +50 -0
  52. package/dist/feeds/categories.js +56 -0
  53. package/dist/feeds/configs.d.ts +54 -0
  54. package/dist/feeds/configs.js +85 -0
  55. package/dist/feeds/identifier-fields.d.ts +25 -0
  56. package/dist/feeds/identifier-fields.js +29 -0
  57. package/dist/feeds/index.d.ts +54 -0
  58. package/dist/feeds/index.js +46 -0
  59. package/dist/feeds/preserve.d.ts +38 -0
  60. package/dist/feeds/preserve.js +74 -0
  61. package/dist/feeds/rules.d.ts +42 -0
  62. package/dist/feeds/rules.js +56 -0
  63. package/dist/feeds/types.d.ts +654 -0
  64. package/dist/feeds/types.js +135 -0
  65. package/dist/fulfillments/index.d.ts +360 -0
  66. package/dist/fulfillments/index.js +425 -0
  67. package/dist/heads/index.d.ts +60 -0
  68. package/dist/heads/index.js +45 -0
  69. package/dist/hooks/assignments.d.ts +90 -0
  70. package/dist/hooks/assignments.js +53 -0
  71. package/dist/hooks/index.d.ts +97 -0
  72. package/dist/hooks/index.js +76 -0
  73. package/dist/index.d.ts +84 -9
  74. package/dist/index.js +16 -1
  75. package/dist/jobs/bulk-action-run.d.ts +65 -0
  76. package/dist/jobs/bulk-action-run.js +70 -0
  77. package/dist/locations/index.d.ts +6 -2
  78. package/dist/meta/index.d.ts +32 -0
  79. package/dist/orders/commit-edit.d.ts +123 -0
  80. package/dist/orders/commit-edit.js +142 -0
  81. package/dist/orders/get.d.ts +722 -0
  82. package/dist/orders/get.js +530 -0
  83. package/dist/orders/index.d.ts +105 -20
  84. package/dist/orders/index.js +44 -0
  85. package/dist/orders/line-price-preview.d.ts +297 -0
  86. package/dist/orders/line-price-preview.js +50 -0
  87. package/dist/orders/manual-discounts.d.ts +132 -0
  88. package/dist/orders/manual-discounts.js +95 -0
  89. package/dist/orders/manual-pricing.d.ts +192 -0
  90. package/dist/orders/manual-pricing.js +72 -0
  91. package/dist/orders/order-entry.d.ts +566 -0
  92. package/dist/orders/order-entry.js +129 -0
  93. package/dist/orders/parcel-charge.d.ts +45 -0
  94. package/dist/orders/parcel-charge.js +55 -0
  95. package/dist/orders/plan-edit.d.ts +489 -0
  96. package/dist/orders/plan-edit.js +93 -0
  97. package/dist/orders/status.d.ts +235 -0
  98. package/dist/orders/status.js +96 -0
  99. package/dist/orders/surcharges.d.ts +75 -2
  100. package/dist/orders/surcharges.js +110 -4
  101. package/dist/payments/account-credit.d.ts +171 -0
  102. package/dist/payments/account-credit.js +107 -0
  103. package/dist/payments/index.d.ts +368 -2
  104. package/dist/payments/index.js +138 -0
  105. package/dist/platform/catalog.d.ts +148 -0
  106. package/dist/platform/catalog.js +74 -0
  107. package/dist/platform/entitlements.d.ts +111 -0
  108. package/dist/platform/entitlements.js +86 -0
  109. package/dist/platform/legal-entities.d.ts +139 -0
  110. package/dist/platform/legal-entities.js +126 -0
  111. package/dist/platform/legal-entity-numbering.d.ts +103 -0
  112. package/dist/platform/legal-entity-numbering.js +101 -0
  113. package/dist/platform/organization-membership.d.ts +80 -0
  114. package/dist/platform/organization-membership.js +71 -0
  115. package/dist/platform/organization-settings.d.ts +33 -0
  116. package/dist/platform/organization-settings.js +42 -0
  117. package/dist/platform/organization-sharing.d.ts +172 -0
  118. package/dist/platform/organization-sharing.js +120 -0
  119. package/dist/platform/organizations.d.ts +205 -0
  120. package/dist/platform/organizations.js +180 -0
  121. package/dist/platform/provision-store.d.ts +88 -8
  122. package/dist/platform/provision-store.js +12 -0
  123. package/dist/platform/reports.d.ts +46 -0
  124. package/dist/platform/reports.js +31 -0
  125. package/dist/platform/server-metrics.d.ts +58 -0
  126. package/dist/platform/server-metrics.js +11 -0
  127. package/dist/pos/index.d.ts +567 -0
  128. package/dist/pos/index.js +205 -0
  129. package/dist/pricing/index.d.ts +405 -0
  130. package/dist/pricing/index.js +351 -0
  131. package/dist/provenance/index.d.ts +93 -0
  132. package/dist/provenance/index.js +53 -0
  133. package/dist/reports/index.d.ts +199 -0
  134. package/dist/reports/index.js +154 -0
  135. package/dist/shipping/parcel-count-suggestion.d.ts +52 -0
  136. package/dist/shipping/parcel-count-suggestion.js +73 -0
  137. package/dist/shipping/parcel-rule.d.ts +48 -0
  138. package/dist/shipping/parcel-rule.js +91 -0
  139. package/dist/stock/index.d.ts +166 -0
  140. package/dist/stock/index.js +115 -0
  141. package/dist/stock/transfers.d.ts +520 -0
  142. package/dist/stock/transfers.js +437 -0
  143. package/dist/stored-value/index.d.ts +154 -0
  144. package/dist/stored-value/index.js +130 -0
  145. package/dist/tenant/capabilities.d.ts +10 -0
  146. package/dist/tenant/entitlements.d.ts +35 -0
  147. package/dist/tenant/entitlements.js +15 -0
  148. package/dist/tenant/field-groups.d.ts +64 -0
  149. package/dist/tenant/field-groups.js +34 -0
  150. package/dist/tenant/legal-entity.d.ts +32 -0
  151. package/dist/tenant/legal-entity.js +41 -0
  152. package/dist/tenant/notifications.d.ts +148 -0
  153. package/dist/tenant/notifications.js +79 -0
  154. package/dist/tenant/retention.d.ts +10 -4
  155. package/dist/tenant/settings-sources.d.ts +103 -0
  156. package/dist/tenant/settings-sources.js +92 -0
  157. package/dist/types.d.ts +86 -11
  158. package/dist/uploads/index.d.ts +11 -7
  159. package/dist/users/index.d.ts +104 -0
  160. package/dist/users/index.js +80 -0
  161. package/package.json +3 -2
@@ -0,0 +1,489 @@
1
+ import { type Page, type Transport } from '@sixtyninecommerce/core';
2
+ import type { JobHandle } from '../jobs/index.js';
3
+ import type { Call, ListOptions } from '../types.js';
4
+ import { type ProductBulkInput, type ProductBulkRun } from './products-bulk.js';
5
+ import { type AssetRef, type Availability, type AvailabilityInput, type CatalogueOwnership, type FacetValueRef, type LanguageCode, type ProductAvailabilityState, type TranslationInput } from './types.js';
6
+ export interface ProductOptionRef {
7
+ id: string;
8
+ code: string;
9
+ name: string;
10
+ }
11
+ export interface ProductOptionGroupRef {
12
+ id: string;
13
+ code: string;
14
+ name: string;
15
+ options: ProductOptionRef[];
16
+ }
17
+ export interface ProductTranslation {
18
+ id: string;
19
+ languageCode: LanguageCode;
20
+ name: string;
21
+ slug: string;
22
+ description: string;
23
+ }
24
+ /**
25
+ * A product, in the language the call asked for (`TenantContext.language`,
26
+ * else the store's default). Variants are read separately
27
+ * (`catalog.variants.list(productId)`); `variantCount` says how many there are.
28
+ */
29
+ export interface Product extends Availability<ProductAvailabilityState> {
30
+ id: string;
31
+ createdAt: string;
32
+ updatedAt: string;
33
+ languageCode: LanguageCode;
34
+ name: string;
35
+ slug: string;
36
+ description: string;
37
+ enabled: boolean;
38
+ featuredAsset: AssetRef | null;
39
+ assets: AssetRef[];
40
+ facetValues: FacetValueRef[];
41
+ optionGroups: ProductOptionGroupRef[];
42
+ translations: ProductTranslation[];
43
+ variantCount: number;
44
+ /** The store's own product, or its organization's; see {@link CatalogueOwnership}. */
45
+ catalogueOwnership: CatalogueOwnership;
46
+ /**
47
+ * The ACTIVE store excludes this product its organization shares with it
48
+ * ({@link ProductsModule.exclude}): it is off the store's storefront and out of its carts,
49
+ * while the store's orders, returns and invoices keep it. Always false for the store's own
50
+ * product and in an organization's workspace.
51
+ */
52
+ excludedFromStore: boolean;
53
+ }
54
+ export interface ProductTranslationInput extends TranslationInput {
55
+ name?: string;
56
+ /** Vendure makes a slug unique within the store by suffixing it, rather than refusing a duplicate. */
57
+ slug?: string;
58
+ description?: string;
59
+ }
60
+ export interface CreateProductInput extends AvailabilityInput<ProductAvailabilityState> {
61
+ /** At least one; the store's default language is the one a shop falls back to. */
62
+ translations: ProductTranslationInput[];
63
+ /** Defaults to true on the engine. */
64
+ enabled?: boolean;
65
+ featuredAssetId?: string | null;
66
+ /** The product's assets, in display order. Replaces the list on update. */
67
+ assetIds?: string[];
68
+ /** Replaces the product's facet values on update — send the whole set. */
69
+ facetValueIds?: string[];
70
+ }
71
+ /** A PATCH: omitted fields are left alone. */
72
+ export interface UpdateProductInput extends Partial<CreateProductInput> {
73
+ id: string;
74
+ }
75
+ /** Every key narrows the list; several are combined with AND. */
76
+ export interface ProductListFilter {
77
+ ids?: string[];
78
+ /** Case-insensitive substring of the name in the requested language. */
79
+ name?: string;
80
+ /** Case-insensitive substring of any variant's SKU. */
81
+ sku?: string;
82
+ enabled?: boolean;
83
+ /** Products carrying ANY of these facet values. */
84
+ facetValueIds?: string[];
85
+ availabilityState?: ProductAvailabilityState;
86
+ }
87
+ export interface ProductListOptions extends ListOptions {
88
+ filter?: ProductListFilter;
89
+ sort?: {
90
+ field: 'name' | 'slug' | 'createdAt' | 'updatedAt';
91
+ direction: 'ASC' | 'DESC';
92
+ };
93
+ }
94
+ /** The engine's bound on one `exclude` or `include` call (`STORE_EXCLUSION_BATCH_LIMIT`). */
95
+ export declare const MAX_STORE_EXCLUSION_PRODUCTS = 500;
96
+ /**
97
+ * The engine's bounds on one `setAvailabilityInStores` or `availabilityInStores` call
98
+ * (`AVAILABILITY_*_LIMIT`).
99
+ */
100
+ export declare const MAX_AVAILABILITY_PRODUCTS = 100;
101
+ export declare const MAX_AVAILABILITY_STORES = 50;
102
+ /**
103
+ * What {@link ProductsModule.setAvailabilityInStores} did to one product in one member store:
104
+ * `excluded` (off: kept by the store for its orders, off its storefront), `unlinked` (off, under
105
+ * the `selected` assortment, from a store that never sold or quoted it), `included` (on again)
106
+ * or `assigned` (on, in a store that did not hold it; its images and variants follow within
107
+ * moments). A string on the wire: a newer engine may add an action.
108
+ */
109
+ export type OrganizationProductAvailabilityAction = 'excluded' | 'included' | 'unlinked' | 'assigned';
110
+ export interface OrganizationProductAvailabilityChange {
111
+ productId: string;
112
+ /** The member store's channel id. */
113
+ channelId: string;
114
+ action: OrganizationProductAvailabilityAction | (string & {});
115
+ }
116
+ /**
117
+ * What a member store does with one of the workspace's products, as
118
+ * {@link ProductsModule.availabilityInStores} read it: `offered` (it holds the product and does
119
+ * not exclude it: the product's state, not a promise that a variant is buyable there), `excluded`
120
+ * (kept for its orders, off its storefront and carts; also a product excluded ahead of the
121
+ * organization's fan-out under the `all` assortment, not held yet) or `not-held` (never
122
+ * assigned, or unlinked). A string on the wire: a newer engine may add a state.
123
+ */
124
+ export type OrganizationProductStoreState = 'offered' | 'excluded' | 'not-held';
125
+ export interface OrganizationProductStoreAvailability {
126
+ productId: string;
127
+ /** The member store's channel id. */
128
+ channelId: string;
129
+ state: OrganizationProductStoreState | (string & {});
130
+ /**
131
+ * The store's own live local copy of this product ({@link ProductsModule.makeLocalCopy}), if
132
+ * it has one; null otherwise.
133
+ */
134
+ localCopyId: string | null;
135
+ }
136
+ export interface AvailabilityInStoresInput {
137
+ /** Products of the organization's workspace: 1 to {@link MAX_AVAILABILITY_PRODUCTS}. */
138
+ productIds: string[];
139
+ /** Member stores, by channel id: 1 to {@link MAX_AVAILABILITY_STORES}. */
140
+ channelIds: string[];
141
+ }
142
+ export interface SetAvailabilityInStoresInput {
143
+ /** Products of the organization's workspace: 1 to {@link MAX_AVAILABILITY_PRODUCTS}. */
144
+ productIds: string[];
145
+ /** Member stores, by channel id: 1 to {@link MAX_AVAILABILITY_STORES}. */
146
+ channelIds: string[];
147
+ /** True: offer the products in those stores; false: stop offering them there. */
148
+ available: boolean;
149
+ }
150
+ /** A SKU for the copy of one of the shared product's variants, taken as given or refused. */
151
+ export interface LocalCopySkuInput {
152
+ /** The shared product's variant, as the store holds it. */
153
+ productVariantId: string;
154
+ /** Trimmed by the engine; at most 255 characters. */
155
+ sku: string;
156
+ }
157
+ /**
158
+ * What became of the organization's product in the store: `excluded` (the store sold or quoted
159
+ * it, or the organization offers every product: it keeps it for its orders, off its storefront)
160
+ * or `unlinked` (removed from the store). A string on the wire: a newer engine may add one.
161
+ */
162
+ export type LocalCopyOriginalOutcome = 'excluded' | 'unlinked';
163
+ export interface LocalCopyResult {
164
+ /** The store's own copy, created DISABLED. */
165
+ product: Product;
166
+ /** The organization's product the copy was made from. */
167
+ originalProductId: string;
168
+ original: LocalCopyOriginalOutcome | (string & {});
169
+ /**
170
+ * How many of the organization's properties had a value on the original: the copy does not
171
+ * carry them (only the store's own property groups are copied), so say so before enabling it.
172
+ */
173
+ droppedOrganizationPropertyCount: number;
174
+ }
175
+ /** The engine's bound on each list of one {@link ProductsModule.setCollections} call. */
176
+ export declare const MAX_PRODUCT_COLLECTION_IDS = 200;
177
+ /**
178
+ * Why a collection {@link ProductsModule.setCollections} was asked to take the product out of
179
+ * still holds it: `MEMBER_BY_FILTER`, the product is not on the collection's hand-picked list but
180
+ * matches its other filters (facet values, names), which the call never changes. A string on the
181
+ * wire: a newer engine may add a reason.
182
+ */
183
+ export type ProductCollectionNotRemovedReason = 'MEMBER_BY_FILTER';
184
+ /** What {@link ProductsModule.setCollections} did, per collection id, each list in id order. */
185
+ export interface ProductCollectionsResult {
186
+ /** Collections whose hand-picked list now names the product. */
187
+ added: string[];
188
+ /** Collections whose hand-picked lists no longer name it. */
189
+ removed: string[];
190
+ /** Collections the call named (or, without `from`, found) that needed no write. */
191
+ unchanged: string[];
192
+ /** Collections the product was to leave but stays in. */
193
+ notRemoved: Array<{
194
+ collectionId: string;
195
+ reason: ProductCollectionNotRemovedReason | (string & {});
196
+ }>;
197
+ }
198
+ /**
199
+ * Product-level catalog writes. Reading needs `ReadCatalog` (or `ReadProduct`),
200
+ * creating `CreateCatalog`, updating `UpdateCatalog`, deleting `DeleteCatalog`.
201
+ *
202
+ * While an app or API token of the store owns a field group (`admin.tenant.fieldGroupOwners()`),
203
+ * an update that would change its Product details, or a delete while
204
+ * any group of the product or its variants is owned, by anyone else is refused `FIELD_GROUP_LOCKED`
205
+ * (`BusinessRuleError`, 422) and nothing is written; `error.details` names each refused field
206
+ * (`field` is a JSON pointer into the call, e.g. `/input/0/price`). A value equal to the stored
207
+ * one passes and is left out of the write. See the README, "Field groups: what an owned group
208
+ * refuses".
209
+ */
210
+ export interface ProductsModule {
211
+ list(options?: ProductListOptions): Promise<Page<Product>>;
212
+ /** Null for an id this store does not have — the same answer another tenant's product gets. */
213
+ get(id: string, options?: Call): Promise<Product | null>;
214
+ create(input: CreateProductInput, options?: Call): Promise<Product>;
215
+ update(input: UpdateProductInput, options?: Call): Promise<Product>;
216
+ /**
217
+ * Soft-deletes the product and its variants. `PRODUCT_NOT_DELETED`
218
+ * (`ConflictError`) carries the engine's own reason when it refuses.
219
+ */
220
+ delete(id: string, options?: Call): Promise<void>;
221
+ /**
222
+ * Duplicate a product (the platform's `cloneProduct`): variants, assets,
223
+ * facet values, prices, option groups, custom fields, properties, documents,
224
+ * visibility, SEO metadata, manual recommendations and manual collection
225
+ * membership. The copy is created DISABLED, named "<Name> (copy)", with SKU
226
+ * "<sku>-copy" (or the next free "<sku>-copy-N") and no stock. Answers the
227
+ * new product's id.
228
+ *
229
+ * Takes no input: the engine's mutation has none.
230
+ */
231
+ clone(id: string, options?: Call): Promise<string>;
232
+ /** Attach an option group; its options then name the product's variants. */
233
+ addOptionGroup(productId: string, optionGroupId: string, options?: Call): Promise<Product>;
234
+ /**
235
+ * Detach an option group. Refused with `PRODUCT_OPTION_IN_USE_ERROR`
236
+ * (`BusinessRuleError`) — "Cannot remove ProductOptionGroup "{code}" as it is
237
+ * used by N ProductVariants. Use the `force` argument to remove it anyway" —
238
+ * unless `force` is set.
239
+ */
240
+ removeOptionGroup(productId: string, optionGroupId: string, options?: Call & {
241
+ force?: boolean;
242
+ }): Promise<Product>;
243
+ /**
244
+ * Stop offering products the store's organization shares with it, in the ACTIVE store only
245
+ * (multi-region decision 58): they leave its storefront and its carts, while its orders,
246
+ * returns and invoices keep them; `excludedFromStore` reads true. Excluding an excluded
247
+ * product changes nothing. All or nothing, audited. Needs `UpdateCatalog` or `UpdateProduct`.
248
+ * Answers the products as the store sees them; no ids answers none, without a request. An
249
+ * Admin API mutation: an idempotency key deduplicates nothing.
250
+ *
251
+ * Refusals (nothing is written), GraphQL errors mapped by `core`:
252
+ * - `STORE_EXCLUSION_LOCAL_PRODUCT` → `BusinessRuleError` (422): a product of the store's own
253
+ * (or the store is in no organization), which it disables or deletes instead. The message
254
+ * says how many of the ids it was.
255
+ * - `STORE_EXCLUSION_INPUT_INVALID` → `ValidationError` (400): more than
256
+ * {@link MAX_STORE_EXCLUSION_PRODUCTS} distinct ids; refused before sending too.
257
+ * - `ORGANIZATION_WORKSPACE_NOT_A_STORE` → `BusinessRuleError` (422): called in an
258
+ * organization's workspace, which sells nothing.
259
+ * - `ENTITY_NOT_FOUND` → `NotFoundError` (404): an id this store does not hold.
260
+ */
261
+ exclude(productIds: string[], options?: Call): Promise<Product[]>;
262
+ /**
263
+ * Offer excluded products in the ACTIVE store again. A product it holds and does not exclude
264
+ * is left as it is. Same permissions, answer and refusals as {@link exclude}, except
265
+ * `STORE_EXCLUSION_LOCAL_PRODUCT`; `ENTITY_NOT_FOUND` is a product the store neither holds
266
+ * nor excludes.
267
+ */
268
+ include(productIds: string[], options?: Call): Promise<Product[]>;
269
+ /**
270
+ * The organization's Availability toggle (spec §7.2.3, decision 79), called with the
271
+ * organization's WORKSPACE as the tenant: offer workspace products in member stores, or stop
272
+ * offering them there. Off, under the `all` assortment: excluded from the store (its orders
273
+ * keep the product). Off, under `selected`: unlinked from a store that never sold or quoted
274
+ * it, else excluded. On: included again, or assigned to a store that lacks it. All or
275
+ * nothing, audited; answers what changed, sorted by store and product, and nothing for what
276
+ * already was so. Needs `ManageOrganization` (an organization admin) or SuperAdmin, and
277
+ * `UpdateCatalog` in each store named.
278
+ *
279
+ * Refusals (nothing is written), GraphQL errors mapped by `core`:
280
+ * - `ORGANIZATION_AVAILABILITY_INPUT_INVALID` → `ValidationError` (400): no products or no
281
+ * stores, more than {@link MAX_AVAILABILITY_PRODUCTS} distinct products or
282
+ * {@link MAX_AVAILABILITY_STORES} distinct stores, or `available` not a boolean; refused
283
+ * before sending too.
284
+ * - `ORGANIZATION_ACCESS_DENIED` → `PermissionDeniedError` (403): the tenant is not an
285
+ * organization's workspace.
286
+ * - `CHANNEL_ACCESS_DENIED` → `PermissionDeniedError` (403): a store the caller may not
287
+ * change the catalogue of.
288
+ * - `ORGANIZATION_CATALOG_NOT_SHARED` → `BusinessRuleError` (422): the organization does not
289
+ * share its products (`catalog` sharing is off).
290
+ * - `ORGANIZATION_PRICE_MISSING` → `BusinessRuleError` (422): a store would be offered a
291
+ * variant it has no price for in a currency it sells.
292
+ * - `ENTITY_NOT_FOUND` → `NotFoundError` (404): a product that is not the workspace's, or a
293
+ * store that is not a member.
294
+ */
295
+ setAvailabilityInStores(input: SetAvailabilityInStoresInput, options?: Call): Promise<OrganizationProductAvailabilityChange[]>;
296
+ /**
297
+ * The read behind the organization's Availability toggle (decision 86), called with the
298
+ * organization's WORKSPACE as the tenant: whether each named member store offers, excludes or
299
+ * does not hold each named workspace product, one row per product and store, products first,
300
+ * in the order named (each distinct id once). Each row names the store's own local copy of the
301
+ * product, if it has one. It answers whether or not the organization shares its products.
302
+ * Needs `ManageOrganization` (an organization admin) or SuperAdmin, and `ReadCatalog`,
303
+ * `ReadProduct` or `UpdateCatalog` in each store named. Platform releases before this method
304
+ * do not have the query and refuse it as `ValidationError` `GRAPHQL_VALIDATION_FAILED` (400),
305
+ * told apart from a refused input by its code.
306
+ *
307
+ * Refusals, GraphQL errors mapped by `core`:
308
+ * - `ORGANIZATION_AVAILABILITY_INPUT_INVALID` → `ValidationError` (400): no products or no
309
+ * stores, or more than {@link MAX_AVAILABILITY_PRODUCTS} distinct products or
310
+ * {@link MAX_AVAILABILITY_STORES} distinct stores; refused before sending too.
311
+ * - `ORGANIZATION_ACCESS_DENIED` → `PermissionDeniedError` (403): the tenant is not an
312
+ * organization's workspace.
313
+ * - `CHANNEL_ACCESS_DENIED` → `PermissionDeniedError` (403): a store the caller may not read
314
+ * the catalogue of.
315
+ * - `ENTITY_NOT_FOUND` → `NotFoundError` (404): a product that is not the workspace's, or a
316
+ * store that is not a member.
317
+ */
318
+ availabilityInStores(input: AvailabilityInStoresInput, options?: Call): Promise<OrganizationProductStoreAvailability[]>;
319
+ /**
320
+ * Make the ACTIVE member store's own copy of a product its organization shares with it, and
321
+ * stop offering the shared one, in one step (a local copy, or detach; spec §7.2.8). The copy
322
+ * is a clone created DISABLED (see {@link clone}), priced with the store's current prices,
323
+ * carrying the store's price-list entries and joined to the store's own collections only. Its
324
+ * product and variant rows, names, prices and properties are the store's own and no longer
325
+ * follow the organization's changes; the workspace's option groups, assets and facet values it
326
+ * still uses do (a workspace rename of an option shows on the copy, and the store cannot
327
+ * change them: `MANAGED_BY_ORGANIZATION`). Its variants' SKUs end in `-<store code>`
328
+ * (first free) unless `skus` names them, which are taken as given or refused. The shared
329
+ * product is excluded from the store when the store sold or quoted it, and always under the
330
+ * organization's `all` assortment; otherwise it is removed from the store (`original`).
331
+ *
332
+ * One transaction, audited. A repeat (a double submit, a retry) never makes a second copy: it
333
+ * is refused `LOCAL_COPY_ALREADY_EXISTS`, whether the first call excluded the original or
334
+ * unlinked it (a platform release older than that answers `ENTITY_NOT_FOUND` after an unlink,
335
+ * the store no longer holding the product). Needs `CreateCatalog` (or `CreateProduct`) AND
336
+ * `UpdateCatalog` in the store.
337
+ *
338
+ * Refusals (nothing is written), GraphQL errors mapped by `core`:
339
+ * - `LOCAL_COPY_PRODUCT_NOT_SHARED` → `BusinessRuleError` (422): the store's own product, or
340
+ * the store is in no organization; clone it instead.
341
+ * - `LOCAL_COPY_ALREADY_EXISTS` → `ConflictError` (409): the store already has a live copy.
342
+ * - `LOCAL_COPY_SKU_CONFLICT` → `ConflictError` (409): a SKU named in `skus` is another
343
+ * product's in the store. `error.details` names each one, its `field` the SKU's place in
344
+ * `skus` (`/skus/<index>/sku`), so a form can mark the inputs (an older platform release
345
+ * sends no details; its message names a single SKU and only counts several).
346
+ * - `LOCAL_COPY_INPUT_INVALID` → `ValidationError` (400): `skus` names a variant the store
347
+ * does not hold on that product, names one twice, repeats a SKU, or has a blank or overlong
348
+ * one.
349
+ * - `ORGANIZATION_WORKSPACE_NOT_A_STORE` → `BusinessRuleError` (422): called in the workspace.
350
+ * - `FORBIDDEN` → `PermissionDeniedError` (403): a permission above is missing.
351
+ * - `ENTITY_NOT_FOUND` → `NotFoundError` (404): a product this store does not hold.
352
+ */
353
+ makeLocalCopy(productId: string, options?: Call & {
354
+ skus?: readonly LocalCopySkuInput[];
355
+ }): Promise<LocalCopyResult>;
356
+ /**
357
+ * Set the collections a product is in by hand (headless spec §7, part of `products.save`).
358
+ * Only MANUAL membership is written: the product is added to the hand-picked list (the
359
+ * `product-id-filter`, see `catalog.collections`) of each collection in `collectionIds` it is not
360
+ * in yet, and taken off the hand-picked lists of each collection it should leave. A collection
361
+ * the product is in only through its other filters (facet values, names) is never rewritten:
362
+ * those filters are the collection's, so it is reported in `notRemoved`
363
+ * (`MEMBER_BY_FILTER`) and stays.
364
+ *
365
+ * One transaction, and every collection it writes is row-locked first: two calls touching one
366
+ * collection (two products saved into it at once, a clone) both keep their change, which a
367
+ * client read-modify-write of the collection's filters (`catalog.collections.update`) cannot
368
+ * promise. All or nothing. Membership is DERIVED: each written collection re-runs its
369
+ * membership job, so the product shows in (or out of) it shortly after the call returns, not
370
+ * during it.
371
+ *
372
+ * `from`: where the product was, as far as this call is concerned. Given, only the difference
373
+ * between `from` and `collectionIds` is applied, and every collection in neither list (or in
374
+ * both) is left as it is. So a change needs no read: `setCollections(id, [x], { from: [] })`
375
+ * puts the product in `x` and touches nothing else, and `setCollections(id, [], { from: [x] })`
376
+ * takes it out of `x` only. A screen that shows the product's collections passes the ones it
377
+ * loaded, so a collection someone else changed since then keeps that change. Without `from`,
378
+ * `collectionIds` is the WHOLE new hand-picked membership, compared with the product's
379
+ * membership now: every other collection that lists the product by hand loses it. A repeat of
380
+ * a call that went through writes nothing: each collection answers `unchanged`, except one the
381
+ * product stays in through other filters, which answers `notRemoved` again (while those filters
382
+ * hold it, and, for a collection with such filters, until its membership job has run). So
383
+ * `notRemoved` on a repeat does not mean the first call failed.
384
+ *
385
+ * Needs `UpdateCatalog` or `UpdateCollection`. Platform releases before this method do not
386
+ * have the mutation and refuse it as `ValidationError` `GRAPHQL_VALIDATION_FAILED` (400).
387
+ *
388
+ * Refusals (nothing is written), GraphQL errors mapped by `core`:
389
+ * - `PRODUCT_COLLECTIONS_INPUT_INVALID` → `ValidationError` (400): a list names a collection
390
+ * twice, or more than {@link MAX_PRODUCT_COLLECTION_IDS}; refused before sending too.
391
+ * `error.details` names each entry (`/collectionIds/<i>`, `/fromCollectionIds/<i>`).
392
+ * - `PRODUCT_COLLECTION_FILTER_INVALID` → `ValidationError` (400): a collection's hand-picked
393
+ * list cannot be read as product ids, so whether it names the product cannot be told. The
394
+ * message names the collection; save its product list again in the collection editor.
395
+ * - `SHARED_COLLECTION_NOT_ALLOWED` → `PermissionDeniedError` (403): a collection to write is
396
+ * also another store's (or one below it is), and you cannot change that store's catalogue.
397
+ * - `MANAGED_BY_ORGANIZATION` → `BusinessRuleError` (422): a collection to write is the store's
398
+ * organization's; change it in the organization's workspace.
399
+ * - `ENTITY_NOT_FOUND` → `NotFoundError` (404): a product or collection this store does not
400
+ * hold (or a deleted product).
401
+ * - `FORBIDDEN` → `PermissionDeniedError` (403): neither permission above.
402
+ */
403
+ setCollections(productId: string, collectionIds: readonly string[], options?: Call & {
404
+ from?: readonly string[];
405
+ }): Promise<ProductCollectionsResult>;
406
+ /**
407
+ * Enable, disable, delete or clone up to `MAX_BULK_PRODUCTS` (50) products of the store in ONE
408
+ * call (headless spec §7 `products.bulkClone`; §6.11).
409
+ *
410
+ * **The run is a job.** The call answers a receipt (`runId`) as soon as the run is queued;
411
+ * `handle.wait()` polls it until it ends and resolves with the run, whatever the ending.
412
+ * `bulkRun(runId)` reads it again later, from any process. Each product's outcome is in
413
+ * `run.items`, in the order the ids were named: `OK` (with `newId`, the copy, for `CLONE`), or
414
+ * `FAILED` with the code the single door would have raised.
415
+ *
416
+ * **Each product succeeds or fails alone.** Every product goes through its own door
417
+ * (`update` with `enabled`, `delete`, `clone`) in a transaction of its own, so a refused product
418
+ * leaves the others done, and a `SUCCEEDED` run can hold `FAILED` items: read them. A product of
419
+ * another store answers `ENTITY_NOT_FOUND` on its item; a product another store also holds
420
+ * answers `SHARED_PRODUCT_NOT_ALLOWED` unless you may change that store's catalogue too; a
421
+ * product the store's organization holds answers `MANAGED_BY_ORGANIZATION` for every caller,
422
+ * SuperAdmin included; a group an app or API token owns answers `FIELD_GROUP_LOCKED` (a delete
423
+ * takes every group of the product; `enabled` is in no group); the external-line carrier
424
+ * answers `EXTERNAL_LINE_CARRIER_PROTECTED`; core declining a delete answers
425
+ * `PRODUCT_NOT_DELETED`.
426
+ *
427
+ * **Idempotency.** `options.idempotencyKey` (minted when omitted): the same key with the same
428
+ * action and ids answers the SAME run, so a resubmit never clones twice; the same key with
429
+ * another selection is refused `IDEMPOTENCY_CONFLICT` (409 `ConflictError`). Each product is
430
+ * keyed within the run as well, so a run the platform has to process again (a worker restart)
431
+ * answers each product it already did from that record.
432
+ *
433
+ * **No dry run.** The refusals that matter are the doors' own, made under the write (the
434
+ * field-group lock, the shared-product rule), so a rehearsal could answer "ok" for a product the
435
+ * real run refuses. Each product's outcome is reported when it runs instead.
436
+ *
437
+ * Needs the single door's permission for the action: `UpdateCatalog` or `UpdateProduct`
438
+ * (ENABLE, DISABLE), `DeleteCatalog` or `DeleteProduct` (DELETE), `CreateCatalog` or
439
+ * `CreateProduct` (CLONE). Reading the run needs `ReadCatalog` or `ReadProduct`. Search is
440
+ * reindexed for every product written.
441
+ *
442
+ * Refusals of the call itself (nothing is queued), GraphQL errors mapped by `core`:
443
+ * - `BULK_ACTION_INPUT_INVALID` → `ValidationError` (400): no products, more than
444
+ * `MAX_BULK_PRODUCTS`, a product named twice, an unknown action; refused before sending
445
+ * too. `error.details` names each entry (`/input/productIds/<index>`).
446
+ * - `BULK_ACTION_NOT_ALLOWED` → `PermissionDeniedError` (403): the action's permission is missing.
447
+ * - `IDEMPOTENCY_CONFLICT` → `ConflictError` (409): the key was used for another selection.
448
+ * - `ENTITY_NOT_FOUND` → `NotFoundError` (404): an id that is not an id at all.
449
+ *
450
+ * Platform releases before this method do not have the mutation and refuse it as
451
+ * `ValidationError` `GRAPHQL_VALIDATION_FAILED` (400).
452
+ */
453
+ bulk(input: ProductBulkInput, options?: Call): Promise<JobHandle<ProductBulkRun>>;
454
+ /**
455
+ * One read of a bulk product run, by the `runId` `bulk()` answered. A run of another store, or
456
+ * one that does not exist, is `BULK_ACTION_RUN_NOT_FOUND` (`NotFoundError`, 404).
457
+ */
458
+ bulkRun(runId: string, options?: Call): Promise<ProductBulkRun>;
459
+ }
460
+ export declare const PRODUCT_FIELDS = "\n id\n \n catalogueOwnership {\n state\n organizationName\n editableHere\n }\n\n createdAt\n updatedAt\n languageCode\n name\n slug\n description\n enabled\n featuredAsset { \n id\n name\n preview\n source\n }\n assets { \n id\n name\n preview\n source\n }\n facetValues { \n id\n code\n name\n facet {\n id\n code\n name\n }\n }\n optionGroups {\n id\n code\n name\n options {\n id\n code\n name\n }\n }\n translations {\n id\n languageCode\n name\n slug\n description\n }\n excludedFromStore\n variantList(options: { take: 1 }) {\n totalItems\n }\n customFields {\n availabilityState\n availableFrom\n preorderLimit\n }\n";
461
+ export declare const PRODUCTS_QUERY = "\n query CatalogProducts($options: ProductListOptions) {\n products(options: $options) {\n items { \n id\n \n catalogueOwnership {\n state\n organizationName\n editableHere\n }\n\n createdAt\n updatedAt\n languageCode\n name\n slug\n description\n enabled\n featuredAsset { \n id\n name\n preview\n source\n }\n assets { \n id\n name\n preview\n source\n }\n facetValues { \n id\n code\n name\n facet {\n id\n code\n name\n }\n }\n optionGroups {\n id\n code\n name\n options {\n id\n code\n name\n }\n }\n translations {\n id\n languageCode\n name\n slug\n description\n }\n excludedFromStore\n variantList(options: { take: 1 }) {\n totalItems\n }\n customFields {\n availabilityState\n availableFrom\n preorderLimit\n }\n }\n totalItems\n }\n }\n";
462
+ export declare const PRODUCT_QUERY = "\n query CatalogProduct($id: ID!) {\n product(id: $id) { \n id\n \n catalogueOwnership {\n state\n organizationName\n editableHere\n }\n\n createdAt\n updatedAt\n languageCode\n name\n slug\n description\n enabled\n featuredAsset { \n id\n name\n preview\n source\n }\n assets { \n id\n name\n preview\n source\n }\n facetValues { \n id\n code\n name\n facet {\n id\n code\n name\n }\n }\n optionGroups {\n id\n code\n name\n options {\n id\n code\n name\n }\n }\n translations {\n id\n languageCode\n name\n slug\n description\n }\n excludedFromStore\n variantList(options: { take: 1 }) {\n totalItems\n }\n customFields {\n availabilityState\n availableFrom\n preorderLimit\n }\n }\n }\n";
463
+ export declare const CREATE_PRODUCT_MUTATION = "\n mutation CatalogCreateProduct($input: CreateProductInput!) {\n createProduct(input: $input) { \n id\n \n catalogueOwnership {\n state\n organizationName\n editableHere\n }\n\n createdAt\n updatedAt\n languageCode\n name\n slug\n description\n enabled\n featuredAsset { \n id\n name\n preview\n source\n }\n assets { \n id\n name\n preview\n source\n }\n facetValues { \n id\n code\n name\n facet {\n id\n code\n name\n }\n }\n optionGroups {\n id\n code\n name\n options {\n id\n code\n name\n }\n }\n translations {\n id\n languageCode\n name\n slug\n description\n }\n excludedFromStore\n variantList(options: { take: 1 }) {\n totalItems\n }\n customFields {\n availabilityState\n availableFrom\n preorderLimit\n }\n }\n }\n";
464
+ export declare const UPDATE_PRODUCT_MUTATION = "\n mutation CatalogUpdateProduct($input: UpdateProductInput!) {\n updateProduct(input: $input) { \n id\n \n catalogueOwnership {\n state\n organizationName\n editableHere\n }\n\n createdAt\n updatedAt\n languageCode\n name\n slug\n description\n enabled\n featuredAsset { \n id\n name\n preview\n source\n }\n assets { \n id\n name\n preview\n source\n }\n facetValues { \n id\n code\n name\n facet {\n id\n code\n name\n }\n }\n optionGroups {\n id\n code\n name\n options {\n id\n code\n name\n }\n }\n translations {\n id\n languageCode\n name\n slug\n description\n }\n excludedFromStore\n variantList(options: { take: 1 }) {\n totalItems\n }\n customFields {\n availabilityState\n availableFrom\n preorderLimit\n }\n }\n }\n";
465
+ export declare const DELETE_PRODUCT_MUTATION = "\n mutation CatalogDeleteProduct($id: ID!) {\n deleteProduct(id: $id) { \n result\n message\n }\n }\n";
466
+ export declare const CLONE_PRODUCT_MUTATION = "\n mutation CatalogCloneProduct($id: ID!) {\n cloneProduct(id: $id)\n }\n";
467
+ export declare const ADD_OPTION_GROUP_MUTATION = "\n mutation CatalogAddOptionGroup($productId: ID!, $optionGroupId: ID!) {\n addOptionGroupToProduct(productId: $productId, optionGroupId: $optionGroupId) { \n id\n \n catalogueOwnership {\n state\n organizationName\n editableHere\n }\n\n createdAt\n updatedAt\n languageCode\n name\n slug\n description\n enabled\n featuredAsset { \n id\n name\n preview\n source\n }\n assets { \n id\n name\n preview\n source\n }\n facetValues { \n id\n code\n name\n facet {\n id\n code\n name\n }\n }\n optionGroups {\n id\n code\n name\n options {\n id\n code\n name\n }\n }\n translations {\n id\n languageCode\n name\n slug\n description\n }\n excludedFromStore\n variantList(options: { take: 1 }) {\n totalItems\n }\n customFields {\n availabilityState\n availableFrom\n preorderLimit\n }\n }\n }\n";
468
+ export declare const REMOVE_OPTION_GROUP_MUTATION = "\n mutation CatalogRemoveOptionGroup($productId: ID!, $optionGroupId: ID!, $force: Boolean) {\n removeOptionGroupFromProduct(productId: $productId, optionGroupId: $optionGroupId, force: $force) {\n ... on Product { \n id\n \n catalogueOwnership {\n state\n organizationName\n editableHere\n }\n\n createdAt\n updatedAt\n languageCode\n name\n slug\n description\n enabled\n featuredAsset { \n id\n name\n preview\n source\n }\n assets { \n id\n name\n preview\n source\n }\n facetValues { \n id\n code\n name\n facet {\n id\n code\n name\n }\n }\n optionGroups {\n id\n code\n name\n options {\n id\n code\n name\n }\n }\n translations {\n id\n languageCode\n name\n slug\n description\n }\n excludedFromStore\n variantList(options: { take: 1 }) {\n totalItems\n }\n customFields {\n availabilityState\n availableFrom\n preorderLimit\n }\n }\n ... on ErrorResult {\n errorCode\n message\n }\n }\n }\n";
469
+ export declare const EXCLUDE_PRODUCTS_FROM_STORE_MUTATION = "\n mutation CatalogExcludeProductsFromStore($productIds: [ID!]!) {\n excludeProductsFromStore(productIds: $productIds) { \n id\n \n catalogueOwnership {\n state\n organizationName\n editableHere\n }\n\n createdAt\n updatedAt\n languageCode\n name\n slug\n description\n enabled\n featuredAsset { \n id\n name\n preview\n source\n }\n assets { \n id\n name\n preview\n source\n }\n facetValues { \n id\n code\n name\n facet {\n id\n code\n name\n }\n }\n optionGroups {\n id\n code\n name\n options {\n id\n code\n name\n }\n }\n translations {\n id\n languageCode\n name\n slug\n description\n }\n excludedFromStore\n variantList(options: { take: 1 }) {\n totalItems\n }\n customFields {\n availabilityState\n availableFrom\n preorderLimit\n }\n }\n }\n";
470
+ export declare const INCLUDE_PRODUCTS_IN_STORE_MUTATION = "\n mutation CatalogIncludeProductsInStore($productIds: [ID!]!) {\n includeProductsInStore(productIds: $productIds) { \n id\n \n catalogueOwnership {\n state\n organizationName\n editableHere\n }\n\n createdAt\n updatedAt\n languageCode\n name\n slug\n description\n enabled\n featuredAsset { \n id\n name\n preview\n source\n }\n assets { \n id\n name\n preview\n source\n }\n facetValues { \n id\n code\n name\n facet {\n id\n code\n name\n }\n }\n optionGroups {\n id\n code\n name\n options {\n id\n code\n name\n }\n }\n translations {\n id\n languageCode\n name\n slug\n description\n }\n excludedFromStore\n variantList(options: { take: 1 }) {\n totalItems\n }\n customFields {\n availabilityState\n availableFrom\n preorderLimit\n }\n }\n }\n";
471
+ export declare const SET_ORGANIZATION_PRODUCT_AVAILABILITY_MUTATION = "\n mutation CatalogSetOrganizationProductAvailability(\n $productIds: [ID!]!\n $channelIds: [ID!]!\n $available: Boolean!\n ) {\n setOrganizationProductAvailability(\n productIds: $productIds\n channelIds: $channelIds\n available: $available\n ) {\n productId\n channelId\n action\n }\n }\n";
472
+ export declare const ORGANIZATION_PRODUCT_AVAILABILITY_QUERY = "\n query CatalogOrganizationProductAvailability($productIds: [ID!]!, $channelIds: [ID!]!) {\n organizationProductAvailability(productIds: $productIds, channelIds: $channelIds) {\n productId\n channelId\n state\n localCopyId\n }\n }\n";
473
+ export declare const MAKE_LOCAL_COPY_MUTATION = "\n mutation CatalogMakeLocalCopy($productId: ID!, $skus: [LocalCopySkuInput!]) {\n makeLocalCopy(productId: $productId, skus: $skus) {\n product { \n id\n \n catalogueOwnership {\n state\n organizationName\n editableHere\n }\n\n createdAt\n updatedAt\n languageCode\n name\n slug\n description\n enabled\n featuredAsset { \n id\n name\n preview\n source\n }\n assets { \n id\n name\n preview\n source\n }\n facetValues { \n id\n code\n name\n facet {\n id\n code\n name\n }\n }\n optionGroups {\n id\n code\n name\n options {\n id\n code\n name\n }\n }\n translations {\n id\n languageCode\n name\n slug\n description\n }\n excludedFromStore\n variantList(options: { take: 1 }) {\n totalItems\n }\n customFields {\n availabilityState\n availableFrom\n preorderLimit\n }\n }\n originalProductId\n original\n droppedOrganizationPropertyCount\n }\n }\n";
474
+ export declare const SET_PRODUCT_COLLECTIONS_MUTATION = "\n mutation CatalogSetProductCollections(\n $productId: ID!\n $collectionIds: [ID!]!\n $fromCollectionIds: [ID!]\n ) {\n setProductCollections(\n productId: $productId\n collectionIds: $collectionIds\n fromCollectionIds: $fromCollectionIds\n ) {\n added\n removed\n unchanged\n notRemoved {\n collectionId\n reason\n }\n }\n }\n";
475
+ /** The product as the Admin API answers it, before `toProduct`. */
476
+ export interface WireProduct extends Omit<Product, keyof Availability<string> | 'variantCount'> {
477
+ variantList: {
478
+ totalItems: number;
479
+ };
480
+ customFields: Partial<Availability<ProductAvailabilityState>> | null;
481
+ }
482
+ /**
483
+ * Lift the availability custom fields to first-class fields. A server older
484
+ * than the pre-order engine has no such fields and would refuse the document
485
+ * outright, so the defaults below only cover a NULL value, never an absent one.
486
+ */
487
+ export declare function toProduct(wire: WireProduct): Product;
488
+ export declare function productFilter(filter: ProductListFilter | undefined): Record<string, unknown>;
489
+ export declare function createProductsModule(transport: Transport): ProductsModule;