@sap-ux/backend-proxy-middleware-cf 0.0.56 → 0.0.58
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 +31 -1
- package/dist/proxy.d.ts +7 -3
- package/dist/proxy.js +23 -9
- package/dist/types.d.ts +6 -0
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -14,6 +14,7 @@ It can be used either with the `ui5 serve` or the `fiori run` commands.
|
|
|
14
14
|
| ------------------- | ---------- | ---------------- | ------------- | ---------------------------------------------------------------------------------------------------------------- |
|
|
15
15
|
| `url` | `string` | **required** | `undefined` | Destination URL to proxy requests to. |
|
|
16
16
|
| `paths` | `string[]` | **required** | `[]` | Array of OData source paths to proxy to this destination. Each path represents an OData service that should be proxied. Requests matching these paths will have the path prefix removed before forwarding. |
|
|
17
|
+
| `pathRewrite` | `string` | optional | `undefined` | Optional path rewriting. When specified, the matched path prefix will be replaced with this value before forwarding to the backend. If not specified, the matched path is simply removed. Example: path `/resources/lib/api` with pathRewrite `/api` transforms `/resources/lib/api/v1/Service` to `/api/v1/Service`. |
|
|
17
18
|
| `credentials` | object | optional | `undefined` | Manual OAuth credentials. If not provided, middleware attempts to auto-detect from Cloud Foundry ADP project. |
|
|
18
19
|
| `credentials.clientId` | `string` | mandatory (if credentials provided) | `undefined` | OAuth2 client ID. |
|
|
19
20
|
| `credentials.clientSecret` | `string` | mandatory (if credentials provided) | `undefined` | OAuth2 client secret. |
|
|
@@ -103,7 +104,36 @@ server:
|
|
|
103
104
|
- /odata/v4/service2
|
|
104
105
|
- /odata/v2/legacy
|
|
105
106
|
```
|
|
106
|
-
|
|
107
|
+
|
|
108
|
+
### Path Rewriting with pathRewrite
|
|
109
|
+
|
|
110
|
+
When your application requests resources with a specific path prefix (e.g., from a UI5 library), but the backend API expects a different path structure, use `pathRewrite`:
|
|
111
|
+
|
|
112
|
+
```yaml
|
|
113
|
+
server:
|
|
114
|
+
customMiddleware:
|
|
115
|
+
- name: backend-proxy-middleware-cf
|
|
116
|
+
afterMiddleware: compression
|
|
117
|
+
configuration:
|
|
118
|
+
backends:
|
|
119
|
+
- url: https://my-backend.example.com
|
|
120
|
+
paths:
|
|
121
|
+
- /resources/my/app/ui/api/example
|
|
122
|
+
pathRewrite: /api/example
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
**How it works:**
|
|
126
|
+
- **Request from app:** `/resources/my/app/ui/api/example/v1/ExampleService/$metadata`
|
|
127
|
+
- **Matched path:** `/resources/my/app/ui/api/example`
|
|
128
|
+
- **Path rewriting:** `/api/example`
|
|
129
|
+
- **Forwarded to backend:** `/api/example/v1/ExampleService/$metadata`
|
|
130
|
+
|
|
131
|
+
Without `pathRewrite`, the matched path prefix is simply removed:
|
|
132
|
+
- **Request:** `/odata/v4/service/EntitySet`
|
|
133
|
+
- **Matched path:** `/odata`
|
|
134
|
+
- **Forwarded:** `/v4/service/EntitySet`
|
|
135
|
+
|
|
136
|
+
### Multiple Backend Services
|
|
107
137
|
|
|
108
138
|
You can proxy multiple backend services:
|
|
109
139
|
|
package/dist/proxy.d.ts
CHANGED
|
@@ -9,24 +9,27 @@ export type EnhancedIncomingMessage = (IncomingMessage & Pick<Request, 'original
|
|
|
9
9
|
* Creates proxy options for http-proxy-middleware.
|
|
10
10
|
*
|
|
11
11
|
* @param {string} targetUrl - The target URL to proxy to.
|
|
12
|
+
* @param {string} matchedPath - The path prefix that was matched by the router.
|
|
13
|
+
* @param {string | undefined} pathRewrite - Optional replacement path.
|
|
12
14
|
* @param {ToolsLogger} logger - Logger instance.
|
|
13
15
|
* @returns {Options} Proxy options configuration.
|
|
14
16
|
*/
|
|
15
|
-
export declare function createProxyOptions(targetUrl: string, logger: ToolsLogger): Options;
|
|
17
|
+
export declare function createProxyOptions(targetUrl: string, matchedPath: string, pathRewrite: string | undefined, logger: ToolsLogger): Options;
|
|
16
18
|
/**
|
|
17
19
|
* Registers a proxy route for a given path.
|
|
18
20
|
*
|
|
19
21
|
* @param {string} path - Path to register.
|
|
20
22
|
* @param {string} destinationUrl - Target URL for proxying.
|
|
23
|
+
* @param {string | undefined} pathRewrite - Optional rewrite path.
|
|
21
24
|
* @param {OAuthTokenProvider} tokenProvider - Token provider instance.
|
|
22
25
|
* @param {ToolsLogger} logger - Logger instance.
|
|
23
26
|
* @param {Router} router - Express router instance.
|
|
24
27
|
*/
|
|
25
|
-
export declare function registerProxyRoute(path: string, destinationUrl: string, tokenProvider: OAuthTokenProvider, logger: ToolsLogger, router: Router): void;
|
|
28
|
+
export declare function registerProxyRoute(path: string, destinationUrl: string, pathRewrite: string | undefined, tokenProvider: OAuthTokenProvider, logger: ToolsLogger, router: Router): void;
|
|
26
29
|
/**
|
|
27
30
|
* Sets up all proxy routes for the configured backends.
|
|
28
31
|
*
|
|
29
|
-
* @param {Array<{url: string, paths: string[]}>} backends - Array of backend configurations.
|
|
32
|
+
* @param {Array<{url: string, paths: string[], pathRewrite?: string}>} backends - Array of backend configurations.
|
|
30
33
|
* @param {OAuthTokenProvider} tokenProvider - Token provider instance.
|
|
31
34
|
* @param {ToolsLogger} logger - Logger instance.
|
|
32
35
|
* @returns {Router} Configured Express router.
|
|
@@ -34,5 +37,6 @@ export declare function registerProxyRoute(path: string, destinationUrl: string,
|
|
|
34
37
|
export declare function setupProxyRoutes(backends: Array<{
|
|
35
38
|
url: string;
|
|
36
39
|
paths: string[];
|
|
40
|
+
pathRewrite?: string;
|
|
37
41
|
}>, tokenProvider: OAuthTokenProvider, logger: ToolsLogger): Router;
|
|
38
42
|
//# sourceMappingURL=proxy.d.ts.map
|
package/dist/proxy.js
CHANGED
|
@@ -9,10 +9,12 @@ const http_proxy_middleware_1 = require("http-proxy-middleware");
|
|
|
9
9
|
* Creates proxy options for http-proxy-middleware.
|
|
10
10
|
*
|
|
11
11
|
* @param {string} targetUrl - The target URL to proxy to.
|
|
12
|
+
* @param {string} matchedPath - The path prefix that was matched by the router.
|
|
13
|
+
* @param {string | undefined} pathRewrite - Optional replacement path.
|
|
12
14
|
* @param {ToolsLogger} logger - Logger instance.
|
|
13
15
|
* @returns {Options} Proxy options configuration.
|
|
14
16
|
*/
|
|
15
|
-
function createProxyOptions(targetUrl, logger) {
|
|
17
|
+
function createProxyOptions(targetUrl, matchedPath, pathRewrite, logger) {
|
|
16
18
|
return {
|
|
17
19
|
target: targetUrl,
|
|
18
20
|
changeOrigin: true,
|
|
@@ -22,9 +24,19 @@ function createProxyOptions(targetUrl, logger) {
|
|
|
22
24
|
const originalUrl = req.originalUrl ?? req.url ?? path;
|
|
23
25
|
const urlPath = originalUrl.split('?')?.[0];
|
|
24
26
|
const queryString = originalUrl.includes('?') ? originalUrl.substring(originalUrl.indexOf('?')) : '';
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
27
|
+
// Strip the matched path prefix
|
|
28
|
+
let rewrittenPath = urlPath;
|
|
29
|
+
if (urlPath.startsWith(matchedPath)) {
|
|
30
|
+
rewrittenPath = urlPath.substring(matchedPath.length);
|
|
31
|
+
}
|
|
32
|
+
// Add the replacement prefix if specified
|
|
33
|
+
if (pathRewrite !== undefined) {
|
|
34
|
+
const sanitizedRewrite = pathRewrite.replace(/\/$/, ''); // Remove trailing slash
|
|
35
|
+
rewrittenPath = sanitizedRewrite + rewrittenPath;
|
|
36
|
+
}
|
|
37
|
+
const finalPath = rewrittenPath + queryString;
|
|
38
|
+
logger.debug(`Rewrite path ${originalUrl} > ${finalPath}`);
|
|
39
|
+
return finalPath;
|
|
28
40
|
},
|
|
29
41
|
on: {
|
|
30
42
|
error: (err, req, _res, _target) => {
|
|
@@ -41,21 +53,23 @@ function createProxyOptions(targetUrl, logger) {
|
|
|
41
53
|
*
|
|
42
54
|
* @param {string} path - Path to register.
|
|
43
55
|
* @param {string} destinationUrl - Target URL for proxying.
|
|
56
|
+
* @param {string | undefined} pathRewrite - Optional rewrite path.
|
|
44
57
|
* @param {OAuthTokenProvider} tokenProvider - Token provider instance.
|
|
45
58
|
* @param {ToolsLogger} logger - Logger instance.
|
|
46
59
|
* @param {Router} router - Express router instance.
|
|
47
60
|
*/
|
|
48
|
-
function registerProxyRoute(path, destinationUrl, tokenProvider, logger, router) {
|
|
49
|
-
const proxyOptions = createProxyOptions(destinationUrl, logger);
|
|
61
|
+
function registerProxyRoute(path, destinationUrl, pathRewrite, tokenProvider, logger, router) {
|
|
62
|
+
const proxyOptions = createProxyOptions(destinationUrl, path, pathRewrite, logger);
|
|
50
63
|
const proxyFn = (0, http_proxy_middleware_1.createProxyMiddleware)(proxyOptions);
|
|
51
64
|
const tokenMiddleware = tokenProvider.createTokenMiddleware();
|
|
52
65
|
router.use(path, tokenMiddleware, proxyFn);
|
|
53
|
-
|
|
66
|
+
const rewriteInfo = pathRewrite ? ` (rewrite to: ${pathRewrite})` : ' (strip prefix)';
|
|
67
|
+
logger.info(`Registered proxy for path: ${path} -> ${destinationUrl}${rewriteInfo}`);
|
|
54
68
|
}
|
|
55
69
|
/**
|
|
56
70
|
* Sets up all proxy routes for the configured backends.
|
|
57
71
|
*
|
|
58
|
-
* @param {Array<{url: string, paths: string[]}>} backends - Array of backend configurations.
|
|
72
|
+
* @param {Array<{url: string, paths: string[], pathRewrite?: string}>} backends - Array of backend configurations.
|
|
59
73
|
* @param {OAuthTokenProvider} tokenProvider - Token provider instance.
|
|
60
74
|
* @param {ToolsLogger} logger - Logger instance.
|
|
61
75
|
* @returns {Router} Configured Express router.
|
|
@@ -65,7 +79,7 @@ function setupProxyRoutes(backends, tokenProvider, logger) {
|
|
|
65
79
|
for (const backend of backends) {
|
|
66
80
|
for (const path of backend.paths) {
|
|
67
81
|
try {
|
|
68
|
-
registerProxyRoute(path, backend.url, tokenProvider, logger, router);
|
|
82
|
+
registerProxyRoute(path, backend.url, backend.pathRewrite, tokenProvider, logger, router);
|
|
69
83
|
}
|
|
70
84
|
catch (e) {
|
|
71
85
|
throw new Error(`Failed to register proxy for ${path}. Check configuration in yaml file. \n\t${e.message}`);
|
package/dist/types.d.ts
CHANGED
|
@@ -12,6 +12,12 @@ export interface BackendDestination {
|
|
|
12
12
|
* Requests matching these paths will have the path prefix removed before forwarding.
|
|
13
13
|
*/
|
|
14
14
|
paths: string[];
|
|
15
|
+
/**
|
|
16
|
+
* Optional path rewriting. When specified, the matched path prefix will be replaced
|
|
17
|
+
* with this value before forwarding to the backend.
|
|
18
|
+
* If not specified, the matched path is simply removed.
|
|
19
|
+
*/
|
|
20
|
+
pathRewrite?: string;
|
|
15
21
|
}
|
|
16
22
|
/**
|
|
17
23
|
* Configuration for Cloud Foundry OAuth middleware.
|
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%3Abackend-proxy-middleware-cf"
|
|
11
11
|
},
|
|
12
|
-
"version": "0.0.
|
|
12
|
+
"version": "0.0.58",
|
|
13
13
|
"license": "Apache-2.0",
|
|
14
14
|
"author": "@SAP/ux-tools-team",
|
|
15
15
|
"main": "dist/index.js",
|
|
@@ -23,9 +23,9 @@
|
|
|
23
23
|
"dependencies": {
|
|
24
24
|
"axios": "1.13.5",
|
|
25
25
|
"http-proxy-middleware": "3.0.5",
|
|
26
|
-
"@sap-ux/adp-tooling": "0.18.
|
|
26
|
+
"@sap-ux/adp-tooling": "0.18.68",
|
|
27
27
|
"@sap-ux/logger": "0.8.1",
|
|
28
|
-
"@sap-ux/project-access": "1.35.
|
|
28
|
+
"@sap-ux/project-access": "1.35.6"
|
|
29
29
|
},
|
|
30
30
|
"devDependencies": {
|
|
31
31
|
"@types/express": "4.17.21",
|