@shopify/ui-extensions 2026.10.0-rc.12 → 2026.10.0-rc.14
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/build/cjs/surfaces/customer-account/preact/authenticated-account.js +1 -1
- package/build/cjs/surfaces/point-of-sale/events.js +37 -21
- package/build/cjs/surfaces/point-of-sale/pos-list-template.js +339 -0
- package/build/cjs/surfaces/point-of-sale.js +2 -0
- package/build/esm/surfaces/customer-account/preact/authenticated-account.mjs +1 -1
- package/build/esm/surfaces/point-of-sale/events.mjs +37 -21
- package/build/esm/surfaces/point-of-sale/pos-list-template.mjs +331 -0
- package/build/esm/surfaces/point-of-sale.mjs +1 -0
- package/build/esnext/surfaces/customer-account/preact/authenticated-account.esnext +1 -1
- package/build/esnext/surfaces/point-of-sale/events.esnext +37 -21
- package/build/esnext/surfaces/point-of-sale/pos-list-template.esnext +331 -0
- package/build/esnext/surfaces/point-of-sale.esnext +1 -0
- package/build/ts/shared.d.ts +6 -20
- package/build/ts/shared.d.ts.map +1 -1
- package/build/ts/surfaces/checkout/api/address-autocomplete/format-suggestion.d.ts +7 -0
- package/build/ts/surfaces/checkout/api/address-autocomplete/format-suggestion.d.ts.map +1 -1
- package/build/ts/surfaces/checkout/api/address-autocomplete/shared.d.ts +8 -1
- package/build/ts/surfaces/checkout/api/address-autocomplete/shared.d.ts.map +1 -1
- package/build/ts/surfaces/checkout/api/address-autocomplete/standard.d.ts +2 -2
- package/build/ts/surfaces/checkout/api/address-autocomplete/standard.d.ts.map +1 -1
- package/build/ts/surfaces/checkout/api/address-autocomplete/suggest.d.ts +7 -0
- package/build/ts/surfaces/checkout/api/address-autocomplete/suggest.d.ts.map +1 -1
- package/build/ts/surfaces/checkout/api/checkout/checkout.d.ts +15 -4
- package/build/ts/surfaces/checkout/api/checkout/checkout.d.ts.map +1 -1
- package/build/ts/surfaces/checkout/api/shared.d.ts +102 -1
- package/build/ts/surfaces/checkout/api/shared.d.ts.map +1 -1
- package/build/ts/surfaces/checkout/api/standard/standard.d.ts +8 -2
- package/build/ts/surfaces/checkout/api/standard/standard.d.ts.map +1 -1
- package/build/ts/surfaces/checkout/components/MoneyField.d.ts +3 -1
- package/build/ts/surfaces/checkout/components/NumberField.d.ts +3 -1
- package/build/ts/surfaces/checkout/preact/country.d.ts +1 -1
- package/build/ts/surfaces/checkout/preact/country.d.ts.map +1 -1
- package/build/ts/surfaces/checkout.d.ts +2 -2
- package/build/ts/surfaces/checkout.d.ts.map +1 -1
- package/build/ts/surfaces/customer-account/api/shared.d.ts +26 -7
- package/build/ts/surfaces/customer-account/api/shared.d.ts.map +1 -1
- package/build/ts/surfaces/customer-account/api.d.ts +1 -1
- package/build/ts/surfaces/customer-account/api.d.ts.map +1 -1
- package/build/ts/surfaces/customer-account/components/MoneyField.d.ts +3 -1
- package/build/ts/surfaces/customer-account/components/NumberField.d.ts +3 -1
- package/build/ts/surfaces/customer-account/preact/authenticated-account.d.ts +3 -3
- package/build/ts/surfaces/customer-account/preact/authenticated-account.d.ts.map +1 -1
- package/build/ts/surfaces/point-of-sale/api/device-api/device-api.d.ts +4 -0
- package/build/ts/surfaces/point-of-sale/api/device-api/device-api.d.ts.map +1 -1
- package/build/ts/surfaces/point-of-sale/api/docs.d.ts +7 -0
- package/build/ts/surfaces/point-of-sale/api/docs.d.ts.map +1 -1
- package/build/ts/surfaces/point-of-sale/api/extension-api/extension-api.d.ts +25 -5
- package/build/ts/surfaces/point-of-sale/api/extension-api/extension-api.d.ts.map +1 -1
- package/build/ts/surfaces/point-of-sale/api/navigation-api/navigation-api.d.ts +19 -7
- package/build/ts/surfaces/point-of-sale/api/navigation-api/navigation-api.d.ts.map +1 -1
- package/build/ts/surfaces/point-of-sale/api/resolution-api/resolution-api.d.ts +28 -3
- package/build/ts/surfaces/point-of-sale/api/resolution-api/resolution-api.d.ts.map +1 -1
- package/build/ts/surfaces/point-of-sale/api.d.ts +1 -1
- package/build/ts/surfaces/point-of-sale/api.d.ts.map +1 -1
- package/build/ts/surfaces/point-of-sale/components/POSList.d.ts +179 -0
- package/build/ts/surfaces/point-of-sale/components/targets/BlockExtensionComponents.d.ts +1 -1
- package/build/ts/surfaces/point-of-sale/components/targets/BlockExtensionComponents.d.ts.map +1 -1
- package/build/ts/surfaces/point-of-sale/components/targets/ResolutionComponents.d.ts +1 -1
- package/build/ts/surfaces/point-of-sale/components/targets/ResolutionComponents.d.ts.map +1 -1
- package/build/ts/surfaces/point-of-sale/components/targets/StandardComponents.d.ts +1 -1
- package/build/ts/surfaces/point-of-sale/components/targets/StandardComponents.d.ts.map +1 -1
- package/build/ts/surfaces/point-of-sale/events/transaction-complete-event.d.ts +8 -0
- package/build/ts/surfaces/point-of-sale/events/transaction-complete-event.d.ts.map +1 -1
- package/build/ts/surfaces/point-of-sale/events.d.ts +49 -27
- package/build/ts/surfaces/point-of-sale/events.d.ts.map +1 -1
- package/build/ts/surfaces/point-of-sale/extension-targets.d.ts +4 -4
- package/build/ts/surfaces/point-of-sale/extension-targets.d.ts.map +1 -1
- package/build/ts/surfaces/point-of-sale/globals.d.ts +0 -2
- package/build/ts/surfaces/point-of-sale/globals.d.ts.map +1 -1
- package/build/ts/surfaces/point-of-sale/pos-list-template.d.ts +36 -0
- package/build/ts/surfaces/point-of-sale/pos-list-template.d.ts.map +1 -0
- package/build/ts/surfaces/point-of-sale/targets/pos.cart.line-item-details.action.render.d.ts +1 -0
- package/build/ts/surfaces/point-of-sale/targets/pos.cart.validations.resolution.render.d.ts +1 -0
- package/build/ts/surfaces/point-of-sale/targets/pos.customer-details.action.render.d.ts +1 -0
- package/build/ts/surfaces/point-of-sale/targets/pos.draft-order-details.action.render.d.ts +1 -0
- package/build/ts/surfaces/point-of-sale/targets/pos.exchange.post.action.render.d.ts +1 -0
- package/build/ts/surfaces/point-of-sale/targets/pos.home.modal.render.d.ts +1 -0
- package/build/ts/surfaces/point-of-sale/targets/pos.order-details.action.render.d.ts +1 -0
- package/build/ts/surfaces/point-of-sale/targets/pos.payment.validations.resolution.render.d.ts +1 -0
- package/build/ts/surfaces/point-of-sale/targets/pos.product-details.action.render.d.ts +1 -0
- package/build/ts/surfaces/point-of-sale/targets/pos.purchase.post.action.render.d.ts +1 -0
- package/build/ts/surfaces/point-of-sale/targets/pos.register-details.action.render.d.ts +1 -0
- package/build/ts/surfaces/point-of-sale/targets/pos.return.post.action.render.d.ts +1 -0
- package/build/ts/surfaces/point-of-sale/types/base-transaction-complete.d.ts +8 -0
- package/build/ts/surfaces/point-of-sale/types/base-transaction-complete.d.ts.map +1 -1
- package/build/ts/surfaces/point-of-sale.d.ts +1 -0
- package/build/ts/surfaces/point-of-sale.d.ts.map +1 -1
- package/build/tsconfig.tsbuildinfo +1 -1
- package/package.json +2 -1
- package/src/shared.ts +22 -21
- package/src/surfaces/checkout/api/address-autocomplete/format-suggestion.ts +9 -0
- package/src/surfaces/checkout/api/address-autocomplete/shared.ts +9 -0
- package/src/surfaces/checkout/api/address-autocomplete/standard.ts +1 -2
- package/src/surfaces/checkout/api/address-autocomplete/suggest.ts +8 -0
- package/src/surfaces/checkout/api/checkout/checkout.ts +19 -9
- package/src/surfaces/checkout/api/shared.ts +110 -1
- package/src/surfaces/checkout/api/standard/standard.ts +11 -1
- package/src/surfaces/checkout/components/MoneyField.d.ts +3 -1
- package/src/surfaces/checkout/components/NumberField.d.ts +3 -1
- package/src/surfaces/checkout/preact/country.ts +1 -1
- package/src/surfaces/checkout.ts +3 -0
- package/src/surfaces/customer-account/api/shared.ts +25 -7
- package/src/surfaces/customer-account/api.ts +1 -0
- package/src/surfaces/customer-account/preact/authenticated-account.ts +3 -3
- package/src/surfaces/point-of-sale/api/device-api/device-api.ts +4 -0
- package/src/surfaces/point-of-sale/api/docs.ts +8 -0
- package/src/surfaces/point-of-sale/api/extension-api/extension-api.ts +25 -5
- package/src/surfaces/point-of-sale/api/navigation-api/navigation-api.ts +22 -7
- package/src/surfaces/point-of-sale/api/resolution-api/resolution-api.ts +30 -3
- package/src/surfaces/point-of-sale/api.ts +1 -0
- package/src/surfaces/point-of-sale/components/POSList.d.ts +179 -0
- package/src/surfaces/point-of-sale/components/targets/BlockExtensionComponents.ts +0 -4
- package/src/surfaces/point-of-sale/components/targets/ResolutionComponents.ts +1 -1
- package/src/surfaces/point-of-sale/components/targets/StandardComponents.ts +1 -3
- package/src/surfaces/point-of-sale/components.d.ts +194 -0
- package/src/surfaces/point-of-sale/events/transaction-complete-event.ts +8 -0
- package/src/surfaces/point-of-sale/events.ts +49 -27
- package/src/surfaces/point-of-sale/extension-targets.ts +4 -4
- package/src/surfaces/point-of-sale/globals.ts +0 -2
- package/src/surfaces/point-of-sale/pos-list-template.ts +351 -0
- package/src/surfaces/point-of-sale/tests/pos-list-template.test.ts +306 -0
- package/src/surfaces/point-of-sale/types/base-transaction-complete.ts +8 -0
- package/src/surfaces/point-of-sale.ts +1 -0
|
@@ -6,7 +6,7 @@ var api = require('./api.js');
|
|
|
6
6
|
var subscription = require('./subscription.js');
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
|
-
* Returns the current
|
|
9
|
+
* Returns the current `AuthenticatedAccountCustomer`.
|
|
10
10
|
*
|
|
11
11
|
* The value is `undefined` if the customer isn't authenticated.
|
|
12
12
|
*/
|
|
@@ -40,26 +40,26 @@ const POS_INTERCEPT_NAMES = {
|
|
|
40
40
|
*
|
|
41
41
|
* Used as the generic type parameter for `shopify.intercept`.
|
|
42
42
|
*
|
|
43
|
-
* @
|
|
43
|
+
* @publicDocs
|
|
44
44
|
*/
|
|
45
45
|
|
|
46
46
|
/**
|
|
47
47
|
* The data carried by a `cartvalidations` event.
|
|
48
48
|
*
|
|
49
|
-
* @
|
|
49
|
+
* @publicDocs
|
|
50
50
|
*/
|
|
51
51
|
|
|
52
52
|
/**
|
|
53
53
|
* The event a `cartvalidations` interceptor receives. Carries a snapshot of
|
|
54
54
|
* the POS cart taken when the event was produced.
|
|
55
55
|
*
|
|
56
|
-
* @
|
|
56
|
+
* @publicDocs
|
|
57
57
|
*/
|
|
58
58
|
|
|
59
59
|
/**
|
|
60
60
|
* The kind of payment method being attempted.
|
|
61
61
|
*
|
|
62
|
-
* @
|
|
62
|
+
* @publicDocs
|
|
63
63
|
*/
|
|
64
64
|
|
|
65
65
|
/**
|
|
@@ -69,7 +69,7 @@ const POS_INTERCEPT_NAMES = {
|
|
|
69
69
|
* disambiguates method types a shop can have several of (for example custom
|
|
70
70
|
* payment methods) as they become interceptable.
|
|
71
71
|
*
|
|
72
|
-
* @
|
|
72
|
+
* @publicDocs
|
|
73
73
|
*/
|
|
74
74
|
|
|
75
75
|
/**
|
|
@@ -77,77 +77,93 @@ const POS_INTERCEPT_NAMES = {
|
|
|
77
77
|
* attempt's payment method and amount; split payments produce one event per
|
|
78
78
|
* tender, each with its own amount.
|
|
79
79
|
*
|
|
80
|
-
* @
|
|
80
|
+
* @publicDocs
|
|
81
81
|
*/
|
|
82
82
|
|
|
83
83
|
/**
|
|
84
84
|
* The data carried by a `paymentvalidations` event.
|
|
85
85
|
*
|
|
86
|
-
* @
|
|
86
|
+
* @publicDocs
|
|
87
87
|
*/
|
|
88
88
|
|
|
89
89
|
/**
|
|
90
90
|
* Targets the whole cart rather than a specific line item.
|
|
91
91
|
*
|
|
92
|
-
* @
|
|
92
|
+
* @publicDocs
|
|
93
93
|
*/
|
|
94
94
|
|
|
95
95
|
/**
|
|
96
96
|
* Targets one cart line item by its `uuid` from this event's `cart` snapshot,
|
|
97
97
|
* for example `$.cart.lineItems['adfd6b06-4a24-4f5f-9f4b-ea21f4432dd4']`.
|
|
98
98
|
*
|
|
99
|
-
* @
|
|
99
|
+
* @publicDocs
|
|
100
100
|
*/
|
|
101
101
|
|
|
102
|
-
/**
|
|
102
|
+
/**
|
|
103
|
+
* A target that a `cartvalidations` interceptor can use: the whole cart or
|
|
104
|
+
* one cart line item.
|
|
105
|
+
*
|
|
106
|
+
* @publicDocs
|
|
107
|
+
*/
|
|
103
108
|
|
|
104
109
|
/**
|
|
105
110
|
* Targets the payment attempt being intercepted.
|
|
106
111
|
*
|
|
107
|
-
* @
|
|
112
|
+
* @publicDocs
|
|
108
113
|
*/
|
|
109
114
|
|
|
110
|
-
/**
|
|
115
|
+
/**
|
|
116
|
+
* A target that a `paymentvalidations` interceptor can use. The only
|
|
117
|
+
* supported target is the payment attempt.
|
|
118
|
+
*
|
|
119
|
+
* @publicDocs
|
|
120
|
+
*/
|
|
111
121
|
|
|
112
122
|
/**
|
|
113
123
|
* Where a validation applies, as an enumerated token. Targets are matched
|
|
114
124
|
* as exact strings, never evaluated as JSON paths.
|
|
115
125
|
*
|
|
116
|
-
* @
|
|
126
|
+
* @publicDocs
|
|
117
127
|
*/
|
|
118
128
|
|
|
119
129
|
/**
|
|
120
130
|
* Maps POS interceptable workflow names to their valid validation targets.
|
|
121
131
|
*
|
|
122
|
-
* @
|
|
132
|
+
* @publicDocs
|
|
123
133
|
*/
|
|
124
134
|
|
|
125
135
|
/**
|
|
126
136
|
* The interceptor callback for a POS interceptable workflow, keyed by the
|
|
127
137
|
* workflow name so the event and its valid validation targets stay paired.
|
|
128
138
|
*
|
|
129
|
-
* @
|
|
139
|
+
* @publicDocs
|
|
130
140
|
*/
|
|
131
141
|
|
|
132
142
|
/**
|
|
133
|
-
* The result an interceptor returns. An empty `operations` list
|
|
134
|
-
*
|
|
143
|
+
* The result an interceptor returns. An empty `operations` list adds no
|
|
144
|
+
* findings from this interceptor and doesn't remove or override findings from
|
|
145
|
+
* other interceptors.
|
|
135
146
|
*
|
|
136
|
-
* @
|
|
147
|
+
* @publicDocs
|
|
137
148
|
*/
|
|
138
149
|
|
|
139
150
|
/**
|
|
140
151
|
* A single host operation produced by an interceptor.
|
|
141
152
|
*
|
|
142
|
-
* @
|
|
153
|
+
* @publicDocs
|
|
143
154
|
*/
|
|
144
155
|
|
|
145
|
-
/**
|
|
156
|
+
/**
|
|
157
|
+
* The severity of a validation. `ERROR` can block the workflow when blocking
|
|
158
|
+
* is declared and allowed by the store. `WARNING` never blocks.
|
|
159
|
+
*
|
|
160
|
+
* @publicDocs
|
|
161
|
+
*/
|
|
146
162
|
|
|
147
163
|
/**
|
|
148
164
|
* Adds a validation to the workflow being intercepted.
|
|
149
165
|
*
|
|
150
|
-
* @
|
|
166
|
+
* @publicDocs
|
|
151
167
|
*/
|
|
152
168
|
|
|
153
169
|
exports.POS_EVENT_NAMES = POS_EVENT_NAMES;
|
|
@@ -0,0 +1,339 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
var htm = require('htm');
|
|
6
|
+
|
|
7
|
+
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
|
|
8
|
+
|
|
9
|
+
var htm__default = /*#__PURE__*/_interopDefaultLegacy(htm);
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* The tagged template that compiles `<s-pos-list-item>` markup into the
|
|
13
|
+
* `itemTemplates` value `<s-pos-list>` accepts. Templates are static: the
|
|
14
|
+
* result contains no functions. Compilation and validation happen when the
|
|
15
|
+
* helper executes, not during the extension build. Define templates at module
|
|
16
|
+
* scope to compile once per module execution.
|
|
17
|
+
* Invalid templates throw synchronously and return no partial collection.
|
|
18
|
+
* An uncaught module-scope exception aborts module evaluation; catch the helper
|
|
19
|
+
* invocation to recover explicitly. There is no automatic list-only fallback.
|
|
20
|
+
*
|
|
21
|
+
* @publicDocs
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
const ITEM_TAG = 's-pos-list-item';
|
|
25
|
+
const LIST_TAG = 's-pos-list';
|
|
26
|
+
const PATH_PATTERN = /^[\w.]+$/;
|
|
27
|
+
const EVENT_PROP_PATTERN = /^on/i;
|
|
28
|
+
const BIND_PREFIX = 'bind:';
|
|
29
|
+
/** `{{#if path}}`, `{{/if}}`, or `{{path}}`; anything else inside `{{ }}` is unsupported. */
|
|
30
|
+
const EXPRESSION_PATTERN = /\{\{\s*(?:#if\s+([\w.]+)|(\/if)|([\w.]+))\s*\}\}/g;
|
|
31
|
+
const ANY_EXPRESSION_PATTERN = /\{\{([\s\S]*?)\}\}/g;
|
|
32
|
+
function fail(message) {
|
|
33
|
+
throw new Error(`posListTemplate: ${message}`);
|
|
34
|
+
}
|
|
35
|
+
function isRawElement(value) {
|
|
36
|
+
return typeof value === 'object' && value !== null && 'tag' in value && 'props' in value && 'children' in value;
|
|
37
|
+
}
|
|
38
|
+
function createRawElement(type, props, ...children) {
|
|
39
|
+
if (typeof type !== 'string') {
|
|
40
|
+
fail('interpolated values are not supported; templates must be static');
|
|
41
|
+
}
|
|
42
|
+
return {
|
|
43
|
+
tag: type,
|
|
44
|
+
props: props !== null && props !== void 0 ? props : {},
|
|
45
|
+
children
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
const parse = htm__default["default"].bind(createRawElement);
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Splits a string into literal and `{{path}}` segments. Used for attribute
|
|
52
|
+
* values, where block expressions have no meaning.
|
|
53
|
+
*/
|
|
54
|
+
function parseSegments(value) {
|
|
55
|
+
const segments = [];
|
|
56
|
+
let lastIndex = 0;
|
|
57
|
+
for (const match of value.matchAll(ANY_EXPRESSION_PATTERN)) {
|
|
58
|
+
var _match$index;
|
|
59
|
+
const expression = match[1].trim();
|
|
60
|
+
if (!PATH_PATTERN.test(expression)) {
|
|
61
|
+
if (expression.startsWith('#if') || expression === '/if') {
|
|
62
|
+
fail(`{{#if}} is not supported inside an attribute value: "${match[0]}"`);
|
|
63
|
+
}
|
|
64
|
+
fail(`unsupported template expression "${match[0]}"`);
|
|
65
|
+
}
|
|
66
|
+
const index = (_match$index = match.index) !== null && _match$index !== void 0 ? _match$index : 0;
|
|
67
|
+
if (index > lastIndex) {
|
|
68
|
+
segments.push(value.slice(lastIndex, index));
|
|
69
|
+
}
|
|
70
|
+
segments.push({
|
|
71
|
+
path: expression
|
|
72
|
+
});
|
|
73
|
+
lastIndex = index + match[0].length;
|
|
74
|
+
}
|
|
75
|
+
if (lastIndex < value.length) {
|
|
76
|
+
segments.push(value.slice(lastIndex));
|
|
77
|
+
}
|
|
78
|
+
return segments;
|
|
79
|
+
}
|
|
80
|
+
function tokenizeText(value, tokens) {
|
|
81
|
+
let lastIndex = 0;
|
|
82
|
+
for (const match of value.matchAll(ANY_EXPRESSION_PATTERN)) {
|
|
83
|
+
var _match$index2;
|
|
84
|
+
const index = (_match$index2 = match.index) !== null && _match$index2 !== void 0 ? _match$index2 : 0;
|
|
85
|
+
if (index > lastIndex) {
|
|
86
|
+
tokens.push({
|
|
87
|
+
kind: 'text',
|
|
88
|
+
value: value.slice(lastIndex, index)
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
EXPRESSION_PATTERN.lastIndex = 0;
|
|
92
|
+
const expression = EXPRESSION_PATTERN.exec(match[0]);
|
|
93
|
+
if (expression === null || expression[0].length !== match[0].length) {
|
|
94
|
+
fail(`unsupported template expression "${match[0]}"`);
|
|
95
|
+
}
|
|
96
|
+
const [, ifPath, endIf, path] = expression;
|
|
97
|
+
if (ifPath !== undefined) {
|
|
98
|
+
tokens.push({
|
|
99
|
+
kind: 'if',
|
|
100
|
+
path: ifPath
|
|
101
|
+
});
|
|
102
|
+
} else if (endIf !== undefined) {
|
|
103
|
+
tokens.push({
|
|
104
|
+
kind: 'endif'
|
|
105
|
+
});
|
|
106
|
+
} else if (path !== undefined) {
|
|
107
|
+
tokens.push({
|
|
108
|
+
kind: 'path',
|
|
109
|
+
path
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
lastIndex = index + match[0].length;
|
|
113
|
+
}
|
|
114
|
+
if (lastIndex < value.length) {
|
|
115
|
+
tokens.push({
|
|
116
|
+
kind: 'text',
|
|
117
|
+
value: value.slice(lastIndex)
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
function tokenize(rawChildren) {
|
|
122
|
+
const tokens = [];
|
|
123
|
+
for (const child of rawChildren.flat()) {
|
|
124
|
+
if (typeof child === 'string') {
|
|
125
|
+
if (child.trim().length > 0) {
|
|
126
|
+
tokenizeText(child, tokens);
|
|
127
|
+
}
|
|
128
|
+
} else if (isRawElement(child)) {
|
|
129
|
+
tokens.push({
|
|
130
|
+
kind: 'element',
|
|
131
|
+
element: child
|
|
132
|
+
});
|
|
133
|
+
} else if (child !== null && child !== undefined && child !== false) {
|
|
134
|
+
fail('interpolated values are not supported; templates must be static');
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
return tokens;
|
|
138
|
+
}
|
|
139
|
+
function compileProp(name, value, props) {
|
|
140
|
+
const isBinding = name.startsWith(BIND_PREFIX);
|
|
141
|
+
const propName = isBinding ? name.slice(BIND_PREFIX.length) : name;
|
|
142
|
+
if (EVENT_PROP_PATTERN.test(propName)) {
|
|
143
|
+
fail(`event handlers are not supported in templates; use onRowClick on <${LIST_TAG}>`);
|
|
144
|
+
}
|
|
145
|
+
if (isBinding) {
|
|
146
|
+
if (typeof value !== 'string' || !PATH_PATTERN.test(value)) {
|
|
147
|
+
fail(`${name} must name a row field path`);
|
|
148
|
+
}
|
|
149
|
+
if (propName in props) {
|
|
150
|
+
fail(`"${propName}" is set both as an attribute and through ${name}`);
|
|
151
|
+
}
|
|
152
|
+
props[propName] = {
|
|
153
|
+
kind: 'field',
|
|
154
|
+
path: value
|
|
155
|
+
};
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
if (typeof value === 'string') {
|
|
159
|
+
props[name] = value.includes('{{') ? {
|
|
160
|
+
kind: 'segments',
|
|
161
|
+
segments: parseSegments(value)
|
|
162
|
+
} : {
|
|
163
|
+
kind: 'literal',
|
|
164
|
+
value
|
|
165
|
+
};
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
if (typeof value === 'boolean') {
|
|
169
|
+
props[name] = {
|
|
170
|
+
kind: 'literal',
|
|
171
|
+
value
|
|
172
|
+
};
|
|
173
|
+
return;
|
|
174
|
+
}
|
|
175
|
+
fail('interpolated values are not supported; templates must be static');
|
|
176
|
+
}
|
|
177
|
+
function compileElement(element, parentIfPath) {
|
|
178
|
+
if (element.tag === ITEM_TAG || element.tag === LIST_TAG) {
|
|
179
|
+
fail(`<${element.tag}> can only appear as a template root`);
|
|
180
|
+
}
|
|
181
|
+
const props = {};
|
|
182
|
+
// Plain attributes first so `bind:` can detect a collision with one.
|
|
183
|
+
const entries = Object.entries(element.props);
|
|
184
|
+
for (const [name, value] of entries) {
|
|
185
|
+
if (!name.startsWith(BIND_PREFIX)) {
|
|
186
|
+
compileProp(name, value, props);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
for (const [name, value] of entries) {
|
|
190
|
+
if (name.startsWith(BIND_PREFIX)) {
|
|
191
|
+
compileProp(name, value, props);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
const node = {
|
|
195
|
+
kind: 'element',
|
|
196
|
+
tag: element.tag,
|
|
197
|
+
props
|
|
198
|
+
};
|
|
199
|
+
const children = compileChildren(element.children, false, parentIfPath);
|
|
200
|
+
if (children.length > 0) {
|
|
201
|
+
node.children = children;
|
|
202
|
+
}
|
|
203
|
+
return node;
|
|
204
|
+
}
|
|
205
|
+
function compileChildren(rawChildren, atRoot, parentIfPath) {
|
|
206
|
+
var _openIf$path2, _openIf2;
|
|
207
|
+
const nodes = [];
|
|
208
|
+
let pendingText = [];
|
|
209
|
+
let openIf;
|
|
210
|
+
const target = () => openIf ? openIf.children : nodes;
|
|
211
|
+
const flushText = () => {
|
|
212
|
+
if (pendingText.length === 0) {
|
|
213
|
+
return;
|
|
214
|
+
}
|
|
215
|
+
if (atRoot) {
|
|
216
|
+
fail('text must be inside a component such as <s-text>');
|
|
217
|
+
}
|
|
218
|
+
target().push({
|
|
219
|
+
kind: 'text',
|
|
220
|
+
segments: pendingText
|
|
221
|
+
});
|
|
222
|
+
pendingText = [];
|
|
223
|
+
};
|
|
224
|
+
for (const token of tokenize(rawChildren)) {
|
|
225
|
+
switch (token.kind) {
|
|
226
|
+
case 'text':
|
|
227
|
+
pendingText.push(token.value);
|
|
228
|
+
break;
|
|
229
|
+
case 'path':
|
|
230
|
+
pendingText.push({
|
|
231
|
+
path: token.path
|
|
232
|
+
});
|
|
233
|
+
break;
|
|
234
|
+
case 'if':
|
|
235
|
+
{
|
|
236
|
+
var _openIf$path, _openIf;
|
|
237
|
+
flushText();
|
|
238
|
+
const enclosingIfPath = (_openIf$path = (_openIf = openIf) === null || _openIf === void 0 ? void 0 : _openIf.path) !== null && _openIf$path !== void 0 ? _openIf$path : parentIfPath;
|
|
239
|
+
if (enclosingIfPath !== undefined) {
|
|
240
|
+
fail(`{{#if}} cannot be nested: {{#if ${token.path}}} inside {{#if ${enclosingIfPath}}}`);
|
|
241
|
+
}
|
|
242
|
+
openIf = {
|
|
243
|
+
path: token.path,
|
|
244
|
+
children: []
|
|
245
|
+
};
|
|
246
|
+
break;
|
|
247
|
+
}
|
|
248
|
+
case 'endif':
|
|
249
|
+
flushText();
|
|
250
|
+
if (!openIf) {
|
|
251
|
+
fail('{{/if}} without a matching {{#if}}');
|
|
252
|
+
}
|
|
253
|
+
nodes.push({
|
|
254
|
+
kind: 'if',
|
|
255
|
+
path: openIf.path,
|
|
256
|
+
children: openIf.children
|
|
257
|
+
});
|
|
258
|
+
openIf = undefined;
|
|
259
|
+
break;
|
|
260
|
+
case 'element':
|
|
261
|
+
flushText();
|
|
262
|
+
target().push(compileElement(token.element, (_openIf$path2 = (_openIf2 = openIf) === null || _openIf2 === void 0 ? void 0 : _openIf2.path) !== null && _openIf$path2 !== void 0 ? _openIf$path2 : parentIfPath));
|
|
263
|
+
break;
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
flushText();
|
|
267
|
+
if (openIf) {
|
|
268
|
+
fail(`{{#if ${openIf.path}}} is missing its {{/if}}`);
|
|
269
|
+
}
|
|
270
|
+
return nodes;
|
|
271
|
+
}
|
|
272
|
+
function compileRoot(root, seen) {
|
|
273
|
+
if (!isRawElement(root) || root.tag !== ITEM_TAG) {
|
|
274
|
+
fail(`every template root must be an <${ITEM_TAG} templateId="…"> element`);
|
|
275
|
+
}
|
|
276
|
+
let templateId;
|
|
277
|
+
let type = 'button';
|
|
278
|
+
for (const [name, value] of Object.entries(root.props)) {
|
|
279
|
+
if (name === 'templateId') {
|
|
280
|
+
if (typeof value !== 'string' || value.length === 0) {
|
|
281
|
+
fail(`<${ITEM_TAG}> requires a literal, non-empty templateId`);
|
|
282
|
+
}
|
|
283
|
+
templateId = value;
|
|
284
|
+
} else if (name === 'type') {
|
|
285
|
+
if (value !== 'button' && value !== 'text') {
|
|
286
|
+
fail(`<${ITEM_TAG}> type must be "button" or "text", got ${JSON.stringify(value)}`);
|
|
287
|
+
}
|
|
288
|
+
type = value;
|
|
289
|
+
} else {
|
|
290
|
+
fail(`<${ITEM_TAG}> does not accept a "${name}" attribute; only templateId and type are allowed`);
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
if (templateId === undefined) {
|
|
294
|
+
fail(`<${ITEM_TAG}> requires a literal, non-empty templateId`);
|
|
295
|
+
}
|
|
296
|
+
if (seen.has(templateId)) {
|
|
297
|
+
fail(`duplicate templateId "${templateId}"`);
|
|
298
|
+
}
|
|
299
|
+
seen.add(templateId);
|
|
300
|
+
return {
|
|
301
|
+
templateId,
|
|
302
|
+
type,
|
|
303
|
+
children: compileChildren(root.children, true)
|
|
304
|
+
};
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
/**
|
|
308
|
+
* Compiles `<s-pos-list-item>` markup into the `itemTemplates` value for
|
|
309
|
+
* `<s-pos-list>`.
|
|
310
|
+
*
|
|
311
|
+
* Compilation and validation happen when this helper executes, not during the
|
|
312
|
+
* extension build. Define templates at module scope to compile once per module
|
|
313
|
+
* execution.
|
|
314
|
+
* Invalid templates throw synchronously and return no partial collection.
|
|
315
|
+
* An uncaught module-scope exception aborts module evaluation; catch the helper
|
|
316
|
+
* invocation to recover explicitly. There is no automatic list-only fallback.
|
|
317
|
+
*
|
|
318
|
+
* Inside a template, `{{path}}` interpolates a row field as text, `bind:prop="path"`
|
|
319
|
+
* passes a row field to a component prop with its own type, and
|
|
320
|
+
* `{{#if path}}…{{/if}}` renders its content only when the field is truthy.
|
|
321
|
+
* Event handlers, interpolated values, and any other `{{…}}` expression are
|
|
322
|
+
* rejected when the template is compiled.
|
|
323
|
+
*
|
|
324
|
+
* @publicDocs
|
|
325
|
+
*/
|
|
326
|
+
const posListTemplate = (strings, ...values) => {
|
|
327
|
+
if (values.length > 0) {
|
|
328
|
+
fail('interpolated values are not supported; templates must be static');
|
|
329
|
+
}
|
|
330
|
+
const parsed = parse(strings);
|
|
331
|
+
const roots = Array.isArray(parsed) ? parsed : [parsed];
|
|
332
|
+
const seen = new Set();
|
|
333
|
+
const templates = roots.filter(root => !(typeof root === 'string' && root.trim().length === 0)).map(root => compileRoot(root, seen));
|
|
334
|
+
return {
|
|
335
|
+
templates
|
|
336
|
+
};
|
|
337
|
+
};
|
|
338
|
+
|
|
339
|
+
exports.posListTemplate = posListTemplate;
|
|
@@ -3,10 +3,12 @@
|
|
|
3
3
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
4
|
|
|
5
5
|
var events = require('./point-of-sale/events.js');
|
|
6
|
+
var posListTemplate = require('./point-of-sale/pos-list-template.js');
|
|
6
7
|
var storage = require('./point-of-sale/types/storage.js');
|
|
7
8
|
|
|
8
9
|
|
|
9
10
|
|
|
10
11
|
exports.POS_EVENT_NAMES = events.POS_EVENT_NAMES;
|
|
11
12
|
exports.POS_INTERCEPT_NAMES = events.POS_INTERCEPT_NAMES;
|
|
13
|
+
exports.posListTemplate = posListTemplate.posListTemplate;
|
|
12
14
|
exports.StorageError = storage.StorageError;
|
|
@@ -2,7 +2,7 @@ import { useApi } from './api.mjs';
|
|
|
2
2
|
import { useSubscription } from './subscription.mjs';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
|
-
* Returns the current
|
|
5
|
+
* Returns the current `AuthenticatedAccountCustomer`.
|
|
6
6
|
*
|
|
7
7
|
* The value is `undefined` if the customer isn't authenticated.
|
|
8
8
|
*/
|
|
@@ -36,26 +36,26 @@ const POS_INTERCEPT_NAMES = {
|
|
|
36
36
|
*
|
|
37
37
|
* Used as the generic type parameter for `shopify.intercept`.
|
|
38
38
|
*
|
|
39
|
-
* @
|
|
39
|
+
* @publicDocs
|
|
40
40
|
*/
|
|
41
41
|
|
|
42
42
|
/**
|
|
43
43
|
* The data carried by a `cartvalidations` event.
|
|
44
44
|
*
|
|
45
|
-
* @
|
|
45
|
+
* @publicDocs
|
|
46
46
|
*/
|
|
47
47
|
|
|
48
48
|
/**
|
|
49
49
|
* The event a `cartvalidations` interceptor receives. Carries a snapshot of
|
|
50
50
|
* the POS cart taken when the event was produced.
|
|
51
51
|
*
|
|
52
|
-
* @
|
|
52
|
+
* @publicDocs
|
|
53
53
|
*/
|
|
54
54
|
|
|
55
55
|
/**
|
|
56
56
|
* The kind of payment method being attempted.
|
|
57
57
|
*
|
|
58
|
-
* @
|
|
58
|
+
* @publicDocs
|
|
59
59
|
*/
|
|
60
60
|
|
|
61
61
|
/**
|
|
@@ -65,7 +65,7 @@ const POS_INTERCEPT_NAMES = {
|
|
|
65
65
|
* disambiguates method types a shop can have several of (for example custom
|
|
66
66
|
* payment methods) as they become interceptable.
|
|
67
67
|
*
|
|
68
|
-
* @
|
|
68
|
+
* @publicDocs
|
|
69
69
|
*/
|
|
70
70
|
|
|
71
71
|
/**
|
|
@@ -73,77 +73,93 @@ const POS_INTERCEPT_NAMES = {
|
|
|
73
73
|
* attempt's payment method and amount; split payments produce one event per
|
|
74
74
|
* tender, each with its own amount.
|
|
75
75
|
*
|
|
76
|
-
* @
|
|
76
|
+
* @publicDocs
|
|
77
77
|
*/
|
|
78
78
|
|
|
79
79
|
/**
|
|
80
80
|
* The data carried by a `paymentvalidations` event.
|
|
81
81
|
*
|
|
82
|
-
* @
|
|
82
|
+
* @publicDocs
|
|
83
83
|
*/
|
|
84
84
|
|
|
85
85
|
/**
|
|
86
86
|
* Targets the whole cart rather than a specific line item.
|
|
87
87
|
*
|
|
88
|
-
* @
|
|
88
|
+
* @publicDocs
|
|
89
89
|
*/
|
|
90
90
|
|
|
91
91
|
/**
|
|
92
92
|
* Targets one cart line item by its `uuid` from this event's `cart` snapshot,
|
|
93
93
|
* for example `$.cart.lineItems['adfd6b06-4a24-4f5f-9f4b-ea21f4432dd4']`.
|
|
94
94
|
*
|
|
95
|
-
* @
|
|
95
|
+
* @publicDocs
|
|
96
96
|
*/
|
|
97
97
|
|
|
98
|
-
/**
|
|
98
|
+
/**
|
|
99
|
+
* A target that a `cartvalidations` interceptor can use: the whole cart or
|
|
100
|
+
* one cart line item.
|
|
101
|
+
*
|
|
102
|
+
* @publicDocs
|
|
103
|
+
*/
|
|
99
104
|
|
|
100
105
|
/**
|
|
101
106
|
* Targets the payment attempt being intercepted.
|
|
102
107
|
*
|
|
103
|
-
* @
|
|
108
|
+
* @publicDocs
|
|
104
109
|
*/
|
|
105
110
|
|
|
106
|
-
/**
|
|
111
|
+
/**
|
|
112
|
+
* A target that a `paymentvalidations` interceptor can use. The only
|
|
113
|
+
* supported target is the payment attempt.
|
|
114
|
+
*
|
|
115
|
+
* @publicDocs
|
|
116
|
+
*/
|
|
107
117
|
|
|
108
118
|
/**
|
|
109
119
|
* Where a validation applies, as an enumerated token. Targets are matched
|
|
110
120
|
* as exact strings, never evaluated as JSON paths.
|
|
111
121
|
*
|
|
112
|
-
* @
|
|
122
|
+
* @publicDocs
|
|
113
123
|
*/
|
|
114
124
|
|
|
115
125
|
/**
|
|
116
126
|
* Maps POS interceptable workflow names to their valid validation targets.
|
|
117
127
|
*
|
|
118
|
-
* @
|
|
128
|
+
* @publicDocs
|
|
119
129
|
*/
|
|
120
130
|
|
|
121
131
|
/**
|
|
122
132
|
* The interceptor callback for a POS interceptable workflow, keyed by the
|
|
123
133
|
* workflow name so the event and its valid validation targets stay paired.
|
|
124
134
|
*
|
|
125
|
-
* @
|
|
135
|
+
* @publicDocs
|
|
126
136
|
*/
|
|
127
137
|
|
|
128
138
|
/**
|
|
129
|
-
* The result an interceptor returns. An empty `operations` list
|
|
130
|
-
*
|
|
139
|
+
* The result an interceptor returns. An empty `operations` list adds no
|
|
140
|
+
* findings from this interceptor and doesn't remove or override findings from
|
|
141
|
+
* other interceptors.
|
|
131
142
|
*
|
|
132
|
-
* @
|
|
143
|
+
* @publicDocs
|
|
133
144
|
*/
|
|
134
145
|
|
|
135
146
|
/**
|
|
136
147
|
* A single host operation produced by an interceptor.
|
|
137
148
|
*
|
|
138
|
-
* @
|
|
149
|
+
* @publicDocs
|
|
139
150
|
*/
|
|
140
151
|
|
|
141
|
-
/**
|
|
152
|
+
/**
|
|
153
|
+
* The severity of a validation. `ERROR` can block the workflow when blocking
|
|
154
|
+
* is declared and allowed by the store. `WARNING` never blocks.
|
|
155
|
+
*
|
|
156
|
+
* @publicDocs
|
|
157
|
+
*/
|
|
142
158
|
|
|
143
159
|
/**
|
|
144
160
|
* Adds a validation to the workflow being intercepted.
|
|
145
161
|
*
|
|
146
|
-
* @
|
|
162
|
+
* @publicDocs
|
|
147
163
|
*/
|
|
148
164
|
|
|
149
165
|
export { POS_EVENT_NAMES, POS_INTERCEPT_NAMES };
|