@sap-ux/preview-middleware 0.10.7 → 0.11.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.
@@ -7,6 +7,7 @@ sap.ui.define([], function () {
7
7
  ApiEndpoints["CHANGES"] = "/preview/api/changes";
8
8
  ApiEndpoints["FRAGMENT"] = "/adp/api/fragment";
9
9
  ApiEndpoints["CONTROLLER"] = "/adp/api/controller";
10
+ ApiEndpoints["CODE_EXT"] = "/adp/api/code_ext";
10
11
  ApiEndpoints["MANIFEST_APP_DESCRIPTOR"] = "/manifest.appdescr_variant";
11
12
  return ApiEndpoints;
12
13
  }(ApiEndpoints || {});
@@ -37,7 +38,9 @@ sap.ui.define([], function () {
37
38
  try {
38
39
  const response = await fetch(endpoint, config);
39
40
  if (!response.ok) {
40
- throw new Error(`Request failed, status: ${response.status}.`);
41
+ const errorData = await response.json();
42
+ const message = errorData?.message ?? '';
43
+ throw new Error(`Request failed, status: ${response.status}. ${message}`.trim());
41
44
  }
42
45
  switch (method) {
43
46
  case RequestMethod.GET:
@@ -103,6 +106,16 @@ sap.ui.define([], function () {
103
106
  return request(ApiEndpoints.CONTROLLER, RequestMethod.POST, data);
104
107
  }
105
108
 
109
+ /**
110
+ * Checks for existing controller in the project's workspace
111
+ *
112
+ * @param controllerName Name of the controller
113
+ * @returns {CodeExtResponse} Returns path to existing controller if found
114
+ */
115
+ async function getExistingController(controllerName) {
116
+ return request(`${ApiEndpoints.CODE_EXT}/${controllerName}`, RequestMethod.GET);
117
+ }
118
+
106
119
  /**
107
120
  * Writes a change object to the project's workspace
108
121
  *
@@ -123,6 +136,7 @@ sap.ui.define([], function () {
123
136
  __exports.getManifestAppdescr = getManifestAppdescr;
124
137
  __exports.readControllers = readControllers;
125
138
  __exports.writeController = writeController;
139
+ __exports.getExistingController = getExistingController;
126
140
  __exports.writeChange = writeChange;
127
141
  return __exports;
128
142
  });
@@ -4,6 +4,7 @@ export const enum ApiEndpoints {
4
4
  CHANGES = '/preview/api/changes',
5
5
  FRAGMENT = '/adp/api/fragment',
6
6
  CONTROLLER = '/adp/api/controller',
7
+ CODE_EXT = '/adp/api/code_ext',
7
8
  MANIFEST_APP_DESCRIPTOR = '/manifest.appdescr_variant'
8
9
  }
9
10
 
@@ -23,6 +24,12 @@ export interface FragmentsResponse {
23
24
  message: string;
24
25
  }
25
26
 
27
+ export interface CodeExtResponse {
28
+ controllerExists: boolean;
29
+ controllerPath: string;
30
+ controllerPathFromRoot: string;
31
+ }
32
+
26
33
  export interface ControllersResponse {
27
34
  controllers: Controllers;
28
35
  message: string;
@@ -60,7 +67,9 @@ export async function request<T>(endpoint: ApiEndpoints, method: RequestMethod,
60
67
  const response: Response = await fetch(endpoint, config);
61
68
 
62
69
  if (!response.ok) {
63
- throw new Error(`Request failed, status: ${response.status}.`);
70
+ const errorData = await response.json();
71
+ const message = errorData?.message ?? '';
72
+ throw new Error(`Request failed, status: ${response.status}. ${message}`.trim());
64
73
  }
65
74
 
66
75
  switch (method) {
@@ -127,6 +136,16 @@ export async function writeController<T>(data: T): Promise<T> {
127
136
  return request<T>(ApiEndpoints.CONTROLLER, RequestMethod.POST, data);
128
137
  }
129
138
 
139
+ /**
140
+ * Checks for existing controller in the project's workspace
141
+ *
142
+ * @param controllerName Name of the controller
143
+ * @returns {CodeExtResponse} Returns path to existing controller if found
144
+ */
145
+ export async function getExistingController(controllerName: string): Promise<CodeExtResponse> {
146
+ return request<CodeExtResponse>(`${ApiEndpoints.CODE_EXT}/${controllerName}` as ApiEndpoints, RequestMethod.GET);
147
+ }
148
+
130
149
  /**
131
150
  * Writes a change object to the project's workspace
132
151
  *
@@ -9,6 +9,7 @@ sap.ui.define(["sap/m/MessageToast", "sap/ui/core/library", "sap/ui/model/json/J
9
9
  /** sap.ui.core */
10
10
  const ValueState = sap_ui_core_library["ValueState"];
11
11
  /** sap.ui.base */
12
+ const getExistingController = ___api_handler["getExistingController"];
12
13
  const getManifestAppdescr = ___api_handler["getManifestAppdescr"];
13
14
  const readControllers = ___api_handler["readControllers"];
14
15
  const writeChange = ___api_handler["writeChange"];
@@ -65,19 +66,71 @@ sap.ui.define(["sap/m/MessageToast", "sap/ui/core/library", "sap/ui/model/json/J
65
66
  },
66
67
  onCreateBtnPress: async function _onCreateBtnPress(event) {
67
68
  const source = event.getSource();
68
- source.setEnabled(false);
69
- const controllerName = this.model.getProperty('/newControllerName');
70
- const viewId = this.model.getProperty('/viewId');
71
- await this.createNewController(controllerName, viewId);
69
+ const controllerExists = this.model.getProperty('/controllerExists');
70
+ if (!controllerExists) {
71
+ source.setEnabled(false);
72
+ const controllerName = this.model.getProperty('/newControllerName');
73
+ const viewId = this.model.getProperty('/viewId');
74
+ await this.createNewController(controllerName, viewId);
75
+ } else {
76
+ const controllerPath = this.model.getProperty('/controllerPath');
77
+ window.open(`vscode://file${controllerPath}`);
78
+ }
72
79
  this.handleDialogClose();
73
80
  },
74
81
  buildDialogData: async function _buildDialogData() {
75
82
  const selectorId = this.overlays.getId();
76
83
  const overlayControl = sap.ui.getCore().byId(selectorId);
84
+ const {
85
+ controllerName,
86
+ viewId
87
+ } = this.getControllerInfo(overlayControl);
88
+ const {
89
+ controllerExists,
90
+ controllerPath,
91
+ controllerPathFromRoot
92
+ } = await this.getExistingController(controllerName);
93
+ if (controllerExists) {
94
+ this.updateModelForExistingController(controllerExists, controllerPath, controllerPathFromRoot);
95
+ } else {
96
+ this.updateModelForNewController(viewId);
97
+ await this.getControllers();
98
+ }
99
+ },
100
+ getControllerInfo: function _getControllerInfo(overlayControl) {
77
101
  const control = overlayControl.getElement();
78
- const viewId = Utils.getViewForControl(control).getId();
102
+ const view = Utils.getViewForControl(control);
103
+ const controllerName = view.getController().getMetadata().getName();
104
+ const viewId = view.getId();
105
+ return {
106
+ controllerName,
107
+ viewId
108
+ };
109
+ },
110
+ updateModelForExistingController: function _updateModelForExistingController(controllerExists, controllerPath, controllerPathFromRoot) {
111
+ this.model.setProperty('/controllerExists', controllerExists);
112
+ this.model.setProperty('/controllerPath', controllerPath);
113
+ this.model.setProperty('/controllerPathFromRoot', controllerPathFromRoot);
114
+ const form = this.byId('controllerExtensionDialog_Form');
115
+ form.setVisible(false);
116
+ const messageForm = this.byId('controllerExtensionDialog_Form--existingController');
117
+ messageForm.setVisible(true);
118
+ this.dialog.getBeginButton().setText('Open in VS Code').setEnabled(true);
119
+ this.dialog.getEndButton().setText('Close');
120
+ },
121
+ updateModelForNewController: function _updateModelForNewController(viewId) {
79
122
  this.model.setProperty('/viewId', viewId);
80
- await this.getControllers();
123
+ },
124
+ getExistingController: async function _getExistingController(controllerName) {
125
+ try {
126
+ const data = await getExistingController(controllerName);
127
+ return data;
128
+ } catch (e) {
129
+ MessageToast.show(e.message, {
130
+ duration: 5000
131
+ });
132
+ throw new Error(e.message);
133
+ }
81
134
  },
82
135
  getControllers: async function _getControllers() {
83
136
  try {
@@ -86,7 +139,9 @@ sap.ui.define(["sap/m/MessageToast", "sap/ui/core/library", "sap/ui/model/json/J
86
139
  } = await readControllers();
87
140
  this.model.setProperty('/controllersList', controllers);
88
141
  } catch (e) {
89
- MessageToast.show(e.message);
142
+ MessageToast.show(e.message, {
143
+ duration: 5000
144
+ });
90
145
  throw new Error(e.message);
91
146
  }
92
147
  },
@@ -20,17 +20,31 @@ import type RuntimeAuthoring from 'sap/ui/rta/RuntimeAuthoring';
20
20
  /** sap.ui.fl */
21
21
  import Utils from 'sap/ui/fl/Utils';
22
22
 
23
+ /** sap.ui.layout */
24
+ import type SimpleForm from 'sap/ui/layout/form/SimpleForm';
25
+
23
26
  /** sap.ui.dt */
24
27
  import type ElementOverlay from 'sap/ui/dt/ElementOverlay';
25
28
 
26
- import type { ControllersResponse } from '../api-handler';
27
- import { getManifestAppdescr, readControllers, writeChange, writeController } from '../api-handler';
29
+ import type { CodeExtResponse, ControllersResponse } from '../api-handler';
30
+ import {
31
+ getExistingController,
32
+ getManifestAppdescr,
33
+ readControllers,
34
+ writeChange,
35
+ writeController
36
+ } from '../api-handler';
28
37
  import BaseDialog from './BaseDialog.controller';
29
38
 
30
39
  interface ControllerExtensionService {
31
40
  add: (codeRef: string, viewId: string) => Promise<unknown>;
32
41
  }
33
42
 
43
+ interface ControllerInfo {
44
+ controllerName: string;
45
+ viewId: string;
46
+ }
47
+
34
48
  /**
35
49
  * @namespace open.ux.preview.client.adp.controllers
36
50
  */
@@ -100,19 +114,15 @@ export default class ControllerExtension extends BaseDialog {
100
114
  return;
101
115
  }
102
116
 
103
- if(controllerName.length > 64) {
104
- updateDialogState(
105
- ValueState.Error,
106
- 'A controller file name cannot contain more than 64 characters.'
107
- );
117
+ if (controllerName.length > 64) {
118
+ updateDialogState(ValueState.Error, 'A controller file name cannot contain more than 64 characters.');
108
119
  return;
109
120
  }
110
-
121
+
111
122
  updateDialogState(ValueState.Success);
112
123
  this.model.setProperty('/newControllerName', controllerName);
113
124
  }
114
125
 
115
-
116
126
  /**
117
127
  * Handles create button press
118
128
  *
@@ -120,28 +130,108 @@ export default class ControllerExtension extends BaseDialog {
120
130
  */
121
131
  async onCreateBtnPress(event: Event) {
122
132
  const source = event.getSource<Button>();
123
- source.setEnabled(false);
133
+ const controllerExists = this.model.getProperty('/controllerExists');
124
134
 
125
- const controllerName = this.model.getProperty('/newControllerName');
126
- const viewId = this.model.getProperty('/viewId');
135
+ if (!controllerExists) {
136
+ source.setEnabled(false);
127
137
 
128
- await this.createNewController(controllerName, viewId);
138
+ const controllerName = this.model.getProperty('/newControllerName');
139
+ const viewId = this.model.getProperty('/viewId');
140
+
141
+ await this.createNewController(controllerName, viewId);
142
+ } else {
143
+ const controllerPath = this.model.getProperty('/controllerPath');
144
+ window.open(`vscode://file${controllerPath}`);
145
+ }
129
146
 
130
147
  this.handleDialogClose();
131
148
  }
132
149
 
133
150
  /**
134
- * Builds data that is used in the dialog
151
+ * Builds data that is used in the dialog.
135
152
  */
136
153
  async buildDialogData(): Promise<void> {
137
154
  const selectorId = this.overlays.getId();
138
155
  const overlayControl = sap.ui.getCore().byId(selectorId) as unknown as ElementOverlay;
156
+
157
+ const { controllerName, viewId } = this.getControllerInfo(overlayControl);
158
+
159
+ const { controllerExists, controllerPath, controllerPathFromRoot } = await this.getExistingController(
160
+ controllerName
161
+ );
162
+
163
+ if (controllerExists) {
164
+ this.updateModelForExistingController(controllerExists, controllerPath, controllerPathFromRoot);
165
+ } else {
166
+ this.updateModelForNewController(viewId);
167
+
168
+ await this.getControllers();
169
+ }
170
+ }
171
+
172
+ /**
173
+ * Gets controller name and view ID for the given overlay control.
174
+ *
175
+ * @param overlayControl The overlay control.
176
+ * @returns The controller name and view ID.
177
+ */
178
+ private getControllerInfo(overlayControl: ElementOverlay): ControllerInfo {
139
179
  const control = overlayControl.getElement();
140
- const viewId = Utils.getViewForControl(control).getId();
180
+ const view = Utils.getViewForControl(control);
181
+ const controllerName = view.getController().getMetadata().getName();
182
+ const viewId = view.getId();
183
+ return { controllerName, viewId };
184
+ }
185
+
186
+ /**
187
+ * Updates the model properties for an existing controller.
188
+ *
189
+ * @param controllerExists Whether the controller exists
190
+ * @param controllerPath The controller path
191
+ * @param controllerPathFromRoot The controller path from the project root
192
+ */
193
+ private updateModelForExistingController(
194
+ controllerExists: boolean,
195
+ controllerPath: string,
196
+ controllerPathFromRoot: string
197
+ ): void {
198
+ this.model.setProperty('/controllerExists', controllerExists);
199
+ this.model.setProperty('/controllerPath', controllerPath);
200
+ this.model.setProperty('/controllerPathFromRoot', controllerPathFromRoot);
201
+
202
+ const form = this.byId('controllerExtensionDialog_Form') as SimpleForm;
203
+ form.setVisible(false);
204
+
205
+ const messageForm = this.byId('controllerExtensionDialog_Form--existingController') as SimpleForm;
206
+ messageForm.setVisible(true);
207
+
208
+ this.dialog.getBeginButton().setText('Open in VS Code').setEnabled(true);
209
+ this.dialog.getEndButton().setText('Close');
210
+ }
141
211
 
212
+ /**
213
+ * Updates the model property for a new controller.
214
+ *
215
+ * @param viewId The view ID
216
+ */
217
+ private updateModelForNewController(viewId: string): void {
142
218
  this.model.setProperty('/viewId', viewId);
219
+ }
143
220
 
144
- await this.getControllers();
221
+ /**
222
+ * Retrieves existing controller data if found in the project's workspace.
223
+ *
224
+ * @param controllerName Controller name that exists in the view
225
+ * @returns Returnsexisting controller data
226
+ */
227
+ private async getExistingController(controllerName: string): Promise<CodeExtResponse> {
228
+ try {
229
+ const data = await getExistingController(controllerName);
230
+ return data;
231
+ } catch (e) {
232
+ MessageToast.show(e.message, { duration: 5000 });
233
+ throw new Error(e.message);
234
+ }
145
235
  }
146
236
 
147
237
  /**
@@ -152,7 +242,7 @@ export default class ControllerExtension extends BaseDialog {
152
242
  const { controllers } = await readControllers<ControllersResponse>();
153
243
  this.model.setProperty('/controllersList', controllers);
154
244
  } catch (e) {
155
- MessageToast.show(e.message);
245
+ MessageToast.show(e.message, { duration: 5000 });
156
246
  throw new Error(e.message);
157
247
  }
158
248
  }
@@ -18,6 +18,17 @@
18
18
  </Input>
19
19
  </f:content>
20
20
  </f:SimpleForm>
21
+ <f:SimpleForm id="controllerExtensionDialog_Form--existingController"
22
+ editable="true"
23
+ layout="ResponsiveGridLayout"
24
+ labelSpanS="12"
25
+ visible="false"
26
+ singleContainerFullSize="false">
27
+ <f:content>
28
+ <Label text="An existing controller extension has been found. Please use the previously created extension controller" />
29
+ <Text text="{/controllerPathFromRoot}" />
30
+ </f:content>
31
+ </f:SimpleForm>
21
32
  </content>
22
33
  <beginButton>
23
34
  <Button
@@ -1,8 +1,9 @@
1
1
  "use strict";
2
2
 
3
- sap.ui.define(["sap/ui/rta/command/CommandFactory"], function (CommandFactory) {
3
+ sap.ui.define(["sap/ui/rta/command/CommandFactory", "./validator"], function (CommandFactory, ___validator) {
4
4
  "use strict";
5
5
 
6
+ const validateBindingModel = ___validator["validateBindingModel"];
6
7
  /**
7
8
  * Function to check a give value is a binding expression.
8
9
  *
@@ -10,7 +11,7 @@ sap.ui.define(["sap/ui/rta/command/CommandFactory"], function (CommandFactory) {
10
11
  * @returns boolean
11
12
  */
12
13
  function isBindingExpression(value) {
13
- return value.includes('{') && value.includes('}');
14
+ return value.includes('{') && value.includes('}') && value.indexOf('{') < value.indexOf('}');
14
15
  }
15
16
 
16
17
  /**
@@ -26,9 +27,15 @@ sap.ui.define(["sap/ui/rta/command/CommandFactory"], function (CommandFactory) {
26
27
  if (!modifiedControl) {
27
28
  return;
28
29
  }
30
+ const isBindingString = typeof change.value === 'string' && isBindingExpression(change.value);
31
+ const modifiedControlModifiedProperties = modifiedControl.getMetadata().getAllProperties()[change.propertyName];
32
+ const isBindingModel = isBindingString && modifiedControlModifiedProperties?.type === 'string';
29
33
  const flexSettings = rta.getFlexSettings();
30
- const changeType = typeof change.value === 'string' && isBindingExpression(change.value) ? 'BindProperty' : 'Property';
31
- const property = typeof change.value === 'string' && isBindingExpression(change.value) ? 'newBinding' : 'newValue';
34
+ const changeType = isBindingString ? 'BindProperty' : 'Property';
35
+ if (isBindingModel) {
36
+ validateBindingModel(change.value);
37
+ }
38
+ const property = isBindingString ? 'newBinding' : 'newValue';
32
39
  const modifiedValue = {
33
40
  generator: flexSettings.generator,
34
41
  propertyName: change.propertyName,
@@ -2,6 +2,7 @@ import type FlexCommand from 'sap/ui/rta/command/FlexCommand';
2
2
  import CommandFactory from 'sap/ui/rta/command/CommandFactory';
3
3
  import type { PropertyChange } from '@sap-ux-private/control-property-editor-common';
4
4
  import type { UI5AdaptationOptions } from '../types';
5
+ import { validateBindingModel } from './validator';
5
6
 
6
7
  /**
7
8
  * Function to check a give value is a binding expression.
@@ -10,7 +11,7 @@ import type { UI5AdaptationOptions } from '../types';
10
11
  * @returns boolean
11
12
  */
12
13
  function isBindingExpression(value: string): boolean {
13
- return value.includes('{') && value.includes('}');
14
+ return value.includes('{') && value.includes('}') && value.indexOf('{') < value.indexOf('}');
14
15
  }
15
16
 
16
17
  /**
@@ -25,12 +26,17 @@ export async function applyChange(options: UI5AdaptationOptions, change: Propert
25
26
  return;
26
27
  }
27
28
 
29
+ const isBindingString = typeof change.value === 'string' && isBindingExpression(change.value);
30
+ const modifiedControlModifiedProperties = modifiedControl.getMetadata().getAllProperties()[change.propertyName];
31
+ const isBindingModel = isBindingString && modifiedControlModifiedProperties?.type === 'string';
28
32
  const flexSettings = rta.getFlexSettings();
33
+ const changeType = isBindingString ? 'BindProperty' : 'Property';
29
34
 
30
- const changeType =
31
- typeof change.value === 'string' && isBindingExpression(change.value) ? 'BindProperty' : 'Property';
35
+ if (isBindingModel) {
36
+ validateBindingModel(change.value as string);
37
+ }
32
38
 
33
- const property = typeof change.value === 'string' && isBindingExpression(change.value) ? 'newBinding' : 'newValue';
39
+ const property = isBindingString ? 'newBinding' : 'newValue';
34
40
  const modifiedValue = {
35
41
  generator: flexSettings.generator,
36
42
  propertyName: change.propertyName,
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+
3
+ sap.ui.define(["sap/base/i18n/ResourceBundle"], function (ResourceBundle) {
4
+ "use strict";
5
+
6
+ /**
7
+ * Function to validate if a given value is a valid binding model.
8
+ *
9
+ * @param value value to be checked.
10
+ */
11
+ function validateBindingModel(value) {
12
+ const bindingValue = value.replace(/[{}]/gi, '').trim();
13
+ const bindingParts = bindingValue.split('>').filter(el => el != '');
14
+ if (!bindingParts.length) {
15
+ throw new SyntaxError('Invalid binding string.');
16
+ }
17
+ if (bindingParts[0].trim() === 'i18n') {
18
+ if (bindingParts.length === 2) {
19
+ const resourceBundle = ResourceBundle.create({
20
+ url: '../i18n/i18n.properties'
21
+ });
22
+ const resourceKey = bindingParts[1].trim();
23
+ if (!resourceBundle.hasText(resourceKey)) {
24
+ throw new SyntaxError('Invalid key in the binding string. Supported value pattern is {i18n>YOUR_KEY}. Check if the key already exists in i18n.properties. If not, add the key in the i18n.properties file and reload the editor for the new key to take effect.');
25
+ }
26
+ } else {
27
+ throw new SyntaxError('Invalid binding string. Supported value pattern is {i18n>YOUR_KEY}');
28
+ }
29
+ }
30
+ }
31
+ var __exports = {
32
+ __esModule: true
33
+ };
34
+ __exports.validateBindingModel = validateBindingModel;
35
+ return __exports;
36
+ });
37
+ //# sourceMappingURL=validator.js.map
@@ -0,0 +1,31 @@
1
+ import ResourceBundle from 'sap/base/i18n/ResourceBundle';
2
+
3
+ /**
4
+ * Function to validate if a given value is a valid binding model.
5
+ *
6
+ * @param value value to be checked.
7
+ */
8
+ export function validateBindingModel(value: string): void {
9
+ const bindingValue = value.replace(/[{}]/gi, '').trim();
10
+ const bindingParts = bindingValue.split('>').filter((el) => el != '');
11
+
12
+ if (!bindingParts.length) {
13
+ throw new SyntaxError('Invalid binding string.');
14
+ }
15
+
16
+ if (bindingParts[0].trim() === 'i18n') {
17
+ if (bindingParts.length === 2) {
18
+ const resourceBundle = ResourceBundle.create({
19
+ url: '../i18n/i18n.properties'
20
+ }) as ResourceBundle;
21
+ const resourceKey = bindingParts[1].trim();
22
+ if (!resourceBundle.hasText(resourceKey)) {
23
+ throw new SyntaxError(
24
+ 'Invalid key in the binding string. Supported value pattern is {i18n>YOUR_KEY}. Check if the key already exists in i18n.properties. If not, add the key in the i18n.properties file and reload the editor for the new key to take effect.'
25
+ );
26
+ }
27
+ } else {
28
+ throw new SyntaxError('Invalid binding string. Supported value pattern is {i18n>YOUR_KEY}');
29
+ }
30
+ }
31
+ }
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.10.7",
12
+ "version": "0.11.1",
13
13
  "license": "Apache-2.0",
14
14
  "author": "@SAP/ux-tools-team",
15
15
  "main": "dist/index.js",
@@ -24,7 +24,7 @@
24
24
  "dependencies": {
25
25
  "ejs": "3.1.9",
26
26
  "@sap-ux/logger": "0.4.0",
27
- "@sap-ux/adp-tooling": "0.5.5",
27
+ "@sap-ux/adp-tooling": "0.6.0",
28
28
  "@sap-ux/control-property-editor-sources": "npm:@sap-ux/control-property-editor@0.4.2"
29
29
  },
30
30
  "devDependencies": {
@@ -36,8 +36,8 @@
36
36
  "npm-run-all": "4.1.5",
37
37
  "nock": "13.2.1",
38
38
  "supertest": "6.3.3",
39
- "@private/preview-middleware-client": "npm:@sap-ux-private/preview-middleware-client@0.7.4",
40
- "@sap-ux/project-access": "1.15.1",
39
+ "@private/preview-middleware-client": "npm:@sap-ux-private/preview-middleware-client@0.8.1",
40
+ "@sap-ux/project-access": "1.15.2",
41
41
  "@sap-ux/store": "0.4.0"
42
42
  },
43
43
  "peerDependencies": {