@sixtyninecommerce/admin 0.9.0 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4598 -128
- package/dist/catalog/assets.d.ts +120 -8
- package/dist/catalog/assets.js +98 -12
- package/dist/catalog/collections.d.ts +279 -14
- package/dist/catalog/collections.js +246 -15
- package/dist/catalog/index.d.ts +9 -2
- package/dist/catalog/index.js +4 -0
- package/dist/catalog/products.d.ts +318 -17
- package/dist/catalog/products.js +182 -14
- package/dist/catalog/properties.d.ts +102 -14
- package/dist/catalog/properties.js +13 -0
- package/dist/catalog/recommendations.d.ts +261 -0
- package/dist/catalog/recommendations.js +145 -0
- package/dist/catalog/reviews.d.ts +368 -0
- package/dist/catalog/reviews.js +318 -0
- package/dist/catalog/types.d.ts +17 -1
- package/dist/catalog/types.js +10 -0
- package/dist/catalog/variant-find.d.ts +136 -0
- package/dist/catalog/variant-find.js +239 -0
- package/dist/catalog/variants.d.ts +282 -25
- package/dist/catalog/variants.js +173 -25
- package/dist/catalog/visibility.d.ts +20 -5
- package/dist/catalog/visibility.js +19 -1
- package/dist/client.d.ts +116 -9
- package/dist/client.js +41 -7
- package/dist/content/assets.d.ts +286 -0
- package/dist/content/assets.js +181 -0
- package/dist/content/items.d.ts +269 -0
- package/dist/content/items.js +170 -0
- package/dist/content/types.d.ts +282 -0
- package/dist/content/types.js +100 -0
- package/dist/customers/age-verification.d.ts +66 -0
- package/dist/customers/age-verification.js +79 -0
- package/dist/customers/credit.d.ts +263 -0
- package/dist/customers/credit.js +244 -0
- package/dist/customers/delivery-preferences.d.ts +120 -0
- package/dist/customers/delivery-preferences.js +97 -0
- package/dist/customers/groups.d.ts +207 -0
- package/dist/customers/groups.js +438 -0
- package/dist/customers/index.d.ts +447 -37
- package/dist/customers/index.js +313 -40
- package/dist/customers/invitation-status.d.ts +57 -0
- package/dist/customers/invitation-status.js +21 -0
- package/dist/customers/notes.d.ts +67 -0
- package/dist/customers/notes.js +51 -0
- package/dist/customers/notification-recipients.d.ts +97 -0
- package/dist/customers/notification-recipients.js +84 -0
- package/dist/customers/saved-lists.d.ts +42 -0
- package/dist/customers/saved-lists.js +61 -0
- package/dist/customers/vat.d.ts +83 -0
- package/dist/customers/vat.js +46 -0
- package/dist/customers/wire.d.ts +20 -0
- package/dist/customers/wire.js +35 -0
- package/dist/documents/ar.d.ts +307 -0
- package/dist/documents/ar.js +254 -0
- package/dist/documents/index.d.ts +731 -21
- package/dist/documents/index.js +436 -24
- package/dist/documents/pdf.d.ts +2 -0
- package/dist/documents/pdf.js +11 -0
- package/dist/fulfillments/create.d.ts +167 -0
- package/dist/fulfillments/create.js +216 -0
- package/dist/fulfillments/index.d.ts +121 -10
- package/dist/fulfillments/index.js +120 -2
- package/dist/fulfillments/payment-policy.d.ts +64 -0
- package/dist/fulfillments/payment-policy.js +140 -0
- package/dist/fulfillments/warehouse.d.ts +724 -0
- package/dist/fulfillments/warehouse.js +914 -0
- package/dist/geo/index.d.ts +119 -0
- package/dist/geo/index.js +107 -0
- package/dist/index.d.ts +129 -30
- package/dist/index.js +47 -9
- package/dist/integrations/afas-actions.d.ts +234 -0
- package/dist/integrations/afas-actions.js +310 -0
- package/dist/integrations/afas-types.d.ts +483 -0
- package/dist/integrations/afas-types.js +5 -0
- package/dist/integrations/afas.d.ts +234 -0
- package/dist/integrations/afas.js +290 -0
- package/dist/integrations/connections.d.ts +103 -0
- package/dist/integrations/connections.js +55 -0
- package/dist/integrations/esp.d.ts +313 -0
- package/dist/integrations/esp.js +169 -0
- package/dist/integrations/exact-online-types.d.ts +423 -0
- package/dist/integrations/exact-online-types.js +6 -0
- package/dist/integrations/exact-online.d.ts +248 -0
- package/dist/integrations/exact-online.js +376 -0
- package/dist/integrations/index.d.ts +40 -0
- package/dist/integrations/index.js +24 -0
- package/dist/integrations/pipeline-keys.d.ts +13 -0
- package/dist/integrations/pipeline-keys.js +22 -0
- package/dist/integrations/pipelines.d.ts +114 -0
- package/dist/integrations/pipelines.js +46 -0
- package/dist/integrations/types.d.ts +322 -0
- package/dist/integrations/types.js +8 -0
- package/dist/jobs/bulk-action-run.d.ts +11 -2
- package/dist/jobs/bulk-action-run.js +4 -5
- package/dist/locations/index.d.ts +66 -0
- package/dist/locations/index.js +31 -0
- package/dist/meta/index.d.ts +162 -0
- package/dist/orders/bulk.d.ts +75 -0
- package/dist/orders/bulk.js +150 -0
- package/dist/orders/cancel-with-money.d.ts +227 -0
- package/dist/orders/cancel-with-money.js +153 -0
- package/dist/orders/commit-edit.d.ts +7 -1
- package/dist/orders/commit-edit.js +5 -1
- package/dist/orders/deposit-policy.d.ts +103 -0
- package/dist/orders/deposit-policy.js +202 -0
- package/dist/orders/drafts.d.ts +800 -0
- package/dist/orders/drafts.js +771 -0
- package/dist/orders/fields.d.ts +245 -0
- package/dist/orders/fields.js +188 -0
- package/dist/orders/get.d.ts +29 -19
- package/dist/orders/get.js +17 -8
- package/dist/orders/index.d.ts +125 -5
- package/dist/orders/index.js +35 -2
- package/dist/orders/lifecycle.d.ts +128 -0
- package/dist/orders/lifecycle.js +158 -0
- package/dist/orders/line-price-preview.d.ts +7 -2
- package/dist/orders/list.d.ts +222 -0
- package/dist/orders/list.js +377 -0
- package/dist/orders/manual-discounts.d.ts +11 -2
- package/dist/orders/manual-discounts.js +2 -0
- package/dist/orders/manual-pricing.d.ts +5 -0
- package/dist/orders/order-entry.d.ts +20 -7
- package/dist/orders/plan-edit.d.ts +1 -1
- package/dist/orders/plan-edit.js +4 -1
- package/dist/orders/settings.d.ts +201 -0
- package/dist/orders/settings.js +325 -0
- package/dist/orders/status.d.ts +159 -13
- package/dist/orders/status.js +21 -0
- package/dist/orders/surcharges.d.ts +8 -1
- package/dist/orders/surcharges.js +3 -2
- package/dist/payments/account-credit.d.ts +30 -0
- package/dist/payments/account-credit.js +19 -0
- package/dist/payments/ar.d.ts +292 -0
- package/dist/payments/ar.js +223 -0
- package/dist/payments/connected-account.d.ts +47 -0
- package/dist/payments/connected-account.js +61 -0
- package/dist/payments/credit-noted-fields.d.ts +12 -0
- package/dist/payments/credit-noted-fields.js +37 -0
- package/dist/payments/index.d.ts +263 -10
- package/dist/payments/index.js +133 -1
- package/dist/payments/methods.d.ts +332 -0
- package/dist/payments/methods.js +363 -0
- package/dist/payments/mollie-methods.d.ts +159 -0
- package/dist/payments/mollie-methods.js +141 -0
- package/dist/payments/payment-links.d.ts +180 -0
- package/dist/payments/payment-links.js +97 -0
- package/dist/payments/provider-keys.d.ts +150 -0
- package/dist/payments/provider-keys.js +118 -0
- package/dist/payments/providers.d.ts +86 -11
- package/dist/payments/providers.js +29 -0
- package/dist/payments/requests.d.ts +144 -0
- package/dist/payments/requests.js +92 -0
- package/dist/payments/store-credit-fields.d.ts +15 -0
- package/dist/payments/store-credit-fields.js +51 -0
- package/dist/pickups/index.d.ts +104 -0
- package/dist/pickups/index.js +105 -0
- package/dist/platform/channels.d.ts +132 -0
- package/dist/platform/channels.js +128 -0
- package/dist/platform/geo.d.ts +123 -0
- package/dist/platform/geo.js +144 -0
- package/dist/platform/tax.d.ts +154 -0
- package/dist/platform/tax.js +139 -0
- package/dist/pos/anomalies.d.ts +158 -0
- package/dist/pos/anomalies.js +64 -0
- package/dist/pos/assisted-selling.d.ts +79 -0
- package/dist/pos/assisted-selling.js +38 -0
- package/dist/pos/exchanges.d.ts +103 -0
- package/dist/pos/exchanges.js +22 -0
- package/dist/pos/gift-cards.d.ts +135 -0
- package/dist/pos/gift-cards.js +47 -0
- package/dist/pos/index.d.ts +2125 -32
- package/dist/pos/index.js +742 -4
- package/dist/pos/no-receipt.d.ts +94 -0
- package/dist/pos/no-receipt.js +25 -0
- package/dist/pos/offline-sales.d.ts +187 -0
- package/dist/pos/offline-sales.js +116 -0
- package/dist/pos/pay-by-link.d.ts +143 -0
- package/dist/pos/pay-by-link.js +57 -0
- package/dist/pos/quick-keys.d.ts +103 -0
- package/dist/pos/quick-keys.js +45 -0
- package/dist/pos/reports.d.ts +360 -0
- package/dist/pos/reports.js +62 -0
- package/dist/pos/returns.d.ts +217 -0
- package/dist/pos/returns.js +53 -0
- package/dist/pricing/bulk-coupons.d.ts +139 -0
- package/dist/pricing/bulk-coupons.js +112 -0
- package/dist/pricing/index.d.ts +177 -4
- package/dist/pricing/index.js +176 -1
- package/dist/pricing/price-lists.d.ts +604 -0
- package/dist/pricing/price-lists.js +600 -0
- package/dist/pricing/vouchers.d.ts +103 -0
- package/dist/pricing/vouchers.js +69 -0
- package/dist/purchasing/alerts.d.ts +89 -0
- package/dist/purchasing/alerts.js +62 -0
- package/dist/purchasing/cost.d.ts +110 -0
- package/dist/purchasing/cost.js +86 -0
- package/dist/purchasing/index.d.ts +36 -0
- package/dist/purchasing/index.js +16 -0
- package/dist/purchasing/purchase-orders.d.ts +548 -0
- package/dist/purchasing/purchase-orders.js +491 -0
- package/dist/purchasing/replenishment.d.ts +281 -0
- package/dist/purchasing/replenishment.js +240 -0
- package/dist/purchasing/settings.d.ts +152 -0
- package/dist/purchasing/settings.js +181 -0
- package/dist/purchasing/suppliers.d.ts +476 -0
- package/dist/purchasing/suppliers.js +438 -0
- package/dist/quotes/index.d.ts +501 -0
- package/dist/quotes/index.js +439 -0
- package/dist/reports/index.d.ts +71 -8
- package/dist/reports/index.js +74 -11
- package/dist/returns/index.d.ts +818 -0
- package/dist/returns/index.js +844 -0
- package/dist/search/index.d.ts +174 -0
- package/dist/search/index.js +125 -0
- package/dist/shipping/definitions.d.ts +29 -0
- package/dist/shipping/definitions.js +47 -0
- package/dist/shipping/fulfillment-profiles.d.ts +174 -0
- package/dist/shipping/fulfillment-profiles.js +104 -0
- package/dist/shipping/hendriks.d.ts +97 -0
- package/dist/shipping/hendriks.js +50 -0
- package/dist/shipping/index.d.ts +48 -0
- package/dist/shipping/index.js +25 -0
- package/dist/shipping/methods.d.ts +198 -0
- package/dist/shipping/methods.js +240 -0
- package/dist/shipping/myparcel.d.ts +254 -0
- package/dist/shipping/myparcel.js +178 -0
- package/dist/shipping/parcel-count-suggestion.d.ts +2 -0
- package/dist/shipping/parcel-rule.d.ts +6 -5
- package/dist/shipping/parcel-rule.js +21 -23
- package/dist/shipping/rate-tables.d.ts +179 -0
- package/dist/shipping/rate-tables.js +184 -0
- package/dist/stock/index.d.ts +10 -3
- package/dist/stock/index.js +3 -0
- package/dist/stock/locations.d.ts +144 -0
- package/dist/stock/locations.js +168 -0
- package/dist/stock/transfers.d.ts +216 -43
- package/dist/stock/transfers.js +140 -13
- package/dist/stored-value/index.d.ts +214 -4
- package/dist/stored-value/index.js +152 -0
- package/dist/subscriptions/index.d.ts +682 -0
- package/dist/subscriptions/index.js +815 -0
- package/dist/tax/index.d.ts +76 -1
- package/dist/tax/index.js +50 -0
- package/dist/tenant/email-style.d.ts +102 -0
- package/dist/tenant/email-style.js +72 -0
- package/dist/tenant/email-templates.d.ts +66 -0
- package/dist/tenant/email-templates.js +54 -0
- package/dist/tenant/notifications.d.ts +23 -17
- package/dist/tenant/settings-sources.d.ts +1 -1
- package/dist/tenant/time-zone.d.ts +17 -0
- package/dist/tenant/time-zone.js +11 -0
- package/dist/types.d.ts +51 -4
- package/dist/users/index.d.ts +3 -0
- package/dist/users/index.js +2 -0
- package/dist/users/warehouses.d.ts +50 -0
- package/dist/users/warehouses.js +51 -0
- package/package.json +2 -2
package/dist/catalog/variants.js
CHANGED
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
import { NotFoundError, UpstreamError, ValidationError, } from '@sixtyninecommerce/core';
|
|
2
|
-
import { ASSET_REF_FIELDS, assertDeleted, availabilityCustomFields, DELETION_FIELDS, FACET_VALUE_REF_FIELDS, fieldOf, vendureListPage, } from './types.js';
|
|
2
|
+
import { ASSET_REF_FIELDS, assertDeleted, availabilityCustomFields, DELETION_FIELDS, FACET_VALUE_REF_FIELDS, fieldOf, MAX_PAGE_SIZE, toAssetRef, vendureListPage, } from './types.js';
|
|
3
|
+
import { findVariants } from './variant-find.js';
|
|
3
4
|
const PARCEL_PACKING_MODES = ['shared', 'separate', 'none'];
|
|
4
5
|
/** The engine's bounds for `parcelCapacity` (shipping-calculator's `MAX_PARCEL_CAPACITY`). */
|
|
5
6
|
const PARCEL_CAPACITY_MIN = 1;
|
|
6
7
|
const PARCEL_CAPACITY_MAX = 10_000;
|
|
8
|
+
/** The variants {@link VariantsModule.optionSets} reads at most by default. */
|
|
9
|
+
export const DEFAULT_OPTION_SET_LIMIT = MAX_PAGE_SIZE;
|
|
10
|
+
/** The most variants one {@link VariantsModule.optionSets} call reads. */
|
|
11
|
+
export const MAX_OPTION_SET_LIMIT = 100_000;
|
|
7
12
|
/** The engine's bound on one `revertPrice` call (`MAX_REVERT_VARIANTS`). */
|
|
8
13
|
export const MAX_REVERT_PRICE_VARIANTS = 500;
|
|
9
14
|
export const VARIANT_FIELDS = /* GraphQL */ `
|
|
@@ -15,9 +20,16 @@ export const VARIANT_FIELDS = /* GraphQL */ `
|
|
|
15
20
|
name
|
|
16
21
|
sku
|
|
17
22
|
enabled
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
23
|
+
storePrice {
|
|
24
|
+
price
|
|
25
|
+
priceWithTax
|
|
26
|
+
currencyCode
|
|
27
|
+
}
|
|
28
|
+
prices {
|
|
29
|
+
currencyCode
|
|
30
|
+
price
|
|
31
|
+
}
|
|
32
|
+
stockOnHand
|
|
21
33
|
taxCategory {
|
|
22
34
|
id
|
|
23
35
|
name
|
|
@@ -51,6 +63,18 @@ export const VARIANT_FIELDS = /* GraphQL */ `
|
|
|
51
63
|
preorderLimit
|
|
52
64
|
parcelCapacity
|
|
53
65
|
parcelPacking
|
|
66
|
+
minOrderQuantity
|
|
67
|
+
salesUnit
|
|
68
|
+
position
|
|
69
|
+
cost
|
|
70
|
+
packageWeightGrams
|
|
71
|
+
packageLengthCm
|
|
72
|
+
packageWidthCm
|
|
73
|
+
packageHeightCm
|
|
74
|
+
backorderPolicy
|
|
75
|
+
backorderLimit
|
|
76
|
+
gtin
|
|
77
|
+
mpn
|
|
54
78
|
}
|
|
55
79
|
`;
|
|
56
80
|
export const VARIANTS_QUERY = /* GraphQL */ `
|
|
@@ -61,6 +85,20 @@ export const VARIANTS_QUERY = /* GraphQL */ `
|
|
|
61
85
|
}
|
|
62
86
|
}
|
|
63
87
|
`;
|
|
88
|
+
/** Two fields a row, for {@link VariantsModule.optionSets}: the id and its options' ids. */
|
|
89
|
+
export const VARIANT_OPTION_SETS_QUERY = /* GraphQL */ `
|
|
90
|
+
query CatalogVariantOptionSets($productId: ID!, $options: ProductVariantListOptions) {
|
|
91
|
+
productVariants(productId: $productId, options: $options) {
|
|
92
|
+
items {
|
|
93
|
+
id
|
|
94
|
+
options {
|
|
95
|
+
id
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
totalItems
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
`;
|
|
64
102
|
export const VARIANT_QUERY = /* GraphQL */ `
|
|
65
103
|
query CatalogVariant($id: ID!) {
|
|
66
104
|
productVariant(id: $id) { ${VARIANT_FIELDS} }
|
|
@@ -112,13 +150,33 @@ export const PRICE_BASIS_QUERY = /* GraphQL */ `
|
|
|
112
150
|
}
|
|
113
151
|
}
|
|
114
152
|
`;
|
|
153
|
+
/** The variant fields read out of `customFields` as they are, null for an unset one. */
|
|
154
|
+
export const LIFTED_CUSTOM_FIELDS = [
|
|
155
|
+
'minOrderQuantity',
|
|
156
|
+
'salesUnit',
|
|
157
|
+
'position',
|
|
158
|
+
'cost',
|
|
159
|
+
'packageWeightGrams',
|
|
160
|
+
'packageLengthCm',
|
|
161
|
+
'packageWidthCm',
|
|
162
|
+
'packageHeightCm',
|
|
163
|
+
'backorderPolicy',
|
|
164
|
+
'backorderLimit',
|
|
165
|
+
'gtin',
|
|
166
|
+
'mpn',
|
|
167
|
+
];
|
|
115
168
|
function isParcelPacking(value) {
|
|
116
169
|
return PARCEL_PACKING_MODES.includes(value);
|
|
117
170
|
}
|
|
171
|
+
/** Lift the custom fields to first-class fields. */
|
|
118
172
|
export function toVariant(wire) {
|
|
119
|
-
const { customFields, ...rest } = wire;
|
|
173
|
+
const { customFields, featuredAsset, assets, ...rest } = wire;
|
|
174
|
+
const lifted = Object.fromEntries(LIFTED_CUSTOM_FIELDS.map((key) => [key, customFields?.[key] ?? null]));
|
|
120
175
|
return {
|
|
121
176
|
...rest,
|
|
177
|
+
...lifted,
|
|
178
|
+
featuredAsset: featuredAsset ? toAssetRef(featuredAsset) : null,
|
|
179
|
+
assets: assets.map(toAssetRef),
|
|
122
180
|
taxClassKey: customFields?.taxClassKey ?? null,
|
|
123
181
|
availabilityState: customFields?.availabilityState ?? 'inherit',
|
|
124
182
|
availableFrom: customFields?.availableFrom ?? null,
|
|
@@ -144,13 +202,30 @@ function assertParcelRule(input) {
|
|
|
144
202
|
}
|
|
145
203
|
}
|
|
146
204
|
function toWireInput(input) {
|
|
147
|
-
const { availabilityState, availableFrom, preorderLimit, taxClassKey, parcelCapacity, parcelPacking, priceBasis, ...rest } = input;
|
|
205
|
+
const { availabilityState, availableFrom, preorderLimit, taxClassKey, parcelCapacity, parcelPacking, priceBasis, minOrderQuantity, salesUnit, cost, packageWeightGrams, packageLengthCm, packageWidthCm, packageHeightCm, backorderPolicy, backorderLimit, gtin, mpn, ...rest } = input;
|
|
148
206
|
void priceBasis;
|
|
149
207
|
const customFields = availabilityCustomFields({
|
|
150
208
|
availabilityState,
|
|
151
209
|
availableFrom,
|
|
152
210
|
preorderLimit,
|
|
153
211
|
});
|
|
212
|
+
const fields = {
|
|
213
|
+
minOrderQuantity,
|
|
214
|
+
salesUnit,
|
|
215
|
+
cost,
|
|
216
|
+
packageWeightGrams,
|
|
217
|
+
packageLengthCm,
|
|
218
|
+
packageWidthCm,
|
|
219
|
+
packageHeightCm,
|
|
220
|
+
backorderPolicy,
|
|
221
|
+
backorderLimit,
|
|
222
|
+
gtin,
|
|
223
|
+
mpn,
|
|
224
|
+
};
|
|
225
|
+
for (const [key, value] of Object.entries(fields)) {
|
|
226
|
+
if (value !== undefined)
|
|
227
|
+
customFields[key] = value;
|
|
228
|
+
}
|
|
154
229
|
if (taxClassKey !== undefined)
|
|
155
230
|
customFields.taxClassKey = taxClassKey;
|
|
156
231
|
if (parcelCapacity !== undefined)
|
|
@@ -163,6 +238,69 @@ function toWireInput(input) {
|
|
|
163
238
|
function refuse(code, message) {
|
|
164
239
|
return new ValidationError({ code, message, status: 400, service: 'vendure' });
|
|
165
240
|
}
|
|
241
|
+
const VARIANT_SORT_FIELDS = [
|
|
242
|
+
'position',
|
|
243
|
+
'name',
|
|
244
|
+
'sku',
|
|
245
|
+
'createdAt',
|
|
246
|
+
'updatedAt',
|
|
247
|
+
];
|
|
248
|
+
/**
|
|
249
|
+
* The engine's `ProductVariantListOptions` for {@link VariantListOptions}, without the page
|
|
250
|
+
* window. ONE sort key, never a tie-breaker beside it: graphql-js coerces an input object in the
|
|
251
|
+
* order its TYPE declares the fields, and `ProductVariantSortParameter` declares `id` before every
|
|
252
|
+
* field named here, so `{ position, id }` reaches the engine as `{ id, position }` and sorts by id
|
|
253
|
+
* alone (W10-113 finding). The engine completes the order itself: `productVariants(productId:)`
|
|
254
|
+
* (core's `getVariantsByProductId`) appends `id ASC` after the caller's key, which makes it total,
|
|
255
|
+
* so offset pages neither repeat nor skip a row even where `position` is null.
|
|
256
|
+
*/
|
|
257
|
+
export function variantListOptions(options) {
|
|
258
|
+
const sort = options?.sort ?? { field: 'position', direction: 'ASC' };
|
|
259
|
+
if (!VARIANT_SORT_FIELDS.includes(sort.field) ||
|
|
260
|
+
(sort.direction !== 'ASC' && sort.direction !== 'DESC')) {
|
|
261
|
+
throw refuse('INVALID_VARIANT_SORT', `sort must name one of ${VARIANT_SORT_FIELDS.join(', ')} and the direction ASC or DESC; got ${JSON.stringify(sort)}. Nothing was sent.`);
|
|
262
|
+
}
|
|
263
|
+
const term = options?.term?.trim() ?? '';
|
|
264
|
+
return {
|
|
265
|
+
sort: { [sort.field]: sort.direction },
|
|
266
|
+
// `filterOperator` joins the top-level fields, which are exactly these two.
|
|
267
|
+
...(term === ''
|
|
268
|
+
? {}
|
|
269
|
+
: {
|
|
270
|
+
filter: { sku: { contains: term }, name: { contains: term } },
|
|
271
|
+
filterOperator: 'OR',
|
|
272
|
+
}),
|
|
273
|
+
};
|
|
274
|
+
}
|
|
275
|
+
/**
|
|
276
|
+
* Every priced input (`price`, or any `prices` entry) must be whole minor units and state its
|
|
277
|
+
* basis, and the basis must be the store's. Read per call, with the call's own options, so a
|
|
278
|
+
* per-call tenant is checked against ITS store rather than the client's default one.
|
|
279
|
+
*/
|
|
280
|
+
export async function assertPricesStateBasis(transport, inputs, options) {
|
|
281
|
+
const priced = inputs.filter((input) => input.price !== undefined || input.prices !== undefined);
|
|
282
|
+
if (priced.length === 0)
|
|
283
|
+
return;
|
|
284
|
+
for (const input of priced) {
|
|
285
|
+
const amounts = [
|
|
286
|
+
...(input.price !== undefined ? [input.price] : []),
|
|
287
|
+
...(input.prices ?? []).map((entry) => entry.price),
|
|
288
|
+
];
|
|
289
|
+
const fractional = amounts.find((amount) => !Number.isInteger(amount));
|
|
290
|
+
if (fractional !== undefined) {
|
|
291
|
+
throw refuse('INVALID_PRICE', `price must be a whole number of minor units; got ${String(fractional)}.`);
|
|
292
|
+
}
|
|
293
|
+
if (input.priceBasis !== 'net' && input.priceBasis !== 'gross') {
|
|
294
|
+
throw refuse('PRICE_BASIS_REQUIRED', 'A variant price must state its basis: priceBasis "net" or "gross".');
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
const channel = await fieldOf(transport, PRICE_BASIS_QUERY, 'activeChannel', {}, options);
|
|
298
|
+
const storeBasis = channel.pricesIncludeTax ? 'gross' : 'net';
|
|
299
|
+
const wrong = priced.find((input) => input.priceBasis !== storeBasis);
|
|
300
|
+
if (wrong) {
|
|
301
|
+
throw refuse('PRICE_BASIS_MISMATCH', `This store states prices ${storeBasis === 'gross' ? 'including' : 'excluding'} tax, so a price must be sent with priceBasis "${storeBasis}"; got "${String(wrong.priceBasis)}". Convert it before sending — the SDK does not, because the rate depends on each order's zone.`);
|
|
302
|
+
}
|
|
303
|
+
}
|
|
166
304
|
export function createVariantsModule(transport) {
|
|
167
305
|
/**
|
|
168
306
|
* Every priced input must state its basis, and the basis must be the store's.
|
|
@@ -170,23 +308,7 @@ export function createVariantsModule(transport) {
|
|
|
170
308
|
* against ITS store rather than the client's default one.
|
|
171
309
|
*/
|
|
172
310
|
const assertPriceBasis = async (inputs, options) => {
|
|
173
|
-
|
|
174
|
-
if (priced.length === 0)
|
|
175
|
-
return;
|
|
176
|
-
for (const input of priced) {
|
|
177
|
-
if (!Number.isInteger(input.price)) {
|
|
178
|
-
throw refuse('INVALID_PRICE', `price must be a whole number of minor units; got ${String(input.price)}.`);
|
|
179
|
-
}
|
|
180
|
-
if (input.priceBasis !== 'net' && input.priceBasis !== 'gross') {
|
|
181
|
-
throw refuse('PRICE_BASIS_REQUIRED', 'A variant price must state its basis: priceBasis "net" or "gross".');
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
const channel = await fieldOf(transport, PRICE_BASIS_QUERY, 'activeChannel', {}, options);
|
|
185
|
-
const storeBasis = channel.pricesIncludeTax ? 'gross' : 'net';
|
|
186
|
-
const wrong = priced.find((input) => input.priceBasis !== storeBasis);
|
|
187
|
-
if (wrong) {
|
|
188
|
-
throw refuse('PRICE_BASIS_MISMATCH', `This store states prices ${storeBasis === 'gross' ? 'including' : 'excluding'} tax, so a price must be sent with priceBasis "${storeBasis}"; got "${String(wrong.priceBasis)}". Convert it before sending — the SDK does not, because the rate depends on each order's zone.`);
|
|
189
|
-
}
|
|
311
|
+
await assertPricesStateBasis(transport, inputs, options);
|
|
190
312
|
};
|
|
191
313
|
const mapAll = (rows, what) => rows.map((row) => {
|
|
192
314
|
if (row === null) {
|
|
@@ -209,13 +331,39 @@ export function createVariantsModule(transport) {
|
|
|
209
331
|
return mapAll(rows, 'updateProductVariants');
|
|
210
332
|
};
|
|
211
333
|
return {
|
|
212
|
-
list(productId, options) {
|
|
213
|
-
|
|
334
|
+
async list(productId, options) {
|
|
335
|
+
const listOptions = variantListOptions(options);
|
|
336
|
+
return vendureListPage(transport, VARIANTS_QUERY, 'productVariants', (skip, take) => ({ productId, options: { skip, take, ...listOptions } }), options, toVariant);
|
|
337
|
+
},
|
|
338
|
+
async optionSets(productId, options) {
|
|
339
|
+
const { limit = DEFAULT_OPTION_SET_LIMIT, ...call } = options ?? {};
|
|
340
|
+
if (!Number.isInteger(limit) || limit < 1 || limit > MAX_OPTION_SET_LIMIT) {
|
|
341
|
+
throw refuse('INVALID_OPTION_SET_LIMIT', `limit must be a whole number from 1 to ${String(MAX_OPTION_SET_LIMIT)}; got ${String(limit)}. Nothing was sent.`);
|
|
342
|
+
}
|
|
343
|
+
const combinations = [];
|
|
344
|
+
let totalItems = 0;
|
|
345
|
+
while (combinations.length < limit) {
|
|
346
|
+
const take = Math.min(MAX_PAGE_SIZE, limit - combinations.length);
|
|
347
|
+
const page = await fieldOf(transport, VARIANT_OPTION_SETS_QUERY, 'productVariants',
|
|
348
|
+
// By id alone (unique, so no page repeats a row of another): one key, as above.
|
|
349
|
+
{ productId, options: { skip: combinations.length, take, sort: { id: 'ASC' } } }, call);
|
|
350
|
+
totalItems = page.totalItems;
|
|
351
|
+
for (const item of page.items) {
|
|
352
|
+
combinations.push(item.options.map((option) => option.id).sort());
|
|
353
|
+
}
|
|
354
|
+
// A short page is the end, whatever `totalItems` claims: never ask past it.
|
|
355
|
+
if (page.items.length < take || combinations.length >= totalItems)
|
|
356
|
+
break;
|
|
357
|
+
}
|
|
358
|
+
return { combinations, totalItems, truncated: totalItems > combinations.length };
|
|
214
359
|
},
|
|
215
360
|
async get(id, options) {
|
|
216
361
|
const variant = await fieldOf(transport, VARIANT_QUERY, 'productVariant', { id }, options);
|
|
217
362
|
return variant ? toVariant(variant) : null;
|
|
218
363
|
},
|
|
364
|
+
find(input, options) {
|
|
365
|
+
return findVariants(transport, input, options);
|
|
366
|
+
},
|
|
219
367
|
async create(inputs, options) {
|
|
220
368
|
inputs.forEach(assertParcelRule);
|
|
221
369
|
await assertPriceBasis(inputs, options);
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { type Transport } from '@sixtyninecommerce/core';
|
|
1
|
+
import { type Page, type Transport } from '@sixtyninecommerce/core';
|
|
2
2
|
import type { Call } from '../types.js';
|
|
3
|
+
import { type Product, type ProductListOptions } from './products.js';
|
|
3
4
|
export type ProductVisibilityMode = 'public' | 'private';
|
|
4
5
|
/**
|
|
5
6
|
* Who a product is shown to on the storefront. A product with no row is
|
|
@@ -29,12 +30,20 @@ export interface SetProductVisibilityInput {
|
|
|
29
30
|
* `USER_INPUT_ERROR` (`ValidationError`): "Product {id} not found in this
|
|
30
31
|
* channel". A write from here is always `source: manual`, which a later
|
|
31
32
|
* pipeline import leaves alone.
|
|
32
|
-
*
|
|
33
|
-
* The Admin API's `productsByVisibility` list is deliberately NOT exposed: it
|
|
34
|
-
* counts and pages visibility rows across every store before narrowing to this
|
|
35
|
-
* one, so its totals and pages are wrong (recorded as a finding).
|
|
36
33
|
*/
|
|
37
34
|
export interface VisibilityModule {
|
|
35
|
+
/**
|
|
36
|
+
* This store's products in one mode, with `products.list`'s filter, sort and
|
|
37
|
+
* paging (filtered before paging; `totalItems` counts this store only).
|
|
38
|
+
* `public` lists products with an explicit public row, not every product
|
|
39
|
+
* without one. With no sort, newest product first.
|
|
40
|
+
*
|
|
41
|
+
* Needs an engine whose `productsByVisibility` honours its options: an older
|
|
42
|
+
* one ignored all but the page and counted other stores' products, so it is
|
|
43
|
+
* refused before running (`ValidationError`, `GRAPHQL_VALIDATION_FAILED` or
|
|
44
|
+
* `BAD_REQUEST`) rather than answered with an unfiltered page.
|
|
45
|
+
*/
|
|
46
|
+
list(mode: ProductVisibilityMode, options?: ProductListOptions): Promise<Page<Product>>;
|
|
38
47
|
/** Null when the product has no override (it is public). `NotFoundError` for an unknown product. */
|
|
39
48
|
get(productId: string, options?: Call): Promise<ProductVisibility | null>;
|
|
40
49
|
set(input: SetProductVisibilityInput, options?: Call): Promise<ProductVisibility>;
|
|
@@ -51,6 +60,12 @@ export interface VisibilityModule {
|
|
|
51
60
|
clear(productId: string, options?: Call): Promise<void>;
|
|
52
61
|
}
|
|
53
62
|
export declare const PRODUCT_VISIBILITY_QUERY = "\n query CatalogProductVisibility($id: ID!) {\n product(id: $id) {\n id\n visibility { \n productId\n mode\n source\n allowedCustomerGroupIds\n createdAt\n updatedAt\n }\n }\n }\n";
|
|
63
|
+
/**
|
|
64
|
+
* The marker field is selected only so that an engine from before the list
|
|
65
|
+
* honoured its options refuses the document as an unknown field; nothing reads
|
|
66
|
+
* its answer. It must stay the SECOND root field.
|
|
67
|
+
*/
|
|
68
|
+
export declare const PRODUCTS_BY_VISIBILITY_QUERY = "\n query CatalogProductsByVisibility($mode: ProductVisibilityMode!, $options: ProductListOptions) {\n productsByVisibility(mode: $mode, 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 type\n mimeType\n customFields {\n altText\n }\n }\n assets { \n id\n name\n preview\n source\n type\n mimeType\n customFields {\n altText\n }\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 customFields {\n isShared\n }\n options {\n id\n code\n name\n }\n translations {\n id\n languageCode\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 brand\n condition\n }\n }\n totalItems\n }\n productsByVisibilityHonoursListOptions\n }\n";
|
|
54
69
|
export declare const SET_VISIBILITY_MUTATION = "\n mutation CatalogSetVisibility($input: SetProductVisibilityInput!) {\n setProductVisibility(input: $input) { \n productId\n mode\n source\n allowedCustomerGroupIds\n createdAt\n updatedAt\n }\n }\n";
|
|
55
70
|
export declare const BULK_SET_VISIBILITY_MUTATION = "\n mutation CatalogBulkSetVisibility($input: BulkSetProductVisibilityInput!) {\n bulkSetProductVisibility(input: $input) {\n updated\n }\n }\n";
|
|
56
71
|
export declare const CLEAR_VISIBILITY_MUTATION = "\n mutation CatalogClearVisibility($productId: ID!) {\n clearProductVisibility(productId: $productId)\n }\n";
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { NotFoundError } from '@sixtyninecommerce/core';
|
|
2
|
-
import {
|
|
2
|
+
import { PRODUCT_FIELDS, productListOptions, toProduct, } from './products.js';
|
|
3
|
+
import { fieldOf, vendureListPage } from './types.js';
|
|
3
4
|
const VISIBILITY_FIELDS = /* GraphQL */ `
|
|
4
5
|
productId
|
|
5
6
|
mode
|
|
@@ -16,6 +17,20 @@ export const PRODUCT_VISIBILITY_QUERY = /* GraphQL */ `
|
|
|
16
17
|
}
|
|
17
18
|
}
|
|
18
19
|
`;
|
|
20
|
+
/**
|
|
21
|
+
* The marker field is selected only so that an engine from before the list
|
|
22
|
+
* honoured its options refuses the document as an unknown field; nothing reads
|
|
23
|
+
* its answer. It must stay the SECOND root field.
|
|
24
|
+
*/
|
|
25
|
+
export const PRODUCTS_BY_VISIBILITY_QUERY = /* GraphQL */ `
|
|
26
|
+
query CatalogProductsByVisibility($mode: ProductVisibilityMode!, $options: ProductListOptions) {
|
|
27
|
+
productsByVisibility(mode: $mode, options: $options) {
|
|
28
|
+
items { ${PRODUCT_FIELDS} }
|
|
29
|
+
totalItems
|
|
30
|
+
}
|
|
31
|
+
productsByVisibilityHonoursListOptions
|
|
32
|
+
}
|
|
33
|
+
`;
|
|
19
34
|
export const SET_VISIBILITY_MUTATION = /* GraphQL */ `
|
|
20
35
|
mutation CatalogSetVisibility($input: SetProductVisibilityInput!) {
|
|
21
36
|
setProductVisibility(input: $input) { ${VISIBILITY_FIELDS} }
|
|
@@ -35,6 +50,9 @@ export const CLEAR_VISIBILITY_MUTATION = /* GraphQL */ `
|
|
|
35
50
|
`;
|
|
36
51
|
export function createVisibilityModule(transport) {
|
|
37
52
|
return {
|
|
53
|
+
list(mode, options) {
|
|
54
|
+
return vendureListPage(transport, PRODUCTS_BY_VISIBILITY_QUERY, 'productsByVisibility', (skip, take) => ({ mode, options: productListOptions(options, skip, take) }), options, toProduct);
|
|
55
|
+
},
|
|
38
56
|
async get(productId, options) {
|
|
39
57
|
const product = await fieldOf(transport, PRODUCT_VISIBILITY_QUERY, 'product', { id: productId }, options);
|
|
40
58
|
if (!product) {
|
package/dist/client.d.ts
CHANGED
|
@@ -10,47 +10,63 @@ import { type AuthModule } from './auth/index.js';
|
|
|
10
10
|
import { type BulkModule } from './bulk/index.js';
|
|
11
11
|
import { type CatalogModule } from './catalog/index.js';
|
|
12
12
|
import { type ComplianceModule } from './compliance/index.js';
|
|
13
|
+
import { type ContentAssetsModule } from './content/assets.js';
|
|
13
14
|
import { type FormsModule } from './content/forms.js';
|
|
15
|
+
import { type ContentItemsModule } from './content/items.js';
|
|
16
|
+
import { type ContentFieldsModule, type ContentPageValuesModule, type ContentTypesModule } from './content/types.js';
|
|
14
17
|
import { type CustomObjectsModule } from './custom-objects/index.js';
|
|
15
18
|
import { type CustomersModule } from './customers/index.js';
|
|
16
19
|
import { type DocumentsModule } from './documents/index.js';
|
|
17
20
|
import { type EventsModule } from './events/index.js';
|
|
18
21
|
import { type FeedsModule } from './feeds/index.js';
|
|
19
22
|
import { type FulfillmentsModule } from './fulfillments/index.js';
|
|
23
|
+
import { type GeoModule } from './geo/index.js';
|
|
20
24
|
import { type HeadsModule } from './heads/index.js';
|
|
21
25
|
import { type HooksModule } from './hooks/index.js';
|
|
26
|
+
import { type IntegrationsModule } from './integrations/index.js';
|
|
22
27
|
import { type JobsModule } from './jobs/index.js';
|
|
23
28
|
import { type LocationsModule } from './locations/index.js';
|
|
24
29
|
import { type MetaModule } from './meta/index.js';
|
|
25
30
|
import { type MetafieldsModule } from './metafields/index.js';
|
|
26
31
|
import { type OrdersModule } from './orders/index.js';
|
|
27
32
|
import { type PaymentsModule } from './payments/index.js';
|
|
33
|
+
import { type PickupsModule } from './pickups/index.js';
|
|
28
34
|
import { type PlatformAppsModule } from './platform/apps.js';
|
|
29
35
|
import { type PlatformCatalogModule } from './platform/catalog.js';
|
|
36
|
+
import { type PlatformChannelsModule } from './platform/channels.js';
|
|
30
37
|
import { type PlatformEntitlementsModule } from './platform/entitlements.js';
|
|
38
|
+
import { type PlatformGeoModule } from './platform/geo.js';
|
|
31
39
|
import { type PlatformLegalEntitiesModule } from './platform/legal-entities.js';
|
|
32
40
|
import { type PlatformOrganizationsModule } from './platform/organizations.js';
|
|
33
41
|
import { type PlatformModule } from './platform/provision-store.js';
|
|
34
42
|
import { type PlatformReportsModule } from './platform/reports.js';
|
|
35
43
|
import { type PlatformServerMetricsModule } from './platform/server-metrics.js';
|
|
44
|
+
import { type PlatformTaxModule } from './platform/tax.js';
|
|
36
45
|
import { type PosModule } from './pos/index.js';
|
|
37
46
|
import { type PricingModule } from './pricing/index.js';
|
|
38
47
|
import { type ProvenanceModule } from './provenance/index.js';
|
|
48
|
+
import { type PurchasingModule } from './purchasing/index.js';
|
|
49
|
+
import { type QuotesModule } from './quotes/index.js';
|
|
39
50
|
import { type ReportsModule } from './reports/index.js';
|
|
51
|
+
import { type ReturnsModule } from './returns/index.js';
|
|
52
|
+
import { type SearchModule } from './search/index.js';
|
|
40
53
|
import { type RedirectsModule } from './seo/redirects.js';
|
|
41
|
-
import { type
|
|
42
|
-
import { type ShippingModule } from './shipping/parcel-rule.js';
|
|
54
|
+
import { type ShippingModule } from './shipping/index.js';
|
|
43
55
|
import { type StockModule } from './stock/index.js';
|
|
44
56
|
import { type StoredValueModule } from './stored-value/index.js';
|
|
57
|
+
import { type SubscriptionsModule } from './subscriptions/index.js';
|
|
45
58
|
import { type TaxModule } from './tax/index.js';
|
|
46
59
|
import { type CapabilitiesModule } from './tenant/capabilities.js';
|
|
47
60
|
import { type ChannelsModule } from './tenant/channels.js';
|
|
61
|
+
import { type EmailStyleModule } from './tenant/email-style.js';
|
|
62
|
+
import { type EmailTemplatesModule } from './tenant/email-templates.js';
|
|
48
63
|
import { type TenantEntitlementsReader } from './tenant/entitlements.js';
|
|
49
64
|
import { type FieldGroupOwnersReader, type FieldGroupSyncSourcesReader } from './tenant/field-groups.js';
|
|
50
65
|
import { type LegalEntityModule } from './tenant/legal-entity.js';
|
|
51
66
|
import { type NotificationsModule } from './tenant/notifications.js';
|
|
52
67
|
import { type RetentionModule } from './tenant/retention.js';
|
|
53
68
|
import { type SettingsSourcesModule } from './tenant/settings-sources.js';
|
|
69
|
+
import { type TenantTimeZoneReader } from './tenant/time-zone.js';
|
|
54
70
|
import { type UploadsModule } from './uploads/index.js';
|
|
55
71
|
import { type UsersModule } from './users/index.js';
|
|
56
72
|
export interface AdminClientConfig {
|
|
@@ -117,13 +133,23 @@ export interface AdminClient {
|
|
|
117
133
|
};
|
|
118
134
|
audit: AuditModule;
|
|
119
135
|
/**
|
|
120
|
-
* Products, variants, options, facets, collections, assets, visibility
|
|
121
|
-
* properties (spec §9.2 `catalog`). Needs the catalog
|
|
136
|
+
* Products, variants, options, facets, collections, assets, visibility,
|
|
137
|
+
* properties and recommendations (spec §9.2 `catalog`). Needs the catalog
|
|
138
|
+
* permissions.
|
|
122
139
|
*/
|
|
123
140
|
catalog: CatalogModule;
|
|
124
141
|
channels: ChannelsModule;
|
|
142
|
+
/**
|
|
143
|
+
* The CMS's content: forms, content types (collections) with their fields, each type's
|
|
144
|
+
* index-page values, the types' items, and the media library (spec §9.2 `content`).
|
|
145
|
+
*/
|
|
125
146
|
content: {
|
|
126
147
|
forms: FormsModule;
|
|
148
|
+
types: ContentTypesModule;
|
|
149
|
+
fields: ContentFieldsModule;
|
|
150
|
+
pageValues: ContentPageValuesModule;
|
|
151
|
+
items: ContentItemsModule;
|
|
152
|
+
assets: ContentAssetsModule;
|
|
127
153
|
};
|
|
128
154
|
/**
|
|
129
155
|
* Compliance requests to installed apps: data requests, customer and
|
|
@@ -141,6 +167,12 @@ export interface AdminClient {
|
|
|
141
167
|
* the store's tax, payment or fulfillment provider; `ping` tests one hook.
|
|
142
168
|
*/
|
|
143
169
|
hooks: HooksModule;
|
|
170
|
+
/**
|
|
171
|
+
* The store's connections to other systems (spec §9.2). `pipelines.drafts` keeps a
|
|
172
|
+
* half-finished import or export set-up on the server for 7 days after its last change, for any
|
|
173
|
+
* admin of the store with pipeline rights, and never holds a credential.
|
|
174
|
+
*/
|
|
175
|
+
integrations: IntegrationsModule;
|
|
144
176
|
/**
|
|
145
177
|
* Platform events (spec §6.9): `poll`/`pollAll`/`replay`/`head` over the event log (a
|
|
146
178
|
* machine credential with `ReadPlatformEvents`), `subscribe` to build a typed webhook
|
|
@@ -166,6 +198,11 @@ export interface AdminClient {
|
|
|
166
198
|
* AI helpers. Channel-scoped throughout — no method takes a channel.
|
|
167
199
|
*/
|
|
168
200
|
feeds: FeedsModule;
|
|
201
|
+
/**
|
|
202
|
+
* Countries and zones (spec §9.2, ruling G128): platform-wide reads, the same for every store.
|
|
203
|
+
* `mostSpecificZone` (exported beside it) answers the zone provisioning picks for a country.
|
|
204
|
+
*/
|
|
205
|
+
geo: GeoModule;
|
|
169
206
|
/** The store's head registry: every client surface it serves (spec §6.7). */
|
|
170
207
|
heads: HeadsModule;
|
|
171
208
|
/** Every long-running operation the platform runs, under one resource (spec §6.11). */
|
|
@@ -197,6 +234,12 @@ export interface AdminClient {
|
|
|
197
234
|
* recorded against an order with what it stands at (spec §8.2).
|
|
198
235
|
*/
|
|
199
236
|
payments: PaymentsModule;
|
|
237
|
+
/**
|
|
238
|
+
* Store pickup (click & collect, POS C1/33): the store's pickups, an order's pickup, and
|
|
239
|
+
* "ready". A location's pickup settings are `locations.pickup/setPickup`; the hand-over is the
|
|
240
|
+
* till's.
|
|
241
|
+
*/
|
|
242
|
+
pickups: PickupsModule;
|
|
200
243
|
/**
|
|
201
244
|
* Point of sale on a machine principal (spec §8.8): register sessions, cash,
|
|
202
245
|
* tenders, the sale, refunds, X and Z — with no paired tablet. Needs a `pos`
|
|
@@ -215,18 +258,54 @@ export interface AdminClient {
|
|
|
215
258
|
* writer only; the history is the platform event log.
|
|
216
259
|
*/
|
|
217
260
|
provenance: ProvenanceModule;
|
|
261
|
+
/**
|
|
262
|
+
* Buying stock from suppliers, per legal entity (purchase-orders spec §10.1): `settings` with
|
|
263
|
+
* its document `numbering`, `suppliers` with their `contacts`, `purchaseOrders` with their
|
|
264
|
+
* `lines`, `replenishment` (reorder rules and suggestions), and `cost` (a variant's cost
|
|
265
|
+
* ledger). Needs the Purchasing plugin on the store.
|
|
266
|
+
*/
|
|
267
|
+
purchasing: PurchasingModule;
|
|
268
|
+
/**
|
|
269
|
+
* B2B quotes: list, read, build and price a quote, move it through its statuses, and convert an
|
|
270
|
+
* approved one into an order (keyed); its PDF, its email, the store's quote design and settings
|
|
271
|
+
* (headless W10-35a). `Quote.editable` / `convertible` are the engine's answer to "what can be
|
|
272
|
+
* done now".
|
|
273
|
+
*/
|
|
274
|
+
quotes: QuotesModule;
|
|
218
275
|
/** Tenant reporting in minor units and ISO-8601 UTC (spec §9.2 `reports`, §9.3). */
|
|
219
276
|
reports: ReportsModule;
|
|
277
|
+
/**
|
|
278
|
+
* Subscription plans (list, read, create, update, products, delete, price breakdown) and the
|
|
279
|
+
* subscriptions sold on them (list, read, a customer's subscriptions and mandates, the store's
|
|
280
|
+
* billing readiness) (headless W10-36), and their lifecycle and billing commands: purchase,
|
|
281
|
+
* pause/resume/skip/reschedule, cancel, payment method replacement, recovery, reconciliation,
|
|
282
|
+
* renewal and settlement retries, attention clearing and price changes, each money command under
|
|
283
|
+
* one idempotency key per attempt (headless W10-114). Statuses are the meta catalog's lower-case
|
|
284
|
+
* words.
|
|
285
|
+
*/
|
|
286
|
+
subscriptions: SubscriptionsModule;
|
|
287
|
+
/**
|
|
288
|
+
* Order returns (RMA): one return, an order's returns, what of an order can
|
|
289
|
+
* still be returned, and the plan for settling a return (headless W9-47). The
|
|
290
|
+
* list and the writes are phase 7.
|
|
291
|
+
*/
|
|
292
|
+
returns: ReturnsModule;
|
|
293
|
+
/**
|
|
294
|
+
* One search across the store (spec §7 `search.entities`): products, orders, customers and
|
|
295
|
+
* content in one call, each type's best matches already loaded, in relevance order. A type
|
|
296
|
+
* the credential may not read is skipped and named, never refused.
|
|
297
|
+
*/
|
|
298
|
+
search: SearchModule;
|
|
220
299
|
seo: {
|
|
221
300
|
redirects: RedirectsModule;
|
|
222
301
|
};
|
|
223
302
|
/**
|
|
224
303
|
* Shipping of the ACTIVE channel (spec §9.2 `shipping`): the channel's
|
|
225
|
-
* `parcelRule`,
|
|
304
|
+
* `parcelRule`, `parcelCountSuggestion` for a set of variant items, the
|
|
305
|
+
* C.J. Hendriks 3PL settings (`hendriks.config`) and the MyParcel set-up,
|
|
306
|
+
* carriers and parcel senders (`myparcel`).
|
|
226
307
|
*/
|
|
227
|
-
shipping: ShippingModule
|
|
228
|
-
parcelCountSuggestion: ParcelCountSuggestionMethod;
|
|
229
|
-
};
|
|
308
|
+
shipping: ShippingModule;
|
|
230
309
|
/**
|
|
231
310
|
* Stock per location by state, the ledger with reasons, reason-carrying
|
|
232
311
|
* adjustments, transfers and allocation release (spec §9.2 `stock`, §8.7).
|
|
@@ -238,7 +317,10 @@ export interface AdminClient {
|
|
|
238
317
|
* payment on an order.
|
|
239
318
|
*/
|
|
240
319
|
storedValue: StoredValueModule;
|
|
241
|
-
/**
|
|
320
|
+
/**
|
|
321
|
+
* The store's own tax classes and their per-country mappings (spec §8.6), and the platform-wide
|
|
322
|
+
* tax categories and rates they map onto.
|
|
323
|
+
*/
|
|
242
324
|
tax: TaxModule;
|
|
243
325
|
/**
|
|
244
326
|
* Signed direct-to-storage uploads (spec §6.11): reserve a place, PUT the
|
|
@@ -269,6 +351,10 @@ export interface AdminClient {
|
|
|
269
351
|
retention: RetentionModule;
|
|
270
352
|
/** Per notification event: on or off, who sends it (spec §8.15), and to whom. */
|
|
271
353
|
notifications: NotificationsModule;
|
|
354
|
+
/** The look of the store's emails: colours, type, logo and layout (`settings.email`). */
|
|
355
|
+
emailStyle: EmailStyleModule;
|
|
356
|
+
/** The store's email templates, by type: previews rendered as the store would send them. */
|
|
357
|
+
emailTemplates: EmailTemplatesModule;
|
|
272
358
|
/**
|
|
273
359
|
* Where each settings group comes from — the store or its organization — and the store's
|
|
274
360
|
* choice to keep its own values (multi-region spec §5.3).
|
|
@@ -279,6 +365,11 @@ export interface AdminClient {
|
|
|
279
365
|
* Changing it needs `UpdateSeller` on every store of the entity.
|
|
280
366
|
*/
|
|
281
367
|
legalEntity: LegalEntityModule;
|
|
368
|
+
/**
|
|
369
|
+
* The active store's IANA time zone as the engine resolves it (`Europe/Amsterdam` when unset
|
|
370
|
+
* or invalid): the zone the API counts calendar days in. Never the browser's.
|
|
371
|
+
*/
|
|
372
|
+
timeZone: TenantTimeZoneReader;
|
|
282
373
|
};
|
|
283
374
|
/**
|
|
284
375
|
* Human SuperAdmin surface. Every method refuses an API token or an app
|
|
@@ -289,11 +380,22 @@ export interface AdminClient {
|
|
|
289
380
|
apps: PlatformAppsModule;
|
|
290
381
|
/** Catalogue maintenance on a named store (the translation-language repair). */
|
|
291
382
|
catalog: PlatformCatalogModule;
|
|
383
|
+
/**
|
|
384
|
+
* The codes renames hold against reuse, and their release: a release that must clear files
|
|
385
|
+
* first is finished by the engine itself — see {@link PlatformChannelsModule}.
|
|
386
|
+
*/
|
|
387
|
+
channels: PlatformChannelsModule;
|
|
292
388
|
/**
|
|
293
389
|
* Which external plugins each store may use: read one store's grants or every store's, and
|
|
294
390
|
* connect or disconnect a plugin for a store — see {@link PlatformEntitlementsModule}.
|
|
295
391
|
*/
|
|
296
392
|
entitlements: PlatformEntitlementsModule;
|
|
393
|
+
/**
|
|
394
|
+
* The platform's zones and countries every store shares: create, rename, delete and change
|
|
395
|
+
* the members of a zone; switch a country on or off — see {@link PlatformGeoModule}. Reads
|
|
396
|
+
* are `geo`.
|
|
397
|
+
*/
|
|
398
|
+
geo: PlatformGeoModule;
|
|
297
399
|
/**
|
|
298
400
|
* The platform's legal entities (multi-region spec §7.1): SuperAdmin list and create; read and
|
|
299
401
|
* update through every store of an entity — see {@link PlatformLegalEntitiesModule}.
|
|
@@ -308,6 +410,11 @@ export interface AdminClient {
|
|
|
308
410
|
reports: PlatformReportsModule;
|
|
309
411
|
/** Basic health of the platform's own servers (CPU, memory, disk, network). */
|
|
310
412
|
serverMetrics: PlatformServerMetricsModule;
|
|
413
|
+
/**
|
|
414
|
+
* The platform's tax categories and tax rates every store shares: create, change and delete
|
|
415
|
+
* them — see {@link PlatformTaxModule}. Reads are `tax.categories` / `tax.rates`.
|
|
416
|
+
*/
|
|
417
|
+
tax: PlatformTaxModule;
|
|
311
418
|
};
|
|
312
419
|
/** A derived client on another tenant, sharing this one's principal. */
|
|
313
420
|
withTenant(tenant: Partial<TenantContext> & {
|