@sixtyninecommerce/admin 0.9.0 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4598 -128
- package/dist/catalog/assets.d.ts +120 -8
- package/dist/catalog/assets.js +98 -12
- package/dist/catalog/collections.d.ts +279 -14
- package/dist/catalog/collections.js +246 -15
- package/dist/catalog/index.d.ts +9 -2
- package/dist/catalog/index.js +4 -0
- package/dist/catalog/products.d.ts +318 -17
- package/dist/catalog/products.js +182 -14
- package/dist/catalog/properties.d.ts +102 -14
- package/dist/catalog/properties.js +13 -0
- package/dist/catalog/recommendations.d.ts +261 -0
- package/dist/catalog/recommendations.js +145 -0
- package/dist/catalog/reviews.d.ts +368 -0
- package/dist/catalog/reviews.js +318 -0
- package/dist/catalog/types.d.ts +17 -1
- package/dist/catalog/types.js +10 -0
- package/dist/catalog/variant-find.d.ts +136 -0
- package/dist/catalog/variant-find.js +239 -0
- package/dist/catalog/variants.d.ts +282 -25
- package/dist/catalog/variants.js +173 -25
- package/dist/catalog/visibility.d.ts +20 -5
- package/dist/catalog/visibility.js +19 -1
- package/dist/client.d.ts +116 -9
- package/dist/client.js +41 -7
- package/dist/content/assets.d.ts +286 -0
- package/dist/content/assets.js +181 -0
- package/dist/content/items.d.ts +269 -0
- package/dist/content/items.js +170 -0
- package/dist/content/types.d.ts +282 -0
- package/dist/content/types.js +100 -0
- package/dist/customers/age-verification.d.ts +66 -0
- package/dist/customers/age-verification.js +79 -0
- package/dist/customers/credit.d.ts +263 -0
- package/dist/customers/credit.js +244 -0
- package/dist/customers/delivery-preferences.d.ts +120 -0
- package/dist/customers/delivery-preferences.js +97 -0
- package/dist/customers/groups.d.ts +207 -0
- package/dist/customers/groups.js +438 -0
- package/dist/customers/index.d.ts +447 -37
- package/dist/customers/index.js +313 -40
- package/dist/customers/invitation-status.d.ts +57 -0
- package/dist/customers/invitation-status.js +21 -0
- package/dist/customers/notes.d.ts +67 -0
- package/dist/customers/notes.js +51 -0
- package/dist/customers/notification-recipients.d.ts +97 -0
- package/dist/customers/notification-recipients.js +84 -0
- package/dist/customers/saved-lists.d.ts +42 -0
- package/dist/customers/saved-lists.js +61 -0
- package/dist/customers/vat.d.ts +83 -0
- package/dist/customers/vat.js +46 -0
- package/dist/customers/wire.d.ts +20 -0
- package/dist/customers/wire.js +35 -0
- package/dist/documents/ar.d.ts +307 -0
- package/dist/documents/ar.js +254 -0
- package/dist/documents/index.d.ts +731 -21
- package/dist/documents/index.js +436 -24
- package/dist/documents/pdf.d.ts +2 -0
- package/dist/documents/pdf.js +11 -0
- package/dist/fulfillments/create.d.ts +167 -0
- package/dist/fulfillments/create.js +216 -0
- package/dist/fulfillments/index.d.ts +121 -10
- package/dist/fulfillments/index.js +120 -2
- package/dist/fulfillments/payment-policy.d.ts +64 -0
- package/dist/fulfillments/payment-policy.js +140 -0
- package/dist/fulfillments/warehouse.d.ts +724 -0
- package/dist/fulfillments/warehouse.js +914 -0
- package/dist/geo/index.d.ts +119 -0
- package/dist/geo/index.js +107 -0
- package/dist/index.d.ts +129 -30
- package/dist/index.js +47 -9
- package/dist/integrations/afas-actions.d.ts +234 -0
- package/dist/integrations/afas-actions.js +310 -0
- package/dist/integrations/afas-types.d.ts +483 -0
- package/dist/integrations/afas-types.js +5 -0
- package/dist/integrations/afas.d.ts +234 -0
- package/dist/integrations/afas.js +290 -0
- package/dist/integrations/connections.d.ts +103 -0
- package/dist/integrations/connections.js +55 -0
- package/dist/integrations/esp.d.ts +313 -0
- package/dist/integrations/esp.js +169 -0
- package/dist/integrations/exact-online-types.d.ts +423 -0
- package/dist/integrations/exact-online-types.js +6 -0
- package/dist/integrations/exact-online.d.ts +248 -0
- package/dist/integrations/exact-online.js +376 -0
- package/dist/integrations/index.d.ts +40 -0
- package/dist/integrations/index.js +24 -0
- package/dist/integrations/pipeline-keys.d.ts +13 -0
- package/dist/integrations/pipeline-keys.js +22 -0
- package/dist/integrations/pipelines.d.ts +114 -0
- package/dist/integrations/pipelines.js +46 -0
- package/dist/integrations/types.d.ts +322 -0
- package/dist/integrations/types.js +8 -0
- package/dist/jobs/bulk-action-run.d.ts +11 -2
- package/dist/jobs/bulk-action-run.js +4 -5
- package/dist/locations/index.d.ts +66 -0
- package/dist/locations/index.js +31 -0
- package/dist/meta/index.d.ts +162 -0
- package/dist/orders/bulk.d.ts +75 -0
- package/dist/orders/bulk.js +150 -0
- package/dist/orders/cancel-with-money.d.ts +227 -0
- package/dist/orders/cancel-with-money.js +153 -0
- package/dist/orders/commit-edit.d.ts +7 -1
- package/dist/orders/commit-edit.js +5 -1
- package/dist/orders/deposit-policy.d.ts +103 -0
- package/dist/orders/deposit-policy.js +202 -0
- package/dist/orders/drafts.d.ts +800 -0
- package/dist/orders/drafts.js +771 -0
- package/dist/orders/fields.d.ts +245 -0
- package/dist/orders/fields.js +188 -0
- package/dist/orders/get.d.ts +29 -19
- package/dist/orders/get.js +17 -8
- package/dist/orders/index.d.ts +125 -5
- package/dist/orders/index.js +35 -2
- package/dist/orders/lifecycle.d.ts +128 -0
- package/dist/orders/lifecycle.js +158 -0
- package/dist/orders/line-price-preview.d.ts +7 -2
- package/dist/orders/list.d.ts +222 -0
- package/dist/orders/list.js +377 -0
- package/dist/orders/manual-discounts.d.ts +11 -2
- package/dist/orders/manual-discounts.js +2 -0
- package/dist/orders/manual-pricing.d.ts +5 -0
- package/dist/orders/order-entry.d.ts +20 -7
- package/dist/orders/plan-edit.d.ts +1 -1
- package/dist/orders/plan-edit.js +4 -1
- package/dist/orders/settings.d.ts +201 -0
- package/dist/orders/settings.js +325 -0
- package/dist/orders/status.d.ts +159 -13
- package/dist/orders/status.js +21 -0
- package/dist/orders/surcharges.d.ts +8 -1
- package/dist/orders/surcharges.js +3 -2
- package/dist/payments/account-credit.d.ts +30 -0
- package/dist/payments/account-credit.js +19 -0
- package/dist/payments/ar.d.ts +292 -0
- package/dist/payments/ar.js +223 -0
- package/dist/payments/connected-account.d.ts +47 -0
- package/dist/payments/connected-account.js +61 -0
- package/dist/payments/credit-noted-fields.d.ts +12 -0
- package/dist/payments/credit-noted-fields.js +37 -0
- package/dist/payments/index.d.ts +263 -10
- package/dist/payments/index.js +133 -1
- package/dist/payments/methods.d.ts +332 -0
- package/dist/payments/methods.js +363 -0
- package/dist/payments/mollie-methods.d.ts +159 -0
- package/dist/payments/mollie-methods.js +141 -0
- package/dist/payments/payment-links.d.ts +180 -0
- package/dist/payments/payment-links.js +97 -0
- package/dist/payments/provider-keys.d.ts +150 -0
- package/dist/payments/provider-keys.js +118 -0
- package/dist/payments/providers.d.ts +86 -11
- package/dist/payments/providers.js +29 -0
- package/dist/payments/requests.d.ts +144 -0
- package/dist/payments/requests.js +92 -0
- package/dist/payments/store-credit-fields.d.ts +15 -0
- package/dist/payments/store-credit-fields.js +51 -0
- package/dist/pickups/index.d.ts +104 -0
- package/dist/pickups/index.js +105 -0
- package/dist/platform/channels.d.ts +132 -0
- package/dist/platform/channels.js +128 -0
- package/dist/platform/geo.d.ts +123 -0
- package/dist/platform/geo.js +144 -0
- package/dist/platform/tax.d.ts +154 -0
- package/dist/platform/tax.js +139 -0
- package/dist/pos/anomalies.d.ts +158 -0
- package/dist/pos/anomalies.js +64 -0
- package/dist/pos/assisted-selling.d.ts +79 -0
- package/dist/pos/assisted-selling.js +38 -0
- package/dist/pos/exchanges.d.ts +103 -0
- package/dist/pos/exchanges.js +22 -0
- package/dist/pos/gift-cards.d.ts +135 -0
- package/dist/pos/gift-cards.js +47 -0
- package/dist/pos/index.d.ts +2125 -32
- package/dist/pos/index.js +742 -4
- package/dist/pos/no-receipt.d.ts +94 -0
- package/dist/pos/no-receipt.js +25 -0
- package/dist/pos/offline-sales.d.ts +187 -0
- package/dist/pos/offline-sales.js +116 -0
- package/dist/pos/pay-by-link.d.ts +143 -0
- package/dist/pos/pay-by-link.js +57 -0
- package/dist/pos/quick-keys.d.ts +103 -0
- package/dist/pos/quick-keys.js +45 -0
- package/dist/pos/reports.d.ts +360 -0
- package/dist/pos/reports.js +62 -0
- package/dist/pos/returns.d.ts +217 -0
- package/dist/pos/returns.js +53 -0
- package/dist/pricing/bulk-coupons.d.ts +139 -0
- package/dist/pricing/bulk-coupons.js +112 -0
- package/dist/pricing/index.d.ts +177 -4
- package/dist/pricing/index.js +176 -1
- package/dist/pricing/price-lists.d.ts +604 -0
- package/dist/pricing/price-lists.js +600 -0
- package/dist/pricing/vouchers.d.ts +103 -0
- package/dist/pricing/vouchers.js +69 -0
- package/dist/purchasing/alerts.d.ts +89 -0
- package/dist/purchasing/alerts.js +62 -0
- package/dist/purchasing/cost.d.ts +110 -0
- package/dist/purchasing/cost.js +86 -0
- package/dist/purchasing/index.d.ts +36 -0
- package/dist/purchasing/index.js +16 -0
- package/dist/purchasing/purchase-orders.d.ts +548 -0
- package/dist/purchasing/purchase-orders.js +491 -0
- package/dist/purchasing/replenishment.d.ts +281 -0
- package/dist/purchasing/replenishment.js +240 -0
- package/dist/purchasing/settings.d.ts +152 -0
- package/dist/purchasing/settings.js +181 -0
- package/dist/purchasing/suppliers.d.ts +476 -0
- package/dist/purchasing/suppliers.js +438 -0
- package/dist/quotes/index.d.ts +501 -0
- package/dist/quotes/index.js +439 -0
- package/dist/reports/index.d.ts +71 -8
- package/dist/reports/index.js +74 -11
- package/dist/returns/index.d.ts +818 -0
- package/dist/returns/index.js +844 -0
- package/dist/search/index.d.ts +174 -0
- package/dist/search/index.js +125 -0
- package/dist/shipping/definitions.d.ts +29 -0
- package/dist/shipping/definitions.js +47 -0
- package/dist/shipping/fulfillment-profiles.d.ts +174 -0
- package/dist/shipping/fulfillment-profiles.js +104 -0
- package/dist/shipping/hendriks.d.ts +97 -0
- package/dist/shipping/hendriks.js +50 -0
- package/dist/shipping/index.d.ts +48 -0
- package/dist/shipping/index.js +25 -0
- package/dist/shipping/methods.d.ts +198 -0
- package/dist/shipping/methods.js +240 -0
- package/dist/shipping/myparcel.d.ts +254 -0
- package/dist/shipping/myparcel.js +178 -0
- package/dist/shipping/parcel-count-suggestion.d.ts +2 -0
- package/dist/shipping/parcel-rule.d.ts +6 -5
- package/dist/shipping/parcel-rule.js +21 -23
- package/dist/shipping/rate-tables.d.ts +179 -0
- package/dist/shipping/rate-tables.js +184 -0
- package/dist/stock/index.d.ts +10 -3
- package/dist/stock/index.js +3 -0
- package/dist/stock/locations.d.ts +144 -0
- package/dist/stock/locations.js +168 -0
- package/dist/stock/transfers.d.ts +216 -43
- package/dist/stock/transfers.js +140 -13
- package/dist/stored-value/index.d.ts +214 -4
- package/dist/stored-value/index.js +152 -0
- package/dist/subscriptions/index.d.ts +682 -0
- package/dist/subscriptions/index.js +815 -0
- package/dist/tax/index.d.ts +76 -1
- package/dist/tax/index.js +50 -0
- package/dist/tenant/email-style.d.ts +102 -0
- package/dist/tenant/email-style.js +72 -0
- package/dist/tenant/email-templates.d.ts +66 -0
- package/dist/tenant/email-templates.js +54 -0
- package/dist/tenant/notifications.d.ts +23 -17
- package/dist/tenant/settings-sources.d.ts +1 -1
- package/dist/tenant/time-zone.d.ts +17 -0
- package/dist/tenant/time-zone.js +11 -0
- package/dist/types.d.ts +51 -4
- package/dist/users/index.d.ts +3 -0
- package/dist/users/index.js +2 -0
- package/dist/users/warehouses.d.ts +50 -0
- package/dist/users/warehouses.js +51 -0
- package/package.json +2 -2
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
import { type Transport } from '@sixtyninecommerce/core';
|
|
2
|
+
import type { Call } from '../types.js';
|
|
3
|
+
/** What `admin.search.entities` searches. */
|
|
4
|
+
export type SearchEntityType = 'PRODUCTS' | 'ORDERS' | 'CUSTOMERS' | 'CONTENT';
|
|
5
|
+
/**
|
|
6
|
+
* Why a type was not searched. A string on the wire: a newer engine may add a reason, so read an
|
|
7
|
+
* unknown one as "not searched".
|
|
8
|
+
*
|
|
9
|
+
* - `PERMISSION`: the credential holds none of the type's read permissions in the store
|
|
10
|
+
* (`ReadCatalog` or `ReadProduct` for products, `ReadOrder` for orders, `ReadCustomer` for
|
|
11
|
+
* customers).
|
|
12
|
+
* - `CUSTOMER_DATA_NOT_GRANTED`: the credential reads customer data below `full` (an app installed
|
|
13
|
+
* at `none` or `identity`). Orders and customers are matched on customers' names, email
|
|
14
|
+
* addresses and companies, so they are not searched for it.
|
|
15
|
+
* - `UNAVAILABLE`: the search service, or for content the content system, did not answer. Try
|
|
16
|
+
* again shortly.
|
|
17
|
+
*/
|
|
18
|
+
export type SearchSkipReason = 'PERMISSION' | 'CUSTOMER_DATA_NOT_GRANTED' | 'UNAVAILABLE' | (string & {});
|
|
19
|
+
export interface SearchProductHit {
|
|
20
|
+
id: string;
|
|
21
|
+
name: string;
|
|
22
|
+
slug: string;
|
|
23
|
+
/** The featured image's preview URL; null when the product has none. */
|
|
24
|
+
previewUrl: string | null;
|
|
25
|
+
}
|
|
26
|
+
export interface SearchOrderHit {
|
|
27
|
+
id: string;
|
|
28
|
+
code: string;
|
|
29
|
+
state: string;
|
|
30
|
+
/** ISO-8601; null for an order not placed yet. */
|
|
31
|
+
orderPlacedAt: string | null;
|
|
32
|
+
/** Minor units. */
|
|
33
|
+
totalWithTax: number;
|
|
34
|
+
currencyCode: string;
|
|
35
|
+
/** The order's lifecycle (`open`, `completed`, …); null until the engine sets it. */
|
|
36
|
+
lifecycleStatus: string | null;
|
|
37
|
+
}
|
|
38
|
+
export interface SearchCustomerHit {
|
|
39
|
+
id: string;
|
|
40
|
+
firstName: string;
|
|
41
|
+
lastName: string;
|
|
42
|
+
emailAddress: string;
|
|
43
|
+
/** The company of the default billing address, else the default shipping one, else any. */
|
|
44
|
+
company: string | null;
|
|
45
|
+
}
|
|
46
|
+
/** A content item of the store's content system. */
|
|
47
|
+
export interface SearchContentHit {
|
|
48
|
+
id: string;
|
|
49
|
+
collectionId: string;
|
|
50
|
+
collectionSlug: string;
|
|
51
|
+
slug: string | null;
|
|
52
|
+
/** `draft`, `published` or `archived`. */
|
|
53
|
+
status: string;
|
|
54
|
+
title: string | null;
|
|
55
|
+
}
|
|
56
|
+
export interface SearchSkip {
|
|
57
|
+
type: SearchEntityType | (string & {});
|
|
58
|
+
reason: SearchSkipReason;
|
|
59
|
+
}
|
|
60
|
+
/** Each list holds the type's best matches, most relevant first. */
|
|
61
|
+
export interface EntitySearchResult {
|
|
62
|
+
products: SearchProductHit[];
|
|
63
|
+
orders: SearchOrderHit[];
|
|
64
|
+
customers: SearchCustomerHit[];
|
|
65
|
+
content: SearchContentHit[];
|
|
66
|
+
/** The types that were not searched, and why; their lists are empty. */
|
|
67
|
+
skipped: SearchSkip[];
|
|
68
|
+
}
|
|
69
|
+
export interface SearchEntitiesOptions extends Call {
|
|
70
|
+
/** The types to search; all four when omitted. An empty list is refused. */
|
|
71
|
+
types?: readonly SearchEntityType[];
|
|
72
|
+
/** Results per type, from 1 to {@link SEARCH_ENTITIES_MAX_TAKE}; 5 when omitted. */
|
|
73
|
+
take?: number;
|
|
74
|
+
}
|
|
75
|
+
/** The engine's bounds, as `searchAcrossEntities` documents them. */
|
|
76
|
+
export declare const SEARCH_ENTITIES_MIN_TERM_LENGTH = 2;
|
|
77
|
+
export declare const SEARCH_ENTITIES_MAX_TAKE = 10;
|
|
78
|
+
export declare const SEARCH_ACROSS_ENTITIES_QUERY = "\n query SearchAcrossEntities($input: CommandSearchInput!) {\n searchAcrossEntities(input: $input) {\n products {\n id\n name\n slug\n previewUrl\n }\n orders {\n id\n code\n state\n orderPlacedAt\n totalWithTax\n currencyCode\n lifecycleStatus\n }\n customers {\n id\n firstName\n lastName\n emailAddress\n company\n }\n content {\n id\n collectionId\n collectionSlug\n slug\n status\n title\n }\n skipped {\n type\n reason\n }\n }\n }\n";
|
|
79
|
+
/**
|
|
80
|
+
* The store's search indexes `search.index` reads, one per kind of record. Each holds the store's
|
|
81
|
+
* rows of that kind; the products index is the admin catalogue index, not the storefront's.
|
|
82
|
+
*/
|
|
83
|
+
export declare const SEARCH_INDEXES: readonly ["products", "orders", "customers", "facets", "promotions", "customer_groups", "stock_locations", "collections"];
|
|
84
|
+
export type SearchIndex = (typeof SEARCH_INDEXES)[number];
|
|
85
|
+
/** The engine's bound on the clauses of one `search.index` call, `filters` and groups together. */
|
|
86
|
+
export declare const SEARCH_INDEX_MAX_FILTERS = 32;
|
|
87
|
+
export interface SearchIndexInput {
|
|
88
|
+
/** Full text; `''` matches every row the filters keep. */
|
|
89
|
+
term: string;
|
|
90
|
+
/**
|
|
91
|
+
* Clauses, all of which must hold, each one of exactly these shapes on an attribute the index
|
|
92
|
+
* lets you filter on: `field = "value"`, `field = true|false`, `field STARTS WITH "value"`,
|
|
93
|
+
* `field CONTAINS "value"`, `field IN ["a", "b"]`, `field IS EMPTY`. Quote a string value with
|
|
94
|
+
* {@link escapeSearchFilterValue}: `code STARTS WITH "${escapeSearchFilterValue(prefix)}"`.
|
|
95
|
+
*/
|
|
96
|
+
filters?: readonly string[];
|
|
97
|
+
/** Groups of clauses: each group must hold, and holds when ANY of its own clauses does. */
|
|
98
|
+
filterGroups?: ReadonlyArray<readonly string[]>;
|
|
99
|
+
/** `field` ascending or `-field` descending, on a field the index sorts by; relevance otherwise. */
|
|
100
|
+
sort?: string;
|
|
101
|
+
/** Rows to skip, 0 when omitted. */
|
|
102
|
+
skip?: number;
|
|
103
|
+
/** Rows to answer, 25 when omitted. */
|
|
104
|
+
take?: number;
|
|
105
|
+
}
|
|
106
|
+
/** One hit: the record's id, how well it matched, and the index's copy of it. */
|
|
107
|
+
export interface SearchIndexHit {
|
|
108
|
+
id: string;
|
|
109
|
+
/** The search engine's ranking score, 0 to 1: higher is a better match. */
|
|
110
|
+
score: number;
|
|
111
|
+
/**
|
|
112
|
+
* The index's snapshot of the record, as the store may see it: written by a job after the
|
|
113
|
+
* record's change commits, so it can lag by seconds. Read the record itself for current values.
|
|
114
|
+
*/
|
|
115
|
+
document: Record<string, unknown>;
|
|
116
|
+
}
|
|
117
|
+
export interface SearchIndexResult {
|
|
118
|
+
items: SearchIndexHit[];
|
|
119
|
+
/** Every hit the term and filters match, not only this page's. */
|
|
120
|
+
total: number;
|
|
121
|
+
}
|
|
122
|
+
export declare const SEARCH_ENTITIES_QUERY = "\n query SearchIndex($input: EntitySearchInput!) {\n searchEntities(input: $input) {\n items {\n id\n score\n document\n }\n totalItems\n }\n }\n";
|
|
123
|
+
/**
|
|
124
|
+
* A string value inside a `search.index` filter's double quotes: its backslashes and quotes
|
|
125
|
+
* escaped, so what a person typed can never close the literal and add a clause.
|
|
126
|
+
*/
|
|
127
|
+
export declare function escapeSearchFilterValue(value: string): string;
|
|
128
|
+
/**
|
|
129
|
+
* One search across the store (spec §7 `search.entities`): products, orders, customers and
|
|
130
|
+
* content items matching a term, in one call.
|
|
131
|
+
*
|
|
132
|
+
* - **Relevance order.** Each list is that type's best matches, most relevant first, every one
|
|
133
|
+
* already loaded in the store you act on; a match the store no longer holds is left out, so a
|
|
134
|
+
* list can be shorter than `take`.
|
|
135
|
+
* - **A type you may not read is skipped and named**, never a refusal: its list is empty and
|
|
136
|
+
* `skipped` says why (see {@link SearchSkipReason}).
|
|
137
|
+
* - **Content may be missing when the content system is down**: the other types still answer,
|
|
138
|
+
* and content is skipped `UNAVAILABLE`.
|
|
139
|
+
* - **Content** is published items, plus drafts and archived items for a `ReadCmsContent` holder.
|
|
140
|
+
*
|
|
141
|
+
* Refused before anything is searched: `SEARCH_INPUT_INVALID` (`ValidationError`, 400) for a term
|
|
142
|
+
* under {@link SEARCH_ENTITIES_MIN_TERM_LENGTH} or over 500 characters once trimmed, a `take`
|
|
143
|
+
* outside 1..{@link SEARCH_ENTITIES_MAX_TAKE}, or an empty `types` list.
|
|
144
|
+
*/
|
|
145
|
+
export interface SearchModule {
|
|
146
|
+
/** @effect read */
|
|
147
|
+
entities(term: string, options?: SearchEntitiesOptions): Promise<EntitySearchResult>;
|
|
148
|
+
/**
|
|
149
|
+
* One page of one search index of the store: hits in relevance order (or `sort`'s), each with
|
|
150
|
+
* the index's copy of the record. Use it to find ids by text or by an indexed attribute the
|
|
151
|
+
* record's own list cannot filter on, then read the records themselves.
|
|
152
|
+
*
|
|
153
|
+
* - **The store is always the one you act on**: no filter reaches another store's rows.
|
|
154
|
+
* - **Documents are index snapshots**, updated by a job after each change: read the record for
|
|
155
|
+
* current values, and expect a just-written record to be missing for a few seconds.
|
|
156
|
+
* - Needs the read permission of the index's own list: `ReadCatalog` or `ReadProduct` for
|
|
157
|
+
* products; `ReadOrder` for orders; `ReadCustomer` for customers; `ReadCustomer` or
|
|
158
|
+
* `ReadCustomerGroup` for customer groups; `ReadCatalog`, `ReadProduct` or `ReadFacet` for
|
|
159
|
+
* facets; `ReadPromotion`; `ReadCatalog` or `ReadStockLocation`; `ReadCatalog` or
|
|
160
|
+
* `ReadCollection`. Without it: `PermissionDeniedError`.
|
|
161
|
+
* - An app reading customer data below `full` is refused the orders and customers indexes
|
|
162
|
+
* (`CUSTOMER_DATA_NOT_GRANTED`): the hits alone would say which customer matches a name.
|
|
163
|
+
*
|
|
164
|
+
* Refused: an index not in {@link SEARCH_INDEXES} (`ValidationError` `SEARCH_INPUT_INVALID`, before
|
|
165
|
+
* anything is asked); and by the engine with `SEARCH_INPUT_INVALID` (400) a clause on an attribute
|
|
166
|
+
* the index does not filter on or in another syntax, more than {@link SEARCH_INDEX_MAX_FILTERS}
|
|
167
|
+
* clauses, or a negative `skip`/`take`. A `sort` field the index cannot sort on is ignored.
|
|
168
|
+
* `SERVICE_UNAVAILABLE` (503, retryable) when the search service did not answer.
|
|
169
|
+
*
|
|
170
|
+
* @effect read
|
|
171
|
+
*/
|
|
172
|
+
index(index: SearchIndex, input: SearchIndexInput, options?: Call): Promise<SearchIndexResult>;
|
|
173
|
+
}
|
|
174
|
+
export declare function createSearchModule(transport: Transport): SearchModule;
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { ValidationError } from '@sixtyninecommerce/core';
|
|
2
|
+
/** The engine's bounds, as `searchAcrossEntities` documents them. */
|
|
3
|
+
export const SEARCH_ENTITIES_MIN_TERM_LENGTH = 2;
|
|
4
|
+
export const SEARCH_ENTITIES_MAX_TAKE = 10;
|
|
5
|
+
export const SEARCH_ACROSS_ENTITIES_QUERY = /* GraphQL */ `
|
|
6
|
+
query SearchAcrossEntities($input: CommandSearchInput!) {
|
|
7
|
+
searchAcrossEntities(input: $input) {
|
|
8
|
+
products {
|
|
9
|
+
id
|
|
10
|
+
name
|
|
11
|
+
slug
|
|
12
|
+
previewUrl
|
|
13
|
+
}
|
|
14
|
+
orders {
|
|
15
|
+
id
|
|
16
|
+
code
|
|
17
|
+
state
|
|
18
|
+
orderPlacedAt
|
|
19
|
+
totalWithTax
|
|
20
|
+
currencyCode
|
|
21
|
+
lifecycleStatus
|
|
22
|
+
}
|
|
23
|
+
customers {
|
|
24
|
+
id
|
|
25
|
+
firstName
|
|
26
|
+
lastName
|
|
27
|
+
emailAddress
|
|
28
|
+
company
|
|
29
|
+
}
|
|
30
|
+
content {
|
|
31
|
+
id
|
|
32
|
+
collectionId
|
|
33
|
+
collectionSlug
|
|
34
|
+
slug
|
|
35
|
+
status
|
|
36
|
+
title
|
|
37
|
+
}
|
|
38
|
+
skipped {
|
|
39
|
+
type
|
|
40
|
+
reason
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
`;
|
|
45
|
+
/**
|
|
46
|
+
* The store's search indexes `search.index` reads, one per kind of record. Each holds the store's
|
|
47
|
+
* rows of that kind; the products index is the admin catalogue index, not the storefront's.
|
|
48
|
+
*/
|
|
49
|
+
export const SEARCH_INDEXES = [
|
|
50
|
+
'products',
|
|
51
|
+
'orders',
|
|
52
|
+
'customers',
|
|
53
|
+
'facets',
|
|
54
|
+
'promotions',
|
|
55
|
+
'customer_groups',
|
|
56
|
+
'stock_locations',
|
|
57
|
+
'collections',
|
|
58
|
+
];
|
|
59
|
+
/** The engine's bound on the clauses of one `search.index` call, `filters` and groups together. */
|
|
60
|
+
export const SEARCH_INDEX_MAX_FILTERS = 32;
|
|
61
|
+
export const SEARCH_ENTITIES_QUERY = /* GraphQL */ `
|
|
62
|
+
query SearchIndex($input: EntitySearchInput!) {
|
|
63
|
+
searchEntities(input: $input) {
|
|
64
|
+
items {
|
|
65
|
+
id
|
|
66
|
+
score
|
|
67
|
+
document
|
|
68
|
+
}
|
|
69
|
+
totalItems
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
`;
|
|
73
|
+
/**
|
|
74
|
+
* A string value inside a `search.index` filter's double quotes: its backslashes and quotes
|
|
75
|
+
* escaped, so what a person typed can never close the literal and add a clause.
|
|
76
|
+
*/
|
|
77
|
+
export function escapeSearchFilterValue(value) {
|
|
78
|
+
return value.replace(/\\/g, '\\\\').replace(/"/g, '\\"');
|
|
79
|
+
}
|
|
80
|
+
export function createSearchModule(transport) {
|
|
81
|
+
return {
|
|
82
|
+
async entities(term, options = {}) {
|
|
83
|
+
const { types, take, ...call } = options;
|
|
84
|
+
const data = await transport.graphql({
|
|
85
|
+
api: 'admin',
|
|
86
|
+
query: SEARCH_ACROSS_ENTITIES_QUERY,
|
|
87
|
+
variables: {
|
|
88
|
+
input: {
|
|
89
|
+
term,
|
|
90
|
+
...(types === undefined ? {} : { types: [...types] }),
|
|
91
|
+
...(take === undefined ? {} : { take }),
|
|
92
|
+
},
|
|
93
|
+
},
|
|
94
|
+
}, call);
|
|
95
|
+
return data.searchAcrossEntities;
|
|
96
|
+
},
|
|
97
|
+
async index(index, input, options) {
|
|
98
|
+
if (!SEARCH_INDEXES.includes(index)) {
|
|
99
|
+
throw new ValidationError({
|
|
100
|
+
code: 'SEARCH_INPUT_INVALID',
|
|
101
|
+
message: `The search index must be one of ${SEARCH_INDEXES.join(', ')}.`,
|
|
102
|
+
status: 400,
|
|
103
|
+
service: 'vendure',
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
const { term, filters, filterGroups, sort, skip, take } = input;
|
|
107
|
+
const data = await transport.graphql({
|
|
108
|
+
api: 'admin',
|
|
109
|
+
query: SEARCH_ENTITIES_QUERY,
|
|
110
|
+
variables: {
|
|
111
|
+
input: {
|
|
112
|
+
term,
|
|
113
|
+
entityType: index,
|
|
114
|
+
...(take === undefined ? {} : { take }),
|
|
115
|
+
...(skip === undefined ? {} : { skip }),
|
|
116
|
+
...(sort === undefined || sort === '' ? {} : { sort }),
|
|
117
|
+
...(filters?.length ? { filters: [...filters] } : {}),
|
|
118
|
+
...(filterGroups?.length ? { filterGroups: filterGroups.map((g) => [...g]) } : {}),
|
|
119
|
+
},
|
|
120
|
+
},
|
|
121
|
+
}, options);
|
|
122
|
+
return { items: data.searchEntities.items, total: data.searchEntities.totalItems };
|
|
123
|
+
},
|
|
124
|
+
};
|
|
125
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { type Transport } from '@sixtyninecommerce/core';
|
|
2
|
+
import type { Call, ConfigurableOperationDefinition } from '../types.js';
|
|
3
|
+
/** What a shipping method's three operations may be, each with the arguments it takes. */
|
|
4
|
+
export interface ShippingDefinitions {
|
|
5
|
+
/** What a method's `calculator` may be: how it prices an order. */
|
|
6
|
+
calculators: ConfigurableOperationDefinition[];
|
|
7
|
+
/** What a method's `checker` may be: which orders it is offered for. */
|
|
8
|
+
eligibilityCheckers: ConfigurableOperationDefinition[];
|
|
9
|
+
/** What a method's `fulfillmentHandler` may be (`manual-fulfillment`, a carrier's handler). */
|
|
10
|
+
fulfillmentHandlers: ConfigurableOperationDefinition[];
|
|
11
|
+
}
|
|
12
|
+
/** `admin.shipping.definitions`. */
|
|
13
|
+
export interface ShippingDefinitionsModule {
|
|
14
|
+
/**
|
|
15
|
+
* The calculators, eligibility checkers and fulfillment handlers the engine has registered, in
|
|
16
|
+
* one request: the same whichever store the client is on (a handler whose plugin the store does
|
|
17
|
+
* not hold is listed, and refused `PLUGIN_ACCESS_DENIED` when a method picks it). Labels and
|
|
18
|
+
* descriptions are in the language of the request. Needs `ReadSettings`, `ReadOrder` or
|
|
19
|
+
* `ReadShippingMethod` (any one).
|
|
20
|
+
*
|
|
21
|
+
* `args[].required` is NOT the enforced rule (see `ConfigArgDefinition.required`); never gate
|
|
22
|
+
* a form on it.
|
|
23
|
+
*
|
|
24
|
+
* @effect read
|
|
25
|
+
*/
|
|
26
|
+
get(options?: Call): Promise<ShippingDefinitions>;
|
|
27
|
+
}
|
|
28
|
+
export declare const SHIPPING_DEFINITIONS_QUERY = "\n query ShippingDefinitions {\n shippingCalculators { \n code\n description\n args {\n name\n type\n list\n required\n defaultValue\n label\n description\n ui\n }\n }\n shippingEligibilityCheckers { \n code\n description\n args {\n name\n type\n list\n required\n defaultValue\n label\n description\n ui\n }\n }\n fulfillmentHandlers { \n code\n description\n args {\n name\n type\n list\n required\n defaultValue\n label\n description\n ui\n }\n }\n }\n";
|
|
29
|
+
export declare function createShippingDefinitionsModule(transport: Transport): ShippingDefinitionsModule;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { UpstreamError } from '@sixtyninecommerce/core';
|
|
2
|
+
const DEFINITION_FIELDS = /* GraphQL */ `
|
|
3
|
+
code
|
|
4
|
+
description
|
|
5
|
+
args {
|
|
6
|
+
name
|
|
7
|
+
type
|
|
8
|
+
list
|
|
9
|
+
required
|
|
10
|
+
defaultValue
|
|
11
|
+
label
|
|
12
|
+
description
|
|
13
|
+
ui
|
|
14
|
+
}
|
|
15
|
+
`;
|
|
16
|
+
export const SHIPPING_DEFINITIONS_QUERY = /* GraphQL */ `
|
|
17
|
+
query ShippingDefinitions {
|
|
18
|
+
shippingCalculators { ${DEFINITION_FIELDS} }
|
|
19
|
+
shippingEligibilityCheckers { ${DEFINITION_FIELDS} }
|
|
20
|
+
fulfillmentHandlers { ${DEFINITION_FIELDS} }
|
|
21
|
+
}
|
|
22
|
+
`;
|
|
23
|
+
export function createShippingDefinitionsModule(transport) {
|
|
24
|
+
return {
|
|
25
|
+
async get(options) {
|
|
26
|
+
const data = await transport.graphql({ api: 'admin', query: SHIPPING_DEFINITIONS_QUERY, variables: {} }, options);
|
|
27
|
+
// Each list is read by name, so a response missing one is refused, never answered empty.
|
|
28
|
+
const list = (field) => {
|
|
29
|
+
const value = data?.[field];
|
|
30
|
+
if (!Array.isArray(value)) {
|
|
31
|
+
throw new UpstreamError({
|
|
32
|
+
code: 'UNEXPECTED_RESPONSE',
|
|
33
|
+
message: `The engine answered without "${field}".`,
|
|
34
|
+
status: 502,
|
|
35
|
+
service: 'vendure',
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
return value;
|
|
39
|
+
};
|
|
40
|
+
return {
|
|
41
|
+
calculators: list('shippingCalculators'),
|
|
42
|
+
eligibilityCheckers: list('shippingEligibilityCheckers'),
|
|
43
|
+
fulfillmentHandlers: list('fulfillmentHandlers'),
|
|
44
|
+
};
|
|
45
|
+
},
|
|
46
|
+
};
|
|
47
|
+
}
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
import type { Transport } from '@sixtyninecommerce/core';
|
|
2
|
+
import type { Call } from '../types.js';
|
|
3
|
+
/**
|
|
4
|
+
* A store's fulfillment profile: a named binding of a warehouse, a fulfillment handler, a
|
|
5
|
+
* shipping method and a minimum order. A fulfilment created with a profile is judged against its
|
|
6
|
+
* minimum and charged its shipping method's delivery cost (`fulfillments.profileChargePreview`
|
|
7
|
+
* prices it beforehand).
|
|
8
|
+
*/
|
|
9
|
+
export interface FulfillmentProfile {
|
|
10
|
+
id: string;
|
|
11
|
+
/** Stable per store; unique within the store. */
|
|
12
|
+
code: string;
|
|
13
|
+
name: string;
|
|
14
|
+
/** A disabled profile is not offered when fulfilling an order. */
|
|
15
|
+
enabled: boolean;
|
|
16
|
+
/** The warehouse (stock location) the profile ships from. */
|
|
17
|
+
stockLocationId: string;
|
|
18
|
+
/** The fulfillment handler (carrier) code, e.g. `manual-fulfillment`. */
|
|
19
|
+
defaultHandlerCode: string;
|
|
20
|
+
/** The shipping method whose price is the profile's delivery charge. */
|
|
21
|
+
shippingMethodId: string;
|
|
22
|
+
/**
|
|
23
|
+
* The minimum a fulfilment's selected lines must reach, in MINOR units of the store's default
|
|
24
|
+
* currency, NET of tax. `0` is no minimum.
|
|
25
|
+
*/
|
|
26
|
+
minOrder: number;
|
|
27
|
+
/** True for the store's default profile, the one storefront checkout applies. */
|
|
28
|
+
isDefault: boolean;
|
|
29
|
+
/** ISO-8601, UTC. */
|
|
30
|
+
createdAt: string;
|
|
31
|
+
/** ISO-8601, UTC. */
|
|
32
|
+
updatedAt: string;
|
|
33
|
+
}
|
|
34
|
+
export interface CreateFulfillmentProfileInput {
|
|
35
|
+
name: string;
|
|
36
|
+
code: string;
|
|
37
|
+
/** Default `true`. */
|
|
38
|
+
enabled?: boolean;
|
|
39
|
+
/** One of the store's own stock locations. */
|
|
40
|
+
stockLocationId: string;
|
|
41
|
+
defaultHandlerCode: string;
|
|
42
|
+
/** One of the store's own shipping methods. */
|
|
43
|
+
shippingMethodId: string;
|
|
44
|
+
/** Minor units, net, in the store's default currency. Default `0`. */
|
|
45
|
+
minOrder?: number;
|
|
46
|
+
}
|
|
47
|
+
/** A PATCH: a key left out keeps the stored value. */
|
|
48
|
+
export interface UpdateFulfillmentProfileInput {
|
|
49
|
+
name?: string;
|
|
50
|
+
code?: string;
|
|
51
|
+
enabled?: boolean;
|
|
52
|
+
stockLocationId?: string;
|
|
53
|
+
defaultHandlerCode?: string;
|
|
54
|
+
shippingMethodId?: string;
|
|
55
|
+
minOrder?: number;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Who is emailed when a fulfilment is created with a handler, in this store. One record per
|
|
59
|
+
* handler; a handler with no record notifies nobody.
|
|
60
|
+
*/
|
|
61
|
+
export interface FulfillmentHandlerNotification {
|
|
62
|
+
id: string;
|
|
63
|
+
handlerCode: string;
|
|
64
|
+
/** Off pauses the mails without forgetting the recipients. */
|
|
65
|
+
enabled: boolean;
|
|
66
|
+
/** Trimmed, de-duplicated (case-insensitive) addresses, at most 25. */
|
|
67
|
+
emails: string[];
|
|
68
|
+
/** ISO-8601, UTC. */
|
|
69
|
+
createdAt: string;
|
|
70
|
+
/** ISO-8601, UTC. */
|
|
71
|
+
updatedAt: string;
|
|
72
|
+
}
|
|
73
|
+
export interface SetFulfillmentHandlerNotificationInput {
|
|
74
|
+
handlerCode: string;
|
|
75
|
+
/** Left out: `true` for a new record, unchanged for an existing one. */
|
|
76
|
+
enabled?: boolean;
|
|
77
|
+
/** The WHOLE list: it replaces the stored one. `[]` clears it. */
|
|
78
|
+
emails: string[];
|
|
79
|
+
}
|
|
80
|
+
/** `admin.shipping.fulfillmentProfiles.handlerNotifications`. */
|
|
81
|
+
export interface FulfillmentHandlerNotificationsModule {
|
|
82
|
+
/**
|
|
83
|
+
* Every handler's recipients in the store, by handler code. Needs `ReadShippingMethod`.
|
|
84
|
+
*
|
|
85
|
+
* @effect read
|
|
86
|
+
* @permission ReadShippingMethod
|
|
87
|
+
*/
|
|
88
|
+
list(options?: Call): Promise<FulfillmentHandlerNotification[]>;
|
|
89
|
+
/**
|
|
90
|
+
* Create or replace one handler's recipients. Needs `UpdateShippingMethod`. Refused, with
|
|
91
|
+
* nothing saved, for a blank handler code, an address that is not one, or more than 25
|
|
92
|
+
* addresses (`USER_INPUT_ERROR`, a `ValidationError`). The handler code is not checked against
|
|
93
|
+
* the store's handlers: a record for a handler nothing uses is kept and never mails.
|
|
94
|
+
*
|
|
95
|
+
* @effect write
|
|
96
|
+
* @permission UpdateShippingMethod
|
|
97
|
+
*/
|
|
98
|
+
set(input: SetFulfillmentHandlerNotificationInput, options?: Call): Promise<FulfillmentHandlerNotification>;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* `admin.shipping.fulfillmentProfiles`: the fulfillment profiles of the store the client is
|
|
102
|
+
* scoped to. There is no channel argument; another store is addressed with
|
|
103
|
+
* `admin.withTenant(...)`.
|
|
104
|
+
*
|
|
105
|
+
* A well-formed profile id the store does not have (another store's, or none at all) is refused
|
|
106
|
+
* on every write with `FULFILLMENT_PROFILE_NOT_FOUND` (`NotFoundError`, 404), worded the same
|
|
107
|
+
* either way, and `get` answers `null` for it. An id that is not a uuid is refused by the engine
|
|
108
|
+
* before any of that, on every method `get` included, with `ENTITY_NOT_FOUND` (`NotFoundError`).
|
|
109
|
+
*/
|
|
110
|
+
export interface FulfillmentProfilesModule {
|
|
111
|
+
/**
|
|
112
|
+
* Every profile of the store, oldest first. Needs `ReadShippingMethod`.
|
|
113
|
+
*
|
|
114
|
+
* @effect read
|
|
115
|
+
* @permission ReadShippingMethod
|
|
116
|
+
*/
|
|
117
|
+
list(options?: Call): Promise<FulfillmentProfile[]>;
|
|
118
|
+
/**
|
|
119
|
+
* One profile, or `null` when the store has none with that id.
|
|
120
|
+
*
|
|
121
|
+
* @effect read
|
|
122
|
+
* @permission ReadShippingMethod
|
|
123
|
+
*/
|
|
124
|
+
get(id: string, options?: Call): Promise<FulfillmentProfile | null>;
|
|
125
|
+
/**
|
|
126
|
+
* Create a profile. Needs `UpdateShippingMethod`. A warehouse or shipping method the store
|
|
127
|
+
* does not have is refused `ENTITY_NOT_FOUND` (`NotFoundError`), the same for another store's
|
|
128
|
+
* id as for one that exists nowhere.
|
|
129
|
+
*
|
|
130
|
+
* @effect write
|
|
131
|
+
* @permission UpdateShippingMethod
|
|
132
|
+
*/
|
|
133
|
+
create(input: CreateFulfillmentProfileInput, options?: Call): Promise<FulfillmentProfile>;
|
|
134
|
+
/**
|
|
135
|
+
* Change a profile; a key left out keeps its value. Needs `UpdateShippingMethod`. Refused
|
|
136
|
+
* `FULFILLMENT_PROFILE_NOT_FOUND` for a profile the store does not have, and
|
|
137
|
+
* `ENTITY_NOT_FOUND` for a warehouse or shipping method it does not have. A changed minimum
|
|
138
|
+
* binds the next fulfilment; fulfilments already created keep what they were charged.
|
|
139
|
+
*
|
|
140
|
+
* @effect write
|
|
141
|
+
* @permission UpdateShippingMethod
|
|
142
|
+
*/
|
|
143
|
+
update(id: string, input: UpdateFulfillmentProfileInput, options?: Call): Promise<FulfillmentProfile>;
|
|
144
|
+
/**
|
|
145
|
+
* Delete a profile for good. When it was the store's default the store is left with NO
|
|
146
|
+
* default profile, so checkout applies no profile minimum until another is set. Fulfilments
|
|
147
|
+
* already created with it are unchanged. Needs `UpdateShippingMethod`; refused
|
|
148
|
+
* `FULFILLMENT_PROFILE_NOT_FOUND` for a profile the store does not have.
|
|
149
|
+
*
|
|
150
|
+
* @effect destructive
|
|
151
|
+
* @permission UpdateShippingMethod
|
|
152
|
+
*/
|
|
153
|
+
delete(id: string, options?: Call): Promise<void>;
|
|
154
|
+
/**
|
|
155
|
+
* Make a profile the store's default (the one storefront checkout applies); answers it.
|
|
156
|
+
* Needs `UpdateShippingMethod`; refused `FULFILLMENT_PROFILE_NOT_FOUND` for a profile the
|
|
157
|
+
* store does not have.
|
|
158
|
+
*
|
|
159
|
+
* @effect write
|
|
160
|
+
* @permission UpdateShippingMethod
|
|
161
|
+
*/
|
|
162
|
+
setDefault(id: string, options?: Call): Promise<FulfillmentProfile>;
|
|
163
|
+
/** Who is emailed when a fulfilment is created with a handler. */
|
|
164
|
+
handlerNotifications: FulfillmentHandlerNotificationsModule;
|
|
165
|
+
}
|
|
166
|
+
export declare const FULFILLMENT_PROFILES_QUERY = "\n query FulfillmentProfiles {\n fulfillmentProfiles { \n id\n code\n name\n enabled\n stockLocationId\n defaultHandlerCode\n shippingMethodId\n minOrder\n isDefault\n createdAt\n updatedAt\n }\n }\n";
|
|
167
|
+
export declare const FULFILLMENT_PROFILE_QUERY = "\n query FulfillmentProfile($id: ID!) {\n fulfillmentProfile(id: $id) { \n id\n code\n name\n enabled\n stockLocationId\n defaultHandlerCode\n shippingMethodId\n minOrder\n isDefault\n createdAt\n updatedAt\n }\n }\n";
|
|
168
|
+
export declare const CREATE_FULFILLMENT_PROFILE_MUTATION = "\n mutation CreateFulfillmentProfile($input: CreateFulfillmentProfileInput!) {\n createFulfillmentProfile(input: $input) { \n id\n code\n name\n enabled\n stockLocationId\n defaultHandlerCode\n shippingMethodId\n minOrder\n isDefault\n createdAt\n updatedAt\n }\n }\n";
|
|
169
|
+
export declare const UPDATE_FULFILLMENT_PROFILE_MUTATION = "\n mutation UpdateFulfillmentProfile($input: UpdateFulfillmentProfileInput!) {\n updateFulfillmentProfile(input: $input) { \n id\n code\n name\n enabled\n stockLocationId\n defaultHandlerCode\n shippingMethodId\n minOrder\n isDefault\n createdAt\n updatedAt\n }\n }\n";
|
|
170
|
+
export declare const DELETE_FULFILLMENT_PROFILE_MUTATION = "\n mutation DeleteFulfillmentProfile($id: ID!) {\n deleteFulfillmentProfile(id: $id) { result message }\n }\n";
|
|
171
|
+
export declare const SET_DEFAULT_FULFILLMENT_PROFILE_MUTATION = "\n mutation SetDefaultFulfillmentProfile($id: ID!) {\n setDefaultFulfillmentProfile(id: $id) { \n id\n code\n name\n enabled\n stockLocationId\n defaultHandlerCode\n shippingMethodId\n minOrder\n isDefault\n createdAt\n updatedAt\n }\n }\n";
|
|
172
|
+
export declare const FULFILLMENT_HANDLER_NOTIFICATIONS_QUERY = "\n query FulfillmentHandlerNotifications {\n fulfillmentHandlerNotifications { \n id\n handlerCode\n enabled\n emails\n createdAt\n updatedAt\n }\n }\n";
|
|
173
|
+
export declare const SET_FULFILLMENT_HANDLER_NOTIFICATION_MUTATION = "\n mutation SetFulfillmentHandlerNotification($input: SetFulfillmentHandlerNotificationInput!) {\n setFulfillmentHandlerNotification(input: $input) { \n id\n handlerCode\n enabled\n emails\n createdAt\n updatedAt\n }\n }\n";
|
|
174
|
+
export declare function createFulfillmentProfilesModule(transport: Transport): FulfillmentProfilesModule;
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { assertDeleted } from '../catalog/types.js';
|
|
2
|
+
const PROFILE_FIELDS = /* GraphQL */ `
|
|
3
|
+
id
|
|
4
|
+
code
|
|
5
|
+
name
|
|
6
|
+
enabled
|
|
7
|
+
stockLocationId
|
|
8
|
+
defaultHandlerCode
|
|
9
|
+
shippingMethodId
|
|
10
|
+
minOrder
|
|
11
|
+
isDefault
|
|
12
|
+
createdAt
|
|
13
|
+
updatedAt
|
|
14
|
+
`;
|
|
15
|
+
const NOTIFICATION_FIELDS = /* GraphQL */ `
|
|
16
|
+
id
|
|
17
|
+
handlerCode
|
|
18
|
+
enabled
|
|
19
|
+
emails
|
|
20
|
+
createdAt
|
|
21
|
+
updatedAt
|
|
22
|
+
`;
|
|
23
|
+
export const FULFILLMENT_PROFILES_QUERY = /* GraphQL */ `
|
|
24
|
+
query FulfillmentProfiles {
|
|
25
|
+
fulfillmentProfiles { ${PROFILE_FIELDS} }
|
|
26
|
+
}
|
|
27
|
+
`;
|
|
28
|
+
export const FULFILLMENT_PROFILE_QUERY = /* GraphQL */ `
|
|
29
|
+
query FulfillmentProfile($id: ID!) {
|
|
30
|
+
fulfillmentProfile(id: $id) { ${PROFILE_FIELDS} }
|
|
31
|
+
}
|
|
32
|
+
`;
|
|
33
|
+
export const CREATE_FULFILLMENT_PROFILE_MUTATION = /* GraphQL */ `
|
|
34
|
+
mutation CreateFulfillmentProfile($input: CreateFulfillmentProfileInput!) {
|
|
35
|
+
createFulfillmentProfile(input: $input) { ${PROFILE_FIELDS} }
|
|
36
|
+
}
|
|
37
|
+
`;
|
|
38
|
+
export const UPDATE_FULFILLMENT_PROFILE_MUTATION = /* GraphQL */ `
|
|
39
|
+
mutation UpdateFulfillmentProfile($input: UpdateFulfillmentProfileInput!) {
|
|
40
|
+
updateFulfillmentProfile(input: $input) { ${PROFILE_FIELDS} }
|
|
41
|
+
}
|
|
42
|
+
`;
|
|
43
|
+
export const DELETE_FULFILLMENT_PROFILE_MUTATION = /* GraphQL */ `
|
|
44
|
+
mutation DeleteFulfillmentProfile($id: ID!) {
|
|
45
|
+
deleteFulfillmentProfile(id: $id) { result message }
|
|
46
|
+
}
|
|
47
|
+
`;
|
|
48
|
+
export const SET_DEFAULT_FULFILLMENT_PROFILE_MUTATION = /* GraphQL */ `
|
|
49
|
+
mutation SetDefaultFulfillmentProfile($id: ID!) {
|
|
50
|
+
setDefaultFulfillmentProfile(id: $id) { ${PROFILE_FIELDS} }
|
|
51
|
+
}
|
|
52
|
+
`;
|
|
53
|
+
export const FULFILLMENT_HANDLER_NOTIFICATIONS_QUERY = /* GraphQL */ `
|
|
54
|
+
query FulfillmentHandlerNotifications {
|
|
55
|
+
fulfillmentHandlerNotifications { ${NOTIFICATION_FIELDS} }
|
|
56
|
+
}
|
|
57
|
+
`;
|
|
58
|
+
export const SET_FULFILLMENT_HANDLER_NOTIFICATION_MUTATION = /* GraphQL */ `
|
|
59
|
+
mutation SetFulfillmentHandlerNotification($input: SetFulfillmentHandlerNotificationInput!) {
|
|
60
|
+
setFulfillmentHandlerNotification(input: $input) { ${NOTIFICATION_FIELDS} }
|
|
61
|
+
}
|
|
62
|
+
`;
|
|
63
|
+
export function createFulfillmentProfilesModule(transport) {
|
|
64
|
+
const call = async (query, variables, options) => transport.graphql({ api: 'admin', query, variables }, options);
|
|
65
|
+
return {
|
|
66
|
+
async list(options) {
|
|
67
|
+
const data = await call(FULFILLMENT_PROFILES_QUERY, undefined, options);
|
|
68
|
+
return data.fulfillmentProfiles;
|
|
69
|
+
},
|
|
70
|
+
async get(id, options) {
|
|
71
|
+
const data = await call(FULFILLMENT_PROFILE_QUERY, { id }, options);
|
|
72
|
+
return data.fulfillmentProfile ?? null;
|
|
73
|
+
},
|
|
74
|
+
async create(input, options) {
|
|
75
|
+
const data = await call(CREATE_FULFILLMENT_PROFILE_MUTATION, { input }, options);
|
|
76
|
+
return data.createFulfillmentProfile;
|
|
77
|
+
},
|
|
78
|
+
async update(id, input, options) {
|
|
79
|
+
const data = await call(UPDATE_FULFILLMENT_PROFILE_MUTATION,
|
|
80
|
+
// The id goes last: an `id` key smuggled into the patch cannot redirect the write.
|
|
81
|
+
{ input: { ...input, id } }, options);
|
|
82
|
+
return data.updateFulfillmentProfile;
|
|
83
|
+
},
|
|
84
|
+
async delete(id, options) {
|
|
85
|
+
const data = await call(DELETE_FULFILLMENT_PROFILE_MUTATION, { id }, options);
|
|
86
|
+
// The engine refuses by throwing today; a NOT_DELETED answer must still never pass as done.
|
|
87
|
+
assertDeleted('FULFILLMENT_PROFILE_NOT_DELETED', [data.deleteFulfillmentProfile]);
|
|
88
|
+
},
|
|
89
|
+
async setDefault(id, options) {
|
|
90
|
+
const data = await call(SET_DEFAULT_FULFILLMENT_PROFILE_MUTATION, { id }, options);
|
|
91
|
+
return data.setDefaultFulfillmentProfile;
|
|
92
|
+
},
|
|
93
|
+
handlerNotifications: {
|
|
94
|
+
async list(options) {
|
|
95
|
+
const data = await call(FULFILLMENT_HANDLER_NOTIFICATIONS_QUERY, undefined, options);
|
|
96
|
+
return data.fulfillmentHandlerNotifications;
|
|
97
|
+
},
|
|
98
|
+
async set(input, options) {
|
|
99
|
+
const data = await call(SET_FULFILLMENT_HANDLER_NOTIFICATION_MUTATION, { input }, options);
|
|
100
|
+
return data.setFulfillmentHandlerNotification;
|
|
101
|
+
},
|
|
102
|
+
},
|
|
103
|
+
};
|
|
104
|
+
}
|