@sixtyninecommerce/admin 0.11.0 → 0.13.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 +1509 -28
- package/dist/auth/index.d.ts +7 -1
- package/dist/auth/index.js +8 -1
- package/dist/catalog/documents.d.ts +142 -0
- package/dist/catalog/documents.js +114 -0
- package/dist/catalog/index.d.ts +48 -7
- package/dist/catalog/index.js +6 -1
- package/dist/catalog/metadata.d.ts +244 -0
- package/dist/catalog/metadata.js +220 -0
- package/dist/catalog/properties.d.ts +38 -0
- package/dist/catalog/properties.js +52 -1
- package/dist/catalog/recommendations.d.ts +33 -6
- package/dist/catalog/recommendations.js +94 -2
- package/dist/catalog/reviews.d.ts +17 -4
- package/dist/catalog/reviews.js +7 -0
- package/dist/catalog/variants.d.ts +60 -0
- package/dist/catalog/variants.js +39 -0
- package/dist/catalog/visibility.d.ts +18 -2
- package/dist/client.d.ts +29 -3
- package/dist/client.js +19 -8
- package/dist/content/assets.d.ts +3 -4
- package/dist/content/forms.d.ts +332 -1
- package/dist/content/forms.js +140 -4
- package/dist/content/items.d.ts +31 -8
- package/dist/content/items.js +1 -1
- package/dist/content/menus.d.ts +254 -0
- package/dist/content/menus.js +70 -0
- package/dist/content/strings.d.ts +137 -0
- package/dist/content/strings.js +82 -0
- package/dist/customers/delivery-terms.d.ts +44 -0
- package/dist/customers/delivery-terms.js +32 -0
- package/dist/customers/groups.d.ts +16 -5
- package/dist/customers/groups.js +6 -2
- package/dist/customers/index.d.ts +15 -0
- package/dist/customers/index.js +4 -0
- package/dist/documents/emails.d.ts +154 -0
- package/dist/documents/emails.js +220 -0
- package/dist/documents/index.d.ts +13 -0
- package/dist/documents/index.js +2 -0
- package/dist/fulfillments/create.d.ts +1 -1
- package/dist/fulfillments/create.js +5 -2
- package/dist/fulfillments/index.d.ts +119 -1
- package/dist/fulfillments/index.js +124 -4
- package/dist/fulfillments/warehouse.d.ts +29 -17
- package/dist/fulfillments/warehouse.js +32 -1
- package/dist/index.d.ts +43 -23
- package/dist/index.js +11 -5
- package/dist/integrations/exact-online-types.d.ts +542 -0
- package/dist/integrations/exact-online.d.ts +541 -5
- package/dist/integrations/exact-online.js +714 -1
- package/dist/integrations/index.d.ts +23 -8
- package/dist/integrations/index.js +9 -4
- package/dist/integrations/pipeline-discoveries.d.ts +65 -0
- package/dist/integrations/pipeline-discoveries.js +65 -0
- package/dist/integrations/pipeline-runs.d.ts +119 -0
- package/dist/integrations/pipeline-runs.js +87 -0
- package/dist/integrations/pipelines.d.ts +73 -2
- package/dist/integrations/pipelines.js +36 -1
- package/dist/integrations/price-import.d.ts +223 -0
- package/dist/integrations/price-import.js +124 -0
- package/dist/integrations/types.d.ts +221 -3
- package/dist/integrations/types.js +4 -3
- package/dist/meta/index.d.ts +10 -0
- package/dist/metafields/index.d.ts +8 -1
- package/dist/metafields/index.js +10 -0
- package/dist/orders/cancel-with-money.d.ts +10 -0
- package/dist/orders/cancel-with-money.js +2 -0
- package/dist/orders/commit-edit.d.ts +16 -0
- package/dist/orders/commit-edit.js +14 -1
- package/dist/orders/deposit-policy.d.ts +3 -1
- package/dist/orders/index.d.ts +22 -11
- package/dist/orders/index.js +5 -2
- package/dist/orders/list.d.ts +26 -5
- package/dist/orders/list.js +123 -13
- package/dist/orders/manual-discounts.d.ts +13 -5
- package/dist/orders/money-view.d.ts +149 -0
- package/dist/orders/money-view.js +99 -0
- package/dist/orders/plan-edit.d.ts +34 -2
- package/dist/orders/plan-edit.js +110 -12
- package/dist/orders/surcharges.d.ts +12 -0
- package/dist/orders/surcharges.js +34 -9
- package/dist/payments/account-credit.d.ts +17 -1
- package/dist/payments/account-credit.js +25 -2
- package/dist/payments/credit-noted-fields.d.ts +8 -1
- package/dist/payments/credit-noted-fields.js +34 -2
- package/dist/payments/customer-consent.d.ts +30 -0
- package/dist/payments/customer-consent.js +49 -0
- package/dist/payments/index.d.ts +89 -14
- package/dist/payments/index.js +22 -2
- package/dist/payments/requests.d.ts +6 -3
- package/dist/payments/requests.js +1 -0
- package/dist/pickups/index.d.ts +5 -3
- package/dist/pickups/index.js +5 -2
- package/dist/platform/email-gateways.d.ts +165 -0
- package/dist/platform/email-gateways.js +78 -0
- package/dist/platform/tax.d.ts +11 -3
- package/dist/platform/tax.js +30 -0
- package/dist/pos/exchanges.d.ts +6 -1
- package/dist/pos/index.d.ts +229 -10
- package/dist/pos/index.js +113 -4
- package/dist/pos/offline-sales.d.ts +44 -3
- package/dist/pos/offline-sales.js +57 -3
- package/dist/pos/returns.d.ts +28 -1
- package/dist/pos/returns.js +36 -6
- package/dist/pricing/price-lists.d.ts +3 -1
- package/dist/purchasing/alerts.d.ts +19 -4
- package/dist/purchasing/alerts.js +29 -3
- package/dist/purchasing/backorders.d.ts +61 -0
- package/dist/purchasing/backorders.js +92 -0
- package/dist/purchasing/index.d.ts +21 -3
- package/dist/purchasing/index.js +8 -0
- package/dist/purchasing/links.d.ts +263 -0
- package/dist/purchasing/links.js +192 -0
- package/dist/purchasing/purchase-orders.d.ts +4 -1
- package/dist/purchasing/receipts.d.ts +396 -0
- package/dist/purchasing/receipts.js +287 -0
- package/dist/purchasing/returns.d.ts +273 -0
- package/dist/purchasing/returns.js +229 -0
- package/dist/quotes/index.d.ts +20 -3
- package/dist/returns/index.d.ts +62 -1
- package/dist/returns/index.js +61 -0
- package/dist/seo/config.d.ts +128 -0
- package/dist/seo/config.js +95 -0
- package/dist/seo/redirects.d.ts +125 -0
- package/dist/seo/redirects.js +60 -1
- package/dist/seo/settings.d.ts +147 -0
- package/dist/seo/settings.js +209 -0
- package/dist/shipping/index.d.ts +6 -0
- package/dist/shipping/index.js +2 -0
- package/dist/shipping/methods.d.ts +8 -1
- package/dist/shipping/myparcel.d.ts +415 -1
- package/dist/shipping/myparcel.js +291 -3
- package/dist/shipping/rate-tables.d.ts +149 -4
- package/dist/shipping/rate-tables.js +229 -23
- package/dist/shipping/ship-to-countries.d.ts +75 -0
- package/dist/shipping/ship-to-countries.js +47 -0
- package/dist/stock/by-location.d.ts +86 -0
- package/dist/stock/by-location.js +94 -0
- package/dist/stock/index.d.ts +8 -1
- package/dist/stock/index.js +4 -0
- package/dist/stock/settings.d.ts +106 -0
- package/dist/stock/settings.js +103 -0
- package/dist/stock/transfers.d.ts +171 -10
- package/dist/stock/transfers.js +82 -4
- package/dist/stored-value/index.d.ts +98 -7
- package/dist/stored-value/index.js +71 -4
- package/dist/tax/display-policy.d.ts +105 -0
- package/dist/tax/display-policy.js +84 -0
- package/dist/tax/index.d.ts +3 -0
- package/dist/tax/index.js +2 -0
- package/dist/tenant/email-templates.d.ts +222 -1
- package/dist/tenant/email-templates.js +227 -10
- package/package.json +2 -2
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { errorForStatus, errorFromErrorResult, isErrorResult, } from '@sixtyninecommerce/core';
|
|
1
|
+
import { errorForStatus, errorFromErrorResult, isErrorResult, ValidationError, } from '@sixtyninecommerce/core';
|
|
2
|
+
import { decodeBase64, MYPARCEL_LABEL_TIMEOUT_MS, } from '../fulfillments/index.js';
|
|
2
3
|
const CONFIG_FIELDS = /* GraphQL */ `
|
|
3
4
|
id
|
|
4
5
|
channelId
|
|
@@ -87,11 +88,138 @@ export const SET_MYPARCEL_SENDER_MUTATION = /* GraphQL */ `
|
|
|
87
88
|
}
|
|
88
89
|
}
|
|
89
90
|
`;
|
|
91
|
+
export const MYPARCEL_SHIPMENT_QUERY = /* GraphQL */ `
|
|
92
|
+
query MyparcelShipment($shipmentId: Int!) {
|
|
93
|
+
myparcelShipment(shipmentId: $shipmentId) {
|
|
94
|
+
id
|
|
95
|
+
referenceIdentifier
|
|
96
|
+
barcode
|
|
97
|
+
status
|
|
98
|
+
carrierId
|
|
99
|
+
created
|
|
100
|
+
modified
|
|
101
|
+
linkConsumerPortal
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
`;
|
|
105
|
+
/** Readiness only: the engine answers no link (it would outlive every check made on it). */
|
|
106
|
+
export const MYPARCEL_LABEL_STATUS_QUERY = /* GraphQL */ `
|
|
107
|
+
query MyparcelLabelStatus($shipmentIds: [Int!]!, $format: MyparcelLabelFormatEnum!) {
|
|
108
|
+
myparcelShipmentLabelUrl(shipmentIds: $shipmentIds, format: $format) {
|
|
109
|
+
status
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
`;
|
|
113
|
+
export const MYPARCEL_SHIPMENT_LABEL_MUTATION = /* GraphQL */ `
|
|
114
|
+
mutation MyparcelShipmentLabel($shipmentId: Int!, $format: MyparcelLabelFormatEnum!) {
|
|
115
|
+
getMyparcelLabel(shipmentId: $shipmentId, format: $format) {
|
|
116
|
+
format
|
|
117
|
+
base64
|
|
118
|
+
contentType
|
|
119
|
+
filename
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
`;
|
|
123
|
+
export const REQUEST_MYPARCEL_LABEL_MUTATION = /* GraphQL */ `
|
|
124
|
+
mutation RequestMyparcelLabel($input: MyparcelRequestLabelInput!) {
|
|
125
|
+
requestMyparcelLabel(input: $input) {
|
|
126
|
+
__typename
|
|
127
|
+
... on MyparcelLabelResult { status }
|
|
128
|
+
... on ErrorResult { errorCode message }
|
|
129
|
+
... on MyparcelValidationError { errors }
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
`;
|
|
133
|
+
export const MYPARCEL_CARRIER_CAPABILITIES_QUERY = /* GraphQL */ `
|
|
134
|
+
query MyparcelCarrierCapabilities {
|
|
135
|
+
myparcelCarrierCapabilities {
|
|
136
|
+
carrierId
|
|
137
|
+
name
|
|
138
|
+
packageTypes
|
|
139
|
+
deliveryTypes
|
|
140
|
+
countries
|
|
141
|
+
supportedOptions
|
|
142
|
+
supportsPickup
|
|
143
|
+
constraints
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
`;
|
|
147
|
+
export const MYPARCEL_DELIVERY_OPTIONS_QUERY = /* GraphQL */ `
|
|
148
|
+
query MyparcelAdminDeliveryOptions($input: MyparcelAdminDeliveryOptionsInput!) {
|
|
149
|
+
myparcelAdminDeliveryOptions(input: $input) {
|
|
150
|
+
__typename
|
|
151
|
+
... on MyparcelAdminDeliveryOptions {
|
|
152
|
+
deliveryOptions {
|
|
153
|
+
deliveryType
|
|
154
|
+
date
|
|
155
|
+
startTime
|
|
156
|
+
endTime
|
|
157
|
+
price { amount currency }
|
|
158
|
+
}
|
|
159
|
+
pickupOptions {
|
|
160
|
+
locationCode
|
|
161
|
+
locationName
|
|
162
|
+
street
|
|
163
|
+
number
|
|
164
|
+
numberSuffix
|
|
165
|
+
postalCode
|
|
166
|
+
city
|
|
167
|
+
countryCode
|
|
168
|
+
carrierId
|
|
169
|
+
distance
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
... on ErrorResult { errorCode message }
|
|
173
|
+
... on MyparcelValidationError { errors }
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
`;
|
|
177
|
+
/**
|
|
178
|
+
* Every member that names fields carries them here, so `myparcelRefusal` can put each in
|
|
179
|
+
* `details[]`. Two members share the `fields` name with one type, which GraphQL allows.
|
|
180
|
+
*/
|
|
181
|
+
const SHIPMENT_REFUSAL_FIELDS = /* GraphQL */ `
|
|
182
|
+
... on ErrorResult { errorCode message }
|
|
183
|
+
... on MyparcelValidationError { errors }
|
|
184
|
+
... on MyparcelInvalidRecipientError { missingFields }
|
|
185
|
+
... on MyparcelInvalidSenderError { fields }
|
|
186
|
+
... on MyparcelPickupLocationInvalidError { fields }
|
|
187
|
+
`;
|
|
188
|
+
export const RECREATE_MYPARCEL_SHIPMENT_MUTATION = /* GraphQL */ `
|
|
189
|
+
mutation RecreateMyparcelShipment($input: MyparcelRecreateShipmentInput!) {
|
|
190
|
+
recreateMyparcelShipment(input: $input) {
|
|
191
|
+
__typename
|
|
192
|
+
... on MyparcelShipmentMutationResult { shipmentId labelFormat }
|
|
193
|
+
${SHIPMENT_REFUSAL_FIELDS}
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
`;
|
|
197
|
+
export const IMPORT_MYPARCEL_SHIPMENT_MUTATION = /* GraphQL */ `
|
|
198
|
+
mutation ImportMyparcelShipment($input: MyparcelImportShipmentInput!) {
|
|
199
|
+
importMyparcelShipment(input: $input) {
|
|
200
|
+
__typename
|
|
201
|
+
... on MyparcelShipmentMutationResult { shipmentId labelFormat }
|
|
202
|
+
... on ErrorResult { errorCode message }
|
|
203
|
+
... on MyparcelValidationError { errors }
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
`;
|
|
207
|
+
export const CREATE_MYPARCEL_RETURN_MUTATION = /* GraphQL */ `
|
|
208
|
+
mutation CreateMyparcelReturnShipment($input: MyparcelReturnShipmentInput!) {
|
|
209
|
+
createMyparcelReturnShipment(input: $input) {
|
|
210
|
+
__typename
|
|
211
|
+
... on MyparcelReturnShipmentResult { shipmentId }
|
|
212
|
+
... on ErrorResult { errorCode message }
|
|
213
|
+
... on MyparcelValidationError { errors }
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
`;
|
|
90
217
|
/** `updateMyparcelConfig` with an empty key answers this member: the set-up is gone. */
|
|
91
218
|
const NOT_CONFIGURED = 'MYPARCEL_NOT_CONFIGURED_ERROR';
|
|
92
219
|
/**
|
|
93
220
|
* A refusal member as its error class, by core's `errorFromErrorResult`. The field names a member
|
|
94
|
-
* carries (`MyparcelInvalidSenderError.fields`, `
|
|
221
|
+
* carries (`MyparcelInvalidSenderError.fields`, `MyparcelPickupLocationInvalidError.fields`,
|
|
222
|
+
* `MyparcelValidationError.errors`, `MyparcelInvalidRecipientError.missingFields`) ride
|
|
95
223
|
* `details[]`, one per field, so a form can mark each without matching the sentence.
|
|
96
224
|
*/
|
|
97
225
|
export function myparcelRefusal(result) {
|
|
@@ -100,7 +228,9 @@ export function myparcelRefusal(result) {
|
|
|
100
228
|
? result.fields
|
|
101
229
|
: Array.isArray(result.errors)
|
|
102
230
|
? result.errors
|
|
103
|
-
:
|
|
231
|
+
: Array.isArray(result.missingFields)
|
|
232
|
+
? result.missingFields
|
|
233
|
+
: [];
|
|
104
234
|
const details = named
|
|
105
235
|
.filter((field) => typeof field === 'string' && field.trim() !== '')
|
|
106
236
|
.map((field) => ({ field, code: base.code, message: base.message }));
|
|
@@ -119,6 +249,62 @@ function settled(answer) {
|
|
|
119
249
|
const { __typename: _typename, ...rest } = answer;
|
|
120
250
|
return rest;
|
|
121
251
|
}
|
|
252
|
+
const LABEL_FORMATS = new Set(['A4', 'A6']);
|
|
253
|
+
function invalidInput(code, field, message) {
|
|
254
|
+
return new ValidationError({
|
|
255
|
+
code,
|
|
256
|
+
message,
|
|
257
|
+
status: 400,
|
|
258
|
+
service: 'vendure',
|
|
259
|
+
details: [{ field, code, message }],
|
|
260
|
+
});
|
|
261
|
+
}
|
|
262
|
+
const LABEL_INPUT_INVALID = 'MYPARCEL_LABEL_INPUT_INVALID';
|
|
263
|
+
/** MyParcel's ids are GraphQL `Int`s: anything else would fail the document, uncoded. */
|
|
264
|
+
function isShipmentId(value) {
|
|
265
|
+
return typeof value === 'number' && Number.isInteger(value) && value > 0 && value <= 2 ** 31 - 1;
|
|
266
|
+
}
|
|
267
|
+
function assertShipmentId(id, field, code) {
|
|
268
|
+
if (!isShipmentId(id)) {
|
|
269
|
+
throw invalidInput(code, field, `A MyParcel shipment id is a positive whole number; got ${JSON.stringify(id)}.`);
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
/** Refused before any request: the engine's enum would refuse it, uncoded. */
|
|
273
|
+
function assertLabelFormat(format) {
|
|
274
|
+
if (!LABEL_FORMATS.has(format)) {
|
|
275
|
+
throw invalidInput(LABEL_INPUT_INVALID, 'format', `format must be 'A4' or 'A6'; got ${JSON.stringify(format)}.`);
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
const INVALID_INPUT = 'INVALID_INPUT';
|
|
279
|
+
function assertFulfillmentId(id) {
|
|
280
|
+
if (typeof id !== 'string' || id.trim() === '') {
|
|
281
|
+
throw invalidInput(INVALID_INPUT, 'fulfillmentId', 'A fulfillment id is required.');
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
/** A non-blank string, trimmed; refused before any request otherwise. */
|
|
285
|
+
function requiredText(value, field) {
|
|
286
|
+
const text = typeof value === 'string' ? value.trim() : '';
|
|
287
|
+
if (text === '')
|
|
288
|
+
throw invalidInput(INVALID_INPUT, field, `${field} is required.`);
|
|
289
|
+
return text;
|
|
290
|
+
}
|
|
291
|
+
/** The handler arguments as the wire takes them; anything else would fail the document uncoded. */
|
|
292
|
+
function handlerArgumentsOf(raw) {
|
|
293
|
+
if (!Array.isArray(raw)) {
|
|
294
|
+
throw invalidInput(INVALID_INPUT, 'handlerArguments', 'handlerArguments must be a list of { name, value } strings.');
|
|
295
|
+
}
|
|
296
|
+
return raw.map((entry, index) => {
|
|
297
|
+
const { name, value } = (entry ?? {});
|
|
298
|
+
if (typeof name !== 'string' || name.trim() === '' || typeof value !== 'string') {
|
|
299
|
+
throw invalidInput(INVALID_INPUT, `handlerArguments[${String(index)}]`, 'Each handler argument is a { name, value } pair of strings, with a name.');
|
|
300
|
+
}
|
|
301
|
+
return { name, value };
|
|
302
|
+
});
|
|
303
|
+
}
|
|
304
|
+
/** `ready` only when the engine says so: any other answer is a label still being made. */
|
|
305
|
+
function readiness(status) {
|
|
306
|
+
return { status: status === 'ready' ? 'ready' : 'pending' };
|
|
307
|
+
}
|
|
122
308
|
export function createMyparcelModule(transport) {
|
|
123
309
|
const gql = (query, variables, options) => transport.graphql({ api: 'admin', query, variables }, options);
|
|
124
310
|
return {
|
|
@@ -164,6 +350,16 @@ export function createMyparcelModule(transport) {
|
|
|
164
350
|
const data = await gql(MYPARCEL_CARRIERS_QUERY, {}, options);
|
|
165
351
|
return data.myparcelCarriers;
|
|
166
352
|
},
|
|
353
|
+
async carrierCapabilities(options) {
|
|
354
|
+
const data = await gql(MYPARCEL_CARRIER_CAPABILITIES_QUERY, {}, options);
|
|
355
|
+
return data.myparcelCarrierCapabilities;
|
|
356
|
+
},
|
|
357
|
+
async deliveryOptions(input, options) {
|
|
358
|
+
const postalCode = requiredText(input?.postalCode, 'postalCode');
|
|
359
|
+
const data = await gql(MYPARCEL_DELIVERY_OPTIONS_QUERY, { input: { ...input, postalCode } }, options);
|
|
360
|
+
const { deliveryOptions, pickupOptions } = settled(data.myparcelAdminDeliveryOptions);
|
|
361
|
+
return { deliveryOptions, pickupOptions };
|
|
362
|
+
},
|
|
167
363
|
senders: {
|
|
168
364
|
async list(options) {
|
|
169
365
|
const data = await gql(MYPARCEL_SENDERS_QUERY, {}, options);
|
|
@@ -174,5 +370,97 @@ export function createMyparcelModule(transport) {
|
|
|
174
370
|
return settled(data.setStockLocationSender);
|
|
175
371
|
},
|
|
176
372
|
},
|
|
373
|
+
shipments: {
|
|
374
|
+
async get(shipmentId, options) {
|
|
375
|
+
assertShipmentId(shipmentId, 'shipmentId', 'INVALID_INPUT');
|
|
376
|
+
const data = await gql(MYPARCEL_SHIPMENT_QUERY, { shipmentId }, options);
|
|
377
|
+
const shipment = data.myparcelShipment;
|
|
378
|
+
if (!shipment)
|
|
379
|
+
return null;
|
|
380
|
+
return {
|
|
381
|
+
id: shipment.id,
|
|
382
|
+
referenceIdentifier: shipment.referenceIdentifier ?? null,
|
|
383
|
+
barcode: shipment.barcode ?? null,
|
|
384
|
+
status: shipment.status,
|
|
385
|
+
carrierId: shipment.carrierId,
|
|
386
|
+
created: shipment.created,
|
|
387
|
+
modified: shipment.modified,
|
|
388
|
+
linkConsumerPortal: shipment.linkConsumerPortal ?? null,
|
|
389
|
+
};
|
|
390
|
+
},
|
|
391
|
+
async recreate(input, options) {
|
|
392
|
+
assertFulfillmentId(input?.fulfillmentId);
|
|
393
|
+
const handlerArguments = handlerArgumentsOf(input.handlerArguments);
|
|
394
|
+
const data = await gql(RECREATE_MYPARCEL_SHIPMENT_MUTATION, { input: { fulfillmentId: input.fulfillmentId, handlerArguments } }, options);
|
|
395
|
+
const { shipmentId, labelFormat } = settled(data.recreateMyparcelShipment);
|
|
396
|
+
return { shipmentId, labelFormat };
|
|
397
|
+
},
|
|
398
|
+
async import(input, options) {
|
|
399
|
+
assertFulfillmentId(input?.fulfillmentId);
|
|
400
|
+
assertShipmentId(input.shipmentId, 'shipmentId', INVALID_INPUT);
|
|
401
|
+
const data = await gql(IMPORT_MYPARCEL_SHIPMENT_MUTATION, { input: { fulfillmentId: input.fulfillmentId, shipmentId: input.shipmentId } }, options);
|
|
402
|
+
const { shipmentId, labelFormat } = settled(data.importMyparcelShipment);
|
|
403
|
+
return { shipmentId, labelFormat };
|
|
404
|
+
},
|
|
405
|
+
},
|
|
406
|
+
returns: {
|
|
407
|
+
async create(input, options) {
|
|
408
|
+
assertShipmentId(input?.parentShipmentId, 'parentShipmentId', INVALID_INPUT);
|
|
409
|
+
if (!isShipmentId(input.carrier)) {
|
|
410
|
+
throw invalidInput(INVALID_INPUT, 'carrier', `A MyParcel carrier id is a positive whole number; got ${JSON.stringify(input.carrier)}.`);
|
|
411
|
+
}
|
|
412
|
+
const name = requiredText(input.name, 'name');
|
|
413
|
+
const email = requiredText(input.email, 'email');
|
|
414
|
+
const data = await gql(CREATE_MYPARCEL_RETURN_MUTATION, {
|
|
415
|
+
input: {
|
|
416
|
+
parentShipmentId: input.parentShipmentId,
|
|
417
|
+
carrier: input.carrier,
|
|
418
|
+
name,
|
|
419
|
+
email,
|
|
420
|
+
},
|
|
421
|
+
}, options);
|
|
422
|
+
return { shipmentId: settled(data.createMyparcelReturnShipment).shipmentId };
|
|
423
|
+
},
|
|
424
|
+
},
|
|
425
|
+
labels: {
|
|
426
|
+
async status(shipmentIds, format, options) {
|
|
427
|
+
const ids = Array.isArray(shipmentIds) ? [...shipmentIds] : [];
|
|
428
|
+
if (ids.length === 0) {
|
|
429
|
+
throw invalidInput(LABEL_INPUT_INVALID, 'shipmentIds', 'Name at least one shipment.');
|
|
430
|
+
}
|
|
431
|
+
for (const [index, id] of ids.entries()) {
|
|
432
|
+
assertShipmentId(id, `shipmentIds[${String(index)}]`, LABEL_INPUT_INVALID);
|
|
433
|
+
}
|
|
434
|
+
assertLabelFormat(format);
|
|
435
|
+
const data = await gql(MYPARCEL_LABEL_STATUS_QUERY, { shipmentIds: ids, format },
|
|
436
|
+
// The engine retries a slow MyParcel on this read as on the download.
|
|
437
|
+
{ timeoutMs: MYPARCEL_LABEL_TIMEOUT_MS, ...options });
|
|
438
|
+
return readiness(data.myparcelShipmentLabelUrl?.status);
|
|
439
|
+
},
|
|
440
|
+
async download(shipmentId, format, options) {
|
|
441
|
+
assertShipmentId(shipmentId, 'shipmentId', LABEL_INPUT_INVALID);
|
|
442
|
+
assertLabelFormat(format);
|
|
443
|
+
const data = await gql(MYPARCEL_SHIPMENT_LABEL_MUTATION, { shipmentId, format }, { timeoutMs: MYPARCEL_LABEL_TIMEOUT_MS, ...options });
|
|
444
|
+
const { base64, ...document } = data.getMyparcelLabel;
|
|
445
|
+
return {
|
|
446
|
+
format: document.format,
|
|
447
|
+
contentType: document.contentType,
|
|
448
|
+
filename: document.filename,
|
|
449
|
+
bytes: decodeBase64(base64),
|
|
450
|
+
};
|
|
451
|
+
},
|
|
452
|
+
async request(input, options) {
|
|
453
|
+
const fulfillmentId = input?.fulfillmentId;
|
|
454
|
+
if (typeof fulfillmentId !== 'string' || fulfillmentId.trim() === '') {
|
|
455
|
+
throw invalidInput(LABEL_INPUT_INVALID, 'fulfillmentId', 'A fulfillment id is required.');
|
|
456
|
+
}
|
|
457
|
+
assertShipmentId(input.shipmentId, 'shipmentId', LABEL_INPUT_INVALID);
|
|
458
|
+
assertLabelFormat(input.format);
|
|
459
|
+
const data = await gql(REQUEST_MYPARCEL_LABEL_MUTATION, {
|
|
460
|
+
input: { fulfillmentId, shipmentId: input.shipmentId, format: input.format },
|
|
461
|
+
}, options);
|
|
462
|
+
return readiness(settled(data.requestMyparcelLabel).status);
|
|
463
|
+
},
|
|
464
|
+
},
|
|
177
465
|
};
|
|
178
466
|
}
|
|
@@ -41,7 +41,10 @@ export interface RateTableRate {
|
|
|
41
41
|
minWeightGrams: number;
|
|
42
42
|
/** Exclusive: the tier covers weights from its start up to, not including, this. */
|
|
43
43
|
maxWeightGrams: number;
|
|
44
|
-
/**
|
|
44
|
+
/**
|
|
45
|
+
* In minor units: hundredths of {@link currencyCode} for EVERY currency, as the platform stores
|
|
46
|
+
* all money (€6.95 is 695, ¥1,200 is 120000). In the tax basis the method's calculator says.
|
|
47
|
+
*/
|
|
45
48
|
price: number;
|
|
46
49
|
/** ISO 4217. */
|
|
47
50
|
currencyCode: string;
|
|
@@ -92,6 +95,140 @@ export interface UpdateRateTableInput {
|
|
|
92
95
|
defaultWeightGrams?: number | null;
|
|
93
96
|
enabled?: boolean;
|
|
94
97
|
}
|
|
98
|
+
/** How a zone matches an address. See {@link RateTableZone.type}. */
|
|
99
|
+
export type RateTableZoneType = 'domestic' | 'international';
|
|
100
|
+
/** A new zone, as {@link RateTableZonesModule.create} takes it. It starts with no members or rates. */
|
|
101
|
+
export interface CreateRateTableZoneInput {
|
|
102
|
+
/** Trimmed; at most 255 characters. */
|
|
103
|
+
name: string;
|
|
104
|
+
type: RateTableZoneType;
|
|
105
|
+
/**
|
|
106
|
+
* Left out: after the table's last zone. A position another zone of the table holds is
|
|
107
|
+
* refused (`SHIPPING_ZONE_POSITION_TAKEN`); {@link RateTableZonesModule.reorder} moves zones.
|
|
108
|
+
*/
|
|
109
|
+
position?: number;
|
|
110
|
+
}
|
|
111
|
+
/** A change to a zone: a field left out keeps what the zone has. */
|
|
112
|
+
export interface UpdateRateTableZoneInput {
|
|
113
|
+
name?: string;
|
|
114
|
+
/** Refused while the zone has members, which a zone of the other type would never match. */
|
|
115
|
+
type?: RateTableZoneType;
|
|
116
|
+
/** Refused (`SHIPPING_ZONE_POSITION_TAKEN`) when another zone of the table holds it. */
|
|
117
|
+
position?: number;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* One place a zone matches, as {@link RateTableZonesModule.setMembers} takes it: a domestic
|
|
121
|
+
* zone's member is a postal-code range (no country), an international zone's a country (no
|
|
122
|
+
* postal codes).
|
|
123
|
+
*/
|
|
124
|
+
export interface RateTableZoneMemberInput {
|
|
125
|
+
/** ISO 3166-1 alpha-2. */
|
|
126
|
+
countryCode?: string | null;
|
|
127
|
+
/** The leading digits of a postal code, start of the range. */
|
|
128
|
+
postalCodeFrom?: string | null;
|
|
129
|
+
/** End of the range, inclusive. */
|
|
130
|
+
postalCodeTo?: string | null;
|
|
131
|
+
}
|
|
132
|
+
/** One weight tier, as {@link RateTableZonesModule.setRates} takes it. */
|
|
133
|
+
export interface RateTableRateInput {
|
|
134
|
+
/** Inclusive, in grams. */
|
|
135
|
+
minWeightGrams: number;
|
|
136
|
+
/** Exclusive, in grams. */
|
|
137
|
+
maxWeightGrams: number;
|
|
138
|
+
/** In minor units, as {@link RateTableRate.price}: hundredths for every currency. */
|
|
139
|
+
price: number;
|
|
140
|
+
/** ISO 4217. */
|
|
141
|
+
currencyCode: string;
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* `admin.shipping.rateTables.zones`: the zones of the store's rate tables, their members and
|
|
145
|
+
* their rates. A table or zone of another store is refused as not found (`ENTITY_NOT_FOUND`; a
|
|
146
|
+
* zone delete `SHIPPING_ZONE_NOT_DELETED`), whatever its id, as a missing one is.
|
|
147
|
+
*
|
|
148
|
+
* Besides {@link RateTablesModule}'s `SHIPPING_ZONE_INPUT_INVALID` (here with pointers such as
|
|
149
|
+
* `/input/type`, `/members/0/postalCodeTo`, `/rates/1/maxWeightGrams` or `/zoneIds/2`, and the
|
|
150
|
+
* rules `enum`, `pattern`, `not`, `exclusiveMinimum`, `uniqueItems` and `overlap`), the doors
|
|
151
|
+
* refuse:
|
|
152
|
+
*
|
|
153
|
+
* - `SHIPPING_ZONE_POSITION_TAKEN` (`ConflictError`, 409, on `/input/position`): another zone of
|
|
154
|
+
* the table is at the position. Zones are matched in position order, first match wins.
|
|
155
|
+
* - `SHIPPING_ZONE_IN_USE` (`BusinessRuleError`, 422): deleting the last zone of a table a
|
|
156
|
+
* shipping method of this store prices with, which would make it quote nothing. The message
|
|
157
|
+
* names the methods.
|
|
158
|
+
*
|
|
159
|
+
* Every write runs in one transaction: a refused write changes nothing, and a replace
|
|
160
|
+
* (`setMembers`, `setRates`) refused keeps the zone's previous members or rates.
|
|
161
|
+
*/
|
|
162
|
+
export interface RateTableZonesModule {
|
|
163
|
+
/**
|
|
164
|
+
* Add a zone to the store's rate table `tableId`, and answer it as {@link RateTablesModule.get}
|
|
165
|
+
* reads a zone. Refused `SHIPPING_ZONE_INPUT_INVALID` (a blank or too long name, a type other
|
|
166
|
+
* than `domestic` or `international`, a negative position), `SHIPPING_ZONE_POSITION_TAKEN`, or
|
|
167
|
+
* `ENTITY_NOT_FOUND` for a table the store does not have.
|
|
168
|
+
*
|
|
169
|
+
* @effect write
|
|
170
|
+
* @permission UpdateSettings
|
|
171
|
+
*/
|
|
172
|
+
create(tableId: string, input: CreateRateTableZoneInput, options?: Call): Promise<RateTableZone>;
|
|
173
|
+
/**
|
|
174
|
+
* Change a zone, and answer it as {@link RateTablesModule.get} reads a zone. Refused as
|
|
175
|
+
* {@link create} is, for `null` on a field (none can be cleared), for a type change while the
|
|
176
|
+
* zone has members, or `ENTITY_NOT_FOUND`.
|
|
177
|
+
*
|
|
178
|
+
* @effect write
|
|
179
|
+
* @permission UpdateSettings
|
|
180
|
+
*/
|
|
181
|
+
update(zoneId: string, patch: UpdateRateTableZoneInput, options?: Call): Promise<RateTableZone>;
|
|
182
|
+
/**
|
|
183
|
+
* Delete a zone with its members and rates. Refused `SHIPPING_ZONE_IN_USE` for the last zone of
|
|
184
|
+
* a table a shipping method of this store prices with.
|
|
185
|
+
*
|
|
186
|
+
* The engine answers a zone the store does not have (a missing, malformed or another store's
|
|
187
|
+
* id, or one already deleted) as a result rather than an error; this SDK raises it as
|
|
188
|
+
* `SHIPPING_ZONE_NOT_DELETED` (`ConflictError`, 409) with the engine's reason.
|
|
189
|
+
*
|
|
190
|
+
* @effect destructive
|
|
191
|
+
* @permission UpdateSettings
|
|
192
|
+
*/
|
|
193
|
+
delete(zoneId: string, options?: Call): Promise<void>;
|
|
194
|
+
/**
|
|
195
|
+
* Put the zones of table `tableId` in the order given; each takes its index as its position.
|
|
196
|
+
* The list names EVERY zone of the table exactly once: one listed twice, or one left out, is
|
|
197
|
+
* refused `SHIPPING_ZONE_INPUT_INVALID` (`uniqueItems` on `/zoneIds/<i>`, `required` on
|
|
198
|
+
* `/zoneIds`), and an id that is not a zone of this table `ENTITY_NOT_FOUND`. Answers the zones
|
|
199
|
+
* in their new order.
|
|
200
|
+
*
|
|
201
|
+
* @effect write
|
|
202
|
+
* @permission UpdateSettings
|
|
203
|
+
*/
|
|
204
|
+
reorder(tableId: string, zoneIds: string[], options?: Call): Promise<RateTableZone[]>;
|
|
205
|
+
/**
|
|
206
|
+
* Replace the zone's members with `members`, and answer them as stored (in the order sent,
|
|
207
|
+
* trimmed, the country upper-cased). Refused `SHIPPING_ZONE_INPUT_INVALID` per member, on `/members/<i>/<field>`:
|
|
208
|
+
* a member the zone's type would never match (`not`), a range missing an end (`required`), a
|
|
209
|
+
* postal code that is not digits (`pattern`), a range that ends before it starts (`minimum`), a
|
|
210
|
+
* country that is not two letters (`pattern`).
|
|
211
|
+
*
|
|
212
|
+
* @effect write
|
|
213
|
+
* @permission UpdateSettings
|
|
214
|
+
*/
|
|
215
|
+
setMembers(zoneId: string, members: RateTableZoneMemberInput[], options?: Call): Promise<RateTableZoneMember[]>;
|
|
216
|
+
/**
|
|
217
|
+
* Replace the zone's weight tiers with `rates`, and answer them as stored (in the order sent,
|
|
218
|
+
* the currency trimmed and upper-cased; {@link RateTablesModule.get} reads them in start-weight
|
|
219
|
+
* order). What every customer whose order the zone prices pays from the next quote on.
|
|
220
|
+
*
|
|
221
|
+
* Refused `SHIPPING_ZONE_INPUT_INVALID` per tier, on `/rates/<i>/<field>`: a negative weight or
|
|
222
|
+
* price (`minimum`), a tier that ends at or before its start (`exclusiveMinimum`), a currency
|
|
223
|
+
* that is not ISO 4217 (`enum`), and, within one currency, two tiers with the same start
|
|
224
|
+
* (`uniqueItems`) or sharing weights (`overlap`). Gaps are allowed: a weight in a gap gets no
|
|
225
|
+
* quote.
|
|
226
|
+
*
|
|
227
|
+
* @effect money
|
|
228
|
+
* @permission UpdateSettings
|
|
229
|
+
*/
|
|
230
|
+
setRates(zoneId: string, rates: RateTableRateInput[], options?: Call): Promise<RateTableRate[]>;
|
|
231
|
+
}
|
|
95
232
|
/**
|
|
96
233
|
* `admin.shipping.rateTables`: the store's weight-zone rate tables (headless spec §9.2
|
|
97
234
|
* `shipping`, "zones, calculator config"). Scoped to the store the client is on: another
|
|
@@ -170,10 +307,18 @@ export interface RateTablesModule {
|
|
|
170
307
|
* @permission UpdateSettings
|
|
171
308
|
*/
|
|
172
309
|
delete(id: string, options?: Call): Promise<void>;
|
|
310
|
+
/** The zones of the store's tables, their members and their rates. */
|
|
311
|
+
zones: RateTableZonesModule;
|
|
173
312
|
}
|
|
174
313
|
export declare const RATE_TABLES_QUERY = "\n query StoreRateTables {\n shippingZoneConfigs { \n id\n name\n volumetricDivisor\n defaultWeightGrams\n enabled\n createdAt\n updatedAt\n }\n }\n";
|
|
175
|
-
export declare const RATE_TABLE_QUERY = "\n query StoreRateTable($id: ID!) {\n shippingZoneConfig(id: $id) { \n \n id\n name\n volumetricDivisor\n defaultWeightGrams\n enabled\n createdAt\n updatedAt\n\n zones {\n
|
|
176
|
-
export declare const CREATE_RATE_TABLE_MUTATION = "\n mutation CreateStoreRateTable($input: CreateShippingZoneConfigInput!) {\n createShippingZoneConfig(input: $input) { \n \n id\n name\n volumetricDivisor\n defaultWeightGrams\n enabled\n createdAt\n updatedAt\n\n zones {\n
|
|
177
|
-
export declare const UPDATE_RATE_TABLE_MUTATION = "\n mutation UpdateStoreRateTable($id: ID!, $input: UpdateShippingZoneConfigInput!) {\n updateShippingZoneConfig(id: $id, input: $input) { \n \n id\n name\n volumetricDivisor\n defaultWeightGrams\n enabled\n createdAt\n updatedAt\n\n zones {\n
|
|
314
|
+
export declare const RATE_TABLE_QUERY = "\n query StoreRateTable($id: ID!) {\n shippingZoneConfig(id: $id) { \n \n id\n name\n volumetricDivisor\n defaultWeightGrams\n enabled\n createdAt\n updatedAt\n\n zones { \n id\n name\n type\n position\n members { \n id\n countryCode\n postalCodeFrom\n postalCodeTo\n }\n rates { \n id\n minWeightGrams\n maxWeightGrams\n price\n currencyCode\n }\n createdAt\n updatedAt\n }\n }\n }\n";
|
|
315
|
+
export declare const CREATE_RATE_TABLE_MUTATION = "\n mutation CreateStoreRateTable($input: CreateShippingZoneConfigInput!) {\n createShippingZoneConfig(input: $input) { \n \n id\n name\n volumetricDivisor\n defaultWeightGrams\n enabled\n createdAt\n updatedAt\n\n zones { \n id\n name\n type\n position\n members { \n id\n countryCode\n postalCodeFrom\n postalCodeTo\n }\n rates { \n id\n minWeightGrams\n maxWeightGrams\n price\n currencyCode\n }\n createdAt\n updatedAt\n }\n }\n }\n";
|
|
316
|
+
export declare const UPDATE_RATE_TABLE_MUTATION = "\n mutation UpdateStoreRateTable($id: ID!, $input: UpdateShippingZoneConfigInput!) {\n updateShippingZoneConfig(id: $id, input: $input) { \n \n id\n name\n volumetricDivisor\n defaultWeightGrams\n enabled\n createdAt\n updatedAt\n\n zones { \n id\n name\n type\n position\n members { \n id\n countryCode\n postalCodeFrom\n postalCodeTo\n }\n rates { \n id\n minWeightGrams\n maxWeightGrams\n price\n currencyCode\n }\n createdAt\n updatedAt\n }\n }\n }\n";
|
|
178
317
|
export declare const DELETE_RATE_TABLE_MUTATION = "\n mutation DeleteStoreRateTable($id: ID!) {\n deleteShippingZoneConfig(id: $id) {\n result\n message\n }\n }\n";
|
|
318
|
+
export declare const CREATE_RATE_TABLE_ZONE_MUTATION = "\n mutation CreateStoreRateTableZone($configId: ID!, $input: CreateShippingZoneInput!) {\n createShippingZone(configId: $configId, input: $input) { \n id\n name\n type\n position\n members { \n id\n countryCode\n postalCodeFrom\n postalCodeTo\n }\n rates { \n id\n minWeightGrams\n maxWeightGrams\n price\n currencyCode\n }\n createdAt\n updatedAt\n }\n }\n";
|
|
319
|
+
export declare const UPDATE_RATE_TABLE_ZONE_MUTATION = "\n mutation UpdateStoreRateTableZone($id: ID!, $input: UpdateShippingZoneInput!) {\n updateShippingZone(id: $id, input: $input) { \n id\n name\n type\n position\n members { \n id\n countryCode\n postalCodeFrom\n postalCodeTo\n }\n rates { \n id\n minWeightGrams\n maxWeightGrams\n price\n currencyCode\n }\n createdAt\n updatedAt\n }\n }\n";
|
|
320
|
+
export declare const DELETE_RATE_TABLE_ZONE_MUTATION = "\n mutation DeleteStoreRateTableZone($id: ID!) {\n deleteShippingZone(id: $id) {\n result\n message\n }\n }\n";
|
|
321
|
+
export declare const REORDER_RATE_TABLE_ZONES_MUTATION = "\n mutation ReorderStoreRateTableZones($configId: ID!, $zoneIds: [ID!]!) {\n reorderShippingZones(configId: $configId, zoneIds: $zoneIds) { \n id\n name\n type\n position\n members { \n id\n countryCode\n postalCodeFrom\n postalCodeTo\n }\n rates { \n id\n minWeightGrams\n maxWeightGrams\n price\n currencyCode\n }\n createdAt\n updatedAt\n }\n }\n";
|
|
322
|
+
export declare const SET_RATE_TABLE_ZONE_MEMBERS_MUTATION = "\n mutation SetStoreRateTableZoneMembers($zoneId: ID!, $members: [ShippingZoneMemberInput!]!) {\n setShippingZoneMembers(zoneId: $zoneId, members: $members) { \n id\n countryCode\n postalCodeFrom\n postalCodeTo\n }\n }\n";
|
|
323
|
+
export declare const SET_RATE_TABLE_ZONE_RATES_MUTATION = "\n mutation SetStoreRateTableZoneRates($zoneId: ID!, $rates: [ShippingRateInput!]!) {\n setShippingRates(zoneId: $zoneId, rates: $rates) { \n id\n minWeightGrams\n maxWeightGrams\n price\n currencyCode\n }\n }\n";
|
|
179
324
|
export declare function createRateTablesModule(transport: Transport): RateTablesModule;
|