@shopify/ui-extensions-tester 2026.4.0-rc.2 → 2026.4.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 +66 -14
- package/build/cjs/_virtual/_rollupPluginBabelHelpers.js +15 -0
- package/build/cjs/admin/factories.js +18 -0
- package/build/cjs/api-version.js +2 -2
- package/build/cjs/checkout/factories.js +0 -5
- package/build/cjs/index.js +209 -86
- package/build/cjs/point-of-sale/factories.js +6 -1
- package/build/esm/_virtual/_rollupPluginBabelHelpers.mjs +10 -0
- package/build/esm/admin/factories.mjs +18 -0
- package/build/esm/api-version.mjs +2 -2
- package/build/esm/checkout/factories.mjs +0 -5
- package/build/esm/index.mjs +208 -87
- package/build/esm/point-of-sale/factories.mjs +6 -1
- package/build/esnext/_virtual/_rollupPluginBabelHelpers.esnext +10 -0
- package/build/esnext/admin/factories.esnext +18 -0
- package/build/esnext/api-version.esnext +2 -2
- package/build/esnext/checkout/factories.esnext +0 -5
- package/build/esnext/index.esnext +208 -87
- package/build/esnext/point-of-sale/factories.esnext +6 -1
- package/build/ts/admin/factories.d.ts.map +1 -1
- package/build/ts/checkout/factories.d.ts.map +1 -1
- package/build/ts/disposable.d.ts +20 -0
- package/build/ts/index.d.ts +62 -14
- package/build/ts/index.d.ts.map +1 -1
- package/build/ts/point-of-sale/factories.d.ts.map +1 -1
- package/build/tsconfig.tsbuildinfo +1 -1
- package/package.json +2 -2
- package/src/admin/README.md +6 -0
- package/src/admin/factories.ts +22 -0
- package/src/checkout/factories.ts +0 -1
- package/src/disposable.d.ts +20 -0
- package/src/index.ts +214 -119
- package/src/point-of-sale/factories.ts +8 -1
- package/src/tests/admin-factories.test.ts +25 -1
- package/src/tests/getExtension.test.ts +93 -1
- package/src/tests/setUpExtension.test.ts +52 -0
package/build/esm/index.mjs
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { classPrivateFieldLooseBase as _classPrivateFieldLooseBase, classPrivateFieldLooseKey as _classPrivateFieldLooseKey } from './_virtual/_rollupPluginBabelHelpers.mjs';
|
|
1
2
|
import * as fs from 'fs';
|
|
2
3
|
import * as path from 'path';
|
|
3
4
|
import { isCheckoutTarget } from './targets.mjs';
|
|
@@ -7,6 +8,8 @@ export { createNavigationHistoryEntry } from './navigation.mjs';
|
|
|
7
8
|
import { API_VERSION } from './api-version.mjs';
|
|
8
9
|
import { installFetchPolyfills, uninstallFetchPolyfills } from './fetch-polyfills.mjs';
|
|
9
10
|
|
|
11
|
+
var _dispose;
|
|
12
|
+
|
|
10
13
|
/**
|
|
11
14
|
* Makes all properties in the API deeply mutable so tests can
|
|
12
15
|
* override any value through the `extension.shopify` proxy:
|
|
@@ -15,6 +18,168 @@ import { installFetchPolyfills, uninstallFetchPolyfills } from './fetch-polyfill
|
|
|
15
18
|
* extension.shopify.i18n.translate = (key) => myTranslations[key];
|
|
16
19
|
*/
|
|
17
20
|
|
|
21
|
+
/**
|
|
22
|
+
* `Symbol.dispose` for runtimes that support it, with a polyfill
|
|
23
|
+
* fallback so the library works on older Node versions too.
|
|
24
|
+
*/
|
|
25
|
+
const SymbolDispose = (_dispose = Symbol.dispose) !== null && _dispose !== void 0 ? _dispose : Symbol.for('Symbol.dispose');
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Members shared by both {@link ExtensionHarness} (returned by
|
|
29
|
+
* `getExtension`) and {@link DisposableExtensionHarness} (returned
|
|
30
|
+
* by `setUpExtension`).
|
|
31
|
+
*/
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Returned by `getExtension`. The caller is responsible for calling
|
|
35
|
+
* `setUp()` before each test and `tearDown()` after.
|
|
36
|
+
*/
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Returned by `setUpExtension`. Already set up — tears down
|
|
40
|
+
* automatically via `Symbol.dispose` (the `using` keyword):
|
|
41
|
+
*
|
|
42
|
+
* ```ts
|
|
43
|
+
* using extension = setUpExtension('purchase.checkout.block.render');
|
|
44
|
+
* ```
|
|
45
|
+
*/
|
|
46
|
+
var _target = /*#__PURE__*/_classPrivateFieldLooseKey("target");
|
|
47
|
+
var _resolvedModule = /*#__PURE__*/_classPrivateFieldLooseKey("resolvedModule");
|
|
48
|
+
var _modulePath = /*#__PURE__*/_classPrivateFieldLooseKey("modulePath");
|
|
49
|
+
var _checkout = /*#__PURE__*/_classPrivateFieldLooseKey("checkout");
|
|
50
|
+
var _networkAccess = /*#__PURE__*/_classPrivateFieldLooseKey("networkAccess");
|
|
51
|
+
var _apiAccess = /*#__PURE__*/_classPrivateFieldLooseKey("apiAccess");
|
|
52
|
+
var _fetchImpl = /*#__PURE__*/_classPrivateFieldLooseKey("fetchImpl");
|
|
53
|
+
var _previousFetch = /*#__PURE__*/_classPrivateFieldLooseKey("previousFetch");
|
|
54
|
+
var _navigationImpl = /*#__PURE__*/_classPrivateFieldLooseKey("navigationImpl");
|
|
55
|
+
var _previousNavigation = /*#__PURE__*/_classPrivateFieldLooseKey("previousNavigation");
|
|
56
|
+
class Extension {
|
|
57
|
+
constructor(target, options) {
|
|
58
|
+
var _options$configSearch;
|
|
59
|
+
Object.defineProperty(this, _target, {
|
|
60
|
+
writable: true,
|
|
61
|
+
value: void 0
|
|
62
|
+
});
|
|
63
|
+
Object.defineProperty(this, _resolvedModule, {
|
|
64
|
+
writable: true,
|
|
65
|
+
value: void 0
|
|
66
|
+
});
|
|
67
|
+
Object.defineProperty(this, _modulePath, {
|
|
68
|
+
writable: true,
|
|
69
|
+
value: void 0
|
|
70
|
+
});
|
|
71
|
+
Object.defineProperty(this, _checkout, {
|
|
72
|
+
writable: true,
|
|
73
|
+
value: void 0
|
|
74
|
+
});
|
|
75
|
+
Object.defineProperty(this, _networkAccess, {
|
|
76
|
+
writable: true,
|
|
77
|
+
value: void 0
|
|
78
|
+
});
|
|
79
|
+
Object.defineProperty(this, _apiAccess, {
|
|
80
|
+
writable: true,
|
|
81
|
+
value: void 0
|
|
82
|
+
});
|
|
83
|
+
Object.defineProperty(this, _fetchImpl, {
|
|
84
|
+
writable: true,
|
|
85
|
+
value: void 0
|
|
86
|
+
});
|
|
87
|
+
Object.defineProperty(this, _previousFetch, {
|
|
88
|
+
writable: true,
|
|
89
|
+
value: void 0
|
|
90
|
+
});
|
|
91
|
+
Object.defineProperty(this, _navigationImpl, {
|
|
92
|
+
writable: true,
|
|
93
|
+
value: createMockNavigation()
|
|
94
|
+
});
|
|
95
|
+
Object.defineProperty(this, _previousNavigation, {
|
|
96
|
+
writable: true,
|
|
97
|
+
value: void 0
|
|
98
|
+
});
|
|
99
|
+
const configSearchDir = (_options$configSearch = options === null || options === void 0 ? void 0 : options.configSearchDir) !== null && _options$configSearch !== void 0 ? _options$configSearch : path.dirname(getCallerFile());
|
|
100
|
+
const tomlPath = findToml(configSearchDir);
|
|
101
|
+
const tomlDir = path.dirname(tomlPath);
|
|
102
|
+
const tomlContent = fs.readFileSync(tomlPath, 'utf-8');
|
|
103
|
+
validateApiVersion(tomlContent);
|
|
104
|
+
const modulePath = parseTargetModule(tomlContent, target);
|
|
105
|
+
_classPrivateFieldLooseBase(this, _target)[_target] = target;
|
|
106
|
+
_classPrivateFieldLooseBase(this, _modulePath)[_modulePath] = modulePath;
|
|
107
|
+
_classPrivateFieldLooseBase(this, _resolvedModule)[_resolvedModule] = path.resolve(tomlDir, modulePath);
|
|
108
|
+
_classPrivateFieldLooseBase(this, _checkout)[_checkout] = isCheckoutTarget(target);
|
|
109
|
+
_classPrivateFieldLooseBase(this, _networkAccess)[_networkAccess] = _classPrivateFieldLooseBase(this, _checkout)[_checkout] && parseNetworkAccess(tomlContent);
|
|
110
|
+
_classPrivateFieldLooseBase(this, _apiAccess)[_apiAccess] = _classPrivateFieldLooseBase(this, _checkout)[_checkout] && parseApiAccess(tomlContent);
|
|
111
|
+
}
|
|
112
|
+
setUp() {
|
|
113
|
+
installFetchPolyfills();
|
|
114
|
+
_classPrivateFieldLooseBase(this, _fetchImpl)[_fetchImpl] = _classPrivateFieldLooseBase(this, _checkout)[_checkout] && !_classPrivateFieldLooseBase(this, _networkAccess)[_networkAccess] && !_classPrivateFieldLooseBase(this, _apiAccess)[_apiAccess] ? async () => {
|
|
115
|
+
// Checkout is the only surface that currently enforces
|
|
116
|
+
// fetch capabilities.
|
|
117
|
+
throw new Error('fetch() is not available. Add network_access = true or ' + 'api_access = true to [extensions.capabilities] in shopify.extension.toml.');
|
|
118
|
+
} : async () => new Response();
|
|
119
|
+
_classPrivateFieldLooseBase(this, _previousFetch)[_previousFetch] = globalThis.fetch;
|
|
120
|
+
_classPrivateFieldLooseBase(this, _previousNavigation)[_previousNavigation] = globalThis.navigation;
|
|
121
|
+
_classPrivateFieldLooseBase(this, _navigationImpl)[_navigationImpl] = createMockNavigation();
|
|
122
|
+
globalThis.shopify = deepWritableProxy(createMockTargetApi(_classPrivateFieldLooseBase(this, _target)[_target]));
|
|
123
|
+
globalThis.fetch = _classPrivateFieldLooseBase(this, _fetchImpl)[_fetchImpl];
|
|
124
|
+
globalThis.navigation = _classPrivateFieldLooseBase(this, _navigationImpl)[_navigationImpl];
|
|
125
|
+
}
|
|
126
|
+
get shopify() {
|
|
127
|
+
if (!globalThis.shopify) {
|
|
128
|
+
throw new Error('You must call extension.setUp() before accessing extension.shopify.');
|
|
129
|
+
}
|
|
130
|
+
return globalThis.shopify;
|
|
131
|
+
}
|
|
132
|
+
get fetch() {
|
|
133
|
+
return _classPrivateFieldLooseBase(this, _fetchImpl)[_fetchImpl];
|
|
134
|
+
}
|
|
135
|
+
set fetch(fn) {
|
|
136
|
+
_classPrivateFieldLooseBase(this, _fetchImpl)[_fetchImpl] = fn;
|
|
137
|
+
globalThis.fetch = fn;
|
|
138
|
+
}
|
|
139
|
+
get navigation() {
|
|
140
|
+
return _classPrivateFieldLooseBase(this, _navigationImpl)[_navigationImpl];
|
|
141
|
+
}
|
|
142
|
+
set navigation(obj) {
|
|
143
|
+
_classPrivateFieldLooseBase(this, _navigationImpl)[_navigationImpl] = obj;
|
|
144
|
+
globalThis.navigation = obj;
|
|
145
|
+
}
|
|
146
|
+
async render() {
|
|
147
|
+
const mod = await import(_classPrivateFieldLooseBase(this, _resolvedModule)[_resolvedModule]);
|
|
148
|
+
const renderFn = mod.default;
|
|
149
|
+
if (typeof renderFn !== 'function') {
|
|
150
|
+
throw new Error(`Expected default export of ${_classPrivateFieldLooseBase(this, _modulePath)[_modulePath]} to be a function, got ${typeof renderFn}`);
|
|
151
|
+
}
|
|
152
|
+
await renderFn();
|
|
153
|
+
}
|
|
154
|
+
tearDown() {
|
|
155
|
+
// Dynamically import preact to unmount cleanly without requiring
|
|
156
|
+
// the test file to depend on preact directly.
|
|
157
|
+
try {
|
|
158
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
159
|
+
const {
|
|
160
|
+
render
|
|
161
|
+
} = require('preact');
|
|
162
|
+
render(null, document.body);
|
|
163
|
+
} catch {
|
|
164
|
+
// Fallback if preact isn't available
|
|
165
|
+
document.body.innerHTML = '';
|
|
166
|
+
}
|
|
167
|
+
delete globalThis.shopify;
|
|
168
|
+
if (_classPrivateFieldLooseBase(this, _previousFetch)[_previousFetch] === undefined) {
|
|
169
|
+
delete globalThis.fetch;
|
|
170
|
+
} else {
|
|
171
|
+
globalThis.fetch = _classPrivateFieldLooseBase(this, _previousFetch)[_previousFetch];
|
|
172
|
+
}
|
|
173
|
+
if (_classPrivateFieldLooseBase(this, _previousNavigation)[_previousNavigation] === undefined) {
|
|
174
|
+
delete globalThis.navigation;
|
|
175
|
+
} else {
|
|
176
|
+
globalThis.navigation = _classPrivateFieldLooseBase(this, _previousNavigation)[_previousNavigation];
|
|
177
|
+
}
|
|
178
|
+
uninstallFetchPolyfills();
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
const extensionCache = new Map();
|
|
182
|
+
|
|
18
183
|
/**
|
|
19
184
|
* Returns an extension test harness for the given target.
|
|
20
185
|
*
|
|
@@ -31,92 +196,46 @@ import { installFetchPolyfills, uninstallFetchPolyfills } from './fetch-polyfill
|
|
|
31
196
|
* `shopify.extension.toml`. Defaults to the calling test file's directory.
|
|
32
197
|
*/
|
|
33
198
|
function getExtension(target, options) {
|
|
34
|
-
var _options$
|
|
35
|
-
const
|
|
36
|
-
const tomlPath = findToml(
|
|
37
|
-
const
|
|
38
|
-
const
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
const
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
let navigationImpl = createMockNavigation();
|
|
48
|
-
let previousNavigation;
|
|
49
|
-
const ext = {
|
|
50
|
-
setUp() {
|
|
51
|
-
installFetchPolyfills();
|
|
52
|
-
fetchImpl = checkout && !networkAccess && !apiAccess ? async () => {
|
|
53
|
-
// Checkout is the only surface that currently enforces
|
|
54
|
-
// fetch capabilities.
|
|
55
|
-
throw new Error('fetch() is not available. Add network_access = true or ' + 'api_access = true to [extensions.capabilities] in shopify.extension.toml.');
|
|
56
|
-
} : async () => new Response();
|
|
57
|
-
previousFetch = globalThis.fetch;
|
|
58
|
-
previousNavigation = globalThis.navigation;
|
|
59
|
-
globalThis.shopify = deepWritableProxy(createMockTargetApi(target));
|
|
60
|
-
globalThis.fetch = fetchImpl;
|
|
61
|
-
globalThis.navigation = navigationImpl;
|
|
62
|
-
},
|
|
63
|
-
get shopify() {
|
|
64
|
-
if (!globalThis.shopify) {
|
|
65
|
-
throw new Error('You must call extension.setUp() before accessing extension.shopify.');
|
|
66
|
-
}
|
|
67
|
-
return globalThis.shopify;
|
|
68
|
-
},
|
|
69
|
-
get fetch() {
|
|
70
|
-
return fetchImpl;
|
|
71
|
-
},
|
|
72
|
-
set fetch(fn) {
|
|
73
|
-
fetchImpl = fn;
|
|
74
|
-
globalThis.fetch = fn;
|
|
75
|
-
},
|
|
76
|
-
get navigation() {
|
|
77
|
-
return navigationImpl;
|
|
78
|
-
},
|
|
79
|
-
set navigation(obj) {
|
|
80
|
-
navigationImpl = obj;
|
|
81
|
-
globalThis.navigation = obj;
|
|
82
|
-
},
|
|
83
|
-
async render() {
|
|
84
|
-
const mod = await import(resolvedModule);
|
|
85
|
-
const renderFn = mod.default;
|
|
86
|
-
if (typeof renderFn !== 'function') {
|
|
87
|
-
throw new Error(`Expected default export of ${modulePath} to be a function, got ${typeof renderFn}`);
|
|
88
|
-
}
|
|
89
|
-
await renderFn();
|
|
90
|
-
},
|
|
91
|
-
tearDown() {
|
|
92
|
-
// Dynamically import preact to unmount cleanly without requiring
|
|
93
|
-
// the test file to depend on preact directly.
|
|
94
|
-
try {
|
|
95
|
-
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
96
|
-
const {
|
|
97
|
-
render
|
|
98
|
-
} = require('preact');
|
|
99
|
-
render(null, document.body);
|
|
100
|
-
} catch {
|
|
101
|
-
// Fallback if preact isn't available
|
|
102
|
-
document.body.innerHTML = '';
|
|
103
|
-
}
|
|
104
|
-
delete globalThis.shopify;
|
|
105
|
-
if (previousFetch === undefined) {
|
|
106
|
-
delete globalThis.fetch;
|
|
107
|
-
} else {
|
|
108
|
-
globalThis.fetch = previousFetch;
|
|
109
|
-
}
|
|
110
|
-
if (previousNavigation === undefined) {
|
|
111
|
-
delete globalThis.navigation;
|
|
112
|
-
} else {
|
|
113
|
-
globalThis.navigation = previousNavigation;
|
|
114
|
-
}
|
|
115
|
-
uninstallFetchPolyfills();
|
|
116
|
-
}
|
|
117
|
-
};
|
|
199
|
+
var _options$configSearch2;
|
|
200
|
+
const resolvedConfigSearchDir = (_options$configSearch2 = options === null || options === void 0 ? void 0 : options.configSearchDir) !== null && _options$configSearch2 !== void 0 ? _options$configSearch2 : path.dirname(getCallerFile());
|
|
201
|
+
const tomlPath = findToml(resolvedConfigSearchDir);
|
|
202
|
+
const tomlMtimeMs = fs.statSync(tomlPath).mtimeMs;
|
|
203
|
+
const cacheKey = JSON.stringify([target, tomlPath, tomlMtimeMs]);
|
|
204
|
+
const cached = extensionCache.get(cacheKey);
|
|
205
|
+
if (cached) {
|
|
206
|
+
return cached;
|
|
207
|
+
}
|
|
208
|
+
const ext = new Extension(target, {
|
|
209
|
+
configSearchDir: resolvedConfigSearchDir
|
|
210
|
+
});
|
|
211
|
+
extensionCache.set(cacheKey, ext);
|
|
118
212
|
return ext;
|
|
119
213
|
}
|
|
214
|
+
|
|
215
|
+
/**
|
|
216
|
+
* Sets up an extension for testing and returns a disposable object
|
|
217
|
+
* that supports automatic teardown with the `using` keyword:
|
|
218
|
+
*
|
|
219
|
+
* ```ts
|
|
220
|
+
* test('rendering the extension', async () => {
|
|
221
|
+
* using extension = setUpExtension(
|
|
222
|
+
* 'purchase.checkout.block.render',
|
|
223
|
+
* );
|
|
224
|
+
* await extension.render();
|
|
225
|
+
* // tearDown() is called automatically at the end of the block
|
|
226
|
+
* });
|
|
227
|
+
* ```
|
|
228
|
+
*
|
|
229
|
+
* @param target - The extension target to mock.
|
|
230
|
+
* @param options - Optional configuration (same as {@link getExtension}).
|
|
231
|
+
*/
|
|
232
|
+
function setUpExtension(target, options) {
|
|
233
|
+
const extension = getExtension(target, options);
|
|
234
|
+
extension.setUp();
|
|
235
|
+
return Object.assign(extension, {
|
|
236
|
+
[SymbolDispose]: () => extension.tearDown()
|
|
237
|
+
});
|
|
238
|
+
}
|
|
120
239
|
function validateApiVersion(toml) {
|
|
121
240
|
const match = toml.match(/^\s*api_version\s*=\s*"([^"]+)"/m);
|
|
122
241
|
const tomlVersion = match === null || match === void 0 ? void 0 : match[1];
|
|
@@ -184,8 +303,10 @@ function getCallerFile() {
|
|
|
184
303
|
const err = new Error();
|
|
185
304
|
let callerFile = '';
|
|
186
305
|
Error.prepareStackTrace = (_err, stack) => {
|
|
187
|
-
//
|
|
188
|
-
|
|
306
|
+
// Walk the stack, skipping all frames that originate from this
|
|
307
|
+
// package file. This works regardless of whether the caller is
|
|
308
|
+
// getExtension() or setUpExtension() → getExtension().
|
|
309
|
+
for (let i = 1; i < stack.length; i++) {
|
|
189
310
|
const fileName = stack[i].getFileName();
|
|
190
311
|
if (fileName && fileName !== thisPackageFilePath) {
|
|
191
312
|
callerFile = fileName;
|
|
@@ -316,4 +437,4 @@ function deepWritableProxy(obj) {
|
|
|
316
437
|
});
|
|
317
438
|
}
|
|
318
439
|
|
|
319
|
-
export { getExtension };
|
|
440
|
+
export { SymbolDispose, getExtension, setUpExtension };
|
|
@@ -53,9 +53,14 @@ function createTransaction() {
|
|
|
53
53
|
lineItems: []
|
|
54
54
|
};
|
|
55
55
|
}
|
|
56
|
+
function createConnectivityApiContent() {
|
|
57
|
+
return {
|
|
58
|
+
current: createReadonlySignalLike(createConnectivityState())
|
|
59
|
+
};
|
|
60
|
+
}
|
|
56
61
|
function createMockBaseEventData() {
|
|
57
62
|
return {
|
|
58
|
-
connectivity:
|
|
63
|
+
connectivity: createConnectivityApiContent(),
|
|
59
64
|
device: {
|
|
60
65
|
name: 'Mock POS Device',
|
|
61
66
|
deviceId: 1,
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
function _classPrivateFieldLooseBase(e, t) {
|
|
2
|
+
if (!{}.hasOwnProperty.call(e, t)) throw new TypeError("attempted to use private field on non-instance");
|
|
3
|
+
return e;
|
|
4
|
+
}
|
|
5
|
+
var id = 0;
|
|
6
|
+
function _classPrivateFieldLooseKey(e) {
|
|
7
|
+
return "__private_" + id++ + "_" + e;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export { _classPrivateFieldLooseBase as classPrivateFieldLooseBase, _classPrivateFieldLooseKey as classPrivateFieldLooseKey };
|
|
@@ -34,6 +34,13 @@ function createConfigApp() {
|
|
|
34
34
|
applicationUrl: 'https://mock-app.test'
|
|
35
35
|
};
|
|
36
36
|
}
|
|
37
|
+
function createIntentResponseApi() {
|
|
38
|
+
return {
|
|
39
|
+
ok: async () => {},
|
|
40
|
+
error: async () => {},
|
|
41
|
+
closed: async () => {}
|
|
42
|
+
};
|
|
43
|
+
}
|
|
37
44
|
function createMockStandardApi(target) {
|
|
38
45
|
return {
|
|
39
46
|
extension: {
|
|
@@ -66,6 +73,15 @@ function createMockStandardRenderingApi(target) {
|
|
|
66
73
|
})
|
|
67
74
|
};
|
|
68
75
|
}
|
|
76
|
+
function createAppIntentRenderMock(target) {
|
|
77
|
+
return {
|
|
78
|
+
...createMockStandardRenderingApi(target),
|
|
79
|
+
intents: {
|
|
80
|
+
...createMockStandardApi(target).intents,
|
|
81
|
+
response: createIntentResponseApi()
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
}
|
|
69
85
|
function createMockBlockApi(target) {
|
|
70
86
|
return {
|
|
71
87
|
...createMockStandardRenderingApi(target),
|
|
@@ -210,6 +226,8 @@ const adminMockFactories = {
|
|
|
210
226
|
// Runnable targets
|
|
211
227
|
'admin.customers.segmentation-templates.data': createCustomerSegmentTemplateMock,
|
|
212
228
|
'admin.app.tools.data': createMockStandardApi,
|
|
229
|
+
// App render targets
|
|
230
|
+
'admin.app.intent.render': createAppIntentRenderMock,
|
|
213
231
|
// Block targets
|
|
214
232
|
'admin.product-details.block.render': createMockBlockApi,
|
|
215
233
|
'admin.order-details.block.render': createMockBlockApi,
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* The API version supported by this version of the library.
|
|
3
3
|
*
|
|
4
|
-
* At build time, `"2026.4.0
|
|
4
|
+
* At build time, `"2026.4.0"` is replaced by rollup with the
|
|
5
5
|
* raw NPM version string from package.json (e.g. `"2026.4.0-rc.1"`).
|
|
6
6
|
*
|
|
7
7
|
* When running from source (e.g. in tests), the placeholder is still
|
|
8
8
|
* present, so we fall back to reading package.json via require.
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
-
const npmVersion = "2026.4.0
|
|
11
|
+
const npmVersion = "2026.4.0";
|
|
12
12
|
function npmVersionToApiVersion(version) {
|
|
13
13
|
const [year, minor] = version.split('.');
|
|
14
14
|
return `${year}-${minor.padStart(2, '0')}`;
|
|
@@ -111,11 +111,6 @@ function createMockStandardApi(target) {
|
|
|
111
111
|
}),
|
|
112
112
|
selectedPaymentOptions: createSubscribableSignalLike([]),
|
|
113
113
|
settings: createSubscribableSignalLike({}),
|
|
114
|
-
ui: {
|
|
115
|
-
overlay: {
|
|
116
|
-
close: () => {}
|
|
117
|
-
}
|
|
118
|
-
},
|
|
119
114
|
version: '0.0.0',
|
|
120
115
|
customerPrivacy: createSubscribableSignalLike({
|
|
121
116
|
allowedProcessing: {
|