@aglyn/plugins-commerce 1.0.0-beta.199 → 1.0.0-beta.201
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/package.json +13 -13
- package/src/lib/components/console/catalog-organization-card.component.js +48 -3
- package/src/lib/components/console/catalog-organization-card.component.js.map +1 -1
- package/src/lib/components/console/gift-cards-card.component.d.ts +9 -0
- package/src/lib/components/console/gift-cards-card.component.js +53 -28
- package/src/lib/components/console/gift-cards-card.component.js.map +1 -1
- package/src/lib/components/console/host-orders-card.component.d.ts +26 -0
- package/src/lib/components/console/host-orders-card.component.js +264 -194
- package/src/lib/components/console/host-orders-card.component.js.map +1 -1
- package/src/lib/components/console/order-detail-dialog.component.js +12 -0
- package/src/lib/components/console/order-detail-dialog.component.js.map +1 -1
- package/src/lib/components/console/pos-page.component.d.ts +14 -0
- package/src/lib/components/console/pos-page.component.js +86 -45
- package/src/lib/components/console/pos-page.component.js.map +1 -1
- package/src/lib/components/console/product-editor-dialog.component.js +30 -6
- package/src/lib/components/console/product-editor-dialog.component.js.map +1 -1
- package/src/lib/components/console/product-slugs.d.ts +43 -0
- package/src/lib/components/console/product-slugs.js +60 -0
- package/src/lib/components/console/product-slugs.js.map +1 -0
- package/src/lib/components/console/products-hub-card.component.d.ts +2 -2
- package/src/lib/components/console/products-hub-card.component.js +229 -282
- package/src/lib/components/console/products-hub-card.component.js.map +1 -1
- package/src/lib/components/console/products-hub-zone.component.d.ts +10 -5
- package/src/lib/components/console/products-hub-zone.component.js +32 -9
- package/src/lib/components/console/products-hub-zone.component.js.map +1 -1
- package/src/lib/components/console/recovery-queue-card.component.d.ts +37 -5
- package/src/lib/components/console/recovery-queue-card.component.js +107 -86
- package/src/lib/components/console/recovery-queue-card.component.js.map +1 -1
- package/src/lib/components/console/reservations-card.component.js +15 -3
- package/src/lib/components/console/reservations-card.component.js.map +1 -1
- package/src/lib/components/console/smart-collections.d.ts +32 -0
- package/src/lib/components/console/smart-collections.js +57 -0
- package/src/lib/components/console/smart-collections.js.map +1 -0
- package/src/lib/components/console/stock-movements-card.component.d.ts +13 -4
- package/src/lib/components/console/stock-movements-card.component.js +142 -180
- package/src/lib/components/console/stock-movements-card.component.js.map +1 -1
- package/src/lib/components/product-grid.d.ts +5 -0
- package/src/lib/components/product-grid.js +95 -34
- package/src/lib/components/product-grid.js.map +1 -1
- package/src/lib/constants/orders-list-query.d.ts +40 -0
- package/src/lib/constants/orders-list-query.js +205 -0
- package/src/lib/constants/orders-list-query.js.map +1 -0
- package/src/lib/constants/product-list-query.d.ts +42 -0
- package/src/lib/constants/product-list-query.js +217 -0
- package/src/lib/constants/product-list-query.js.map +1 -0
- package/src/lib/constants/stock-movement-query.d.ts +27 -0
- package/src/lib/constants/stock-movement-query.js +110 -0
- package/src/lib/constants/stock-movement-query.js.map +1 -0
- package/src/lib/constants/storefront-catalog-query.d.ts +103 -0
- package/src/lib/constants/storefront-catalog-query.js +312 -0
- package/src/lib/constants/storefront-catalog-query.js.map +1 -0
- package/src/lib/model/checkout-recovery.d.ts +37 -0
- package/src/lib/model/checkout-recovery.js +44 -0
- package/src/lib/model/checkout-recovery.js.map +1 -0
- package/src/lib/model/commerce-orders.d.ts +7 -0
- package/src/lib/model/commerce-orders.js.map +1 -1
- package/src/lib/model/commerce.d.ts +80 -0
- package/src/lib/model/commerce.js +67 -6
- package/src/lib/model/commerce.js.map +1 -1
- package/src/lib/model/gift-card-search.d.ts +24 -0
- package/src/lib/model/gift-card-search.js +48 -0
- package/src/lib/model/gift-card-search.js.map +1 -0
- package/src/lib/model/index.d.ts +1 -0
- package/src/lib/model/index.js +1 -0
- package/src/lib/model/index.js.map +1 -1
- package/src/lib/model/order-list-fields.d.ts +80 -0
- package/src/lib/model/order-list-fields.js +112 -0
- package/src/lib/model/order-list-fields.js.map +1 -0
- package/src/lib/server/billing-webhook.js +180 -99
- package/src/lib/server/billing-webhook.js.map +1 -1
- package/src/lib/server/cancel-order.js +6 -6
- package/src/lib/server/cancel-order.js.map +1 -1
- package/src/lib/server/cart-checkout.js +9 -2
- package/src/lib/server/cart-checkout.js.map +1 -1
- package/src/lib/server/catalog.d.ts +46 -30
- package/src/lib/server/catalog.js +507 -170
- package/src/lib/server/catalog.js.map +1 -1
- package/src/lib/server/checkout.js +3 -1
- package/src/lib/server/checkout.js.map +1 -1
- package/src/lib/server/collection-membership.d.ts +35 -0
- package/src/lib/server/collection-membership.js +172 -0
- package/src/lib/server/collection-membership.js.map +1 -0
- package/src/lib/server/draft-order.js +5 -3
- package/src/lib/server/draft-order.js.map +1 -1
- package/src/lib/server/gift-cards.js +7 -1
- package/src/lib/server/gift-cards.js.map +1 -1
- package/src/lib/server/member-name-search.d.ts +17 -0
- package/src/lib/server/member-name-search.js +23 -1
- package/src/lib/server/member-name-search.js.map +1 -1
- package/src/lib/server/membership-account.js +7 -3
- package/src/lib/server/membership-account.js.map +1 -1
- package/src/lib/server/membership-admin-password.js +8 -2
- package/src/lib/server/membership-admin-password.js.map +1 -1
- package/src/lib/server/membership-recover.js +4 -1
- package/src/lib/server/membership-recover.js.map +1 -1
- package/src/lib/server/membership-register.js +3 -1
- package/src/lib/server/membership-register.js.map +1 -1
- package/src/lib/server/pos-order.js +9 -5
- package/src/lib/server/pos-order.js.map +1 -1
- package/src/lib/server/process-abandoned.js +20 -7
- package/src/lib/server/process-abandoned.js.map +1 -1
- package/src/lib/server/process-restock.js +6 -2
- package/src/lib/server/process-restock.js.map +1 -1
- package/src/lib/server/reserve-stock.js +3 -4
- package/src/lib/server/reserve-stock.js.map +1 -1
- package/src/lib/server/reserve.js +3 -1
- package/src/lib/server/reserve.js.map +1 -1
- package/src/lib/server/site-page-enricher.js +3 -3
- package/src/lib/server/site-page-enricher.js.map +1 -1
- package/src/lib/server.js +4 -0
- package/src/lib/server.js.map +1 -1
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2026 Aglyn LLC
|
|
4
|
+
*
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
*
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
*
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/
|
|
17
|
+
import { type OrderDisputeTone } from './commerce-dispute';
|
|
18
|
+
import { type HostOrder, type OrderChannel, type OrderDispute, type OrderStatus } from './commerce-orders';
|
|
19
|
+
/** Tokens past this many are dropped from the quick search's array. */
|
|
20
|
+
export declare const ORDER_SEARCH_TOKEN_LIMIT = 200;
|
|
21
|
+
/** The fields the orders list's query reads, as every writer stamps them. */
|
|
22
|
+
export interface OrderListFields {
|
|
23
|
+
/**
|
|
24
|
+
* Always present. A Commerce Starter order (AGL-90) carried none and was
|
|
25
|
+
* read as `paid` (`liftLegacyOrder`); the lift is written down so the
|
|
26
|
+
* Status filter finds it.
|
|
27
|
+
*/
|
|
28
|
+
status: OrderStatus;
|
|
29
|
+
/** Always present; absent was always read as `online`. */
|
|
30
|
+
channel: OrderChannel;
|
|
31
|
+
/**
|
|
32
|
+
* Every product the order holds, line items first and the legacy flat
|
|
33
|
+
* `productId` after — the Product filter's `array-contains-any`.
|
|
34
|
+
*/
|
|
35
|
+
productIds: string[];
|
|
36
|
+
/**
|
|
37
|
+
* The dispute badge's tone (`describeOrderDispute`), or null with no
|
|
38
|
+
* dispute. `open` is a case with a deadline; `lost` a chargeback; `won` and
|
|
39
|
+
* `settled` closed with no money reversed. What the Disputes filter and the
|
|
40
|
+
* open-dispute banner ask.
|
|
41
|
+
*/
|
|
42
|
+
disputeKey: OrderDisputeTone | null;
|
|
43
|
+
/** The buyer's address, lower-cased — the Customer filter's `equals`. */
|
|
44
|
+
customerEmailLower: string | null;
|
|
45
|
+
/** The address's search prefixes (`emailSearchTokens`) — its `contains`. */
|
|
46
|
+
customerEmailTokens: string[];
|
|
47
|
+
/** The order number's prefixes, with and without its `#` — Order `contains`. */
|
|
48
|
+
orderLabelTokens: string[];
|
|
49
|
+
/**
|
|
50
|
+
* The quick search: the order number's, the buyer's address's and every
|
|
51
|
+
* line item name's word prefixes, capped at {@link ORDER_SEARCH_TOKEN_LIMIT}
|
|
52
|
+
* with the item names cut first.
|
|
53
|
+
*/
|
|
54
|
+
searchTokens: string[];
|
|
55
|
+
}
|
|
56
|
+
/** The dispute badge's tone, stored — see {@link OrderListFields.disputeKey}. */
|
|
57
|
+
export declare function orderDisputeKey(dispute: OrderDispute | null | undefined): OrderDisputeTone | null;
|
|
58
|
+
/**
|
|
59
|
+
* The order number's prefixes, as `#1042` and as `1042`, so a reader who
|
|
60
|
+
* types either finds it. An order with no number is labelled by its document
|
|
61
|
+
* id (`formatOrderNumber`), and is found by that label the same way.
|
|
62
|
+
*/
|
|
63
|
+
export declare function orderLabelTokens(order: Pick<Partial<HostOrder>, 'number'>, docId: string): string[];
|
|
64
|
+
/**
|
|
65
|
+
* The fields the orders list's query reads, from an order as it will be
|
|
66
|
+
* stored — see {@link OrderListFields}. Pure: the same answer on the server,
|
|
67
|
+
* in a spec and (restated) in the backfill.
|
|
68
|
+
*
|
|
69
|
+
* `legacyProductName` names the product of a Commerce Starter order, which
|
|
70
|
+
* stored an id and no line items; only the backfill has it to give.
|
|
71
|
+
*/
|
|
72
|
+
export declare function orderListFields(order: object, docId: string, options?: {
|
|
73
|
+
legacyProductName?: string;
|
|
74
|
+
}): OrderListFields;
|
|
75
|
+
/**
|
|
76
|
+
* An order document with its list fields spread over it — what a creator
|
|
77
|
+
* writes. The document's own `status` and `channel` win where it names them,
|
|
78
|
+
* which every creator does; the rest is derived from it.
|
|
79
|
+
*/
|
|
80
|
+
export declare function withOrderListFields<T extends object>(docId: string, doc: T): T & OrderListFields;
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { _ as _extends } from "@swc/helpers/_/_extends";
|
|
2
|
+
/**
|
|
3
|
+
* @license
|
|
4
|
+
* Copyright 2026 Aglyn LLC
|
|
5
|
+
*
|
|
6
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
7
|
+
* you may not use this file except in compliance with the License.
|
|
8
|
+
* You may obtain a copy of the License at
|
|
9
|
+
*
|
|
10
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
11
|
+
*
|
|
12
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
13
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
14
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
15
|
+
* See the License for the specific language governing permissions and
|
|
16
|
+
* limitations under the License.
|
|
17
|
+
*/ import { emailSearchTokens } from "@aglyn/aglyn/app-utils/email-search";
|
|
18
|
+
import { nameSearchKey, nameSearchTokens } from "@aglyn/aglyn/app-utils/name-search";
|
|
19
|
+
import { describeOrderDispute } from "./commerce-dispute.js";
|
|
20
|
+
import { formatOrderNumber } from "./commerce-orders.js";
|
|
21
|
+
/*
|
|
22
|
+
* WHAT THE ORDERS LIST ASKS ITS QUERY, WRITTEN ON THE ORDER (AGL-3321).
|
|
23
|
+
*
|
|
24
|
+
* The orders list puts every filter and its search on the Firestore query,
|
|
25
|
+
* and a query can only ask about a field a document stores. The list used to
|
|
26
|
+
* derive five of its columns in the browser — a legacy order's status and
|
|
27
|
+
* channel, the products in a cart, the dispute badge, the order number — and
|
|
28
|
+
* match them over the two hundred rows it had read, which answered "none"
|
|
29
|
+
* for an order on the next page.
|
|
30
|
+
*
|
|
31
|
+
* So every writer of `hosts/{hostId}/orders` spreads `orderListFields` over
|
|
32
|
+
* the document it writes, computed from the whole document as it will stand:
|
|
33
|
+
* the creators (cart, buy-now, subscription renewal, POS, draft) and every
|
|
34
|
+
* write that moves an input — the dispute record, the address a paid draft
|
|
35
|
+
* learns. A write that moves none of them (a status flip, a fulfillment, a
|
|
36
|
+
* refund, a timeline note) moves none of these either: `status` is its own
|
|
37
|
+
* field and is what the Status filter reads.
|
|
38
|
+
*
|
|
39
|
+
* `tools/scripts/backfill-orders-list-fields.mjs` restates this for the
|
|
40
|
+
* orders written before it; the two answer the same worked examples,
|
|
41
|
+
* `tools/scripts/lib/order-list-fields.fixtures.json`.
|
|
42
|
+
*/ /** Tokens past this many are dropped from the quick search's array. */ export const ORDER_SEARCH_TOKEN_LIMIT = 200;
|
|
43
|
+
/** The dispute badge's tone, stored — see {@link OrderListFields.disputeKey}. */ export function orderDisputeKey(dispute) {
|
|
44
|
+
var _ref;
|
|
45
|
+
var _describeOrderDispute;
|
|
46
|
+
if (!dispute || typeof dispute !== 'object') return null;
|
|
47
|
+
return (_ref = (_describeOrderDispute = describeOrderDispute({
|
|
48
|
+
dispute
|
|
49
|
+
})) == null ? void 0 : _describeOrderDispute.tone) != null ? _ref : null;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* The order number's prefixes, as `#1042` and as `1042`, so a reader who
|
|
53
|
+
* types either finds it. An order with no number is labelled by its document
|
|
54
|
+
* id (`formatOrderNumber`), and is found by that label the same way.
|
|
55
|
+
*/ export function orderLabelTokens(order, docId) {
|
|
56
|
+
const label = nameSearchKey(formatOrderNumber({
|
|
57
|
+
number: order.number
|
|
58
|
+
}, docId));
|
|
59
|
+
const bare = label.replace(/^#+/, '');
|
|
60
|
+
return nameSearchTokens(bare && bare !== label ? `${label} ${bare}` : label);
|
|
61
|
+
}
|
|
62
|
+
const text = (value)=>typeof value === 'string' ? value : '';
|
|
63
|
+
/**
|
|
64
|
+
* The fields the orders list's query reads, from an order as it will be
|
|
65
|
+
* stored — see {@link OrderListFields}. Pure: the same answer on the server,
|
|
66
|
+
* in a spec and (restated) in the backfill.
|
|
67
|
+
*
|
|
68
|
+
* `legacyProductName` names the product of a Commerce Starter order, which
|
|
69
|
+
* stored an id and no line items; only the backfill has it to give.
|
|
70
|
+
*/ export function orderListFields(order, docId, options = {}) {
|
|
71
|
+
const source = order;
|
|
72
|
+
const lineItems = Array.isArray(source.lineItems) ? source.lineItems : [];
|
|
73
|
+
const productIds = [
|
|
74
|
+
...new Set([
|
|
75
|
+
...lineItems.map((line)=>line == null ? void 0 : line.productId),
|
|
76
|
+
source.productId
|
|
77
|
+
].filter((id)=>typeof id === 'string' && id !== ''))
|
|
78
|
+
];
|
|
79
|
+
const email = text(source.customerEmail);
|
|
80
|
+
const emailTokens = emailSearchTokens(email);
|
|
81
|
+
const labelTokens = orderLabelTokens(source, docId);
|
|
82
|
+
const names = lineItems.map((line)=>text(line == null ? void 0 : line.name)).filter(Boolean);
|
|
83
|
+
if (!names.length && options.legacyProductName) {
|
|
84
|
+
names.push(options.legacyProductName);
|
|
85
|
+
}
|
|
86
|
+
const searchTokens = [
|
|
87
|
+
...new Set([
|
|
88
|
+
...labelTokens,
|
|
89
|
+
...emailTokens,
|
|
90
|
+
...names.flatMap((name)=>nameSearchTokens(name))
|
|
91
|
+
])
|
|
92
|
+
].slice(0, ORDER_SEARCH_TOKEN_LIMIT);
|
|
93
|
+
return {
|
|
94
|
+
status: text(source.status) || 'paid',
|
|
95
|
+
channel: text(source.channel) || 'online',
|
|
96
|
+
productIds,
|
|
97
|
+
disputeKey: orderDisputeKey(source.dispute),
|
|
98
|
+
customerEmailLower: nameSearchKey(email) || null,
|
|
99
|
+
customerEmailTokens: emailTokens,
|
|
100
|
+
orderLabelTokens: labelTokens,
|
|
101
|
+
searchTokens
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* An order document with its list fields spread over it — what a creator
|
|
106
|
+
* writes. The document's own `status` and `channel` win where it names them,
|
|
107
|
+
* which every creator does; the rest is derived from it.
|
|
108
|
+
*/ export function withOrderListFields(docId, doc) {
|
|
109
|
+
return _extends({}, doc, orderListFields(doc, docId));
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
//# sourceMappingURL=order-list-fields.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../../libs/plugins/commerce/src/lib/model/order-list-fields.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2026 Aglyn LLC\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { emailSearchTokens } from '@aglyn/aglyn/app-utils/email-search'\nimport {\n nameSearchKey,\n nameSearchTokens,\n} from '@aglyn/aglyn/app-utils/name-search'\nimport { describeOrderDispute, type OrderDisputeTone } from './commerce-dispute'\nimport {\n formatOrderNumber,\n type HostOrder,\n type OrderChannel,\n type OrderDispute,\n type OrderStatus,\n} from './commerce-orders'\n\n/*\n * WHAT THE ORDERS LIST ASKS ITS QUERY, WRITTEN ON THE ORDER (AGL-3321).\n *\n * The orders list puts every filter and its search on the Firestore query,\n * and a query can only ask about a field a document stores. The list used to\n * derive five of its columns in the browser — a legacy order's status and\n * channel, the products in a cart, the dispute badge, the order number — and\n * match them over the two hundred rows it had read, which answered \"none\"\n * for an order on the next page.\n *\n * So every writer of `hosts/{hostId}/orders` spreads `orderListFields` over\n * the document it writes, computed from the whole document as it will stand:\n * the creators (cart, buy-now, subscription renewal, POS, draft) and every\n * write that moves an input — the dispute record, the address a paid draft\n * learns. A write that moves none of them (a status flip, a fulfillment, a\n * refund, a timeline note) moves none of these either: `status` is its own\n * field and is what the Status filter reads.\n *\n * `tools/scripts/backfill-orders-list-fields.mjs` restates this for the\n * orders written before it; the two answer the same worked examples,\n * `tools/scripts/lib/order-list-fields.fixtures.json`.\n */\n\n/** Tokens past this many are dropped from the quick search's array. */\nexport const ORDER_SEARCH_TOKEN_LIMIT = 200\n\n/** The fields the orders list's query reads, as every writer stamps them. */\nexport interface OrderListFields {\n /**\n * Always present. A Commerce Starter order (AGL-90) carried none and was\n * read as `paid` (`liftLegacyOrder`); the lift is written down so the\n * Status filter finds it.\n */\n status: OrderStatus\n /** Always present; absent was always read as `online`. */\n channel: OrderChannel\n /**\n * Every product the order holds, line items first and the legacy flat\n * `productId` after — the Product filter's `array-contains-any`.\n */\n productIds: string[]\n /**\n * The dispute badge's tone (`describeOrderDispute`), or null with no\n * dispute. `open` is a case with a deadline; `lost` a chargeback; `won` and\n * `settled` closed with no money reversed. What the Disputes filter and the\n * open-dispute banner ask.\n */\n disputeKey: OrderDisputeTone | null\n /** The buyer's address, lower-cased — the Customer filter's `equals`. */\n customerEmailLower: string | null\n /** The address's search prefixes (`emailSearchTokens`) — its `contains`. */\n customerEmailTokens: string[]\n /** The order number's prefixes, with and without its `#` — Order `contains`. */\n orderLabelTokens: string[]\n /**\n * The quick search: the order number's, the buyer's address's and every\n * line item name's word prefixes, capped at {@link ORDER_SEARCH_TOKEN_LIMIT}\n * with the item names cut first.\n */\n searchTokens: string[]\n}\n\n/** The dispute badge's tone, stored — see {@link OrderListFields.disputeKey}. */\nexport function orderDisputeKey(\n dispute: OrderDispute | null | undefined,\n): OrderDisputeTone | null {\n if (!dispute || typeof dispute !== 'object') return null\n return describeOrderDispute({ dispute })?.tone ?? null\n}\n\n/**\n * The order number's prefixes, as `#1042` and as `1042`, so a reader who\n * types either finds it. An order with no number is labelled by its document\n * id (`formatOrderNumber`), and is found by that label the same way.\n */\nexport function orderLabelTokens(\n order: Pick<Partial<HostOrder>, 'number'>,\n docId: string,\n): string[] {\n const label = nameSearchKey(formatOrderNumber({ number: order.number }, docId))\n const bare = label.replace(/^#+/, '')\n return nameSearchTokens(bare && bare !== label ? `${label} ${bare}` : label)\n}\n\nconst text = (value: unknown): string =>\n typeof value === 'string' ? value : ''\n\n/**\n * The fields the orders list's query reads, from an order as it will be\n * stored — see {@link OrderListFields}. Pure: the same answer on the server,\n * in a spec and (restated) in the backfill.\n *\n * `legacyProductName` names the product of a Commerce Starter order, which\n * stored an id and no line items; only the backfill has it to give.\n */\nexport function orderListFields(\n order: object,\n docId: string,\n options: { legacyProductName?: string } = {},\n): OrderListFields {\n const source = order as Partial<HostOrder> & Record<string, unknown>\n const lineItems = Array.isArray(source.lineItems) ? source.lineItems : []\n const productIds = [\n ...new Set(\n [...lineItems.map((line) => line?.productId), source.productId].filter(\n (id): id is string => typeof id === 'string' && id !== '',\n ),\n ),\n ]\n const email = text(source.customerEmail)\n const emailTokens = emailSearchTokens(email)\n const labelTokens = orderLabelTokens(source, docId)\n const names = lineItems.map((line) => text(line?.name)).filter(Boolean)\n if (!names.length && options.legacyProductName) {\n names.push(options.legacyProductName)\n }\n const searchTokens = [\n ...new Set([\n ...labelTokens,\n ...emailTokens,\n ...names.flatMap((name) => nameSearchTokens(name)),\n ]),\n ].slice(0, ORDER_SEARCH_TOKEN_LIMIT)\n return {\n status: (text(source.status) || 'paid') as OrderStatus,\n channel: (text(source.channel) || 'online') as OrderChannel,\n productIds,\n disputeKey: orderDisputeKey(source.dispute),\n customerEmailLower: nameSearchKey(email) || null,\n customerEmailTokens: emailTokens,\n orderLabelTokens: labelTokens,\n searchTokens,\n }\n}\n\n/**\n * An order document with its list fields spread over it — what a creator\n * writes. The document's own `status` and `channel` win where it names them,\n * which every creator does; the rest is derived from it.\n */\nexport function withOrderListFields<T extends object>(\n docId: string,\n doc: T,\n): T & OrderListFields {\n return { ...doc, ...orderListFields(doc, docId) }\n}\n"],"names":["emailSearchTokens","nameSearchKey","nameSearchTokens","describeOrderDispute","formatOrderNumber","ORDER_SEARCH_TOKEN_LIMIT","orderDisputeKey","dispute","tone","orderLabelTokens","order","docId","label","number","bare","replace","text","value","orderListFields","options","source","lineItems","Array","isArray","productIds","Set","map","line","productId","filter","id","email","customerEmail","emailTokens","labelTokens","names","name","Boolean","length","legacyProductName","push","searchTokens","flatMap","slice","status","channel","disputeKey","customerEmailLower","customerEmailTokens","withOrderListFields","doc"],"mappings":";AAAA;;;;;;;;;;;;;;;CAeC,GAED,SAASA,iBAAiB,QAAQ,sCAAqC;AACvE,SACEC,aAAa,EACbC,gBAAgB,QACX,qCAAoC;AAC3C,SAASC,oBAAoB,QAA+B,wBAAoB;AAChF,SACEC,iBAAiB,QAKZ,uBAAmB;AAE1B;;;;;;;;;;;;;;;;;;;;;CAqBC,GAED,qEAAqE,GACrE,OAAO,MAAMC,2BAA2B,IAAG;AAsC3C,+EAA+E,GAC/E,OAAO,SAASC,gBACdC,OAAwC;;QAGjCJ;IADP,IAAI,CAACI,WAAW,OAAOA,YAAY,UAAU,OAAO;IACpD,gBAAOJ,wBAAAA,qBAAqB;QAAEI;IAAQ,uBAA/BJ,sBAAmCK,IAAI,mBAAI;AACpD;AAEA;;;;CAIC,GACD,OAAO,SAASC,iBACdC,KAAyC,EACzCC,KAAa;IAEb,MAAMC,QAAQX,cAAcG,kBAAkB;QAAES,QAAQH,MAAMG,MAAM;IAAC,GAAGF;IACxE,MAAMG,OAAOF,MAAMG,OAAO,CAAC,OAAO;IAClC,OAAOb,iBAAiBY,QAAQA,SAASF,QAAQ,GAAGA,MAAM,CAAC,EAAEE,MAAM,GAAGF;AACxE;AAEA,MAAMI,OAAO,CAACC,QACZ,OAAOA,UAAU,WAAWA,QAAQ;AAEtC;;;;;;;CAOC,GACD,OAAO,SAASC,gBACdR,KAAa,EACbC,KAAa,EACbQ,UAA0C,CAAC,CAAC;IAE5C,MAAMC,SAASV;IACf,MAAMW,YAAYC,MAAMC,OAAO,CAACH,OAAOC,SAAS,IAAID,OAAOC,SAAS,GAAG,EAAE;IACzE,MAAMG,aAAa;WACd,IAAIC,IACL;eAAIJ,UAAUK,GAAG,CAAC,CAACC,OAASA,wBAAAA,KAAMC,SAAS;YAAGR,OAAOQ,SAAS;SAAC,CAACC,MAAM,CACpE,CAACC,KAAqB,OAAOA,OAAO,YAAYA,OAAO;KAG5D;IACD,MAAMC,QAAQf,KAAKI,OAAOY,aAAa;IACvC,MAAMC,cAAcjC,kBAAkB+B;IACtC,MAAMG,cAAczB,iBAAiBW,QAAQT;IAC7C,MAAMwB,QAAQd,UAAUK,GAAG,CAAC,CAACC,OAASX,KAAKW,wBAAAA,KAAMS,IAAI,GAAGP,MAAM,CAACQ;IAC/D,IAAI,CAACF,MAAMG,MAAM,IAAInB,QAAQoB,iBAAiB,EAAE;QAC9CJ,MAAMK,IAAI,CAACrB,QAAQoB,iBAAiB;IACtC;IACA,MAAME,eAAe;WAChB,IAAIhB,IAAI;eACNS;eACAD;eACAE,MAAMO,OAAO,CAAC,CAACN,OAASlC,iBAAiBkC;SAC7C;KACF,CAACO,KAAK,CAAC,GAAGtC;IACX,OAAO;QACLuC,QAAS5B,KAAKI,OAAOwB,MAAM,KAAK;QAChCC,SAAU7B,KAAKI,OAAOyB,OAAO,KAAK;QAClCrB;QACAsB,YAAYxC,gBAAgBc,OAAOb,OAAO;QAC1CwC,oBAAoB9C,cAAc8B,UAAU;QAC5CiB,qBAAqBf;QACrBxB,kBAAkByB;QAClBO;IACF;AACF;AAEA;;;;CAIC,GACD,OAAO,SAASQ,oBACdtC,KAAa,EACbuC,GAAM;IAEN,OAAO,aAAKA,KAAQhC,gBAAgBgC,KAAKvC;AAC3C"}
|