@sap-ux/preview-middleware 0.26.8 → 0.26.11
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/base/flex.d.ts +35 -0
- package/dist/base/flex.js +205 -0
- package/dist/base/flp.d.ts +27 -0
- package/dist/base/flp.js +56 -0
- package/package.json +5 -5
package/dist/base/flex.d.ts
CHANGED
|
@@ -2,6 +2,22 @@ import type { Logger } from '@sap-ux/logger';
|
|
|
2
2
|
import type { ReaderCollection } from '@ui5/fs';
|
|
3
3
|
import type { Editor } from 'mem-fs-editor';
|
|
4
4
|
import type { CommonChangeProperties } from '@sap-ux/adp-tooling';
|
|
5
|
+
/**
|
|
6
|
+
* Set of local module paths (fragments, controllers) used to strip
|
|
7
|
+
* inlined modules from the LrepConnector response so that UI5 loads
|
|
8
|
+
* local workspace versions via HTTP instead.
|
|
9
|
+
*/
|
|
10
|
+
export type LocalModulePaths = Set<string>;
|
|
11
|
+
/**
|
|
12
|
+
* State of local module files in the workspace.
|
|
13
|
+
* - `active`: paths derived from local change files — deployed changes should be served from the local workspace.
|
|
14
|
+
* - `orphaned`: local files with no corresponding local change record (e.g. change file was deleted) —
|
|
15
|
+
* the associated deployed change should be suppressed entirely.
|
|
16
|
+
*/
|
|
17
|
+
export interface LocalModuleState {
|
|
18
|
+
active: LocalModulePaths;
|
|
19
|
+
orphaned: LocalModulePaths;
|
|
20
|
+
}
|
|
5
21
|
/**
|
|
6
22
|
* Read changes from the file system and return them.
|
|
7
23
|
*
|
|
@@ -10,6 +26,25 @@ import type { CommonChangeProperties } from '@sap-ux/adp-tooling';
|
|
|
10
26
|
* @returns object with the file name as key and the file content as value
|
|
11
27
|
*/
|
|
12
28
|
export declare function readChanges(project: ReaderCollection, logger: Logger): Promise<Record<string, CommonChangeProperties>>;
|
|
29
|
+
/**
|
|
30
|
+
* Reads local module state from the workspace.
|
|
31
|
+
*
|
|
32
|
+
* @param project reference to the UI5 project
|
|
33
|
+
* @param logger logger instance
|
|
34
|
+
* @returns LocalModuleState with `active` and `orphaned` sets of relative paths under /changes/
|
|
35
|
+
*/
|
|
36
|
+
export declare function readLocalModulePaths(project: ReaderCollection, logger: Logger): Promise<LocalModuleState>;
|
|
37
|
+
/**
|
|
38
|
+
* Patches an LREP flex data response so that deployed changes whose module
|
|
39
|
+
* files exist locally in the workspace are loaded from the local workspace
|
|
40
|
+
* instead of from ABAP.
|
|
41
|
+
*
|
|
42
|
+
* @param responseData the parsed LREP flex data response
|
|
43
|
+
* @param localModuleState state of local module files (active and orphaned)
|
|
44
|
+
* @param logger logger instance
|
|
45
|
+
* @returns the (possibly patched) response data
|
|
46
|
+
*/
|
|
47
|
+
export declare function stripLocalModulesFromLrepResponse(responseData: Record<string, unknown>, localModuleState: LocalModuleState, logger: Logger): Record<string, unknown>;
|
|
13
48
|
/**
|
|
14
49
|
* Writes flex changes to the user's workspace.
|
|
15
50
|
*
|
package/dist/base/flex.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.readChanges = readChanges;
|
|
4
|
+
exports.readLocalModulePaths = readLocalModulePaths;
|
|
5
|
+
exports.stripLocalModulesFromLrepResponse = stripLocalModulesFromLrepResponse;
|
|
4
6
|
exports.writeChange = writeChange;
|
|
5
7
|
exports.deleteChange = deleteChange;
|
|
6
8
|
const node_fs_1 = require("node:fs");
|
|
@@ -26,6 +28,209 @@ async function readChanges(project, logger) {
|
|
|
26
28
|
}
|
|
27
29
|
return changes;
|
|
28
30
|
}
|
|
31
|
+
/**
|
|
32
|
+
* Extracts the local module path from a change's type and content.
|
|
33
|
+
* Returns the fragmentPath for addXML changes, codeRef for codeExt changes, and undefined otherwise.
|
|
34
|
+
*
|
|
35
|
+
* @param changeType
|
|
36
|
+
* @param content
|
|
37
|
+
*/
|
|
38
|
+
function extractLocalModulePath(changeType, content) {
|
|
39
|
+
if (changeType === 'addXML' && typeof content?.fragmentPath === 'string') {
|
|
40
|
+
return content.fragmentPath;
|
|
41
|
+
}
|
|
42
|
+
if (changeType === 'codeExt' && typeof content?.codeRef === 'string') {
|
|
43
|
+
return content.codeRef;
|
|
44
|
+
}
|
|
45
|
+
return undefined;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Reads local module state from the workspace.
|
|
49
|
+
*
|
|
50
|
+
* @param project reference to the UI5 project
|
|
51
|
+
* @param logger logger instance
|
|
52
|
+
* @returns LocalModuleState with `active` and `orphaned` sets of relative paths under /changes/
|
|
53
|
+
*/
|
|
54
|
+
async function readLocalModulePaths(project, logger) {
|
|
55
|
+
const active = new Set();
|
|
56
|
+
const orphaned = new Set();
|
|
57
|
+
const changeFiles = await project.byGlob('/**/changes/**/*.{change,variant,ctrl_variant,ctrl_variant_change,ctrl_variant_management_change}');
|
|
58
|
+
for (const file of changeFiles) {
|
|
59
|
+
try {
|
|
60
|
+
const change = JSON.parse(await file.getString());
|
|
61
|
+
const content = change.content;
|
|
62
|
+
const localPath = extractLocalModulePath(change.changeType, content);
|
|
63
|
+
if (localPath) {
|
|
64
|
+
active.add(localPath);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
catch {
|
|
68
|
+
// ignore malformed change files — readChanges already warns about them
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
const moduleFiles = await project.byGlob('/**/changes/{fragments/**/*.xml,coding/**/*.js,coding/**/*.ts}');
|
|
72
|
+
for (const file of moduleFiles) {
|
|
73
|
+
const filePath = file.getPath();
|
|
74
|
+
const changesIdx = filePath.lastIndexOf('/changes/');
|
|
75
|
+
if (changesIdx !== -1) {
|
|
76
|
+
const relativePath = filePath.substring(changesIdx + '/changes/'.length);
|
|
77
|
+
// normalise .ts → .js so the orphaned key matches the codeRef in deployed changes
|
|
78
|
+
const normalizedPath = relativePath.endsWith('.ts') ? relativePath.slice(0, -3) + '.js' : relativePath;
|
|
79
|
+
if (!active.has(normalizedPath)) {
|
|
80
|
+
orphaned.add(normalizedPath);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
logger.debug(`Found ${active.size} active and ${orphaned.size} orphaned local module(s) for LREP filtering`);
|
|
85
|
+
return { active, orphaned };
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Strips inlined module entries from `result.modules` whose paths match active local modules.
|
|
89
|
+
*
|
|
90
|
+
* @param result the response object being patched (mutated when modules are stripped)
|
|
91
|
+
* @param active set of active local module paths
|
|
92
|
+
* @param logger logger instance
|
|
93
|
+
* @returns true if `result.modules` was modified
|
|
94
|
+
*/
|
|
95
|
+
function stripInlinedModules(result, active, logger) {
|
|
96
|
+
if (!result.modules || typeof result.modules !== 'object') {
|
|
97
|
+
return false;
|
|
98
|
+
}
|
|
99
|
+
const originalModules = result.modules;
|
|
100
|
+
const filteredEntries = Object.entries(originalModules).filter(([key]) => {
|
|
101
|
+
// lastIndexOf anchors on the flex /changes/ segment even if the namespace contains "changes"
|
|
102
|
+
const changesIdx = key.lastIndexOf('/changes/');
|
|
103
|
+
if (changesIdx === -1) {
|
|
104
|
+
return true;
|
|
105
|
+
}
|
|
106
|
+
const relativePath = key.substring(changesIdx + '/changes/'.length);
|
|
107
|
+
if (active.has(relativePath)) {
|
|
108
|
+
logger.debug(`Stripping inlined module '${key}' — local version will be served instead`);
|
|
109
|
+
return false;
|
|
110
|
+
}
|
|
111
|
+
return true;
|
|
112
|
+
});
|
|
113
|
+
const removedCount = Object.keys(originalModules).length - filteredEntries.length;
|
|
114
|
+
if (removedCount === 0) {
|
|
115
|
+
return false;
|
|
116
|
+
}
|
|
117
|
+
logger.info(`Stripped ${removedCount} inlined module(s) from LREP response in favor of local versions`);
|
|
118
|
+
result.modules = Object.fromEntries(filteredEntries);
|
|
119
|
+
return true;
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Injects expected `moduleName` values into changes whose local paths are active so UI5 resolves
|
|
123
|
+
* them via the adp.proxy instead of expecting inlined module content.
|
|
124
|
+
*
|
|
125
|
+
* @param changes the array of change objects
|
|
126
|
+
* @param active set of active local module paths
|
|
127
|
+
* @param logger logger instance
|
|
128
|
+
* @returns updated changes array if any moduleName was injected, otherwise null
|
|
129
|
+
*/
|
|
130
|
+
function injectModuleNames(changes, active, logger) {
|
|
131
|
+
let changesModified = false;
|
|
132
|
+
const updatedChanges = changes.map((change) => {
|
|
133
|
+
const c = change;
|
|
134
|
+
const content = c.content;
|
|
135
|
+
const reference = typeof c.reference === 'string' ? c.reference : '';
|
|
136
|
+
const changeType = c.changeType;
|
|
137
|
+
const localPath = extractLocalModulePath(changeType, content);
|
|
138
|
+
if (!localPath || !active.has(localPath) || !reference) {
|
|
139
|
+
return change;
|
|
140
|
+
}
|
|
141
|
+
const prefix = reference.replaceAll('.', '/');
|
|
142
|
+
// codeExt modules are JS — strip the trailing .js so the path is a valid UI5 module ID
|
|
143
|
+
const modulePathSuffix = changeType === 'codeExt' && localPath.endsWith('.js') ? localPath.slice(0, -3) : localPath;
|
|
144
|
+
const expectedModuleName = `${prefix}/changes/${modulePathSuffix}`;
|
|
145
|
+
if (c.moduleName === expectedModuleName) {
|
|
146
|
+
return change;
|
|
147
|
+
}
|
|
148
|
+
logger.debug(`Setting moduleName '${expectedModuleName}' for local '${localPath}'`);
|
|
149
|
+
changesModified = true;
|
|
150
|
+
return { ...c, moduleName: expectedModuleName };
|
|
151
|
+
});
|
|
152
|
+
return changesModified ? updatedChanges : null;
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Filters out deployed changes whose local file exists but whose local change record was deleted
|
|
156
|
+
* (i.e. orphaned). Returning these changes would re-apply ABAP state that the user already removed.
|
|
157
|
+
*
|
|
158
|
+
* @param changes the array of change objects
|
|
159
|
+
* @param orphaned set of orphaned local module paths
|
|
160
|
+
* @param logger logger instance
|
|
161
|
+
* @returns filtered changes array if any change was suppressed, otherwise null
|
|
162
|
+
*/
|
|
163
|
+
function suppressOrphanedChanges(changes, orphaned, logger) {
|
|
164
|
+
const filteredChanges = changes.filter((change) => {
|
|
165
|
+
const c = change;
|
|
166
|
+
const content = c.content;
|
|
167
|
+
const localPath = extractLocalModulePath(c.changeType, content);
|
|
168
|
+
if (localPath && orphaned.has(localPath)) {
|
|
169
|
+
logger.debug(`Suppressing deployed change for orphaned local file '${localPath}'`);
|
|
170
|
+
return false;
|
|
171
|
+
}
|
|
172
|
+
return true;
|
|
173
|
+
});
|
|
174
|
+
const removedCount = changes.length - filteredChanges.length;
|
|
175
|
+
if (removedCount === 0) {
|
|
176
|
+
return null;
|
|
177
|
+
}
|
|
178
|
+
logger.info(`Suppressed ${removedCount} deployed change(s) whose local files exist but change records were deleted`);
|
|
179
|
+
return filteredChanges;
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Applies moduleName injection and orphaned-change suppression to `result.changes`.
|
|
183
|
+
*
|
|
184
|
+
* @param result the response object being patched (mutated when changes are updated)
|
|
185
|
+
* @param state local module state (active and orphaned)
|
|
186
|
+
* @param logger logger instance
|
|
187
|
+
* @returns true if `result.changes` was modified
|
|
188
|
+
*/
|
|
189
|
+
function processChanges(result, state, logger) {
|
|
190
|
+
if (!result.changes || !Array.isArray(result.changes)) {
|
|
191
|
+
return false;
|
|
192
|
+
}
|
|
193
|
+
let modified = false;
|
|
194
|
+
const injected = injectModuleNames(result.changes, state.active, logger);
|
|
195
|
+
if (injected) {
|
|
196
|
+
result.changes = injected;
|
|
197
|
+
modified = true;
|
|
198
|
+
}
|
|
199
|
+
if (state.orphaned.size > 0) {
|
|
200
|
+
const suppressed = suppressOrphanedChanges(result.changes, state.orphaned, logger);
|
|
201
|
+
if (suppressed) {
|
|
202
|
+
result.changes = suppressed;
|
|
203
|
+
modified = true;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
return modified;
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* Patches an LREP flex data response so that deployed changes whose module
|
|
210
|
+
* files exist locally in the workspace are loaded from the local workspace
|
|
211
|
+
* instead of from ABAP.
|
|
212
|
+
*
|
|
213
|
+
* @param responseData the parsed LREP flex data response
|
|
214
|
+
* @param localModuleState state of local module files (active and orphaned)
|
|
215
|
+
* @param logger logger instance
|
|
216
|
+
* @returns the (possibly patched) response data
|
|
217
|
+
*/
|
|
218
|
+
function stripLocalModulesFromLrepResponse(responseData, localModuleState, logger) {
|
|
219
|
+
if (localModuleState.active.size === 0 && localModuleState.orphaned.size === 0) {
|
|
220
|
+
return responseData;
|
|
221
|
+
}
|
|
222
|
+
const result = { ...responseData };
|
|
223
|
+
let modified = stripInlinedModules(result, localModuleState.active, logger);
|
|
224
|
+
if (result.loadModules === true && localModuleState.active.size > 0) {
|
|
225
|
+
logger.debug('Stripping loadModules flag — modules will be loaded on-demand so adp.proxy can serve local versions');
|
|
226
|
+
delete result.loadModules;
|
|
227
|
+
modified = true;
|
|
228
|
+
}
|
|
229
|
+
if (processChanges(result, localModuleState, logger)) {
|
|
230
|
+
modified = true;
|
|
231
|
+
}
|
|
232
|
+
return modified ? result : responseData;
|
|
233
|
+
}
|
|
29
234
|
/**
|
|
30
235
|
* Writes flex changes to the user's workspace.
|
|
31
236
|
*
|
package/dist/base/flp.d.ts
CHANGED
|
@@ -341,6 +341,33 @@ export declare class FlpSandbox {
|
|
|
341
341
|
* @param adp AdpPreview instance
|
|
342
342
|
*/
|
|
343
343
|
private setupAdpCommonHandlers;
|
|
344
|
+
/**
|
|
345
|
+
* Registers a middleware that intercepts LREP flex data responses to apply
|
|
346
|
+
* local workspace overrides: stripping inlined modules for active local files,
|
|
347
|
+
* removing the loadModules pre-fetch flag, injecting correct moduleNames, and
|
|
348
|
+
* suppressing deployed changes for orphaned local files (change record deleted).
|
|
349
|
+
*
|
|
350
|
+
* The local module state is captured once at server startup by `readLocalModulePaths`
|
|
351
|
+
* and is not refreshed during the preview session. If a developer adds, renames, or deletes
|
|
352
|
+
* a local fragment, controller, or change file while the preview is running, the filter will
|
|
353
|
+
* be stale until the server is restarted. This is an intentional trade-off — re-scanning the
|
|
354
|
+
* VFS on every flex-data request would add latency to every preview round-trip.
|
|
355
|
+
*
|
|
356
|
+
* @param adp AdpPreview instance with access to the ABAP service provider
|
|
357
|
+
* @param localModuleState pre-scanned local module state
|
|
358
|
+
*/
|
|
359
|
+
private registerLrepFlexDataFilter;
|
|
360
|
+
/**
|
|
361
|
+
* Handler for LREP flex data requests. Strips inlined modules that exist locally
|
|
362
|
+
* so that UI5 fetches them via HTTP from the local workspace instead.
|
|
363
|
+
*
|
|
364
|
+
* @param req the request
|
|
365
|
+
* @param res the response
|
|
366
|
+
* @param next the next middleware
|
|
367
|
+
* @param provider the ABAP service provider for backend calls
|
|
368
|
+
* @param localModuleState pre-scanned local module state
|
|
369
|
+
*/
|
|
370
|
+
private lrepFlexDataFilterHandler;
|
|
344
371
|
/**
|
|
345
372
|
* Setup the CF build path mode for the ADP project.
|
|
346
373
|
*
|
package/dist/base/flp.js
CHANGED
|
@@ -936,6 +936,8 @@ class FlpSandbox {
|
|
|
936
936
|
const descriptor = adp.descriptor;
|
|
937
937
|
const { name, manifest } = descriptor;
|
|
938
938
|
await this.init(manifest, name, adp.resources, adp);
|
|
939
|
+
const localModuleState = await (0, flex_1.readLocalModulePaths)(this.project, this.logger);
|
|
940
|
+
this.registerLrepFlexDataFilter(adp, localModuleState);
|
|
939
941
|
this.router.use(adp.descriptor.url, adp.proxy.bind(adp));
|
|
940
942
|
await this.setupAdpCommonHandlers(adp);
|
|
941
943
|
}
|
|
@@ -951,6 +953,60 @@ class FlpSandbox {
|
|
|
951
953
|
// Register i18n store route for ADP projects (used by OVP bridge functions)
|
|
952
954
|
await this.addStoreI18nKeysRoute();
|
|
953
955
|
}
|
|
956
|
+
/**
|
|
957
|
+
* Registers a middleware that intercepts LREP flex data responses to apply
|
|
958
|
+
* local workspace overrides: stripping inlined modules for active local files,
|
|
959
|
+
* removing the loadModules pre-fetch flag, injecting correct moduleNames, and
|
|
960
|
+
* suppressing deployed changes for orphaned local files (change record deleted).
|
|
961
|
+
*
|
|
962
|
+
* The local module state is captured once at server startup by `readLocalModulePaths`
|
|
963
|
+
* and is not refreshed during the preview session. If a developer adds, renames, or deletes
|
|
964
|
+
* a local fragment, controller, or change file while the preview is running, the filter will
|
|
965
|
+
* be stale until the server is restarted. This is an intentional trade-off — re-scanning the
|
|
966
|
+
* VFS on every flex-data request would add latency to every preview round-trip.
|
|
967
|
+
*
|
|
968
|
+
* @param adp AdpPreview instance with access to the ABAP service provider
|
|
969
|
+
* @param localModuleState pre-scanned local module state
|
|
970
|
+
*/
|
|
971
|
+
registerLrepFlexDataFilter(adp, localModuleState) {
|
|
972
|
+
const provider = adp.serviceProvider;
|
|
973
|
+
if (!provider) {
|
|
974
|
+
return;
|
|
975
|
+
}
|
|
976
|
+
if (localModuleState.active.size === 0 && localModuleState.orphaned.size === 0) {
|
|
977
|
+
this.logger.debug('No local module files found — LREP flex data filter not registered');
|
|
978
|
+
return;
|
|
979
|
+
}
|
|
980
|
+
const lrepFlexDataPath = '/sap/bc/lrep/flex/data/';
|
|
981
|
+
this.router.get(`${lrepFlexDataPath}*`, async (req, res, next) => {
|
|
982
|
+
await this.lrepFlexDataFilterHandler(req, res, next, provider, localModuleState);
|
|
983
|
+
});
|
|
984
|
+
this.logger.info(`Registered LREP flex data filter for ${localModuleState.active.size} active and ${localModuleState.orphaned.size} orphaned local module(s)`);
|
|
985
|
+
}
|
|
986
|
+
/**
|
|
987
|
+
* Handler for LREP flex data requests. Strips inlined modules that exist locally
|
|
988
|
+
* so that UI5 fetches them via HTTP from the local workspace instead.
|
|
989
|
+
*
|
|
990
|
+
* @param req the request
|
|
991
|
+
* @param res the response
|
|
992
|
+
* @param next the next middleware
|
|
993
|
+
* @param provider the ABAP service provider for backend calls
|
|
994
|
+
* @param localModuleState pre-scanned local module state
|
|
995
|
+
*/
|
|
996
|
+
async lrepFlexDataFilterHandler(req, res, next, provider, localModuleState) {
|
|
997
|
+
try {
|
|
998
|
+
const response = await provider.get(req.url);
|
|
999
|
+
const responseData = typeof response.data === 'string' ? JSON.parse(response.data) : response.data;
|
|
1000
|
+
const filtered = (0, flex_1.stripLocalModulesFromLrepResponse)(responseData, localModuleState, this.logger);
|
|
1001
|
+
res.status(200).json(filtered);
|
|
1002
|
+
}
|
|
1003
|
+
catch (error) {
|
|
1004
|
+
this.logger.error(`LREP flex data filter failed for '${req.url}' — falling back to unfiltered backend response. Local workspace files may not take effect. Error: ${error?.message ?? error}`);
|
|
1005
|
+
// Fall through to the next middleware (e.g. backend-proxy-middleware)
|
|
1006
|
+
// so that preview remains functional even if filtering fails.
|
|
1007
|
+
next();
|
|
1008
|
+
}
|
|
1009
|
+
}
|
|
954
1010
|
/**
|
|
955
1011
|
* Setup the CF build path mode for the ADP project.
|
|
956
1012
|
*
|
package/package.json
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
"bugs": {
|
|
10
10
|
"url": "https://github.com/SAP/open-ux-tools/issues?q=is%3Aopen+is%3Aissue+label%3Abug+label%3Apreview-middleware"
|
|
11
11
|
},
|
|
12
|
-
"version": "0.26.
|
|
12
|
+
"version": "0.26.11",
|
|
13
13
|
"license": "Apache-2.0",
|
|
14
14
|
"author": "@SAP/ux-tools-team",
|
|
15
15
|
"main": "dist/index.js",
|
|
@@ -27,13 +27,13 @@
|
|
|
27
27
|
"mem-fs-editor": "9.4.0",
|
|
28
28
|
"qrcode": "1.5.4",
|
|
29
29
|
"@sap/bas-sdk": "3.13.7",
|
|
30
|
+
"@sap-ux/adp-tooling": "0.19.10",
|
|
30
31
|
"@sap-ux/btp-utils": "1.2.1",
|
|
31
|
-
"@sap-ux/adp-tooling": "0.19.7",
|
|
32
32
|
"@sap-ux/control-property-editor-sources": "npm:@sap-ux/control-property-editor@0.8.1",
|
|
33
33
|
"@sap-ux/feature-toggle": "0.4.0",
|
|
34
34
|
"@sap-ux/logger": "0.9.0",
|
|
35
35
|
"@sap-ux/project-access": "1.38.1",
|
|
36
|
-
"@sap-ux/system-access": "0.8.
|
|
36
|
+
"@sap-ux/system-access": "0.8.2",
|
|
37
37
|
"@sap-ux/i18n": "0.4.0"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
@@ -52,10 +52,10 @@
|
|
|
52
52
|
"nock": "14.0.11",
|
|
53
53
|
"npm-run-all2": "8.0.4",
|
|
54
54
|
"supertest": "7.2.2",
|
|
55
|
-
"@private/preview-middleware-client": "npm:@sap-ux-private/preview-middleware-client@0.26.
|
|
55
|
+
"@private/preview-middleware-client": "npm:@sap-ux-private/preview-middleware-client@0.26.11",
|
|
56
56
|
"@sap-ux-private/playwright": "0.3.1",
|
|
57
|
-
"@sap-ux/store": "1.6.0",
|
|
58
57
|
"@sap-ux/axios-extension": "1.26.1",
|
|
58
|
+
"@sap-ux/store": "1.6.1",
|
|
59
59
|
"@sap-ux/ui5-info": "0.14.0"
|
|
60
60
|
},
|
|
61
61
|
"peerDependencies": {
|