@rokt/dcui-orchestrator 1.2.1-rc.50 → 1.2.1-rc.52
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/dist/index.cjs +33 -33
- package/dist/index.js +38 -38
- package/dist/libraries/dcui-components/src/failure-codes.d.ts +1 -0
- package/dist/libraries/domain/src/models/form-state.d.ts +85 -0
- package/dist/modules/add-to-cart/src/actions/catalog-item.d.ts +15 -1
- package/dist/modules/add-to-cart/src/sagas/index.d.ts +1 -0
- package/dist/modules/add-to-cart/src/sagas/update-cart-item/sagas.d.ts +2 -1
- package/dist/modules/add-to-cart/src/selectors/cart/selectors.d.ts +32 -0
- package/dist/modules/add-to-cart/src/utils/index.d.ts +1 -0
- package/dist/modules/add-to-cart/src/utils/quantity-rules/index.d.ts +1 -0
- package/dist/modules/add-to-cart/src/utils/quantity-rules/quantity-rules.d.ts +174 -0
- package/package.json +1 -1
|
@@ -6,3 +6,4 @@ export declare const FAILED_TO_MAP_STATIC_DATA = "FAILED_TO_MAP_STATIC_DATA";
|
|
|
6
6
|
export declare const FAILED_SANITISING_HTML = "FAILED_SANITISING_HTML";
|
|
7
7
|
export declare const UNRESOLVED_FORM_VALIDATION_TARGET = "UNRESOLVED_FORM_VALIDATION_TARGET";
|
|
8
8
|
export declare const MISSING_LEAD_IDENTITY = "MISSING_LEAD_IDENTITY";
|
|
9
|
+
export declare const UNSAFE_FORM_VALIDATION_PATTERN = "UNSAFE_FORM_VALIDATION_PATTERN";
|
|
@@ -83,3 +83,88 @@ export interface FormFieldRef {
|
|
|
83
83
|
* ActionButton (to gate dispatch) so both resolve entries identically.
|
|
84
84
|
*/
|
|
85
85
|
export declare function resolveFormFieldRefs(formStates: FormStatesState, entries: string[]): FormFieldRef[];
|
|
86
|
+
/**
|
|
87
|
+
* The longest `Pattern` a layout may register. A longer one is refused by
|
|
88
|
+
* {@link scanPattern}: the form-state reducer drops it at registration and
|
|
89
|
+
* {@link matchesPattern} treats it as non-blocking.
|
|
90
|
+
*/
|
|
91
|
+
export declare const MAX_PATTERN_LENGTH = 256;
|
|
92
|
+
/**
|
|
93
|
+
* The longest value a `Pattern` validation tests, whatever the pattern. A
|
|
94
|
+
* longer value fails the validation with its message, untested. The rules of
|
|
95
|
+
* {@link scanPattern} bound the engine's work on a value of this length and
|
|
96
|
+
* on no other.
|
|
97
|
+
*/
|
|
98
|
+
export declare const MAX_PATTERN_VALUE_LENGTH = 512;
|
|
99
|
+
/** Why {@link scanPattern} refused a pattern: the first rule it broke. */
|
|
100
|
+
export type PatternRefusal = 'too-long' | 'backreference' | 'nested-quantifier' | 'repeated-alternation' | 'quantified-lookaround' | 'too-many-repetitions' | 'count-too-wide' | 'too-many-ways' | 'too-many-steps' | 'invalid';
|
|
101
|
+
/** What {@link scanPattern} read: the verdict, with a refusal's reason. */
|
|
102
|
+
export type PatternScan = {
|
|
103
|
+
safe: true;
|
|
104
|
+
} | {
|
|
105
|
+
safe: false;
|
|
106
|
+
reason: PatternRefusal;
|
|
107
|
+
};
|
|
108
|
+
/**
|
|
109
|
+
* The walk behind {@link isSafePattern}: one pass over the pattern's syntax,
|
|
110
|
+
* with no reading of what the atoms match. Escapes and `[...]` classes are
|
|
111
|
+
* one token each, so a `(`, `|` or `*` inside them is literal. The rules are
|
|
112
|
+
* blunt by design: each refuses a shape that can backtrack past the value
|
|
113
|
+
* cap, and with it the safe patterns of the same shape. The check that reads
|
|
114
|
+
* a pattern's real cost belongs at publish time, in the service that stores
|
|
115
|
+
* the layout. Refused, in the order the rules are read:
|
|
116
|
+
*
|
|
117
|
+
* 1. a pattern longer than {@link MAX_PATTERN_LENGTH};
|
|
118
|
+
* 2. a backreference, `\1` or `\k<name>`;
|
|
119
|
+
* 3. a repeated group that holds a quantifier of its own, at any depth:
|
|
120
|
+
* `(a+)+`, `(\d{3}-?)+`, `(a+){3}`. A `?` or a `{1}` on the group takes
|
|
121
|
+
* it whole or not at all, so `(a+)?` is accepted. A fixed count is copies
|
|
122
|
+
* of the group in sequence, so `(\d{4}[- ]?){3}` is accepted;
|
|
123
|
+
* 4. a repeated group that holds a `|`, at any depth: `(a|ab)+`. A fixed
|
|
124
|
+
* count is copies here too, so `(?:a|ab){3}` is accepted;
|
|
125
|
+
* 5. a quantifier on a lookaround, inside one, or on a group that holds
|
|
126
|
+
* one: `(?=a)+`, `(?=.*\d)`, `(?:(?=a)b){3}`;
|
|
127
|
+
* 6. more than {@link MAX_REPETITIONS} repetitions that can run on in the
|
|
128
|
+
* whole pattern, or more than {@link MAX_ANCHORED_REPETITIONS} in one
|
|
129
|
+
* anchored at `^`: `\w*\w*\w*-`, `^\w*\w*\w*\w*$`, where `^\w*\w*\w*$`
|
|
130
|
+
* and `^[^\s@]+@[^\s@]+\.[^\s@]+$` are accepted;
|
|
131
|
+
* 7. a count past {@link MAX_PATTERN_VALUE_LENGTH}, on its own or multiplied
|
|
132
|
+
* through the counts of the groups that hold it: `\w{513}`, `.{0,1000}`,
|
|
133
|
+
* `(?:\b){999}`, `(?:(?:\b){512}){512}`;
|
|
134
|
+
* 8. {@link MAX_WAYS_STEPS} steps or more from the ways alone: each atom's
|
|
135
|
+
* count, once per way of the atoms before it. Thirty `a?`, eight
|
|
136
|
+
* `\d{1,9}`, `^(?:\d{1,9}){5}\w{467}$` and sixteen `a?` before `\w{495}$`
|
|
137
|
+
* are refused, where a phone, card, IPv4 or optional-scheme URL pattern
|
|
138
|
+
* is accepted;
|
|
139
|
+
* 9. {@link MAX_PATTERN_STEPS} steps or more from the ways and the runs
|
|
140
|
+
* together: the same sum, each run multiplying the paths to the atoms
|
|
141
|
+
* after it by the cap over the run's rank on its own path (its branch
|
|
142
|
+
* and the branches of the groups that hold it, never a sibling `|`
|
|
143
|
+
* alternative, so the branches of a `|` add up), and a pattern with no
|
|
144
|
+
* `^` running from every position. Twelve `a?` before `\w*\w*$`,
|
|
145
|
+
* `\w*\w*-`, `^\w*\w*\w{511}$` and `^\w*!|^` with nine `a?` before
|
|
146
|
+
* `\w*\w*!` are refused, where `^\w*\w*\w*!`, `\S+@\S+` and `^\S+@\S+$`
|
|
147
|
+
* are accepted;
|
|
148
|
+
* 10. a pattern RegExp rejects, as `(`.
|
|
149
|
+
*
|
|
150
|
+
* An accepted pattern is tested on a value of {@link MAX_PATTERN_VALUE_LENGTH}
|
|
151
|
+
* characters at most; {@link matchesPattern} fails a longer value untested.
|
|
152
|
+
*/
|
|
153
|
+
export declare function scanPattern(pattern: string): PatternScan;
|
|
154
|
+
/**
|
|
155
|
+
* Whether a layout author's `Pattern` can be tested without hanging the
|
|
156
|
+
* plugin. The regular expression runs synchronously on the UI thread, inside
|
|
157
|
+
* a reducer, on every keystroke, and cannot be interrupted, so the only
|
|
158
|
+
* control is on the pattern's shape before it runs: the rules of
|
|
159
|
+
* {@link scanPattern}. A `pattern` that is no string is not refused, so a
|
|
160
|
+
* layout no schema checked still registers, but {@link matchesPattern}
|
|
161
|
+
* never compiles it.
|
|
162
|
+
*/
|
|
163
|
+
export declare function isSafePattern(pattern: string): boolean;
|
|
164
|
+
/**
|
|
165
|
+
* Whether a validation may be registered on a field: every validation but a
|
|
166
|
+
* `Pattern` that {@link isSafePattern} refuses. Shared by the form-state
|
|
167
|
+
* reducer, which drops the refused ones, and the TextInput, which reports
|
|
168
|
+
* them, so the two never disagree on what was dropped.
|
|
169
|
+
*/
|
|
170
|
+
export declare function isSafeInputValidation(validation: InputValidation): boolean;
|
|
@@ -8,4 +8,18 @@ export type CatalogItemResponse = {
|
|
|
8
8
|
type: typeof CATALOG_ITEM_RESPONSE;
|
|
9
9
|
payload: CatalogItemResponsePayload;
|
|
10
10
|
};
|
|
11
|
-
export type
|
|
11
|
+
export type CatalogItemExactResponsePayload = {
|
|
12
|
+
catalogItem: PluginCatalogItem;
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* Sets an exact-quantity item to its exact quantity, or to the offer capacity
|
|
16
|
+
* the other items leave when the exact quantity is above it. The quantity is
|
|
17
|
+
* read from the item's own rules and the cart in the saga, so a stale closure
|
|
18
|
+
* never sets another number, and the item cap does not apply to it.
|
|
19
|
+
*/
|
|
20
|
+
export declare const CATALOG_ITEM_EXACT_RESPONSE = "CATALOG_ITEM/EXACT_RESPONSE";
|
|
21
|
+
export type CatalogItemExactResponse = {
|
|
22
|
+
type: typeof CATALOG_ITEM_EXACT_RESPONSE;
|
|
23
|
+
payload: CatalogItemExactResponsePayload;
|
|
24
|
+
};
|
|
25
|
+
export type CatalogItemActions = CatalogItemResponse | CatalogItemExactResponse;
|
|
@@ -2,6 +2,7 @@ import { GlobalGateway } from '../../../../libraries/module-connector/src/main';
|
|
|
2
2
|
import { Log } from '../../../../libraries/domain/src/models';
|
|
3
3
|
export declare const sagaActionTypes: {
|
|
4
4
|
readonly CATALOG_ITEM_RESPONSE: "CATALOG_ITEM/RESPONSE";
|
|
5
|
+
readonly CATALOG_ITEM_EXACT_RESPONSE: "CATALOG_ITEM/EXACT_RESPONSE";
|
|
5
6
|
readonly RAISE_METRIC: "GLOBAL/RAISE_METRIC";
|
|
6
7
|
readonly PREPARE_SIGNAL: "GLOBAL/PREPARE_SIGNAL";
|
|
7
8
|
readonly OFFER_ENGAGEMENT: "GLOBAL/OFFER_ENGAGEMENT";
|
|
@@ -3,8 +3,9 @@ import { GlobalActions } from '../../../../../libraries/domain/src/behaviors';
|
|
|
3
3
|
import { Log, PluginCartItem, PluginCatalogItem } from '../../../../../libraries/domain/src/models';
|
|
4
4
|
import { GlobalGateway } from '../../../../../libraries/module-connector/src/main';
|
|
5
5
|
import { Cart } from '@rokt/partner-integration';
|
|
6
|
-
import { CatalogItemResponse } from '../../actions';
|
|
6
|
+
import { CatalogItemExactResponse, CatalogItemResponse } from '../../actions';
|
|
7
7
|
export declare function processPreselectedCatalogItems(logger: (log: Log) => void): Generator<SelectEffect | CallEffect | PutEffect, void, PluginCartItem | null | undefined>;
|
|
8
8
|
export declare function processUpdateCartItem(gateway: GlobalGateway, logger: (log: Log) => void, action: CatalogItemResponse): Generator<SelectEffect | CallEffect | PutEffect, void, undefined | GlobalActions | string>;
|
|
9
|
+
export declare function processSetExactCartItem(gateway: GlobalGateway, logger: (log: Log) => void, action: CatalogItemExactResponse): Generator<SelectEffect | CallEffect | PutEffect, void, unknown>;
|
|
9
10
|
export declare function listenForUpdateCartItemPartnerMessage(gateway: GlobalGateway, logger: (log: Log) => void): Generator<TakeEffect | CallEffect | CancelledEffect | ChannelTakeEffect<Cart.V2.UpdateCartItemPartnerMessageBody>, void, Cart.V2.UpdateCartItemPartnerMessageBody>;
|
|
10
11
|
export declare function processPartnerUpdateCartItem(message: Cart.V2.UpdateCartItemPartnerMessageBody): Generator<SelectEffect | PutEffect, void, PluginCatalogItem | string | number | null | undefined>;
|
|
@@ -9,4 +9,36 @@ export declare function getCartItem(state: {
|
|
|
9
9
|
}, cartItemId: string): PluginCartItem | null;
|
|
10
10
|
export declare function getOfferCartItems(state: AppState): Array<PluginCartItem>;
|
|
11
11
|
export declare function getOfferCartItemsQuantity(state: AppState): number;
|
|
12
|
+
/**
|
|
13
|
+
* The offer limit the offer's catalog items carry: the cap on the total
|
|
14
|
+
* quantity across all the offer's cart items, read as the first positive
|
|
15
|
+
* whole number across the items, the given item's own attributes first
|
|
16
|
+
* (readOfferQuantityLimit). Undefined when no item carries one, so 0 and an
|
|
17
|
+
* absent key mean no additional offer limit.
|
|
18
|
+
*/
|
|
19
|
+
export declare function getOfferQuantityLimit(state: AppState, catalogItem?: Pick<PluginCatalogItem, 'copy'>): number | undefined;
|
|
20
|
+
/**
|
|
21
|
+
* The cap on the total quantity across the offer's cart items: the smaller
|
|
22
|
+
* of the offer's existing maxTotalItemsQtyInOffer and the offer limit its
|
|
23
|
+
* items carry (getOfferQuantityLimit), or Infinity when neither is set. Both
|
|
24
|
+
* apply, in every path that adds to the offer.
|
|
25
|
+
*/
|
|
26
|
+
export declare function getOfferTotalCap(state: AppState, catalogItem?: Pick<PluginCatalogItem, 'copy'>): number;
|
|
27
|
+
/**
|
|
28
|
+
* The quantity the ordinary update can still add to this item: the smaller
|
|
29
|
+
* of the offer capacity left under the offer cap (getOfferTotalCap) and the
|
|
30
|
+
* item's own cap less the quantity held. The own cap is the item's max,
|
|
31
|
+
* where it sets one, beside its existing per-item cap (getItemCap). An item
|
|
32
|
+
* with no max of its own keeps its existing cap alone, as before the rules.
|
|
33
|
+
* An exact item's own rules do not cap it, so the ordinary update keeps its
|
|
34
|
+
* existing cap alone for it, as before; the exact path bypasses that cap and
|
|
35
|
+
* the offer capacity bounds it (getCartItemApplicableCap).
|
|
36
|
+
*/
|
|
12
37
|
export declare function getCartItemMaxAddableQuantity(state: AppState, catalogItem: PluginCatalogItem): number;
|
|
38
|
+
/**
|
|
39
|
+
* The cap this item's quantity can reach under its quantity rules beside the
|
|
40
|
+
* existing item and offer caps, the offer limit the items carry among them.
|
|
41
|
+
* With no static data the offer's existing cap is unbounded, so the item's
|
|
42
|
+
* own limit and cap, and an offer limit on the item itself, still apply.
|
|
43
|
+
*/
|
|
44
|
+
export declare function getCartItemApplicableCap(state: AppState, catalogItem: PluginCatalogItem): number;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './quantity-rules';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './quantity-rules';
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
import { PluginCatalogItem } from '../../../../../libraries/domain/src/models';
|
|
2
|
+
/**
|
|
3
|
+
* The keys under which the transport emits the quantity rules on a catalog
|
|
4
|
+
* item's `copy` map, each mapped to the name the plugin uses for it. The
|
|
5
|
+
* keys carry the `provider.` prefix every partner-supplied field on the map
|
|
6
|
+
* carries, and each names the quantity it bounds, beside the item's
|
|
7
|
+
* `maxItemCount` and the offer's `maxTotalItemsQtyInOffer`, so a layout
|
|
8
|
+
* reads a rule as `%^DATA.catalogItem.copy.provider.quantityLimit^%`. Each
|
|
9
|
+
* value is a whole number as a string, and a rule that does not apply to the
|
|
10
|
+
* item is absent or 0. The first four are the item's own rules
|
|
11
|
+
* (readQuantityRules). The offer limit is the offer's: the transport writes
|
|
12
|
+
* the offer-wide max on every item of the offer, and it caps the total
|
|
13
|
+
* quantity across all the offer's items (readOfferQuantityLimit). The
|
|
14
|
+
* boundary is this map alone: the rest of the plugin reads the rules by the
|
|
15
|
+
* names on the left.
|
|
16
|
+
*/
|
|
17
|
+
export declare const QUANTITY_RULE_KEYS: {
|
|
18
|
+
readonly max: "provider.quantityLimit";
|
|
19
|
+
readonly min: "provider.minimumQuantity";
|
|
20
|
+
readonly multiple: "provider.quantityMultiple";
|
|
21
|
+
readonly exact: "provider.exactQuantity";
|
|
22
|
+
readonly offerLimit: "provider.offerQuantityLimit";
|
|
23
|
+
};
|
|
24
|
+
export type QuantityRules = {
|
|
25
|
+
/**
|
|
26
|
+
* The per-item maximum: the max the item sets, or Infinity when it sets
|
|
27
|
+
* none, or 0, whatever other rules it carries. The transport supplies the
|
|
28
|
+
* max where one applies, so the plugin never defaults it, and an item
|
|
29
|
+
* without one is bounded by its existing per-item cap and the offer caps
|
|
30
|
+
* alone. Never null.
|
|
31
|
+
*/
|
|
32
|
+
max: number;
|
|
33
|
+
/** The least quantity the item can hold besides 0; 0 when absent. */
|
|
34
|
+
min: number;
|
|
35
|
+
/** The step every quantity besides 0 is a multiple of; 1 when absent. */
|
|
36
|
+
multiple: number;
|
|
37
|
+
/**
|
|
38
|
+
* The only quantity the item can hold besides 0, or the offer capacity left
|
|
39
|
+
* by the other items when that is lower; absent when unset.
|
|
40
|
+
*/
|
|
41
|
+
exact?: number;
|
|
42
|
+
};
|
|
43
|
+
export type ExactRules = QuantityRules & {
|
|
44
|
+
exact: number;
|
|
45
|
+
};
|
|
46
|
+
export type QuantityBounds = {
|
|
47
|
+
/**
|
|
48
|
+
* The item's existing per-item minimum, a floor under the rules; 0 when
|
|
49
|
+
* absent.
|
|
50
|
+
*/
|
|
51
|
+
minItemCount: number;
|
|
52
|
+
/** The cap the item's own rules set, from getItemCap. */
|
|
53
|
+
itemCap: number;
|
|
54
|
+
/**
|
|
55
|
+
* The cap the quantity can reach under the offer capacity as well, from
|
|
56
|
+
* getApplicableCap, or a bound the caller sets in its place, at or below
|
|
57
|
+
* the item cap. Only the item cap overrides the minimum, so this cap admits
|
|
58
|
+
* nothing when it is below the first admitted multiple.
|
|
59
|
+
*/
|
|
60
|
+
cap: number;
|
|
61
|
+
};
|
|
62
|
+
export type CapInputs = {
|
|
63
|
+
/** The item's existing per-item cap. */
|
|
64
|
+
maxItemCount?: number;
|
|
65
|
+
/**
|
|
66
|
+
* The offer's existing cap on the total quantity across its items,
|
|
67
|
+
* maxTotalItemsQtyInOffer; absent, or null as the offer may carry it, when
|
|
68
|
+
* the offer sets none.
|
|
69
|
+
*/
|
|
70
|
+
offerCap?: number | null;
|
|
71
|
+
/**
|
|
72
|
+
* The offer limit the items carry (readOfferQuantityLimit), a second cap
|
|
73
|
+
* on the same total; absent when no item carries one. Both caps apply and
|
|
74
|
+
* the smaller wins (getOfferCap).
|
|
75
|
+
*/
|
|
76
|
+
offerLimit?: number;
|
|
77
|
+
/** The offer's total quantity minus this item's own quantity. */
|
|
78
|
+
offerQuantityOfOthers: number;
|
|
79
|
+
};
|
|
80
|
+
/**
|
|
81
|
+
* Reads the item's four quantity rules from a catalog item's attributes,
|
|
82
|
+
* applying the effective defaults (no max, minimum 0, multiple 1, no exact
|
|
83
|
+
* quantity) so that an item with no rules behaves as the counter does today.
|
|
84
|
+
* A max that is absent or 0 reads as no max of its own, Infinity, whatever
|
|
85
|
+
* other rules the item carries: the transport supplies the max where one
|
|
86
|
+
* applies, so the plugin never defaults it, and the item's existing per-item
|
|
87
|
+
* cap and the offer caps alone bound it. The offer limit is the offer's and
|
|
88
|
+
* is not an item rule (readOfferQuantityLimit).
|
|
89
|
+
*/
|
|
90
|
+
export declare function readQuantityRules(catalogItem: Pick<PluginCatalogItem, 'copy'>): QuantityRules;
|
|
91
|
+
/**
|
|
92
|
+
* The offer limit the items of an offer carry: the cap on the total quantity
|
|
93
|
+
* across all the offer's cart items, which the transport writes under the
|
|
94
|
+
* same key, with the same value, on every item of the offer. Read as the
|
|
95
|
+
* first positive whole number across the offer's catalog items, the item's
|
|
96
|
+
* own attributes first, so an item that lacks the key is still bounded by
|
|
97
|
+
* the limit its siblings carry. Undefined when no item carries one: the
|
|
98
|
+
* transport writes 0 for no additional offer limit, and 0, like an absent or
|
|
99
|
+
* malformed value, is no rule. It applies beside the offer's existing
|
|
100
|
+
* maxTotalItemsQtyInOffer, and the smaller wins (getOfferCap).
|
|
101
|
+
*/
|
|
102
|
+
export declare function readOfferQuantityLimit(catalogItems: ReadonlyArray<Pick<PluginCatalogItem, 'copy'>>, ownItem?: Pick<PluginCatalogItem, 'copy'>): number | undefined;
|
|
103
|
+
/**
|
|
104
|
+
* Whether the item carries a rule beyond the effective defaults: a max of
|
|
105
|
+
* its own, a minimum, a multiple or an exact quantity. An item with no rule
|
|
106
|
+
* keeps today's behaviour under its existing cap and the offer caps alone.
|
|
107
|
+
* The offer limit is the offer's and makes no item a rule-carrying one.
|
|
108
|
+
*/
|
|
109
|
+
export declare function hasQuantityRules(rules: QuantityRules): boolean;
|
|
110
|
+
export declare function isExactRules(rules: QuantityRules): rules is ExactRules;
|
|
111
|
+
/**
|
|
112
|
+
* The cap the item's own rules set: the smaller of its max and its existing
|
|
113
|
+
* per-item cap. An item that sets no max, with or without other rules, has
|
|
114
|
+
* no max of its own, so its existing cap alone bounds it, as before the
|
|
115
|
+
* rules. An exact item has no own cap, because its exact quantity overrides
|
|
116
|
+
* its own limits; the offer capacity alone bounds it, in getApplicableCap.
|
|
117
|
+
* This cap alone overrides the minimum, and a quantity the cart already holds
|
|
118
|
+
* is corrected against it alone, because the offer capacity bounds additions
|
|
119
|
+
* and never cuts an existing quantity.
|
|
120
|
+
*/
|
|
121
|
+
export declare function getItemCap(rules: QuantityRules, maxItemCount: number | undefined): number;
|
|
122
|
+
/**
|
|
123
|
+
* The cap on the total quantity across the offer's items: the smaller of the
|
|
124
|
+
* offer's existing maxTotalItemsQtyInOffer and the offer limit the items
|
|
125
|
+
* carry, each applying where it is set, or Infinity when neither is.
|
|
126
|
+
*/
|
|
127
|
+
export declare function getOfferCap(caps: Pick<CapInputs, 'offerCap' | 'offerLimit'>): number;
|
|
128
|
+
/**
|
|
129
|
+
* The cap an item's quantity can reach: the smaller of its own cap and the
|
|
130
|
+
* offer capacity left by the other items under the offer cap (getOfferCap),
|
|
131
|
+
* or Infinity when none applies. An exact item has no own cap, so for it
|
|
132
|
+
* this is the offer capacity alone: an exact quantity above it is capped
|
|
133
|
+
* there.
|
|
134
|
+
*/
|
|
135
|
+
export declare function getApplicableCap(rules: QuantityRules, caps: CapInputs): number;
|
|
136
|
+
/**
|
|
137
|
+
* The correction applied to a typed quantity when it is committed and to an
|
|
138
|
+
* existing quantity on the first render. Zero and anything that is not a
|
|
139
|
+
* positive number mean removal. Any positive quantity on an exact item becomes
|
|
140
|
+
* the exact quantity, or the cap when the exact quantity is above it, or
|
|
141
|
+
* removal when the cap admits nothing. Otherwise a positive quantity becomes
|
|
142
|
+
* the multiple at or below it, raised to the first admitted multiple when it
|
|
143
|
+
* is below that and cut to the last when it is above it, the item's own cap
|
|
144
|
+
* winning over the minimum when the two disagree. So with the default step a
|
|
145
|
+
* quantity below the minimum becomes the minimum and a quantity above the cap
|
|
146
|
+
* becomes the cap. The first multiple lies at or above the item's existing
|
|
147
|
+
* minimum too, so a correction never goes below that floor. A cap that admits
|
|
148
|
+
* nothing means removal.
|
|
149
|
+
*/
|
|
150
|
+
export declare function normalizeQuantity(rules: QuantityRules, bounds: QuantityBounds, quantity: number): number;
|
|
151
|
+
/**
|
|
152
|
+
* The quantity the increment button selects from a normalized quantity: the
|
|
153
|
+
* next admitted multiple above it. From zero with a minimum of 3 and a
|
|
154
|
+
* multiple of 2 that is 4, and from 4 it is 6. At the last multiple under the
|
|
155
|
+
* cap it changes nothing, and the increment is disabled there, as it is from
|
|
156
|
+
* zero when the cap admits nothing. On an exact item it selects the exact
|
|
157
|
+
* quantity, or the cap below it, and changes nothing once the quantity is at
|
|
158
|
+
* or above that.
|
|
159
|
+
*/
|
|
160
|
+
export declare function plusStep(rules: QuantityRules, bounds: QuantityBounds, quantity: number): number;
|
|
161
|
+
/**
|
|
162
|
+
* The quantity the decrement button selects from a normalized quantity: the
|
|
163
|
+
* previous multiple below it, or 0 when that multiple is below the first
|
|
164
|
+
* admitted one. From 4 with a minimum of 3 and a multiple of 2 it removes the
|
|
165
|
+
* item, because 2 is below the minimum. On an exact item any positive
|
|
166
|
+
* quantity goes to zero.
|
|
167
|
+
*/
|
|
168
|
+
export declare function minusStep(rules: QuantityRules, bounds: QuantityBounds, quantity: number): number;
|
|
169
|
+
/**
|
|
170
|
+
* Whether the increment button is disabled: when no admitted multiple lies
|
|
171
|
+
* above the quantity under the cap, when no more of the item can be added to
|
|
172
|
+
* the offer, or once an exact item holds its quantity, or the cap below it.
|
|
173
|
+
*/
|
|
174
|
+
export declare function isIncrementDisabled(rules: QuantityRules, bounds: QuantityBounds, quantity: number, maxAddableQuantity: number): boolean;
|