@sixtyninecommerce/admin 0.8.0 → 0.10.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 +2739 -17
- package/dist/api-tokens/index.d.ts +15 -5
- package/dist/api-tokens/index.js +1 -0
- package/dist/apps/event-subscription.d.ts +59 -0
- package/dist/apps/event-subscription.js +32 -0
- package/dist/apps/hook-secret.d.ts +22 -0
- package/dist/apps/hook-secret.js +36 -0
- package/dist/apps/index.d.ts +54 -3
- package/dist/apps/index.js +17 -0
- package/dist/audit/index.d.ts +7 -0
- package/dist/auth/queries.d.ts +5 -1
- package/dist/auth/queries.js +6 -0
- package/dist/bulk/index.d.ts +323 -0
- package/dist/bulk/index.js +162 -0
- package/dist/catalog/assets.d.ts +147 -0
- package/dist/catalog/assets.js +164 -0
- package/dist/catalog/collections.d.ts +109 -0
- package/dist/catalog/collections.js +91 -0
- package/dist/catalog/facets.d.ts +103 -0
- package/dist/catalog/facets.js +100 -0
- package/dist/catalog/index.d.ts +115 -0
- package/dist/catalog/index.js +21 -0
- package/dist/catalog/options.d.ts +89 -0
- package/dist/catalog/options.js +88 -0
- package/dist/catalog/products-bulk.d.ts +21 -0
- package/dist/catalog/products-bulk.js +58 -0
- package/dist/catalog/products.d.ts +650 -0
- package/dist/catalog/products.js +458 -0
- package/dist/catalog/properties.d.ts +234 -0
- package/dist/catalog/properties.js +158 -0
- package/dist/catalog/types.d.ts +174 -0
- package/dist/catalog/types.js +141 -0
- package/dist/catalog/variants.d.ts +324 -0
- package/dist/catalog/variants.js +288 -0
- package/dist/catalog/visibility.d.ts +57 -0
- package/dist/catalog/visibility.js +59 -0
- package/dist/client.d.ts +192 -3
- package/dist/client.js +87 -12
- package/dist/compliance/index.d.ts +88 -0
- package/dist/compliance/index.js +88 -0
- package/dist/customer-data-redaction.d.ts +14 -0
- package/dist/customer-data-redaction.js +22 -0
- package/dist/customers/index.d.ts +428 -17
- package/dist/customers/index.js +322 -15
- package/dist/documents/index.d.ts +513 -16
- package/dist/documents/index.js +229 -3
- package/dist/events/index.d.ts +259 -0
- package/dist/events/index.js +147 -0
- package/dist/feeds/ai.d.ts +46 -0
- package/dist/feeds/ai.js +43 -0
- package/dist/feeds/categories.d.ts +50 -0
- package/dist/feeds/categories.js +56 -0
- package/dist/feeds/configs.d.ts +54 -0
- package/dist/feeds/configs.js +85 -0
- package/dist/feeds/identifier-fields.d.ts +25 -0
- package/dist/feeds/identifier-fields.js +29 -0
- package/dist/feeds/index.d.ts +54 -0
- package/dist/feeds/index.js +46 -0
- package/dist/feeds/preserve.d.ts +38 -0
- package/dist/feeds/preserve.js +74 -0
- package/dist/feeds/rules.d.ts +42 -0
- package/dist/feeds/rules.js +56 -0
- package/dist/feeds/types.d.ts +654 -0
- package/dist/feeds/types.js +135 -0
- package/dist/fulfillments/index.d.ts +437 -0
- package/dist/fulfillments/index.js +534 -0
- package/dist/heads/index.d.ts +60 -0
- package/dist/heads/index.js +45 -0
- package/dist/hooks/assignments.d.ts +90 -0
- package/dist/hooks/assignments.js +53 -0
- package/dist/hooks/index.d.ts +97 -0
- package/dist/hooks/index.js +76 -0
- package/dist/index.d.ts +95 -9
- package/dist/index.js +21 -1
- package/dist/integrations/index.d.ts +14 -0
- package/dist/integrations/index.js +9 -0
- package/dist/integrations/pipelines.d.ts +113 -0
- package/dist/integrations/pipelines.js +62 -0
- package/dist/integrations/types.d.ts +176 -0
- package/dist/integrations/types.js +8 -0
- package/dist/jobs/bulk-action-run.d.ts +74 -0
- package/dist/jobs/bulk-action-run.js +69 -0
- package/dist/locations/index.d.ts +6 -2
- package/dist/meta/index.d.ts +32 -0
- package/dist/orders/bulk.d.ts +75 -0
- package/dist/orders/bulk.js +150 -0
- package/dist/orders/commit-edit.d.ts +123 -0
- package/dist/orders/commit-edit.js +142 -0
- package/dist/orders/deposit-policy.d.ts +103 -0
- package/dist/orders/deposit-policy.js +202 -0
- package/dist/orders/get.d.ts +722 -0
- package/dist/orders/get.js +530 -0
- package/dist/orders/index.d.ts +186 -21
- package/dist/orders/index.js +57 -0
- package/dist/orders/line-price-preview.d.ts +297 -0
- package/dist/orders/line-price-preview.js +50 -0
- package/dist/orders/manual-discounts.d.ts +141 -0
- package/dist/orders/manual-discounts.js +97 -0
- package/dist/orders/manual-pricing.d.ts +192 -0
- package/dist/orders/manual-pricing.js +72 -0
- package/dist/orders/order-entry.d.ts +566 -0
- package/dist/orders/order-entry.js +129 -0
- package/dist/orders/parcel-charge.d.ts +45 -0
- package/dist/orders/parcel-charge.js +55 -0
- package/dist/orders/plan-edit.d.ts +489 -0
- package/dist/orders/plan-edit.js +93 -0
- package/dist/orders/status.d.ts +235 -0
- package/dist/orders/status.js +96 -0
- package/dist/orders/surcharges.d.ts +75 -2
- package/dist/orders/surcharges.js +110 -4
- package/dist/payments/account-credit.d.ts +171 -0
- package/dist/payments/account-credit.js +107 -0
- package/dist/payments/index.d.ts +241 -9
- package/dist/payments/index.js +92 -0
- package/dist/payments/methods.d.ts +37 -0
- package/dist/payments/methods.js +33 -0
- package/dist/platform/catalog.d.ts +148 -0
- package/dist/platform/catalog.js +74 -0
- package/dist/platform/entitlements.d.ts +111 -0
- package/dist/platform/entitlements.js +86 -0
- package/dist/platform/legal-entities.d.ts +139 -0
- package/dist/platform/legal-entities.js +126 -0
- package/dist/platform/legal-entity-numbering.d.ts +103 -0
- package/dist/platform/legal-entity-numbering.js +101 -0
- package/dist/platform/organization-membership.d.ts +80 -0
- package/dist/platform/organization-membership.js +71 -0
- package/dist/platform/organization-settings.d.ts +33 -0
- package/dist/platform/organization-settings.js +42 -0
- package/dist/platform/organization-sharing.d.ts +172 -0
- package/dist/platform/organization-sharing.js +120 -0
- package/dist/platform/organizations.d.ts +205 -0
- package/dist/platform/organizations.js +180 -0
- package/dist/platform/provision-store.d.ts +88 -8
- package/dist/platform/provision-store.js +12 -0
- package/dist/platform/reports.d.ts +46 -0
- package/dist/platform/reports.js +31 -0
- package/dist/platform/server-metrics.d.ts +58 -0
- package/dist/platform/server-metrics.js +11 -0
- package/dist/pos/index.d.ts +567 -0
- package/dist/pos/index.js +205 -0
- package/dist/pricing/index.d.ts +408 -0
- package/dist/pricing/index.js +353 -0
- package/dist/pricing/vouchers.d.ts +103 -0
- package/dist/pricing/vouchers.js +69 -0
- package/dist/provenance/index.d.ts +93 -0
- package/dist/provenance/index.js +53 -0
- package/dist/reports/index.d.ts +199 -0
- package/dist/reports/index.js +154 -0
- package/dist/returns/index.d.ts +225 -0
- package/dist/returns/index.js +160 -0
- package/dist/search/index.d.ts +99 -0
- package/dist/search/index.js +62 -0
- package/dist/shipping/parcel-count-suggestion.d.ts +52 -0
- package/dist/shipping/parcel-count-suggestion.js +73 -0
- package/dist/shipping/parcel-rule.d.ts +48 -0
- package/dist/shipping/parcel-rule.js +91 -0
- package/dist/stock/index.d.ts +166 -0
- package/dist/stock/index.js +115 -0
- package/dist/stock/transfers.d.ts +520 -0
- package/dist/stock/transfers.js +437 -0
- package/dist/stored-value/index.d.ts +154 -0
- package/dist/stored-value/index.js +130 -0
- package/dist/tenant/capabilities.d.ts +10 -0
- package/dist/tenant/entitlements.d.ts +35 -0
- package/dist/tenant/entitlements.js +15 -0
- package/dist/tenant/field-groups.d.ts +64 -0
- package/dist/tenant/field-groups.js +34 -0
- package/dist/tenant/legal-entity.d.ts +32 -0
- package/dist/tenant/legal-entity.js +41 -0
- package/dist/tenant/notifications.d.ts +148 -0
- package/dist/tenant/notifications.js +79 -0
- package/dist/tenant/retention.d.ts +10 -4
- package/dist/tenant/settings-sources.d.ts +103 -0
- package/dist/tenant/settings-sources.js +92 -0
- package/dist/types.d.ts +86 -11
- package/dist/uploads/index.d.ts +11 -7
- package/dist/users/index.d.ts +104 -0
- package/dist/users/index.js +80 -0
- package/package.json +3 -2
|
@@ -0,0 +1,534 @@
|
|
|
1
|
+
import { errorFromErrorResult, isErrorResult, NotFoundError, ValidationError, } from '@sixtyninecommerce/core';
|
|
2
|
+
/** The longest override reason the engine stores. */
|
|
3
|
+
export const FULFILLMENT_COVERAGE_REASON_MAX_LENGTH = 500;
|
|
4
|
+
/** Every field of `OrderOverpaymentOption`. */
|
|
5
|
+
const OVERPAYMENT_OPTION_FIELDS = /* GraphQL */ `
|
|
6
|
+
available
|
|
7
|
+
code
|
|
8
|
+
message
|
|
9
|
+
`;
|
|
10
|
+
/**
|
|
11
|
+
* Its own document, like every call here: on an engine without the query this call alone fails
|
|
12
|
+
* validation.
|
|
13
|
+
*/
|
|
14
|
+
export const FULFILLMENT_CANCEL_PREVIEW_QUERY = /* GraphQL */ `
|
|
15
|
+
query FulfillmentCancelPreview($fulfillmentId: ID!) {
|
|
16
|
+
fulfillmentCancelPreview(fulfillmentId: $fulfillmentId) {
|
|
17
|
+
fulfillmentId
|
|
18
|
+
overpayments {
|
|
19
|
+
orderId
|
|
20
|
+
orderCode
|
|
21
|
+
amount
|
|
22
|
+
currencyCode
|
|
23
|
+
refund { ${OVERPAYMENT_OPTION_FIELDS} }
|
|
24
|
+
accountCredit { ${OVERPAYMENT_OPTION_FIELDS} }
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
`;
|
|
29
|
+
/** `$overpayment` and `$idempotencyKey` are optional and left out of the variables when not given. */
|
|
30
|
+
export const CANCEL_FULFILLMENT_MUTATION = /* GraphQL */ `
|
|
31
|
+
mutation CancelFulfillment(
|
|
32
|
+
$fulfillmentId: ID!
|
|
33
|
+
$overpayment: [FulfillmentCancelOverpaymentInput!]
|
|
34
|
+
$idempotencyKey: String
|
|
35
|
+
) {
|
|
36
|
+
cancelFulfillment(
|
|
37
|
+
fulfillmentId: $fulfillmentId
|
|
38
|
+
overpayment: $overpayment
|
|
39
|
+
idempotencyKey: $idempotencyKey
|
|
40
|
+
) {
|
|
41
|
+
fulfillment {
|
|
42
|
+
id
|
|
43
|
+
state
|
|
44
|
+
}
|
|
45
|
+
settlements {
|
|
46
|
+
orderId
|
|
47
|
+
orderCode
|
|
48
|
+
amount
|
|
49
|
+
currencyCode
|
|
50
|
+
choice
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
`;
|
|
55
|
+
/** Every field of `OrderFulfillmentCoverageOverride`. */
|
|
56
|
+
const COVERAGE_OVERRIDE_FIELDS = /* GraphQL */ `
|
|
57
|
+
id
|
|
58
|
+
orderId
|
|
59
|
+
reason
|
|
60
|
+
actorKind
|
|
61
|
+
actorId
|
|
62
|
+
outstandingAtGrant
|
|
63
|
+
currencyCode
|
|
64
|
+
createdAt
|
|
65
|
+
active
|
|
66
|
+
`;
|
|
67
|
+
/** Its own document: on an engine without the query this call alone fails validation. */
|
|
68
|
+
export const ORDER_FULFILLMENT_COVERAGE_QUERY = /* GraphQL */ `
|
|
69
|
+
query OrderFulfillmentCoverage($orderId: ID!) {
|
|
70
|
+
orderFulfillmentCoverage(orderId: $orderId) {
|
|
71
|
+
orderId
|
|
72
|
+
orderCode
|
|
73
|
+
currencyCode
|
|
74
|
+
policyActive
|
|
75
|
+
covered
|
|
76
|
+
outstanding
|
|
77
|
+
exempt
|
|
78
|
+
exemptReason
|
|
79
|
+
allowed
|
|
80
|
+
override { ${COVERAGE_OVERRIDE_FIELDS} }
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
`;
|
|
84
|
+
/** `$idempotencyKey` is optional and left out of the variables when not given. */
|
|
85
|
+
export const ALLOW_UNCOVERED_FULFILLMENT_MUTATION = /* GraphQL */ `
|
|
86
|
+
mutation AllowUncoveredFulfillment($orderId: ID!, $reason: String!, $idempotencyKey: String) {
|
|
87
|
+
allowUncoveredFulfillment(orderId: $orderId, reason: $reason, idempotencyKey: $idempotencyKey) {
|
|
88
|
+
${COVERAGE_OVERRIDE_FIELDS}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
`;
|
|
92
|
+
function invalidCoverage(field, message) {
|
|
93
|
+
return new ValidationError({
|
|
94
|
+
code: 'FULFILLMENT_COVERAGE_OVERRIDE_INVALID',
|
|
95
|
+
message,
|
|
96
|
+
status: 400,
|
|
97
|
+
service: 'vendure',
|
|
98
|
+
details: [{ field, code: 'FULFILLMENT_COVERAGE_OVERRIDE_INVALID', message }],
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
function assertOrderId(orderId) {
|
|
102
|
+
if (typeof orderId !== 'string' || orderId.trim() === '') {
|
|
103
|
+
throw invalidCoverage('orderId', 'An order id is required.');
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
/** Refused before any request: the engine would refuse it the same way. */
|
|
107
|
+
function assertOverrideReason(reason) {
|
|
108
|
+
const text = typeof reason === 'string' ? reason.trim() : '';
|
|
109
|
+
if (text === '') {
|
|
110
|
+
throw invalidCoverage('reason', 'Say why this order may be handed over before it is paid: a reason is required.');
|
|
111
|
+
}
|
|
112
|
+
if (text.length > FULFILLMENT_COVERAGE_REASON_MAX_LENGTH) {
|
|
113
|
+
throw invalidCoverage('reason', `The reason is at most ${FULFILLMENT_COVERAGE_REASON_MAX_LENGTH} characters.`);
|
|
114
|
+
}
|
|
115
|
+
return text;
|
|
116
|
+
}
|
|
117
|
+
function toCoverageOverride(raw) {
|
|
118
|
+
return {
|
|
119
|
+
id: raw.id,
|
|
120
|
+
orderId: raw.orderId,
|
|
121
|
+
reason: raw.reason,
|
|
122
|
+
actorKind: raw.actorKind,
|
|
123
|
+
actorId: raw.actorId,
|
|
124
|
+
outstandingAtGrant: raw.outstandingAtGrant,
|
|
125
|
+
currencyCode: raw.currencyCode,
|
|
126
|
+
createdAt: raw.createdAt,
|
|
127
|
+
active: raw.active,
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
const OVERPAYMENT_CHOICES = new Set([
|
|
131
|
+
'REFUND',
|
|
132
|
+
'ACCOUNT_CREDIT',
|
|
133
|
+
]);
|
|
134
|
+
function invalidCancel(field, message) {
|
|
135
|
+
return new ValidationError({
|
|
136
|
+
code: 'FULFILLMENT_CANCEL_OVERPAYMENT_INVALID',
|
|
137
|
+
message,
|
|
138
|
+
status: 400,
|
|
139
|
+
service: 'vendure',
|
|
140
|
+
details: [{ field, code: 'FULFILLMENT_CANCEL_OVERPAYMENT_INVALID', message }],
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
/** Refused before any request: the engine would refuse each, less legibly. */
|
|
144
|
+
function assertCancelRequest(fulfillmentId, input) {
|
|
145
|
+
if (typeof fulfillmentId !== 'string' || fulfillmentId.trim() === '') {
|
|
146
|
+
throw invalidCancel('fulfillmentId', 'A fulfillment id is required.');
|
|
147
|
+
}
|
|
148
|
+
const seen = new Set();
|
|
149
|
+
for (const [index, entry] of (input.overpayment ?? []).entries()) {
|
|
150
|
+
const orderId = entry?.orderId;
|
|
151
|
+
if (typeof orderId !== 'string' || orderId.trim() === '') {
|
|
152
|
+
throw invalidCancel(`overpayment[${String(index)}].orderId`, 'Each choice names an order.');
|
|
153
|
+
}
|
|
154
|
+
if (!OVERPAYMENT_CHOICES.has(entry.choice)) {
|
|
155
|
+
throw invalidCancel(`overpayment[${String(index)}].choice`, `The choice for order ${orderId} must be REFUND or ACCOUNT_CREDIT; got ${JSON.stringify(entry.choice)}.`);
|
|
156
|
+
}
|
|
157
|
+
if (seen.has(orderId)) {
|
|
158
|
+
throw invalidCancel(`overpayment[${String(index)}].orderId`, `Order ${orderId} is named twice: give one choice per order.`);
|
|
159
|
+
}
|
|
160
|
+
seen.add(orderId);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
/** An option as the SDK types it: `code` and `message` are null when it is open. */
|
|
164
|
+
function toOption(raw) {
|
|
165
|
+
return { available: raw.available, code: raw.code ?? null, message: raw.message ?? null };
|
|
166
|
+
}
|
|
167
|
+
export const REPORT_APP_FULFILLMENT_MUTATION = /* GraphQL */ `
|
|
168
|
+
mutation ReportAppFulfillment(
|
|
169
|
+
$fulfillmentId: ID!
|
|
170
|
+
$input: ReportAppFulfillmentInput!
|
|
171
|
+
$idempotencyKey: String
|
|
172
|
+
) {
|
|
173
|
+
reportAppFulfillment(
|
|
174
|
+
fulfillmentId: $fulfillmentId
|
|
175
|
+
input: $input
|
|
176
|
+
idempotencyKey: $idempotencyKey
|
|
177
|
+
) {
|
|
178
|
+
id
|
|
179
|
+
state
|
|
180
|
+
trackingCode
|
|
181
|
+
method
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
`;
|
|
185
|
+
export const ORDER_FULFILLMENT_PARCELS_QUERY = /* GraphQL */ `
|
|
186
|
+
query OrderFulfillmentParcels($id: ID!) {
|
|
187
|
+
order(id: $id) {
|
|
188
|
+
id
|
|
189
|
+
fulfillments {
|
|
190
|
+
id
|
|
191
|
+
trackingCode
|
|
192
|
+
customFields {
|
|
193
|
+
myparcelShipmentId
|
|
194
|
+
myparcelShipmentIds
|
|
195
|
+
parcelCount
|
|
196
|
+
trackingCodes
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
`;
|
|
202
|
+
/** Every field of `MyparcelUnretractedShipment`, shared with the stock-transfer twin. */
|
|
203
|
+
export const UNRETRACTED_SHIPMENT_FIELDS = /* GraphQL */ `
|
|
204
|
+
shipmentId
|
|
205
|
+
reference
|
|
206
|
+
verdict
|
|
207
|
+
status
|
|
208
|
+
statusName
|
|
209
|
+
billable
|
|
210
|
+
hidden
|
|
211
|
+
reason
|
|
212
|
+
cause
|
|
213
|
+
firstRecordedAt
|
|
214
|
+
lastCheckedAt
|
|
215
|
+
resolvedAt
|
|
216
|
+
`;
|
|
217
|
+
/**
|
|
218
|
+
* Its own document, never part of the parcel read: an engine without the
|
|
219
|
+
* field refuses this call alone, and the order card still renders.
|
|
220
|
+
*/
|
|
221
|
+
export const ORDER_FULFILLMENT_UNRETRACTED_SHIPMENTS_QUERY = /* GraphQL */ `
|
|
222
|
+
query OrderFulfillmentUnretractedShipments($id: ID!) {
|
|
223
|
+
order(id: $id) {
|
|
224
|
+
id
|
|
225
|
+
fulfillments {
|
|
226
|
+
id
|
|
227
|
+
myparcelUnretractedShipments { ${UNRETRACTED_SHIPMENT_FIELDS} }
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
`;
|
|
232
|
+
export const FULFILLMENT_PARCEL_TRACKING_QUERY = /* GraphQL */ `
|
|
233
|
+
query FulfillmentParcelTracking($id: ID!) {
|
|
234
|
+
warehouseFulfillment(id: $id) {
|
|
235
|
+
trackingCodes
|
|
236
|
+
parcelTrackingCodes
|
|
237
|
+
parcelCount
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
`;
|
|
241
|
+
/**
|
|
242
|
+
* Its own document on purpose: `chargedParcelCount` exists only on an engine
|
|
243
|
+
* that serves it, so on an older one this call alone fails validation and the
|
|
244
|
+
* demand the create flow reads beside it does not.
|
|
245
|
+
*/
|
|
246
|
+
export const WAREHOUSE_CHARGED_PARCEL_COUNT_QUERY = /* GraphQL */ `
|
|
247
|
+
query WarehouseChargedParcelCount($input: WarehouseDemandInput!) {
|
|
248
|
+
warehouseDemand(input: $input) {
|
|
249
|
+
items {
|
|
250
|
+
orderId
|
|
251
|
+
chargedParcelCount
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
`;
|
|
256
|
+
export const MYPARCEL_FULFILLMENT_LABEL_MUTATION = /* GraphQL */ `
|
|
257
|
+
mutation MyparcelFulfillmentLabel($fulfillmentId: ID!, $format: MyparcelLabelFormatEnum!) {
|
|
258
|
+
getMyparcelFulfillmentLabel(fulfillmentId: $fulfillmentId, format: $format) {
|
|
259
|
+
format
|
|
260
|
+
base64
|
|
261
|
+
contentType
|
|
262
|
+
filename
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
`;
|
|
266
|
+
/**
|
|
267
|
+
* Its own document, like every call here: on an engine without the mutation
|
|
268
|
+
* this call alone fails validation. `$format` is optional and left out of the
|
|
269
|
+
* variables when not asked for.
|
|
270
|
+
*/
|
|
271
|
+
export const LABEL_MYPARCEL_FULFILLMENT_PARCELS_MUTATION = /* GraphQL */ `
|
|
272
|
+
mutation LabelMyparcelFulfillmentParcels($fulfillmentId: ID!, $format: MyparcelLabelFormatEnum) {
|
|
273
|
+
labelMyparcelFulfillmentParcels(fulfillmentId: $fulfillmentId, format: $format) {
|
|
274
|
+
__typename
|
|
275
|
+
... on MyparcelLabelParcelsQueued {
|
|
276
|
+
fulfillmentId
|
|
277
|
+
parcels
|
|
278
|
+
missing
|
|
279
|
+
queued
|
|
280
|
+
}
|
|
281
|
+
... on ErrorResult {
|
|
282
|
+
errorCode
|
|
283
|
+
message
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
`;
|
|
288
|
+
/**
|
|
289
|
+
* Clears the engine's MyParcel budget: 3 × 10s attempts plus two capped waits.
|
|
290
|
+
* Every merged MyParcel label (a fulfillment's, a stock transfer's) runs the
|
|
291
|
+
* same engine download, so they share it.
|
|
292
|
+
*/
|
|
293
|
+
export const MYPARCEL_LABEL_TIMEOUT_MS = 55_000;
|
|
294
|
+
/** The engine's entries as they are: the fields are the SDK's, one to one. */
|
|
295
|
+
export function toUnretractedShipments(raw) {
|
|
296
|
+
return (raw ?? []).map((entry) => ({
|
|
297
|
+
shipmentId: entry.shipmentId,
|
|
298
|
+
reference: entry.reference ?? null,
|
|
299
|
+
verdict: entry.verdict,
|
|
300
|
+
status: entry.status ?? null,
|
|
301
|
+
statusName: entry.statusName ?? null,
|
|
302
|
+
billable: entry.billable ?? null,
|
|
303
|
+
hidden: entry.hidden,
|
|
304
|
+
reason: entry.reason,
|
|
305
|
+
cause: entry.cause,
|
|
306
|
+
firstRecordedAt: entry.firstRecordedAt,
|
|
307
|
+
lastCheckedAt: entry.lastCheckedAt,
|
|
308
|
+
resolvedAt: entry.resolvedAt ?? null,
|
|
309
|
+
}));
|
|
310
|
+
}
|
|
311
|
+
function orderNotFound(orderId) {
|
|
312
|
+
return new NotFoundError({
|
|
313
|
+
code: 'ORDER_NOT_FOUND',
|
|
314
|
+
message: `This store has no order ${orderId}.`,
|
|
315
|
+
status: 404,
|
|
316
|
+
service: 'vendure',
|
|
317
|
+
});
|
|
318
|
+
}
|
|
319
|
+
/** The stale-list rule: trust the carrier's list only while it starts with `trackingCode`. */
|
|
320
|
+
function trustedTrackingCodes(list, trackingCode) {
|
|
321
|
+
const single = trackingCode?.trim() ?? '';
|
|
322
|
+
const listed = (list ?? []).filter((code) => typeof code === 'string' && code.trim() !== '');
|
|
323
|
+
if (listed.length > 0 && listed[0] === single)
|
|
324
|
+
return listed;
|
|
325
|
+
return single ? [single] : [];
|
|
326
|
+
}
|
|
327
|
+
/** The engine's `authoritativeShipmentIds`: the list only while it starts with the single id. */
|
|
328
|
+
function trustedShipmentIds(list, single) {
|
|
329
|
+
if (typeof single !== 'number' || !Number.isInteger(single) || single <= 0)
|
|
330
|
+
return [];
|
|
331
|
+
const first = String(single);
|
|
332
|
+
return list?.[0] === first ? [...list] : [first];
|
|
333
|
+
}
|
|
334
|
+
/** The bytes of a base64 label document (`atob`: no Node `Buffer`, it ships to browsers). */
|
|
335
|
+
export function decodeBase64(base64) {
|
|
336
|
+
const binary = atob(base64);
|
|
337
|
+
const bytes = new Uint8Array(binary.length);
|
|
338
|
+
for (let index = 0; index < binary.length; index += 1)
|
|
339
|
+
bytes[index] = binary.charCodeAt(index);
|
|
340
|
+
return bytes;
|
|
341
|
+
}
|
|
342
|
+
const LABEL_FORMATS = new Set(['A4', 'A6']);
|
|
343
|
+
function invalidLabelRequest(field, message) {
|
|
344
|
+
return new ValidationError({
|
|
345
|
+
code: 'MYPARCEL_LABEL_INPUT_INVALID',
|
|
346
|
+
message,
|
|
347
|
+
status: 400,
|
|
348
|
+
service: 'vendure',
|
|
349
|
+
details: [{ field, code: 'MYPARCEL_LABEL_INPUT_INVALID', message }],
|
|
350
|
+
});
|
|
351
|
+
}
|
|
352
|
+
/** Refused before any request: the engine would refuse both, less legibly. */
|
|
353
|
+
function assertLabelRequest(fulfillmentId, format) {
|
|
354
|
+
if (typeof fulfillmentId !== 'string' || fulfillmentId.trim() === '') {
|
|
355
|
+
throw invalidLabelRequest('fulfillmentId', 'A fulfillment id is required.');
|
|
356
|
+
}
|
|
357
|
+
if (format !== undefined && !LABEL_FORMATS.has(format)) {
|
|
358
|
+
throw invalidLabelRequest('format', `format must be 'A4' or 'A6', or left out to label every parcel still missing one; got ${JSON.stringify(format)}.`);
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
export function createFulfillmentsModule(transport) {
|
|
362
|
+
return {
|
|
363
|
+
async parcelsOfOrder(orderId, options) {
|
|
364
|
+
const data = await transport.graphql({ api: 'admin', query: ORDER_FULFILLMENT_PARCELS_QUERY, variables: { id: orderId } }, options);
|
|
365
|
+
if (!data.order)
|
|
366
|
+
throw orderNotFound(orderId);
|
|
367
|
+
return (data.order.fulfillments ?? []).map((fulfillment) => ({
|
|
368
|
+
fulfillmentId: fulfillment.id,
|
|
369
|
+
shipmentIds: trustedShipmentIds(fulfillment.customFields?.myparcelShipmentIds, fulfillment.customFields?.myparcelShipmentId),
|
|
370
|
+
parcelCount: fulfillment.customFields?.parcelCount ?? null,
|
|
371
|
+
trackingCode: fulfillment.trackingCode ?? null,
|
|
372
|
+
trackingCodes: trustedTrackingCodes(fulfillment.customFields?.trackingCodes, fulfillment.trackingCode ?? null),
|
|
373
|
+
}));
|
|
374
|
+
},
|
|
375
|
+
async unretractedShipmentsOfOrder(orderId, options) {
|
|
376
|
+
const data = await transport.graphql({
|
|
377
|
+
api: 'admin',
|
|
378
|
+
query: ORDER_FULFILLMENT_UNRETRACTED_SHIPMENTS_QUERY,
|
|
379
|
+
variables: { id: orderId },
|
|
380
|
+
}, options);
|
|
381
|
+
if (!data.order)
|
|
382
|
+
throw orderNotFound(orderId);
|
|
383
|
+
return (data.order.fulfillments ?? []).map((fulfillment) => ({
|
|
384
|
+
fulfillmentId: fulfillment.id,
|
|
385
|
+
shipments: toUnretractedShipments(fulfillment.myparcelUnretractedShipments),
|
|
386
|
+
}));
|
|
387
|
+
},
|
|
388
|
+
async parcelTracking(fulfillmentId, options) {
|
|
389
|
+
const data = await transport.graphql({
|
|
390
|
+
api: 'admin',
|
|
391
|
+
query: FULFILLMENT_PARCEL_TRACKING_QUERY,
|
|
392
|
+
variables: { id: fulfillmentId },
|
|
393
|
+
}, options);
|
|
394
|
+
return data.warehouseFulfillment;
|
|
395
|
+
},
|
|
396
|
+
async chargedParcelCount(input, options) {
|
|
397
|
+
const data = await transport.graphql({
|
|
398
|
+
api: 'admin',
|
|
399
|
+
query: WAREHOUSE_CHARGED_PARCEL_COUNT_QUERY,
|
|
400
|
+
variables: {
|
|
401
|
+
input: {
|
|
402
|
+
stockLocationId: input.stockLocationId,
|
|
403
|
+
orderIds: [input.orderId],
|
|
404
|
+
...(input.includeIneligible ? { includeIneligible: true } : {}),
|
|
405
|
+
...(input.routing ? { routing: [...input.routing] } : {}),
|
|
406
|
+
take: 1,
|
|
407
|
+
},
|
|
408
|
+
},
|
|
409
|
+
}, options);
|
|
410
|
+
const entry = data.warehouseDemand.items.find((item) => item.orderId === input.orderId);
|
|
411
|
+
return entry?.chargedParcelCount ?? null;
|
|
412
|
+
},
|
|
413
|
+
async myparcelLabel(fulfillmentId, format, options) {
|
|
414
|
+
const data = await transport.graphql({
|
|
415
|
+
api: 'admin',
|
|
416
|
+
query: MYPARCEL_FULFILLMENT_LABEL_MUTATION,
|
|
417
|
+
variables: { fulfillmentId, format },
|
|
418
|
+
}, { timeoutMs: MYPARCEL_LABEL_TIMEOUT_MS, ...options });
|
|
419
|
+
const { base64, ...document } = data.getMyparcelFulfillmentLabel;
|
|
420
|
+
return { ...document, bytes: decodeBase64(base64) };
|
|
421
|
+
},
|
|
422
|
+
async labelMyparcelParcels(fulfillmentId, input = {}, options) {
|
|
423
|
+
const format = input?.format;
|
|
424
|
+
assertLabelRequest(fulfillmentId, format);
|
|
425
|
+
const data = await transport.graphql({
|
|
426
|
+
api: 'admin',
|
|
427
|
+
query: LABEL_MYPARCEL_FULFILLMENT_PARCELS_MUTATION,
|
|
428
|
+
variables: { fulfillmentId, ...(format === undefined ? {} : { format }) },
|
|
429
|
+
}, options);
|
|
430
|
+
const result = data.labelMyparcelFulfillmentParcels;
|
|
431
|
+
if (isErrorResult(result))
|
|
432
|
+
throw errorFromErrorResult(result);
|
|
433
|
+
const queued = result;
|
|
434
|
+
return {
|
|
435
|
+
fulfillmentId: queued.fulfillmentId,
|
|
436
|
+
parcels: queued.parcels,
|
|
437
|
+
missing: queued.missing,
|
|
438
|
+
queued: queued.queued,
|
|
439
|
+
};
|
|
440
|
+
},
|
|
441
|
+
async cancelPreview(fulfillmentId, options) {
|
|
442
|
+
if (typeof fulfillmentId !== 'string' || fulfillmentId.trim() === '') {
|
|
443
|
+
throw invalidCancel('fulfillmentId', 'A fulfillment id is required.');
|
|
444
|
+
}
|
|
445
|
+
const data = await transport.graphql({ api: 'admin', query: FULFILLMENT_CANCEL_PREVIEW_QUERY, variables: { fulfillmentId } }, options);
|
|
446
|
+
const preview = data.fulfillmentCancelPreview;
|
|
447
|
+
return {
|
|
448
|
+
fulfillmentId: preview.fulfillmentId,
|
|
449
|
+
overpayments: preview.overpayments.map((entry) => ({
|
|
450
|
+
orderId: entry.orderId,
|
|
451
|
+
orderCode: entry.orderCode,
|
|
452
|
+
amount: entry.amount,
|
|
453
|
+
currencyCode: entry.currencyCode,
|
|
454
|
+
refund: toOption(entry.refund),
|
|
455
|
+
accountCredit: toOption(entry.accountCredit),
|
|
456
|
+
})),
|
|
457
|
+
};
|
|
458
|
+
},
|
|
459
|
+
async cancel(fulfillmentId, input = {}, options) {
|
|
460
|
+
assertCancelRequest(fulfillmentId, input);
|
|
461
|
+
const overpayment = input.overpayment ?? [];
|
|
462
|
+
const data = await transport.graphql({
|
|
463
|
+
api: 'admin',
|
|
464
|
+
query: CANCEL_FULFILLMENT_MUTATION,
|
|
465
|
+
// A variable, not a header: the Admin API takes the key as an argument.
|
|
466
|
+
variables: {
|
|
467
|
+
fulfillmentId,
|
|
468
|
+
...(overpayment.length > 0
|
|
469
|
+
? { overpayment: overpayment.map(({ orderId, choice }) => ({ orderId, choice })) }
|
|
470
|
+
: {}),
|
|
471
|
+
...(options?.idempotencyKey ? { idempotencyKey: options.idempotencyKey } : {}),
|
|
472
|
+
},
|
|
473
|
+
}, options);
|
|
474
|
+
const result = data.cancelFulfillment;
|
|
475
|
+
return {
|
|
476
|
+
fulfillment: { id: result.fulfillment.id, state: result.fulfillment.state },
|
|
477
|
+
settlements: result.settlements.map((entry) => ({
|
|
478
|
+
orderId: entry.orderId,
|
|
479
|
+
orderCode: entry.orderCode,
|
|
480
|
+
amount: entry.amount,
|
|
481
|
+
currencyCode: entry.currencyCode,
|
|
482
|
+
choice: entry.choice,
|
|
483
|
+
})),
|
|
484
|
+
};
|
|
485
|
+
},
|
|
486
|
+
async coverage(orderId, options) {
|
|
487
|
+
assertOrderId(orderId);
|
|
488
|
+
const data = await transport.graphql({ api: 'admin', query: ORDER_FULFILLMENT_COVERAGE_QUERY, variables: { orderId } }, options);
|
|
489
|
+
const coverage = data.orderFulfillmentCoverage;
|
|
490
|
+
return {
|
|
491
|
+
orderId: coverage.orderId,
|
|
492
|
+
orderCode: coverage.orderCode,
|
|
493
|
+
currencyCode: coverage.currencyCode,
|
|
494
|
+
policyActive: coverage.policyActive,
|
|
495
|
+
covered: coverage.covered,
|
|
496
|
+
outstanding: coverage.outstanding,
|
|
497
|
+
exempt: coverage.exempt,
|
|
498
|
+
exemptReason: coverage.exemptReason ?? null,
|
|
499
|
+
allowed: coverage.allowed,
|
|
500
|
+
override: coverage.override ? toCoverageOverride(coverage.override) : null,
|
|
501
|
+
};
|
|
502
|
+
},
|
|
503
|
+
async allowUncovered(orderId, reason, options) {
|
|
504
|
+
assertOrderId(orderId);
|
|
505
|
+
const text = assertOverrideReason(reason);
|
|
506
|
+
const data = await transport.graphql({
|
|
507
|
+
api: 'admin',
|
|
508
|
+
query: ALLOW_UNCOVERED_FULFILLMENT_MUTATION,
|
|
509
|
+
// A variable, not a header: the Admin API takes the key as an argument.
|
|
510
|
+
variables: {
|
|
511
|
+
orderId,
|
|
512
|
+
reason: text,
|
|
513
|
+
...(options?.idempotencyKey ? { idempotencyKey: options.idempotencyKey } : {}),
|
|
514
|
+
},
|
|
515
|
+
}, options);
|
|
516
|
+
return toCoverageOverride(data.allowUncoveredFulfillment);
|
|
517
|
+
},
|
|
518
|
+
async reportAppFulfillment(fulfillmentId, input, options) {
|
|
519
|
+
const data = await transport.graphql({
|
|
520
|
+
api: 'admin',
|
|
521
|
+
query: REPORT_APP_FULFILLMENT_MUTATION,
|
|
522
|
+
// A variable, not a header: the Admin API takes the key as an argument.
|
|
523
|
+
variables: {
|
|
524
|
+
fulfillmentId,
|
|
525
|
+
input,
|
|
526
|
+
...(options?.idempotencyKey ? { idempotencyKey: options.idempotencyKey } : {}),
|
|
527
|
+
},
|
|
528
|
+
}, options);
|
|
529
|
+
const reported = data.reportAppFulfillment;
|
|
530
|
+
// Core stores "no tracking code" as an empty string.
|
|
531
|
+
return { ...reported, trackingCode: reported.trackingCode || null };
|
|
532
|
+
},
|
|
533
|
+
};
|
|
534
|
+
}
|
package/dist/heads/index.d.ts
CHANGED
|
@@ -83,6 +83,64 @@ export declare const CREATE_MUTATION = "\n mutation CreateChannelHead($input: C
|
|
|
83
83
|
export declare const UPDATE_MUTATION = "\n mutation UpdateChannelHead($id: ID!, $input: UpdateChannelHeadInput!) {\n updateChannelHead(id: $id, input: $input) { \n id\n channelId\n installationId\n key\n kind\n name\n origins\n deepLinkBase\n deepLinkScheme\n defaultOrderScope\n eventSubscriptionId\n isDefault\n createdAt\n updatedAt\n }\n }\n";
|
|
84
84
|
export declare const DELETE_MUTATION = "\n mutation DeleteChannelHead($id: ID!) {\n deleteChannelHead(id: $id)\n }\n";
|
|
85
85
|
export declare const SET_DEFAULT_MUTATION = "\n mutation SetDefaultChannelHead($id: ID!) {\n setDefaultChannelHead(id: $id) { \n id\n channelId\n installationId\n key\n kind\n name\n origins\n deepLinkBase\n deepLinkScheme\n defaultOrderScope\n eventSubscriptionId\n isDefault\n createdAt\n updatedAt\n }\n }\n";
|
|
86
|
+
/**
|
|
87
|
+
* A head's PRIVATE STOREFRONT TOKEN (`s69p_`, spec §6.3, §15.21) — never the
|
|
88
|
+
* token itself, which {@link HeadPrivateTokensModule.issue} returns once.
|
|
89
|
+
*/
|
|
90
|
+
export interface HeadStorefrontToken {
|
|
91
|
+
id: string;
|
|
92
|
+
headId: string;
|
|
93
|
+
name: string;
|
|
94
|
+
/** `s69p_<lookup id>` — enough to recognise the token in a list, never to use it. */
|
|
95
|
+
prefix: string;
|
|
96
|
+
createdAt: string;
|
|
97
|
+
/** When a service last verified it, to within about a minute. */
|
|
98
|
+
lastUsedAt: string | null;
|
|
99
|
+
/** When it was revoked. A revoked token never verifies again. */
|
|
100
|
+
revokedAt: string | null;
|
|
101
|
+
}
|
|
102
|
+
export interface IssuedHeadStorefrontToken {
|
|
103
|
+
/** The whole token. Shown ONCE: put it in the storefront server's secrets now. */
|
|
104
|
+
token: string;
|
|
105
|
+
record: HeadStorefrontToken;
|
|
106
|
+
}
|
|
107
|
+
export declare const STOREFRONT_TOKEN_FIELDS = "\n id\n headId\n name\n prefix\n createdAt\n lastUsedAt\n revokedAt\n";
|
|
108
|
+
export declare const PRIVATE_TOKENS_QUERY = "\n query HeadStorefrontTokens($headId: ID!) {\n headStorefrontTokens(headId: $headId) { \n id\n headId\n name\n prefix\n createdAt\n lastUsedAt\n revokedAt\n }\n }\n";
|
|
109
|
+
export declare const ISSUE_PRIVATE_TOKEN_MUTATION = "\n mutation IssueHeadStorefrontToken($headId: ID!, $name: String!) {\n issueHeadStorefrontToken(headId: $headId, name: $name) {\n token\n record { \n id\n headId\n name\n prefix\n createdAt\n lastUsedAt\n revokedAt\n }\n }\n }\n";
|
|
110
|
+
export declare const REVOKE_PRIVATE_TOKEN_MUTATION = "\n mutation RevokeHeadStorefrontToken($id: ID!) {\n revokeHeadStorefrontToken(id: $id) { \n id\n headId\n name\n prefix\n createdAt\n lastUsedAt\n revokedAt\n }\n }\n";
|
|
111
|
+
/**
|
|
112
|
+
* Private storefront tokens per head (spec §6.3, §6.7, §15.21).
|
|
113
|
+
*
|
|
114
|
+
* A server-side storefront sends its token with
|
|
115
|
+
* `createStorefrontClient({ storeCode, privateToken, buyerIp })` from
|
|
116
|
+
* `@sixtyninecommerce/client`. It grants NO permission: it gives that server its
|
|
117
|
+
* own rate-limit budget and makes the platform key per-shopper budgets (and the
|
|
118
|
+
* form limiter) on the shopper address the server forwards. Never ship it to a
|
|
119
|
+
* browser — the storefront SDK refuses to (`CREDENTIAL_IN_BROWSER`).
|
|
120
|
+
*
|
|
121
|
+
* Read with `ReadSettings`, issued and revoked with `UpdateSettings`. At most 10
|
|
122
|
+
* live tokens per head (`HEAD_STOREFRONT_TOKEN_LIMIT`), which is room to rotate:
|
|
123
|
+
* issue the new one, deploy it, revoke the old. `issue` takes no idempotency key
|
|
124
|
+
* — its response is the credential, and no replay store may keep it.
|
|
125
|
+
*/
|
|
126
|
+
export interface HeadPrivateTokensModule {
|
|
127
|
+
/** A head's tokens, newest first, revoked ones included. `HEAD_NOT_FOUND` for another store's head. */
|
|
128
|
+
list(headId: string, options?: Call): Promise<HeadStorefrontToken[]>;
|
|
129
|
+
/**
|
|
130
|
+
* Issue a token for a head. The plaintext is in `token`, once; it cannot be
|
|
131
|
+
* read again. Refused `INVALID_STOREFRONT_TOKEN_NAME` (1-100 characters, no
|
|
132
|
+
* control characters) or `HEAD_STOREFRONT_TOKEN_LIMIT`.
|
|
133
|
+
*/
|
|
134
|
+
issue(headId: string, input: {
|
|
135
|
+
name: string;
|
|
136
|
+
}, options?: Call): Promise<IssuedHeadStorefrontToken>;
|
|
137
|
+
/**
|
|
138
|
+
* Revoke a token. Terminal and idempotent. Every service stops honouring it
|
|
139
|
+
* within 15 seconds; the store's public channel token is untouched.
|
|
140
|
+
* `HEAD_STOREFRONT_TOKEN_NOT_FOUND` for another store's token.
|
|
141
|
+
*/
|
|
142
|
+
revoke(id: string, options?: Call): Promise<HeadStorefrontToken>;
|
|
143
|
+
}
|
|
86
144
|
/**
|
|
87
145
|
* The store's head registry (spec §6.7).
|
|
88
146
|
*
|
|
@@ -99,5 +157,7 @@ export interface HeadsModule {
|
|
|
99
157
|
delete(id: string, options?: Call): Promise<boolean>;
|
|
100
158
|
/** Move the store's default head. There is no way to unset one, only to move it. */
|
|
101
159
|
setDefault(id: string, options?: Call): Promise<Head>;
|
|
160
|
+
/** Each head's private storefront tokens (`s69p_`). */
|
|
161
|
+
privateTokens: HeadPrivateTokensModule;
|
|
102
162
|
}
|
|
103
163
|
export declare function createHeadsModule(transport: Transport): HeadsModule;
|
package/dist/heads/index.js
CHANGED
|
@@ -44,6 +44,33 @@ export const SET_DEFAULT_MUTATION = /* GraphQL */ `
|
|
|
44
44
|
setDefaultChannelHead(id: $id) { ${HEAD_FIELDS} }
|
|
45
45
|
}
|
|
46
46
|
`;
|
|
47
|
+
export const STOREFRONT_TOKEN_FIELDS = /* GraphQL */ `
|
|
48
|
+
id
|
|
49
|
+
headId
|
|
50
|
+
name
|
|
51
|
+
prefix
|
|
52
|
+
createdAt
|
|
53
|
+
lastUsedAt
|
|
54
|
+
revokedAt
|
|
55
|
+
`;
|
|
56
|
+
export const PRIVATE_TOKENS_QUERY = /* GraphQL */ `
|
|
57
|
+
query HeadStorefrontTokens($headId: ID!) {
|
|
58
|
+
headStorefrontTokens(headId: $headId) { ${STOREFRONT_TOKEN_FIELDS} }
|
|
59
|
+
}
|
|
60
|
+
`;
|
|
61
|
+
export const ISSUE_PRIVATE_TOKEN_MUTATION = /* GraphQL */ `
|
|
62
|
+
mutation IssueHeadStorefrontToken($headId: ID!, $name: String!) {
|
|
63
|
+
issueHeadStorefrontToken(headId: $headId, name: $name) {
|
|
64
|
+
token
|
|
65
|
+
record { ${STOREFRONT_TOKEN_FIELDS} }
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
`;
|
|
69
|
+
export const REVOKE_PRIVATE_TOKEN_MUTATION = /* GraphQL */ `
|
|
70
|
+
mutation RevokeHeadStorefrontToken($id: ID!) {
|
|
71
|
+
revokeHeadStorefrontToken(id: $id) { ${STOREFRONT_TOKEN_FIELDS} }
|
|
72
|
+
}
|
|
73
|
+
`;
|
|
47
74
|
export function createHeadsModule(transport) {
|
|
48
75
|
return {
|
|
49
76
|
async list(options) {
|
|
@@ -70,5 +97,23 @@ export function createHeadsModule(transport) {
|
|
|
70
97
|
const data = await transport.graphql({ api: 'admin', query: SET_DEFAULT_MUTATION, variables: { id } }, options);
|
|
71
98
|
return data.setDefaultChannelHead;
|
|
72
99
|
},
|
|
100
|
+
privateTokens: {
|
|
101
|
+
async list(headId, options) {
|
|
102
|
+
const data = await transport.graphql({ api: 'admin', query: PRIVATE_TOKENS_QUERY, variables: { headId } }, options);
|
|
103
|
+
return data.headStorefrontTokens;
|
|
104
|
+
},
|
|
105
|
+
async issue(headId, input, options) {
|
|
106
|
+
const data = await transport.graphql({
|
|
107
|
+
api: 'admin',
|
|
108
|
+
query: ISSUE_PRIVATE_TOKEN_MUTATION,
|
|
109
|
+
variables: { headId, name: input.name },
|
|
110
|
+
}, options);
|
|
111
|
+
return data.issueHeadStorefrontToken;
|
|
112
|
+
},
|
|
113
|
+
async revoke(id, options) {
|
|
114
|
+
const data = await transport.graphql({ api: 'admin', query: REVOKE_PRIVATE_TOKEN_MUTATION, variables: { id } }, options);
|
|
115
|
+
return data.revokeHeadStorefrontToken;
|
|
116
|
+
},
|
|
117
|
+
},
|
|
73
118
|
};
|
|
74
119
|
}
|