@sap-ux/project-access 1.35.16 → 1.35.17

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.
@@ -95,6 +95,21 @@ export declare function getCdsServices(projectRoot: string, ignoreErrors?: boole
95
95
  * @returns - string containing the edmx
96
96
  */
97
97
  export declare function readCapServiceMetadataEdmx(root: string, uri: string, version?: 'v2' | 'v4'): Promise<string>;
98
+ /**
99
+ * Checks whether a given URL path matches one of the supported service prefix patterns
100
+ * and ends with the expected service suffix path.
101
+ *
102
+ * Currently method validates against DwC service patterns, supported patterns:
103
+ * - `/ui/<inbound-service-name>/v<version>/<suffix>`
104
+ * - `/<string>.<string>/external-ui/<inbound-service-name>/v<version>/<suffix>`
105
+ *
106
+ * The `<suffix>` (e.g. `odata/v4/myService`) must match exactly.
107
+ *
108
+ * @param path - The full request path to validate.
109
+ * @param expectedSuffixPath - The expected service path (e.g. `odata/v4/myService`).
110
+ * @returns `true` if the path matches one of the supported patterns and ends with the expected suffix.
111
+ */
112
+ export declare function isMatchingServiceUri(path: string, expectedSuffixPath: string): boolean;
98
113
  /**
99
114
  * Get CAP CDS project environment config for project root.
100
115
  *
@@ -12,6 +12,7 @@ exports.getCdsFiles = getCdsFiles;
12
12
  exports.getCdsRoots = getCdsRoots;
13
13
  exports.getCdsServices = getCdsServices;
14
14
  exports.readCapServiceMetadataEdmx = readCapServiceMetadataEdmx;
15
+ exports.isMatchingServiceUri = isMatchingServiceUri;
15
16
  exports.getCapEnvironment = getCapEnvironment;
16
17
  exports.clearCdsModuleCache = clearCdsModuleCache;
17
18
  exports.clearGlobalCdsModulePromiseCache = clearGlobalCdsModulePromiseCache;
@@ -361,6 +362,41 @@ async function readCapServiceMetadataEdmx(root, uri, version = 'v4') {
361
362
  throw Error(`Error while reading CAP service metadata. Path: '${root}', service uri: '${uri}', error: '${error.toString()}'}`);
362
363
  }
363
364
  }
365
+ /**
366
+ * Normalizes a service URL path by removing a leading and/or trailing slash.
367
+ *
368
+ * @param urlPath - The URL path to normalize.
369
+ * @returns The normalized path without leading or trailing slashes.
370
+ */
371
+ function normalizeServiceUrlPath(urlPath) {
372
+ return urlPath.replaceAll(/(?:^\/)|(?:\/$)/g, '');
373
+ }
374
+ /**
375
+ * Checks whether a given URL path matches one of the supported service prefix patterns
376
+ * and ends with the expected service suffix path.
377
+ *
378
+ * Currently method validates against DwC service patterns, supported patterns:
379
+ * - `/ui/<inbound-service-name>/v<version>/<suffix>`
380
+ * - `/<string>.<string>/external-ui/<inbound-service-name>/v<version>/<suffix>`
381
+ *
382
+ * The `<suffix>` (e.g. `odata/v4/myService`) must match exactly.
383
+ *
384
+ * @param path - The full request path to validate.
385
+ * @param expectedSuffixPath - The expected service path (e.g. `odata/v4/myService`).
386
+ * @returns `true` if the path matches one of the supported patterns and ends with the expected suffix.
387
+ */
388
+ function isMatchingServiceUri(path, expectedSuffixPath) {
389
+ const normalizedPath = path.startsWith('/') ? path : `/${path}`;
390
+ // Escapes special regex characters in a string so it can be embedded into regular expression
391
+ const escapedSuffix = expectedSuffixPath.replaceAll(/[.*+?^${}()|[\]\\]/g, String.raw `\$&`);
392
+ const patterns = [
393
+ // regex for pattern -> /ui/<inbound-service-name>/v<version>/...
394
+ String.raw `^/ui/[^/]+/v\d+/${escapedSuffix}$`,
395
+ // regex for pattern -> /<string>.<string>/external-ui/<inbound-service-name>/v<version>/...
396
+ String.raw `^/[^/]+\.[^/]+/external-ui/[^/]+/v\d+/${escapedSuffix}$`
397
+ ];
398
+ return patterns.some((pattern) => new RegExp(pattern).test(normalizedPath));
399
+ }
364
400
  /**
365
401
  * Find a service in a list of services ignoring leading and trailing slashes.
366
402
  *
@@ -369,8 +405,15 @@ async function readCapServiceMetadataEdmx(root, uri, version = 'v4') {
369
405
  * @returns - name and uri of the service, undefined if service not found
370
406
  */
371
407
  function findServiceByUri(services, uri) {
372
- const searchUri = uniformUrl(uri).replace(/(?:^\/)|(?:\/$)/g, '');
373
- return services.find((srv) => srv.urlPath.replace(/(?:^\/)|(?:\/$)/g, '') === searchUri);
408
+ const searchUri = normalizeServiceUrlPath(uniformUrl(uri));
409
+ // Try to find a service by exact path match
410
+ let service = services.find((srv) => normalizeServiceUrlPath(srv.urlPath) === searchUri);
411
+ // If no exact match is found, try matching while ignoring the service prefix
412
+ service ??= services.find((srv) => {
413
+ const normalizedServiceUrlPath = normalizeServiceUrlPath(srv.urlPath);
414
+ return isMatchingServiceUri(searchUri, normalizedServiceUrlPath);
415
+ });
416
+ return service;
374
417
  }
375
418
  /**
376
419
  * Get CAP CDS project environment config for project root.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sap-ux/project-access",
3
- "version": "1.35.16",
3
+ "version": "1.35.17",
4
4
  "description": "Library to access SAP Fiori tools projects",
5
5
  "repository": {
6
6
  "type": "git",