@raydiant/playlist-window-manager 0.26.2 → 0.27.1
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/PresentationWindow.d.ts +1 -0
- package/build/PresentationWindow.js +34 -10
- package/build/PresentationWindow.test.js +26 -5
- package/build/embeddedApps.js +15 -0
- package/build/embeddedApps.test.js +21 -0
- package/build/testUtils.js +3 -0
- package/build/types.d.ts +1 -0
- package/package.json +1 -1
- package/src/PresentationWindow.test.ts +27 -5
- package/src/PresentationWindow.ts +32 -3
- package/src/embeddedApps.test.ts +37 -0
- package/src/embeddedApps.ts +14 -0
- package/src/testUtils.ts +3 -0
- package/src/types.ts +1 -0
|
@@ -659,17 +659,30 @@ var PresentationWindow = /** @class */ (function () {
|
|
|
659
659
|
this.forceMute = forceMute;
|
|
660
660
|
};
|
|
661
661
|
PresentationWindow.prototype.reload = function () {
|
|
662
|
+
var _a;
|
|
662
663
|
return __awaiter(this, void 0, void 0, function () {
|
|
663
|
-
var
|
|
664
|
-
return __generator(this, function (
|
|
665
|
-
switch (
|
|
664
|
+
var _b, applicationVersion, windowId, updatedInputs, url;
|
|
665
|
+
return __generator(this, function (_c) {
|
|
666
|
+
switch (_c.label) {
|
|
666
667
|
case 0:
|
|
667
|
-
|
|
668
|
+
_b = this.options, applicationVersion = _b.applicationVersion, windowId = _b.windowId;
|
|
668
669
|
if (!this.isEmbeddedApp()) return [3 /*break*/, 4];
|
|
669
670
|
if (!applicationVersion.embeddedUrlFormat) return [3 /*break*/, 3];
|
|
670
671
|
if (!this.previewSubscriptions.has('inputs')) return [3 /*break*/, 1];
|
|
671
672
|
this.logInfo("Reload window '".concat(windowId, "' for embedded app preview state"));
|
|
672
673
|
updatedInputs = transformInputValues(this.presentation.applicationVariables);
|
|
674
|
+
// Add metadata to inputs if they exist in the URL template. These need to be
|
|
675
|
+
// consistent with metadata keys in embeddedApps.ts.
|
|
676
|
+
if (applicationVersion.embeddedUrlFormat.includes(':$renderMode')) {
|
|
677
|
+
updatedInputs['$renderMode'] = this.getRenderMode();
|
|
678
|
+
}
|
|
679
|
+
if (applicationVersion.embeddedUrlFormat.includes(':$token')) {
|
|
680
|
+
updatedInputs['$token'] = this.presentation.token;
|
|
681
|
+
}
|
|
682
|
+
if (applicationVersion.embeddedUrlFormat.includes(':$deviceId')) {
|
|
683
|
+
updatedInputs['$deviceId'] = (_a = this.options.device) === null || _a === void 0 ? void 0 : _a.id;
|
|
684
|
+
}
|
|
685
|
+
// Send the updated inputs to the embedded app if they have changed.
|
|
673
686
|
if (!(0, fast_deep_equal_1.default)(updatedInputs, this.previewState.inputs)) {
|
|
674
687
|
this.sendMessageObject('preview-inputs', updatedInputs);
|
|
675
688
|
}
|
|
@@ -680,13 +693,13 @@ var PresentationWindow = /** @class */ (function () {
|
|
|
680
693
|
this.logInfo("Reload window '".concat(windowId, "' for embedded app url '").concat(url, "'"));
|
|
681
694
|
return [4 /*yield*/, this.loadWindow(url)];
|
|
682
695
|
case 2:
|
|
683
|
-
|
|
684
|
-
|
|
696
|
+
_c.sent();
|
|
697
|
+
_c.label = 3;
|
|
685
698
|
case 3: return [3 /*break*/, 5];
|
|
686
699
|
case 4:
|
|
687
700
|
this.logInfo("Reload window '".concat(windowId, "'"));
|
|
688
701
|
this.sendRenderMessage();
|
|
689
|
-
|
|
702
|
+
_c.label = 5;
|
|
690
703
|
case 5: return [2 /*return*/];
|
|
691
704
|
}
|
|
692
705
|
});
|
|
@@ -1144,10 +1157,13 @@ var PresentationWindow = /** @class */ (function () {
|
|
|
1144
1157
|
}
|
|
1145
1158
|
};
|
|
1146
1159
|
PresentationWindow.prototype.getEmbeddedAppUrl = function () {
|
|
1147
|
-
var _a = this.options, windowId = _a.windowId, appRendererOfflineSupport = _a.appRendererOfflineSupport;
|
|
1160
|
+
var _a = this.options, windowId = _a.windowId, appRendererOfflineSupport = _a.appRendererOfflineSupport, device = _a.device;
|
|
1148
1161
|
var metadata = {
|
|
1149
|
-
renderMode: this.
|
|
1162
|
+
renderMode: this.getRenderMode(),
|
|
1150
1163
|
};
|
|
1164
|
+
if (device) {
|
|
1165
|
+
metadata.deviceId = device.id;
|
|
1166
|
+
}
|
|
1151
1167
|
var url = (0, embeddedApps_1.default)(this.presentation, this.options.applicationVersion, metadata);
|
|
1152
1168
|
return this.getFullAppRendererUrl({
|
|
1153
1169
|
appRendererUrl: url,
|
|
@@ -1375,6 +1391,9 @@ var PresentationWindow = /** @class */ (function () {
|
|
|
1375
1391
|
}
|
|
1376
1392
|
this.previouslyLocked = currentlyLocked;
|
|
1377
1393
|
};
|
|
1394
|
+
PresentationWindow.prototype.getRenderMode = function () {
|
|
1395
|
+
return this.options.isPreview ? 'preview' : 'live';
|
|
1396
|
+
};
|
|
1378
1397
|
return PresentationWindow;
|
|
1379
1398
|
}());
|
|
1380
1399
|
exports.default = PresentationWindow;
|
|
@@ -1405,7 +1424,12 @@ var transformInputValues = function (inputs) {
|
|
|
1405
1424
|
transformed[key] = [];
|
|
1406
1425
|
for (var _c = 0, value_1 = value; _c < value_1.length; _c++) {
|
|
1407
1426
|
var item = value_1[_c];
|
|
1408
|
-
|
|
1427
|
+
if (typeof item === 'object' && item !== null) {
|
|
1428
|
+
transformed[key].push(transformInputValues(item));
|
|
1429
|
+
}
|
|
1430
|
+
else {
|
|
1431
|
+
transformed[key].push(item);
|
|
1432
|
+
}
|
|
1409
1433
|
}
|
|
1410
1434
|
}
|
|
1411
1435
|
else {
|
|
@@ -111,12 +111,21 @@ describe('embedded apps', function () {
|
|
|
111
111
|
window = (0, testUtils_1.createPresentationWindow)({
|
|
112
112
|
windowId: 'test-reload-message',
|
|
113
113
|
presentation: (0, testUtils_1.createPresentation)({
|
|
114
|
-
applicationVariables: {
|
|
114
|
+
applicationVariables: {
|
|
115
|
+
input: 'test',
|
|
116
|
+
multi: [],
|
|
117
|
+
},
|
|
118
|
+
token: 'token',
|
|
115
119
|
}),
|
|
116
120
|
applicationVersion: (0, testUtils_1.createApplicationVersion)({
|
|
117
|
-
embeddedUrlFormat: 'http://test.local/:input',
|
|
118
|
-
presentationProperties: [
|
|
121
|
+
embeddedUrlFormat: 'http://test.local/:input?renderMode=:$renderMode&token=:$token&deviceId=:$deviceId',
|
|
122
|
+
presentationProperties: [
|
|
123
|
+
{ name: 'input', type: 'string' },
|
|
124
|
+
{ name: 'multi', type: 'select' },
|
|
125
|
+
],
|
|
119
126
|
}),
|
|
127
|
+
isPreview: true,
|
|
128
|
+
device: { id: 'device-id', name: 'device-name' },
|
|
120
129
|
renderer: testRenderer,
|
|
121
130
|
});
|
|
122
131
|
return [4 /*yield*/, window.load()];
|
|
@@ -124,13 +133,25 @@ describe('embedded apps', function () {
|
|
|
124
133
|
_a.sent();
|
|
125
134
|
// Subscribe to receive input updates via message.
|
|
126
135
|
testRenderer.runReceiveMessageCallback('preview-subscribe', 'inputs');
|
|
127
|
-
window.setPresentation((0, testUtils_1.createPresentation)({
|
|
136
|
+
window.setPresentation((0, testUtils_1.createPresentation)({
|
|
137
|
+
applicationVariables: {
|
|
138
|
+
input: 'updated',
|
|
139
|
+
multi: ['a', 'b', 'c'],
|
|
140
|
+
},
|
|
141
|
+
token: 'token',
|
|
142
|
+
}), (0, testUtils_1.createPlaylistWindowManagerState)(), (0, testUtils_1.createRuleEngineState)());
|
|
128
143
|
return [4 /*yield*/, window.reload()];
|
|
129
144
|
case 2:
|
|
130
145
|
_a.sent();
|
|
131
146
|
// loadWindow should only be called once for the initial load.
|
|
132
147
|
expect(testRenderer.loadWindow).toHaveBeenCalledTimes(1);
|
|
133
|
-
expect(testRenderer.sendMessageObject).toHaveBeenCalledWith('test-reload-message', 'preview-inputs', {
|
|
148
|
+
expect(testRenderer.sendMessageObject).toHaveBeenCalledWith('test-reload-message', 'preview-inputs', {
|
|
149
|
+
$renderMode: 'preview',
|
|
150
|
+
$token: 'token',
|
|
151
|
+
$deviceId: 'device-id',
|
|
152
|
+
input: 'updated',
|
|
153
|
+
multi: ['a', 'b', 'c'],
|
|
154
|
+
});
|
|
134
155
|
// sendMessageObject should not be called again for the same inputs.
|
|
135
156
|
return [4 /*yield*/, window.reload()];
|
|
136
157
|
case 3:
|
package/build/embeddedApps.js
CHANGED
|
@@ -13,6 +13,7 @@ function createEmbeddedApp(presentation, applicationVersion, metadata) {
|
|
|
13
13
|
} while (match !== null);
|
|
14
14
|
// replace
|
|
15
15
|
var url = applicationVersion.embeddedUrlFormat || '';
|
|
16
|
+
var queryIndex = url.indexOf('?');
|
|
16
17
|
matches.forEach(function (m) {
|
|
17
18
|
var queryParamVariableName = m[1]; // Where the value of your input will be injected. E.g. ":location"
|
|
18
19
|
var queryParamName = m[2]; // The query param name. E.g. "location"
|
|
@@ -20,6 +21,8 @@ function createEmbeddedApp(presentation, applicationVersion, metadata) {
|
|
|
20
21
|
var shouldEncodeValue = true;
|
|
21
22
|
var value = '';
|
|
22
23
|
if (variableName.charAt(0) === '$') {
|
|
24
|
+
var variableIndex = url.indexOf(queryParamVariableName);
|
|
25
|
+
var isPartOfQuery = queryIndex != -1 && variableIndex > queryIndex;
|
|
23
26
|
var metadataKey = variableName.slice(1);
|
|
24
27
|
if (metadataKey === 'renderMode') {
|
|
25
28
|
value = metadata.renderMode;
|
|
@@ -27,6 +30,18 @@ function createEmbeddedApp(presentation, applicationVersion, metadata) {
|
|
|
27
30
|
else if (metadataKey === 'token') {
|
|
28
31
|
value = presentation.token;
|
|
29
32
|
}
|
|
33
|
+
else if (metadataKey === 'deviceId') {
|
|
34
|
+
if (metadata.deviceId) {
|
|
35
|
+
value = metadata.deviceId;
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
// If :$deviceId is part of the URL path, avoid creating a broken URL if metadata.deviceId is not defined.
|
|
39
|
+
// This will use the variable name as the value instead of an empty string.
|
|
40
|
+
if (!isPartOfQuery) {
|
|
41
|
+
value = queryParamVariableName;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
30
45
|
}
|
|
31
46
|
else {
|
|
32
47
|
// Don't replace variables that are numbers to allow setting
|
|
@@ -128,3 +128,24 @@ test('Replaces $token with presentation token', function () {
|
|
|
128
128
|
});
|
|
129
129
|
expect((0, embeddedApps_1.default)(presentation, applicationVersion, createMetadata())).toBe('https://example.com?token=abc');
|
|
130
130
|
});
|
|
131
|
+
test('Replaces $deviceId with metadata deviceId when provided', function () {
|
|
132
|
+
var presentation = createPresentation();
|
|
133
|
+
var applicationVersion = createApplicationVersion({
|
|
134
|
+
embeddedUrlFormat: 'https://example.com/:$deviceId/content',
|
|
135
|
+
});
|
|
136
|
+
expect((0, embeddedApps_1.default)(presentation, applicationVersion, createMetadata({ deviceId: 'device-id' }))).toBe('https://example.com/device-id/content');
|
|
137
|
+
});
|
|
138
|
+
test('Do not replace $deviceId when in the URI with metadata not defined', function () {
|
|
139
|
+
var presentation = createPresentation();
|
|
140
|
+
var applicationVersion = createApplicationVersion({
|
|
141
|
+
embeddedUrlFormat: 'https://example.com/:$deviceId/content',
|
|
142
|
+
});
|
|
143
|
+
expect((0, embeddedApps_1.default)(presentation, applicationVersion, createMetadata())).toBe("https://example.com/".concat(encodeURIComponent(':$deviceId'), "/content"));
|
|
144
|
+
});
|
|
145
|
+
test('Replaces $deviceId with empty string when in the query string and metadata not defined', function () {
|
|
146
|
+
var presentation = createPresentation();
|
|
147
|
+
var applicationVersion = createApplicationVersion({
|
|
148
|
+
embeddedUrlFormat: 'https://example.com/content?device=:$deviceId',
|
|
149
|
+
});
|
|
150
|
+
expect((0, embeddedApps_1.default)(presentation, applicationVersion, createMetadata())).toBe("https://example.com/content?device=");
|
|
151
|
+
});
|
package/build/testUtils.js
CHANGED
|
@@ -99,6 +99,8 @@ function createPresentationWindow(overrides) {
|
|
|
99
99
|
unMuteWindow: function () { },
|
|
100
100
|
},
|
|
101
101
|
getTerminal: overrides.getTerminal,
|
|
102
|
+
isPreview: overrides.isPreview,
|
|
103
|
+
device: overrides.device,
|
|
102
104
|
});
|
|
103
105
|
}
|
|
104
106
|
exports.createPresentationWindow = createPresentationWindow;
|
|
@@ -113,6 +115,7 @@ function createPresentation(overrides) {
|
|
|
113
115
|
applicationVariables: (_e = overrides.applicationVariables) !== null && _e !== void 0 ? _e : {},
|
|
114
116
|
duration: (_f = overrides.duration) !== null && _f !== void 0 ? _f : 1,
|
|
115
117
|
r: createPresentationRelationships(overrides.r),
|
|
118
|
+
token: overrides.token,
|
|
116
119
|
};
|
|
117
120
|
}
|
|
118
121
|
exports.createPresentation = createPresentation;
|
package/build/types.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -81,12 +81,22 @@ describe('embedded apps', () => {
|
|
|
81
81
|
const window = createPresentationWindow({
|
|
82
82
|
windowId: 'test-reload-message',
|
|
83
83
|
presentation: createPresentation({
|
|
84
|
-
applicationVariables: {
|
|
84
|
+
applicationVariables: {
|
|
85
|
+
input: 'test',
|
|
86
|
+
multi: [],
|
|
87
|
+
},
|
|
88
|
+
token: 'token',
|
|
85
89
|
}),
|
|
86
90
|
applicationVersion: createApplicationVersion({
|
|
87
|
-
embeddedUrlFormat:
|
|
88
|
-
|
|
91
|
+
embeddedUrlFormat:
|
|
92
|
+
'http://test.local/:input?renderMode=:$renderMode&token=:$token&deviceId=:$deviceId',
|
|
93
|
+
presentationProperties: [
|
|
94
|
+
{ name: 'input', type: 'string' },
|
|
95
|
+
{ name: 'multi', type: 'select' },
|
|
96
|
+
],
|
|
89
97
|
}),
|
|
98
|
+
isPreview: true,
|
|
99
|
+
device: { id: 'device-id', name: 'device-name' },
|
|
90
100
|
renderer: testRenderer,
|
|
91
101
|
});
|
|
92
102
|
|
|
@@ -96,7 +106,13 @@ describe('embedded apps', () => {
|
|
|
96
106
|
testRenderer.runReceiveMessageCallback('preview-subscribe', 'inputs');
|
|
97
107
|
|
|
98
108
|
window.setPresentation(
|
|
99
|
-
createPresentation({
|
|
109
|
+
createPresentation({
|
|
110
|
+
applicationVariables: {
|
|
111
|
+
input: 'updated',
|
|
112
|
+
multi: ['a', 'b', 'c'],
|
|
113
|
+
},
|
|
114
|
+
token: 'token',
|
|
115
|
+
}),
|
|
100
116
|
createPlaylistWindowManagerState(),
|
|
101
117
|
createRuleEngineState()
|
|
102
118
|
);
|
|
@@ -109,7 +125,13 @@ describe('embedded apps', () => {
|
|
|
109
125
|
expect(testRenderer.sendMessageObject).toHaveBeenCalledWith(
|
|
110
126
|
'test-reload-message',
|
|
111
127
|
'preview-inputs',
|
|
112
|
-
{
|
|
128
|
+
{
|
|
129
|
+
$renderMode: 'preview',
|
|
130
|
+
$token: 'token',
|
|
131
|
+
$deviceId: 'device-id',
|
|
132
|
+
input: 'updated',
|
|
133
|
+
multi: ['a', 'b', 'c'],
|
|
134
|
+
}
|
|
113
135
|
);
|
|
114
136
|
|
|
115
137
|
// sendMessageObject should not be called again for the same inputs.
|
|
@@ -427,6 +427,8 @@ export default class PresentationWindow {
|
|
|
427
427
|
|
|
428
428
|
if (this.isEmbeddedApp()) {
|
|
429
429
|
if (applicationVersion.embeddedUrlFormat) {
|
|
430
|
+
// If the embedded app has subscribed to inputs event, send it the updated inputs
|
|
431
|
+
// with postMessage. Otherwise, reload the window with the new inputs.
|
|
430
432
|
if (this.previewSubscriptions.has('inputs')) {
|
|
431
433
|
this.logInfo(
|
|
432
434
|
`Reload window '${windowId}' for embedded app preview state`
|
|
@@ -436,6 +438,21 @@ export default class PresentationWindow {
|
|
|
436
438
|
this.presentation.applicationVariables
|
|
437
439
|
);
|
|
438
440
|
|
|
441
|
+
// Add metadata to inputs if they exist in the URL template. These need to be
|
|
442
|
+
// consistent with metadata keys in embeddedApps.ts.
|
|
443
|
+
if (applicationVersion.embeddedUrlFormat.includes(':$renderMode')) {
|
|
444
|
+
updatedInputs['$renderMode'] = this.getRenderMode();
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
if (applicationVersion.embeddedUrlFormat.includes(':$token')) {
|
|
448
|
+
updatedInputs['$token'] = this.presentation.token;
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
if (applicationVersion.embeddedUrlFormat.includes(':$deviceId')) {
|
|
452
|
+
updatedInputs['$deviceId'] = this.options.device?.id;
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
// Send the updated inputs to the embedded app if they have changed.
|
|
439
456
|
if (!deepEqual(updatedInputs, this.previewState.inputs)) {
|
|
440
457
|
this.sendMessageObject('preview-inputs', updatedInputs);
|
|
441
458
|
}
|
|
@@ -953,12 +970,16 @@ export default class PresentationWindow {
|
|
|
953
970
|
}
|
|
954
971
|
|
|
955
972
|
private getEmbeddedAppUrl() {
|
|
956
|
-
const { windowId, appRendererOfflineSupport } = this.options;
|
|
973
|
+
const { windowId, appRendererOfflineSupport, device } = this.options;
|
|
957
974
|
|
|
958
975
|
const metadata: EmbeddedAppMetadata = {
|
|
959
|
-
renderMode: this.
|
|
976
|
+
renderMode: this.getRenderMode(),
|
|
960
977
|
};
|
|
961
978
|
|
|
979
|
+
if (device) {
|
|
980
|
+
metadata.deviceId = device.id;
|
|
981
|
+
}
|
|
982
|
+
|
|
962
983
|
const url = createEmbeddedApp(
|
|
963
984
|
this.presentation,
|
|
964
985
|
this.options.applicationVersion,
|
|
@@ -1626,6 +1647,10 @@ export default class PresentationWindow {
|
|
|
1626
1647
|
|
|
1627
1648
|
this.previouslyLocked = currentlyLocked;
|
|
1628
1649
|
}
|
|
1650
|
+
|
|
1651
|
+
private getRenderMode() {
|
|
1652
|
+
return this.options.isPreview ? 'preview' : 'live';
|
|
1653
|
+
}
|
|
1629
1654
|
}
|
|
1630
1655
|
|
|
1631
1656
|
const isValidCreateObjectURLResultPayload = (
|
|
@@ -1657,7 +1682,11 @@ const transformInputValues = (inputs: Record<string, any>) => {
|
|
|
1657
1682
|
// Value is an array input, traverse each item in the array for file input values.
|
|
1658
1683
|
transformed[key] = [];
|
|
1659
1684
|
for (const item of value) {
|
|
1660
|
-
|
|
1685
|
+
if (typeof item === 'object' && item !== null) {
|
|
1686
|
+
transformed[key].push(transformInputValues(item));
|
|
1687
|
+
} else {
|
|
1688
|
+
transformed[key].push(item);
|
|
1689
|
+
}
|
|
1661
1690
|
}
|
|
1662
1691
|
} else {
|
|
1663
1692
|
transformed[key] = value;
|
package/src/embeddedApps.test.ts
CHANGED
|
@@ -240,3 +240,40 @@ test('Replaces $token with presentation token', () => {
|
|
|
240
240
|
createEmbeddedApp(presentation, applicationVersion, createMetadata())
|
|
241
241
|
).toBe('https://example.com?token=abc');
|
|
242
242
|
});
|
|
243
|
+
|
|
244
|
+
test('Replaces $deviceId with metadata deviceId when provided', () => {
|
|
245
|
+
const presentation = createPresentation();
|
|
246
|
+
const applicationVersion = createApplicationVersion({
|
|
247
|
+
embeddedUrlFormat: 'https://example.com/:$deviceId/content',
|
|
248
|
+
});
|
|
249
|
+
|
|
250
|
+
expect(
|
|
251
|
+
createEmbeddedApp(
|
|
252
|
+
presentation,
|
|
253
|
+
applicationVersion,
|
|
254
|
+
createMetadata({ deviceId: 'device-id' })
|
|
255
|
+
)
|
|
256
|
+
).toBe('https://example.com/device-id/content');
|
|
257
|
+
});
|
|
258
|
+
|
|
259
|
+
test('Do not replace $deviceId when in the URI with metadata not defined', () => {
|
|
260
|
+
const presentation = createPresentation();
|
|
261
|
+
const applicationVersion = createApplicationVersion({
|
|
262
|
+
embeddedUrlFormat: 'https://example.com/:$deviceId/content',
|
|
263
|
+
});
|
|
264
|
+
|
|
265
|
+
expect(
|
|
266
|
+
createEmbeddedApp(presentation, applicationVersion, createMetadata())
|
|
267
|
+
).toBe(`https://example.com/${encodeURIComponent(':$deviceId')}/content`);
|
|
268
|
+
});
|
|
269
|
+
|
|
270
|
+
test('Replaces $deviceId with empty string when in the query string and metadata not defined', () => {
|
|
271
|
+
const presentation = createPresentation();
|
|
272
|
+
const applicationVersion = createApplicationVersion({
|
|
273
|
+
embeddedUrlFormat: 'https://example.com/content?device=:$deviceId',
|
|
274
|
+
});
|
|
275
|
+
|
|
276
|
+
expect(
|
|
277
|
+
createEmbeddedApp(presentation, applicationVersion, createMetadata())
|
|
278
|
+
).toBe(`https://example.com/content?device=`);
|
|
279
|
+
});
|
package/src/embeddedApps.ts
CHANGED
|
@@ -19,6 +19,7 @@ export default function createEmbeddedApp(
|
|
|
19
19
|
|
|
20
20
|
// replace
|
|
21
21
|
let url = applicationVersion.embeddedUrlFormat || '';
|
|
22
|
+
const queryIndex = url.indexOf('?');
|
|
22
23
|
matches.forEach((m) => {
|
|
23
24
|
const queryParamVariableName = m[1]; // Where the value of your input will be injected. E.g. ":location"
|
|
24
25
|
const queryParamName = m[2]; // The query param name. E.g. "location"
|
|
@@ -29,11 +30,24 @@ export default function createEmbeddedApp(
|
|
|
29
30
|
let value: any = '';
|
|
30
31
|
|
|
31
32
|
if (variableName.charAt(0) === '$') {
|
|
33
|
+
const variableIndex = url.indexOf(queryParamVariableName);
|
|
34
|
+
const isPartOfQuery = queryIndex != -1 && variableIndex > queryIndex;
|
|
35
|
+
|
|
32
36
|
const metadataKey = variableName.slice(1);
|
|
33
37
|
if (metadataKey === 'renderMode') {
|
|
34
38
|
value = metadata.renderMode;
|
|
35
39
|
} else if (metadataKey === 'token') {
|
|
36
40
|
value = presentation.token;
|
|
41
|
+
} else if (metadataKey === 'deviceId') {
|
|
42
|
+
if (metadata.deviceId) {
|
|
43
|
+
value = metadata.deviceId;
|
|
44
|
+
} else {
|
|
45
|
+
// If :$deviceId is part of the URL path, avoid creating a broken URL if metadata.deviceId is not defined.
|
|
46
|
+
// This will use the variable name as the value instead of an empty string.
|
|
47
|
+
if (!isPartOfQuery) {
|
|
48
|
+
value = queryParamVariableName;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
37
51
|
}
|
|
38
52
|
} else {
|
|
39
53
|
// Don't replace variables that are numbers to allow setting
|
package/src/testUtils.ts
CHANGED
|
@@ -39,6 +39,8 @@ export function createPresentationWindow(
|
|
|
39
39
|
unMuteWindow() {},
|
|
40
40
|
},
|
|
41
41
|
getTerminal: overrides.getTerminal,
|
|
42
|
+
isPreview: overrides.isPreview,
|
|
43
|
+
device: overrides.device,
|
|
42
44
|
});
|
|
43
45
|
}
|
|
44
46
|
|
|
@@ -54,6 +56,7 @@ export function createPresentation(
|
|
|
54
56
|
applicationVariables: overrides.applicationVariables ?? {},
|
|
55
57
|
duration: overrides.duration ?? 1,
|
|
56
58
|
r: createPresentationRelationships(overrides.r),
|
|
59
|
+
token: overrides.token,
|
|
57
60
|
};
|
|
58
61
|
}
|
|
59
62
|
|