@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.
Files changed (179) hide show
  1. package/README.md +2739 -17
  2. package/dist/api-tokens/index.d.ts +15 -5
  3. package/dist/api-tokens/index.js +1 -0
  4. package/dist/apps/event-subscription.d.ts +59 -0
  5. package/dist/apps/event-subscription.js +32 -0
  6. package/dist/apps/hook-secret.d.ts +22 -0
  7. package/dist/apps/hook-secret.js +36 -0
  8. package/dist/apps/index.d.ts +54 -3
  9. package/dist/apps/index.js +17 -0
  10. package/dist/audit/index.d.ts +7 -0
  11. package/dist/auth/queries.d.ts +5 -1
  12. package/dist/auth/queries.js +6 -0
  13. package/dist/bulk/index.d.ts +323 -0
  14. package/dist/bulk/index.js +162 -0
  15. package/dist/catalog/assets.d.ts +147 -0
  16. package/dist/catalog/assets.js +164 -0
  17. package/dist/catalog/collections.d.ts +109 -0
  18. package/dist/catalog/collections.js +91 -0
  19. package/dist/catalog/facets.d.ts +103 -0
  20. package/dist/catalog/facets.js +100 -0
  21. package/dist/catalog/index.d.ts +115 -0
  22. package/dist/catalog/index.js +21 -0
  23. package/dist/catalog/options.d.ts +89 -0
  24. package/dist/catalog/options.js +88 -0
  25. package/dist/catalog/products-bulk.d.ts +21 -0
  26. package/dist/catalog/products-bulk.js +58 -0
  27. package/dist/catalog/products.d.ts +650 -0
  28. package/dist/catalog/products.js +458 -0
  29. package/dist/catalog/properties.d.ts +234 -0
  30. package/dist/catalog/properties.js +158 -0
  31. package/dist/catalog/types.d.ts +174 -0
  32. package/dist/catalog/types.js +141 -0
  33. package/dist/catalog/variants.d.ts +324 -0
  34. package/dist/catalog/variants.js +288 -0
  35. package/dist/catalog/visibility.d.ts +57 -0
  36. package/dist/catalog/visibility.js +59 -0
  37. package/dist/client.d.ts +192 -3
  38. package/dist/client.js +87 -12
  39. package/dist/compliance/index.d.ts +88 -0
  40. package/dist/compliance/index.js +88 -0
  41. package/dist/customer-data-redaction.d.ts +14 -0
  42. package/dist/customer-data-redaction.js +22 -0
  43. package/dist/customers/index.d.ts +428 -17
  44. package/dist/customers/index.js +322 -15
  45. package/dist/documents/index.d.ts +513 -16
  46. package/dist/documents/index.js +229 -3
  47. package/dist/events/index.d.ts +259 -0
  48. package/dist/events/index.js +147 -0
  49. package/dist/feeds/ai.d.ts +46 -0
  50. package/dist/feeds/ai.js +43 -0
  51. package/dist/feeds/categories.d.ts +50 -0
  52. package/dist/feeds/categories.js +56 -0
  53. package/dist/feeds/configs.d.ts +54 -0
  54. package/dist/feeds/configs.js +85 -0
  55. package/dist/feeds/identifier-fields.d.ts +25 -0
  56. package/dist/feeds/identifier-fields.js +29 -0
  57. package/dist/feeds/index.d.ts +54 -0
  58. package/dist/feeds/index.js +46 -0
  59. package/dist/feeds/preserve.d.ts +38 -0
  60. package/dist/feeds/preserve.js +74 -0
  61. package/dist/feeds/rules.d.ts +42 -0
  62. package/dist/feeds/rules.js +56 -0
  63. package/dist/feeds/types.d.ts +654 -0
  64. package/dist/feeds/types.js +135 -0
  65. package/dist/fulfillments/index.d.ts +437 -0
  66. package/dist/fulfillments/index.js +534 -0
  67. package/dist/heads/index.d.ts +60 -0
  68. package/dist/heads/index.js +45 -0
  69. package/dist/hooks/assignments.d.ts +90 -0
  70. package/dist/hooks/assignments.js +53 -0
  71. package/dist/hooks/index.d.ts +97 -0
  72. package/dist/hooks/index.js +76 -0
  73. package/dist/index.d.ts +95 -9
  74. package/dist/index.js +21 -1
  75. package/dist/integrations/index.d.ts +14 -0
  76. package/dist/integrations/index.js +9 -0
  77. package/dist/integrations/pipelines.d.ts +113 -0
  78. package/dist/integrations/pipelines.js +62 -0
  79. package/dist/integrations/types.d.ts +176 -0
  80. package/dist/integrations/types.js +8 -0
  81. package/dist/jobs/bulk-action-run.d.ts +74 -0
  82. package/dist/jobs/bulk-action-run.js +69 -0
  83. package/dist/locations/index.d.ts +6 -2
  84. package/dist/meta/index.d.ts +32 -0
  85. package/dist/orders/bulk.d.ts +75 -0
  86. package/dist/orders/bulk.js +150 -0
  87. package/dist/orders/commit-edit.d.ts +123 -0
  88. package/dist/orders/commit-edit.js +142 -0
  89. package/dist/orders/deposit-policy.d.ts +103 -0
  90. package/dist/orders/deposit-policy.js +202 -0
  91. package/dist/orders/get.d.ts +722 -0
  92. package/dist/orders/get.js +530 -0
  93. package/dist/orders/index.d.ts +186 -21
  94. package/dist/orders/index.js +57 -0
  95. package/dist/orders/line-price-preview.d.ts +297 -0
  96. package/dist/orders/line-price-preview.js +50 -0
  97. package/dist/orders/manual-discounts.d.ts +141 -0
  98. package/dist/orders/manual-discounts.js +97 -0
  99. package/dist/orders/manual-pricing.d.ts +192 -0
  100. package/dist/orders/manual-pricing.js +72 -0
  101. package/dist/orders/order-entry.d.ts +566 -0
  102. package/dist/orders/order-entry.js +129 -0
  103. package/dist/orders/parcel-charge.d.ts +45 -0
  104. package/dist/orders/parcel-charge.js +55 -0
  105. package/dist/orders/plan-edit.d.ts +489 -0
  106. package/dist/orders/plan-edit.js +93 -0
  107. package/dist/orders/status.d.ts +235 -0
  108. package/dist/orders/status.js +96 -0
  109. package/dist/orders/surcharges.d.ts +75 -2
  110. package/dist/orders/surcharges.js +110 -4
  111. package/dist/payments/account-credit.d.ts +171 -0
  112. package/dist/payments/account-credit.js +107 -0
  113. package/dist/payments/index.d.ts +241 -9
  114. package/dist/payments/index.js +92 -0
  115. package/dist/payments/methods.d.ts +37 -0
  116. package/dist/payments/methods.js +33 -0
  117. package/dist/platform/catalog.d.ts +148 -0
  118. package/dist/platform/catalog.js +74 -0
  119. package/dist/platform/entitlements.d.ts +111 -0
  120. package/dist/platform/entitlements.js +86 -0
  121. package/dist/platform/legal-entities.d.ts +139 -0
  122. package/dist/platform/legal-entities.js +126 -0
  123. package/dist/platform/legal-entity-numbering.d.ts +103 -0
  124. package/dist/platform/legal-entity-numbering.js +101 -0
  125. package/dist/platform/organization-membership.d.ts +80 -0
  126. package/dist/platform/organization-membership.js +71 -0
  127. package/dist/platform/organization-settings.d.ts +33 -0
  128. package/dist/platform/organization-settings.js +42 -0
  129. package/dist/platform/organization-sharing.d.ts +172 -0
  130. package/dist/platform/organization-sharing.js +120 -0
  131. package/dist/platform/organizations.d.ts +205 -0
  132. package/dist/platform/organizations.js +180 -0
  133. package/dist/platform/provision-store.d.ts +88 -8
  134. package/dist/platform/provision-store.js +12 -0
  135. package/dist/platform/reports.d.ts +46 -0
  136. package/dist/platform/reports.js +31 -0
  137. package/dist/platform/server-metrics.d.ts +58 -0
  138. package/dist/platform/server-metrics.js +11 -0
  139. package/dist/pos/index.d.ts +567 -0
  140. package/dist/pos/index.js +205 -0
  141. package/dist/pricing/index.d.ts +408 -0
  142. package/dist/pricing/index.js +353 -0
  143. package/dist/pricing/vouchers.d.ts +103 -0
  144. package/dist/pricing/vouchers.js +69 -0
  145. package/dist/provenance/index.d.ts +93 -0
  146. package/dist/provenance/index.js +53 -0
  147. package/dist/reports/index.d.ts +199 -0
  148. package/dist/reports/index.js +154 -0
  149. package/dist/returns/index.d.ts +225 -0
  150. package/dist/returns/index.js +160 -0
  151. package/dist/search/index.d.ts +99 -0
  152. package/dist/search/index.js +62 -0
  153. package/dist/shipping/parcel-count-suggestion.d.ts +52 -0
  154. package/dist/shipping/parcel-count-suggestion.js +73 -0
  155. package/dist/shipping/parcel-rule.d.ts +48 -0
  156. package/dist/shipping/parcel-rule.js +91 -0
  157. package/dist/stock/index.d.ts +166 -0
  158. package/dist/stock/index.js +115 -0
  159. package/dist/stock/transfers.d.ts +520 -0
  160. package/dist/stock/transfers.js +437 -0
  161. package/dist/stored-value/index.d.ts +154 -0
  162. package/dist/stored-value/index.js +130 -0
  163. package/dist/tenant/capabilities.d.ts +10 -0
  164. package/dist/tenant/entitlements.d.ts +35 -0
  165. package/dist/tenant/entitlements.js +15 -0
  166. package/dist/tenant/field-groups.d.ts +64 -0
  167. package/dist/tenant/field-groups.js +34 -0
  168. package/dist/tenant/legal-entity.d.ts +32 -0
  169. package/dist/tenant/legal-entity.js +41 -0
  170. package/dist/tenant/notifications.d.ts +148 -0
  171. package/dist/tenant/notifications.js +79 -0
  172. package/dist/tenant/retention.d.ts +10 -4
  173. package/dist/tenant/settings-sources.d.ts +103 -0
  174. package/dist/tenant/settings-sources.js +92 -0
  175. package/dist/types.d.ts +86 -11
  176. package/dist/uploads/index.d.ts +11 -7
  177. package/dist/users/index.d.ts +104 -0
  178. package/dist/users/index.js +80 -0
  179. package/package.json +3 -2
@@ -0,0 +1,135 @@
1
+ /**
2
+ * The product-feed contract: the rule AST a merchant builds, the configuration
3
+ * it lives in, and everything the generator, the review queues and the AI
4
+ * helpers report back.
5
+ *
6
+ * TWO CASING WORLDS meet here, and the difference is not cosmetic.
7
+ *
8
+ * 1. **The DTOs are camelCase**, like every other module: the wire is
9
+ * snake_case (`language_code`, `refresh_interval_minutes` — the plugins
10
+ * controllers project every row onto it) and the transport converts in both
11
+ * directions.
12
+ * 2. **The rule AST inside `mappingJson`, `filtersJson`, `settingsJson`,
13
+ * `rulesJson`, `entriesJson`, `perDestinationJson`, `payloadJson`,
14
+ * `statsJson` and `defaultSource` is camelCase ON THE WIRE**, stored and
15
+ * echoed byte-for-byte by the service. Those subtrees are never converted
16
+ * (see `preserve.ts`), so what a consumer builds is what the compiler reads.
17
+ *
18
+ * SYNC NOTE — the AST block mirrors `services/plugins/src/feeds/rules/types.ts`
19
+ * (plus `destinations/types.ts` for the destination and delivery keys, and the
20
+ * entity modules for the string unions). It is a hand-kept mirror, not
21
+ * generated: every shape is copied verbatim, never "improved" in transit. When
22
+ * the engine's AST changes, change this file in the same branch, or the rules a
23
+ * consumer emits come back as a 400 `INVALID_RULES`.
24
+ */
25
+ /** Every `FeedValueSource.kind`, in the order a builder should offer them. */
26
+ export const FEED_VALUE_SOURCE_KINDS = [
27
+ 'field',
28
+ 'static',
29
+ 'combine',
30
+ 'lookup',
31
+ 'extract',
32
+ 'internal',
33
+ ];
34
+ /** Discriminates a {@link FeedValueSource} without a switch at every call site. */
35
+ export function isFeedValueSourceKind(source, kind) {
36
+ return source.kind === kind;
37
+ }
38
+ export const FEED_CONDITION_OPERATORS = [
39
+ 'eq',
40
+ 'neq',
41
+ 'contains',
42
+ 'not_contains',
43
+ 'blank',
44
+ 'not_blank',
45
+ 'gt',
46
+ 'lt',
47
+ 'gte',
48
+ 'lte',
49
+ 'in',
50
+ ];
51
+ /** Operators that take NO `value` — a builder must hide the operand input for these. */
52
+ export const VALUELESS_FEED_CONDITION_OPERATORS = [
53
+ 'blank',
54
+ 'not_blank',
55
+ ];
56
+ /** Narrows a node of a {@link FeedConditionGroup.conditions} array. */
57
+ export function isFeedConditionGroup(node) {
58
+ return 'logic' in node && Array.isArray(node.conditions);
59
+ }
60
+ /** Every `FeedTransformSpec.kind`, in the order a builder should offer them. */
61
+ export const FEED_TRANSFORM_KINDS = [
62
+ 'strip_html',
63
+ 'truncate',
64
+ 'upper',
65
+ 'lower',
66
+ 'capitalize',
67
+ 'price_format',
68
+ ];
69
+ /** Enforced by a CHECK constraint on `feed_config.destination`. */
70
+ export const FEED_DESTINATIONS = ['google', 'meta', 'tiktok', 'pinterest'];
71
+ /** Server default page size; a list that omits `limit` gets this many rows. */
72
+ export const DEFAULT_FEED_PAGE_LIMIT = 20;
73
+ /** Hard ceiling — a larger `limit` is a 400, not a silent clamp. */
74
+ export const MAX_FEED_PAGE_LIMIT = 100;
75
+ /**
76
+ * Accepted range for `refreshIntervalMinutes` — mirrors the DTO's own bounds.
77
+ *
78
+ * The floor is the sweep's, not an arbitrary one: the scheduler ticks every 10
79
+ * minutes and refuses to rebuild a feed more often than every 30, so a shorter
80
+ * interval was accepted and then quietly held to 30 — a setting that read back
81
+ * as something the platform never did.
82
+ */
83
+ export const MIN_REFRESH_INTERVAL_MINUTES = 30;
84
+ export const MAX_REFRESH_INTERVAL_MINUTES = 10080;
85
+ /** Column default: rebuild every 6 hours. */
86
+ export const DEFAULT_REFRESH_INTERVAL_MINUTES = 360;
87
+ export const FEED_RUN_STATUSES = ['running', 'completed', 'failed'];
88
+ export const FEED_RUN_TRIGGERS = ['scheduled', 'source_changed', 'manual'];
89
+ export const FEED_ITEM_ISSUE_SEVERITIES = ['error', 'warning'];
90
+ /**
91
+ * The 429 a forced regeneration is refused with while the CHANNEL's throttle
92
+ * window is still open. Every forced pass walks the whole catalogue on a
93
+ * `concurrency: 1` worker shared by every tenant, so a tenant with twenty feeds
94
+ * cannot queue twenty walks ahead of everyone else's scheduled refresh.
95
+ *
96
+ * It is NOT the dedup case above: that one is a 202 and means "your job is
97
+ * already running". This one means "nothing was queued, come back later".
98
+ */
99
+ export const FEED_REGENERATE_THROTTLED = 'FEED_REGENERATE_THROTTLED';
100
+ /**
101
+ * Read a rejected {@link FeedsModule.regenerate} as a throttle refusal, or
102
+ * `null` for anything else (a 404, a network failure) — those stay generic.
103
+ *
104
+ * A guard rather than a class check: the transport maps the problem body onto a
105
+ * `RateLimitedError`, and a caller should key on the stable CODE rather than on
106
+ * an instance that a future mapping change could swap.
107
+ */
108
+ export function readFeedRegenerateThrottle(error) {
109
+ if (error === null || typeof error !== 'object')
110
+ return null;
111
+ const candidate = error;
112
+ if (candidate.code !== FEED_REGENERATE_THROTTLED)
113
+ return null;
114
+ const seconds = candidate.retryAfterSeconds;
115
+ return typeof seconds === 'number' && Number.isFinite(seconds) && seconds > 0
116
+ ? { retryAfterSeconds: Math.ceil(seconds) }
117
+ : {};
118
+ }
119
+ /** Sample size when the caller does not ask for one. */
120
+ export const DEFAULT_PREVIEW_SAMPLE_SIZE = 10;
121
+ /** Hard ceiling on a preview sample; a bigger request is a 400. */
122
+ export const MAX_PREVIEW_SAMPLE_SIZE = 50;
123
+ /** Identifier rule shared by internal fields and lookup tables. */
124
+ export const FEED_IDENTIFIER_PATTERN = /^[a-z][a-z0-9_]*$/;
125
+ /** Server cap on `entriesJson` length. */
126
+ export const MAX_LOOKUP_ENTRIES = 5000;
127
+ export const FEED_CATEGORY_MATCH_TYPES = ['collection', 'facet_value', 'default'];
128
+ export const FEED_CATEGORY_MAPPING_SOURCES = ['manual', 'ai'];
129
+ export const FEED_CATEGORY_MAPPING_STATUSES = ['approved', 'suggested', 'rejected'];
130
+ /** Server cap on one bulk status call. */
131
+ export const MAX_BULK_STATUS_IDS = 500;
132
+ export const TAXONOMY_DEFAULT_LIMIT = 20;
133
+ export const TAXONOMY_MAX_LIMIT = 50;
134
+ /** The 409 both AI endpoints refuse with when no LLM is configured. */
135
+ export const AI_UNAVAILABLE_CODE = 'AI_UNAVAILABLE';
@@ -0,0 +1,437 @@
1
+ import { type Transport } from '@sixtyninecommerce/core';
2
+ import type { OrderOverpaymentChoice, OverpaymentOption } from '../orders/surcharges.js';
3
+ import type { Call } from '../types.js';
4
+ /**
5
+ * A fulfillment's parcels as the order records them: one MyParcel shipment per
6
+ * parcel, and the barcodes the carrier has issued so far.
7
+ */
8
+ export interface OrderFulfillmentParcels {
9
+ fulfillmentId: string;
10
+ /**
11
+ * Every parcel's MyParcel shipment id, in parcel order, as the engine reads
12
+ * them: the list only while its first entry IS the single
13
+ * `myparcelShipmentId` (older writers rewrite that one alone, e.g. a
14
+ * recreate), else `[single]`, or `[]` when there is none.
15
+ */
16
+ shipmentIds: string[];
17
+ /** How many parcels were asked for. Null when the fulfillment never said. */
18
+ parcelCount: number | null;
19
+ /** The fulfillment's own tracking code, or null. */
20
+ trackingCode: string | null;
21
+ /**
22
+ * Every barcode to show, in parcel order. The carrier's list is used only
23
+ * while its first entry IS `trackingCode`: another writer (a code typed at
24
+ * ship, an external tracking sync) may have replaced `trackingCode` alone,
25
+ * and the list it went stale under names the wrong parcels. Otherwise this is
26
+ * `[trackingCode]`, or `[]` when there is none.
27
+ */
28
+ trackingCodes: string[];
29
+ }
30
+ /** A warehouse fulfillment's barcodes, per parcel. */
31
+ export interface FulfillmentParcelTracking {
32
+ /** Every barcode the fulfillment is known to have, holes collapsed. */
33
+ trackingCodes: string[];
34
+ /**
35
+ * Parcel i+1's OWN barcode at index i, null until it has one. Null as a whole
36
+ * when the carrier bookkeeping could not be read.
37
+ */
38
+ parcelTrackingCodes: Array<string | null> | null;
39
+ /** Packed parcels, else the instructed count, else 1. */
40
+ parcelCount: number;
41
+ }
42
+ export type FulfillmentLabelFormat = 'A4' | 'A6';
43
+ /** How a warehouse's "To ship" queue routes a line (`WarehouseDemandRouting`). */
44
+ export type WarehouseDemandRouting = 'preferred' | 'allocated' | 'unrouted' | 'no_stock';
45
+ /**
46
+ * Which "To ship" entry of an order to read. The entry, and so whether it
47
+ * holds the whole order, depends on the warehouse and on the routing filters:
48
+ * pass the ones the entry you show was read with.
49
+ */
50
+ export interface ChargedParcelCountInput {
51
+ stockLocationId: string;
52
+ orderId: string;
53
+ /** Office staff only: also an order the queue leaves out (on hold, …). */
54
+ includeIneligible?: boolean;
55
+ /** Default: preferred, allocated, unrouted. `no_stock` is honoured for office staff only. */
56
+ routing?: WarehouseDemandRouting[];
57
+ }
58
+ /** What `labelMyparcelParcels` asks for. */
59
+ export interface LabelMyparcelParcelsInput {
60
+ /**
61
+ * Ask MyParcel again for EVERY parcel's label in this format (the operator's
62
+ * request), even beside a ready label. Omitted: only the parcels still
63
+ * missing their label or barcode are labelled, in the formats the
64
+ * fulfillment recorded.
65
+ */
66
+ format?: FulfillmentLabelFormat;
67
+ }
68
+ /** What `labelMyparcelParcels` did (`MyparcelLabelParcelsQueued`). */
69
+ export interface MyparcelParcelsLabelRequest {
70
+ fulfillmentId: string;
71
+ /** How many parcels (MyParcel shipments) the fulfillment holds. */
72
+ parcels: number;
73
+ /** How many of them were still missing their label or their barcode. */
74
+ missing: number;
75
+ /**
76
+ * `false` when every parcel already had its label and barcode and no
77
+ * `format` was asked for: nothing was queued. `true` means ONE job was
78
+ * queued; the labels land when it has run, not when this call answers.
79
+ */
80
+ queued: boolean;
81
+ }
82
+ /**
83
+ * What the latest attempt to retract a MyParcel shipment found:
84
+ * - `KEPT`: MyParcel keeps it (only a concept can be deleted; a registered
85
+ * label cannot be deleted through the API);
86
+ * - `UNREACHABLE`: not deleted yet and not known to be kept (MyParcel could
87
+ * not be reached, or refused to delete a concept);
88
+ * - `DELETED` / `ALREADY_GONE`: a later attempt deleted it, or MyParcel no
89
+ * longer holds it. Such an entry carries `resolvedAt` and stays listed.
90
+ */
91
+ export type MyparcelRetractionVerdict = 'KEPT' | 'UNREACHABLE' | 'DELETED' | 'ALREADY_GONE';
92
+ /**
93
+ * A MyParcel shipment a fulfillment or stock transfer let go of (a cancel, a
94
+ * recreate, a removed shipment) that MyParcel did not delete. The engine keeps
95
+ * the record for good and never adopts the shipment again: its label must not
96
+ * be handed to the carrier.
97
+ */
98
+ export interface MyparcelUnretractedShipment {
99
+ shipmentId: number;
100
+ /** What MyParcel knows it by (`F-12`, `F-12#2`, a transfer's reference); null when unknown. */
101
+ reference: string | null;
102
+ verdict: MyparcelRetractionVerdict;
103
+ /** MyParcel's status as last read; null when it could not be read. */
104
+ status: number | null;
105
+ /** MyParcel's machine name for `status` (`pending_registered`, …). */
106
+ statusName: string | null;
107
+ /**
108
+ * MyParcel bills it (handed to the carrier, or a registered digital stamp).
109
+ * `null` is UNKNOWN, which is not `false`.
110
+ */
111
+ billable: boolean | null;
112
+ /** MyParcel accepted the request to hide it from its own lists. */
113
+ hidden: boolean;
114
+ /** The engine's operator-readable explanation. */
115
+ reason: string;
116
+ /** Why it was let go (`fulfillment_cancelled`, `recreated`, `transfer_removed`, …). */
117
+ cause: string;
118
+ /** ISO-8601 UTC. */
119
+ firstRecordedAt: string;
120
+ /** ISO-8601 UTC. */
121
+ lastCheckedAt: string;
122
+ /** ISO-8601 UTC when a later attempt found it deleted or gone; null while it is not. */
123
+ resolvedAt: string | null;
124
+ }
125
+ /** One fulfillment's record of the MyParcel shipments it could not retract. */
126
+ export interface OrderFulfillmentUnretractedShipments {
127
+ fulfillmentId: string;
128
+ /** Every entry, resolved ones included, in the order the engine recorded them. */
129
+ shipments: MyparcelUnretractedShipment[];
130
+ }
131
+ /** One PDF holding every parcel's label, in parcel order. */
132
+ export interface FulfillmentLabel {
133
+ format: FulfillmentLabelFormat;
134
+ contentType: string;
135
+ filename: string;
136
+ bytes: Uint8Array;
137
+ }
138
+ /** Where the goods of an app-fulfilled shipment are, as the app reports it. */
139
+ export type AppFulfillmentReportState = 'Shipped' | 'Delivered';
140
+ /** A fulfilment app's report on a fulfillment it accepted. At least one field. */
141
+ export interface ReportAppFulfillmentInput {
142
+ /** The shipment's tracking code, at most 255 characters. Replaces the fulfillment's. */
143
+ trackingCode?: string;
144
+ /**
145
+ * `Shipped` or `Delivered`. Forward only: a state the fulfillment is already
146
+ * at or past is ignored, so a repeated report is harmless.
147
+ */
148
+ state?: AppFulfillmentReportState;
149
+ }
150
+ /** The fulfillment as it stands after an app's report. */
151
+ export interface ReportedAppFulfillment {
152
+ id: string;
153
+ /** `Pending`, `Shipped`, `Delivered`, … */
154
+ state: string;
155
+ trackingCode: string | null;
156
+ method: string;
157
+ }
158
+ /**
159
+ * What cancelling a fulfillment would owe one order's customer back: a delivery charge they
160
+ * already paid, held to what the order's payments can still hand back (an order still owing
161
+ * gets back only what goes beyond what it owes). Money is integer MINOR UNITS.
162
+ */
163
+ export interface FulfillmentCancelOverpayment {
164
+ orderId: string;
165
+ orderCode: string;
166
+ amount: number;
167
+ currencyCode: string;
168
+ /** Refund to the customer's payment: open, or the refusal choosing it would answer. */
169
+ refund: OverpaymentOption;
170
+ /** Credit to the customer's account: open, or the refusal choosing it would answer. */
171
+ accountCredit: OverpaymentOption;
172
+ }
173
+ /** What a fulfillment cancel would owe back (`cancelPreview`). Nothing was written. */
174
+ export interface FulfillmentCancelPreview {
175
+ fulfillmentId: string;
176
+ /** One entry per order the cancel would leave overpaid; empty when it owes nobody anything. */
177
+ overpayments: FulfillmentCancelOverpayment[];
178
+ }
179
+ /** How one order's paid delivery charge goes back when the fulfillment is cancelled. */
180
+ export interface FulfillmentCancelChoice {
181
+ orderId: string;
182
+ choice: OrderOverpaymentChoice;
183
+ }
184
+ /** What `cancel` sends besides the fulfillment. */
185
+ export interface CancelFulfillmentInput {
186
+ /**
187
+ * One choice for EACH order the cancel leaves overpaid (`cancelPreview` lists them). An order
188
+ * named twice, or one this fulfillment does not ship, is refused before any request.
189
+ */
190
+ overpayment?: FulfillmentCancelChoice[];
191
+ }
192
+ /** What a cancel queued for one order. */
193
+ export interface FulfillmentCancelSettlement {
194
+ orderId: string;
195
+ orderCode: string;
196
+ amount: number;
197
+ currencyCode: string;
198
+ choice: OrderOverpaymentChoice;
199
+ }
200
+ /** A cancelled fulfillment and what its cancel queued. */
201
+ export interface CancelledFulfillment {
202
+ fulfillment: {
203
+ id: string;
204
+ state: string;
205
+ };
206
+ /**
207
+ * One entry per order the cancel left overpaid. The refund or account credit is made right
208
+ * after the cancel commits (normally within seconds): it is QUEUED here, not done. A card
209
+ * refund then stays `Pending` until the provider confirms it; if it cannot be made, the
210
+ * order's history says so and why.
211
+ */
212
+ settlements: FulfillmentCancelSettlement[];
213
+ }
214
+ /** Why an order that is not paid in full may still be handed over. */
215
+ export type FulfillmentCoverageExemption = 'NET_TERMS' | 'EXEMPT_METHOD';
216
+ /** Who granted a coverage override, as the platform names principals. */
217
+ export type FulfillmentCoverageActorKind = 'user' | 'api_token' | 'app_installation';
218
+ /**
219
+ * A recorded decision to hand an order's goods over before it is paid in full. The latest one
220
+ * of an order holds while the order owes no more than `outstandingAtGrant`, in the same currency.
221
+ * Money is integer MINOR UNITS.
222
+ */
223
+ export interface FulfillmentCoverageOverride {
224
+ id: string;
225
+ orderId: string;
226
+ reason: string;
227
+ actorKind: FulfillmentCoverageActorKind;
228
+ /** The user, API token or app installation id. */
229
+ actorId: string;
230
+ outstandingAtGrant: number;
231
+ currencyCode: string;
232
+ /** ISO-8601 UTC. */
233
+ createdAt: string;
234
+ /** Whether it still allows a hand-over now. */
235
+ active: boolean;
236
+ }
237
+ /**
238
+ * Whether an order's goods may be handed over now under the store's fulfilment payment policy
239
+ * (Channel `fulfillmentPaymentPolicy`). Collected money is settled or held by a payment provider;
240
+ * an offline authorization (bank transfer, invoice, cash on delivery) does not count.
241
+ */
242
+ export interface OrderFulfillmentCoverage {
243
+ orderId: string;
244
+ orderCode: string;
245
+ currencyCode: string;
246
+ /** The store requires full payment before a fulfilment is created, extended or shipped. */
247
+ policyActive: boolean;
248
+ /** The collected money covers what the order bills. */
249
+ covered: boolean;
250
+ /** What is still to collect, minor units. */
251
+ outstanding: number;
252
+ exempt: boolean;
253
+ exemptReason: FulfillmentCoverageExemption | null;
254
+ /** A fulfilment may be created, extended and shipped now. */
255
+ allowed: boolean;
256
+ /** The order's latest override, whether or not it still holds. */
257
+ override: FulfillmentCoverageOverride | null;
258
+ }
259
+ /** The longest override reason the engine stores. */
260
+ export declare const FULFILLMENT_COVERAGE_REASON_MAX_LENGTH = 500;
261
+ /**
262
+ * Fulfillment parcels (multi-parcel shipments). Each method is its own request
263
+ * on purpose: a caller deployed ahead of an engine without these fields sees
264
+ * only that call refused, never the order or fulfillment read beside it.
265
+ */
266
+ export interface FulfillmentsModule {
267
+ /** Every fulfillment of an order, with its parcels. Needs `ReadOrder`. */
268
+ parcelsOfOrder(orderId: string, options?: Call): Promise<OrderFulfillmentParcels[]>;
269
+ /**
270
+ * One fulfillment's barcodes per parcel. Needs `ReadFulfillment` and the
271
+ * warehouse entitlement — a Warehouse-role user has no `ReadOrder`.
272
+ */
273
+ parcelTracking(fulfillmentId: string, options?: Call): Promise<FulfillmentParcelTracking>;
274
+ /**
275
+ * Every fulfillment of an order with the MyParcel shipments it let go of
276
+ * (a cancel, a recreate, an abandoned booking) that MyParcel kept or could
277
+ * not be reached to delete, resolved entries included. Needs `ReadOrder`.
278
+ * Reads the engine only, never MyParcel.
279
+ */
280
+ unretractedShipmentsOfOrder(orderId: string, options?: Call): Promise<OrderFulfillmentUnretractedShipments[]>;
281
+ /**
282
+ * Every parcel's MyParcel label merged by MyParcel into one PDF, fetched live
283
+ * and never cached. Needs `ReadOrder`. Allowed up to 55s: the engine retries
284
+ * a slow MyParcel within a budget the default timeout does not cover.
285
+ */
286
+ myparcelLabel(fulfillmentId: string, format: FulfillmentLabelFormat, options?: Call): Promise<FulfillmentLabel>;
287
+ /**
288
+ * The parcel count the customer paid shipping for, as the warehouse's "To
289
+ * ship" entry of the order reports it: only while that entry holds the whole
290
+ * order (every line, nothing of it in a fulfillment yet). `null` otherwise,
291
+ * when the order is not in that queue, or when it was not priced per parcel.
292
+ * Needs `ReadFulfillment` with the warehouse entitlement, or office staff
293
+ * (`UpdateOrder`) — no `ReadOrder`, unlike `admin.orders.parcelCharge`.
294
+ */
295
+ chargedParcelCount(input: ChargedParcelCountInput, options?: Call): Promise<number | null>;
296
+ /**
297
+ * Acquire the MyParcel label of EVERY parcel of a fulfillment: one job asks
298
+ * MyParcel for each parcel's missing label, then reads its barcode back.
299
+ * Labels only — a parcel never booked is booked by the booking's Retry or a
300
+ * recreate. Needs `UpdateOrder`.
301
+ *
302
+ * A refusal throws its coded error: another store's fulfillment is a
303
+ * `NotFoundError` (`MYPARCEL_ORDER_NOT_FOUND_ERROR`); a cancelled one, or
304
+ * one holding no shipment, a `BusinessRuleError`
305
+ * (`MYPARCEL_VALIDATION_ERROR`), as is MyParcel switched off for the store
306
+ * (`MYPARCEL_NOT_CONFIGURED_ERROR`). Only queues work, so the default
307
+ * timeout applies.
308
+ */
309
+ labelMyparcelParcels(fulfillmentId: string, input?: LabelMyparcelParcelsInput, options?: Call): Promise<MyparcelParcelsLabelRequest>;
310
+ /**
311
+ * **For a fulfilment app, with its installation token.** Report the tracking
312
+ * code of a fulfillment the platform asked you to fulfil (your
313
+ * `fulfillment.service` hook's `request`, whose `data.fulfillment.id` is the
314
+ * `fulfillmentId` here) and/or that its goods shipped or arrived. The move
315
+ * goes through the store's own fulfillment process, so the order's state and
316
+ * the `fulfillment.shipped` / `fulfillment.delivered` events follow; the
317
+ * tracking code is written first, so `fulfillment.shipped` carries it.
318
+ *
319
+ * Only the installation the fulfillment was requested from may report, and
320
+ * only while it may act at the fulfillment's stock location (the
321
+ * installation's `locationIds`). `options.idempotencyKey` is optional: a
322
+ * repeat under it answers the fulfillment as it now is.
323
+ *
324
+ * Refusals: `FULFILLMENT_NOT_OWNED_BY_INSTALLATION` (a `PermissionDeniedError`,
325
+ * 403: not a fulfillment requested from this installation on this store — one
326
+ * answer whatever the reason), `LOCATION_NOT_ALLOWED` (403: your installation
327
+ * is restricted to other stock locations), `APP_FULFILLMENT_NOT_BOOKED` (your
328
+ * acceptance is not recorded yet: answer the request, which the platform
329
+ * retries), `APP_FULFILLMENT_STATE_NOT_REPORTABLE` (the fulfillment is
330
+ * cancelled, or the store refused the move), `APP_FULFILLMENT_REPORT_INVALID`.
331
+ */
332
+ reportAppFulfillment(fulfillmentId: string, input: ReportAppFulfillmentInput, options?: Call & {
333
+ idempotencyKey?: string;
334
+ }): Promise<ReportedAppFulfillment>;
335
+ /**
336
+ * What cancelling the fulfillment would owe each order's customer back (a delivery charge
337
+ * they already paid), and which ways of settling it are open. Read now, without a lock; the
338
+ * cancel judges it again. Needs `UpdateOrder`. Another store's fulfillment is a
339
+ * `NotFoundError` (`ENTITY_NOT_FOUND`).
340
+ */
341
+ cancelPreview(fulfillmentId: string, options?: Call): Promise<FulfillmentCancelPreview>;
342
+ /**
343
+ * Cancel a fulfillment (the order page's Remove). Its delivery charge comes off every order it
344
+ * charged; where the customer already paid it, `input.overpayment` says for EACH such order
345
+ * whether it is refunded to their payment (`REFUND`) or credited to their account
346
+ * (`ACCOUNT_CREDIT`). Needs `UpdateOrder`.
347
+ *
348
+ * Refusals, each before anything is written and before the carrier is told:
349
+ * `FULFILLMENT_CANCEL_OVERPAYMENT_CHOICE_REQUIRED` (→ `BusinessRuleError`) when an order owing
350
+ * money has no choice: read `cancelPreview`, ask, and cancel again;
351
+ * `FULFILLMENT_CANCEL_OVERPAYMENT_NOT_SETTLEABLE` (→ `BusinessRuleError`) when neither way is
352
+ * open for an order; `FULFILLMENT_CANCEL_OVERPAYMENT_INVALID` (→ `ValidationError`) for an
353
+ * order the fulfillment does not ship; a closed way chosen anyway answers its own refusal
354
+ * (`REFUND_EXCEEDS_PAYMENT`, `REFUND_METHOD_UNAVAILABLE`, `AR_ACCOUNT_REQUIRED`,
355
+ * `AR_ACCOUNT_IN_ERP`, `ORDER_OVERPAYMENT_REFUND_UNRECONCILED`, …);
356
+ * `FULFILLMENT_CANCEL_REFUSED` (→ `BusinessRuleError`) when the fulfillment's process refuses
357
+ * the cancel (already cancelled, a carrier that cannot let go). Another store's fulfillment is
358
+ * a `NotFoundError`.
359
+ *
360
+ * `options.idempotencyKey`: a repeat under it answers the first call's result, never a second
361
+ * cancel; the same key with a different choice is `IDEMPOTENCY_CONFLICT`.
362
+ */
363
+ cancel(fulfillmentId: string, input?: CancelFulfillmentInput, options?: Call & {
364
+ idempotencyKey?: string;
365
+ }): Promise<CancelledFulfillment>;
366
+ /**
367
+ * Whether the order's goods may be handed over now under the store's fulfilment payment
368
+ * policy, and why: covered, exempt (net terms, an exempt method), or an override that still
369
+ * holds. Needs `ReadOrder`. Another store's order is a `NotFoundError`
370
+ * (`FULFILLMENT_COVERAGE_ORDER_NOT_FOUND`).
371
+ *
372
+ * On a store that requires full payment, creating, extending or shipping a fulfilment of an
373
+ * uncovered order is refused `ORDER_NOT_COVERED` (→ `BusinessRuleError`; the GraphQL error's
374
+ * `extensions` carry `orderId`, `orderCode`, `outstanding` and `currencyCode`, and this call
375
+ * reads the same facts); a warehouse API call answers it as
376
+ * `WarehouseError { code: ORDER_NOT_COVERED }`.
377
+ */
378
+ coverage(orderId: string, options?: Call): Promise<OrderFulfillmentCoverage>;
379
+ /**
380
+ * Record that the order may be handed over before it is paid in full, while it owes no more
381
+ * than it does now. Needs `OverrideFulfillmentPaymentCoverage`. Append-only: a later grant
382
+ * supersedes the earlier ones. The order's history gets a private entry and the audit trail
383
+ * an event.
384
+ *
385
+ * A blank reason, or one over 500 characters, is refused before any request
386
+ * (`FULFILLMENT_COVERAGE_OVERRIDE_INVALID`, → `ValidationError`), as the engine would.
387
+ * `options.idempotencyKey`: a repeat under it answers the first grant, never a second one.
388
+ */
389
+ allowUncovered(orderId: string, reason: string, options?: Call & {
390
+ idempotencyKey?: string;
391
+ }): Promise<FulfillmentCoverageOverride>;
392
+ }
393
+ /**
394
+ * Its own document, like every call here: on an engine without the query this call alone fails
395
+ * validation.
396
+ */
397
+ export declare const FULFILLMENT_CANCEL_PREVIEW_QUERY = "\n query FulfillmentCancelPreview($fulfillmentId: ID!) {\n fulfillmentCancelPreview(fulfillmentId: $fulfillmentId) {\n fulfillmentId\n overpayments {\n orderId\n orderCode\n amount\n currencyCode\n refund { \n available\n code\n message\n }\n accountCredit { \n available\n code\n message\n }\n }\n }\n }\n";
398
+ /** `$overpayment` and `$idempotencyKey` are optional and left out of the variables when not given. */
399
+ export declare const CANCEL_FULFILLMENT_MUTATION = "\n mutation CancelFulfillment(\n $fulfillmentId: ID!\n $overpayment: [FulfillmentCancelOverpaymentInput!]\n $idempotencyKey: String\n ) {\n cancelFulfillment(\n fulfillmentId: $fulfillmentId\n overpayment: $overpayment\n idempotencyKey: $idempotencyKey\n ) {\n fulfillment {\n id\n state\n }\n settlements {\n orderId\n orderCode\n amount\n currencyCode\n choice\n }\n }\n }\n";
400
+ /** Its own document: on an engine without the query this call alone fails validation. */
401
+ export declare const ORDER_FULFILLMENT_COVERAGE_QUERY = "\n query OrderFulfillmentCoverage($orderId: ID!) {\n orderFulfillmentCoverage(orderId: $orderId) {\n orderId\n orderCode\n currencyCode\n policyActive\n covered\n outstanding\n exempt\n exemptReason\n allowed\n override { \n id\n orderId\n reason\n actorKind\n actorId\n outstandingAtGrant\n currencyCode\n createdAt\n active\n }\n }\n }\n";
402
+ /** `$idempotencyKey` is optional and left out of the variables when not given. */
403
+ export declare const ALLOW_UNCOVERED_FULFILLMENT_MUTATION = "\n mutation AllowUncoveredFulfillment($orderId: ID!, $reason: String!, $idempotencyKey: String) {\n allowUncoveredFulfillment(orderId: $orderId, reason: $reason, idempotencyKey: $idempotencyKey) {\n \n id\n orderId\n reason\n actorKind\n actorId\n outstandingAtGrant\n currencyCode\n createdAt\n active\n\n }\n }\n";
404
+ export declare const REPORT_APP_FULFILLMENT_MUTATION = "\n mutation ReportAppFulfillment(\n $fulfillmentId: ID!\n $input: ReportAppFulfillmentInput!\n $idempotencyKey: String\n ) {\n reportAppFulfillment(\n fulfillmentId: $fulfillmentId\n input: $input\n idempotencyKey: $idempotencyKey\n ) {\n id\n state\n trackingCode\n method\n }\n }\n";
405
+ export declare const ORDER_FULFILLMENT_PARCELS_QUERY = "\n query OrderFulfillmentParcels($id: ID!) {\n order(id: $id) {\n id\n fulfillments {\n id\n trackingCode\n customFields {\n myparcelShipmentId\n myparcelShipmentIds\n parcelCount\n trackingCodes\n }\n }\n }\n }\n";
406
+ /** Every field of `MyparcelUnretractedShipment`, shared with the stock-transfer twin. */
407
+ export declare const UNRETRACTED_SHIPMENT_FIELDS = "\n shipmentId\n reference\n verdict\n status\n statusName\n billable\n hidden\n reason\n cause\n firstRecordedAt\n lastCheckedAt\n resolvedAt\n";
408
+ /**
409
+ * Its own document, never part of the parcel read: an engine without the
410
+ * field refuses this call alone, and the order card still renders.
411
+ */
412
+ export declare const ORDER_FULFILLMENT_UNRETRACTED_SHIPMENTS_QUERY = "\n query OrderFulfillmentUnretractedShipments($id: ID!) {\n order(id: $id) {\n id\n fulfillments {\n id\n myparcelUnretractedShipments { \n shipmentId\n reference\n verdict\n status\n statusName\n billable\n hidden\n reason\n cause\n firstRecordedAt\n lastCheckedAt\n resolvedAt\n }\n }\n }\n }\n";
413
+ export declare const FULFILLMENT_PARCEL_TRACKING_QUERY = "\n query FulfillmentParcelTracking($id: ID!) {\n warehouseFulfillment(id: $id) {\n trackingCodes\n parcelTrackingCodes\n parcelCount\n }\n }\n";
414
+ /**
415
+ * Its own document on purpose: `chargedParcelCount` exists only on an engine
416
+ * that serves it, so on an older one this call alone fails validation and the
417
+ * demand the create flow reads beside it does not.
418
+ */
419
+ export declare const WAREHOUSE_CHARGED_PARCEL_COUNT_QUERY = "\n query WarehouseChargedParcelCount($input: WarehouseDemandInput!) {\n warehouseDemand(input: $input) {\n items {\n orderId\n chargedParcelCount\n }\n }\n }\n";
420
+ export declare const MYPARCEL_FULFILLMENT_LABEL_MUTATION = "\n mutation MyparcelFulfillmentLabel($fulfillmentId: ID!, $format: MyparcelLabelFormatEnum!) {\n getMyparcelFulfillmentLabel(fulfillmentId: $fulfillmentId, format: $format) {\n format\n base64\n contentType\n filename\n }\n }\n";
421
+ /**
422
+ * Its own document, like every call here: on an engine without the mutation
423
+ * this call alone fails validation. `$format` is optional and left out of the
424
+ * variables when not asked for.
425
+ */
426
+ export declare const LABEL_MYPARCEL_FULFILLMENT_PARCELS_MUTATION = "\n mutation LabelMyparcelFulfillmentParcels($fulfillmentId: ID!, $format: MyparcelLabelFormatEnum) {\n labelMyparcelFulfillmentParcels(fulfillmentId: $fulfillmentId, format: $format) {\n __typename\n ... on MyparcelLabelParcelsQueued {\n fulfillmentId\n parcels\n missing\n queued\n }\n ... on ErrorResult {\n errorCode\n message\n }\n }\n }\n";
427
+ /**
428
+ * Clears the engine's MyParcel budget: 3 × 10s attempts plus two capped waits.
429
+ * Every merged MyParcel label (a fulfillment's, a stock transfer's) runs the
430
+ * same engine download, so they share it.
431
+ */
432
+ export declare const MYPARCEL_LABEL_TIMEOUT_MS = 55000;
433
+ /** The engine's entries as they are: the fields are the SDK's, one to one. */
434
+ export declare function toUnretractedShipments(raw: readonly MyparcelUnretractedShipment[] | null | undefined): MyparcelUnretractedShipment[];
435
+ /** The bytes of a base64 label document (`atob`: no Node `Buffer`, it ships to browsers). */
436
+ export declare function decodeBase64(base64: string): Uint8Array;
437
+ export declare function createFulfillmentsModule(transport: Transport): FulfillmentsModule;