@salesforce/mrt-utilities 0.0.1 → 0.1.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/README.md +49 -45
- package/dist/cjs/index.d.ts +4 -0
- package/dist/cjs/index.js +10 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/metrics/index.d.ts +1 -0
- package/dist/cjs/metrics/index.js +7 -0
- package/dist/cjs/metrics/index.js.map +1 -0
- package/dist/cjs/metrics/metrics-sender.d.ts +136 -0
- package/dist/cjs/metrics/metrics-sender.js +240 -0
- package/dist/cjs/metrics/metrics-sender.js.map +1 -0
- package/dist/cjs/middleware/data-store.d.ts +56 -0
- package/dist/cjs/middleware/data-store.js +124 -0
- package/dist/cjs/middleware/data-store.js.map +1 -0
- package/dist/cjs/middleware/index.d.ts +3 -0
- package/dist/cjs/middleware/index.js +8 -0
- package/dist/cjs/middleware/index.js.map +1 -0
- package/dist/cjs/middleware/middleware.d.ts +126 -0
- package/dist/cjs/middleware/middleware.js +416 -0
- package/dist/cjs/middleware/middleware.js.map +1 -0
- package/dist/cjs/package.json +1 -0
- package/dist/cjs/streaming/create-lambda-adapter.d.ts +68 -0
- package/dist/cjs/streaming/create-lambda-adapter.js +797 -0
- package/dist/cjs/streaming/create-lambda-adapter.js.map +1 -0
- package/dist/cjs/streaming/index.d.ts +1 -0
- package/dist/cjs/streaming/index.js +7 -0
- package/dist/cjs/streaming/index.js.map +1 -0
- package/dist/cjs/utils/configure-proxying.d.ts +160 -0
- package/dist/cjs/utils/configure-proxying.js +204 -0
- package/dist/cjs/utils/configure-proxying.js.map +1 -0
- package/dist/cjs/utils/ssr-proxying.d.ts +300 -0
- package/dist/cjs/utils/ssr-proxying.js +713 -0
- package/dist/cjs/utils/ssr-proxying.js.map +1 -0
- package/dist/cjs/utils/utils.d.ts +27 -0
- package/dist/cjs/utils/utils.js +44 -0
- package/dist/cjs/utils/utils.js.map +1 -0
- package/dist/esm/index.d.ts +4 -0
- package/dist/esm/index.js +10 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/metrics/index.d.ts +1 -0
- package/dist/esm/metrics/index.js +7 -0
- package/dist/esm/metrics/index.js.map +1 -0
- package/dist/esm/metrics/metrics-sender.d.ts +136 -0
- package/dist/esm/metrics/metrics-sender.js +240 -0
- package/dist/esm/metrics/metrics-sender.js.map +1 -0
- package/dist/esm/middleware/data-store.d.ts +56 -0
- package/dist/esm/middleware/data-store.js +124 -0
- package/dist/esm/middleware/data-store.js.map +1 -0
- package/dist/esm/middleware/index.d.ts +3 -0
- package/dist/esm/middleware/index.js +9 -0
- package/dist/esm/middleware/index.js.map +1 -0
- package/dist/esm/middleware/middleware.d.ts +126 -0
- package/dist/esm/middleware/middleware.js +416 -0
- package/dist/esm/middleware/middleware.js.map +1 -0
- package/dist/esm/streaming/create-lambda-adapter.d.ts +68 -0
- package/dist/esm/streaming/create-lambda-adapter.js +797 -0
- package/dist/esm/streaming/create-lambda-adapter.js.map +1 -0
- package/dist/esm/streaming/index.d.ts +1 -0
- package/dist/esm/streaming/index.js +7 -0
- package/dist/esm/streaming/index.js.map +1 -0
- package/dist/esm/utils/configure-proxying.d.ts +160 -0
- package/dist/esm/utils/configure-proxying.js +204 -0
- package/dist/esm/utils/configure-proxying.js.map +1 -0
- package/dist/esm/utils/ssr-proxying.d.ts +300 -0
- package/dist/esm/utils/ssr-proxying.js +713 -0
- package/dist/esm/utils/ssr-proxying.js.map +1 -0
- package/dist/esm/utils/utils.d.ts +27 -0
- package/dist/esm/utils/utils.js +44 -0
- package/dist/esm/utils/utils.js.map +1 -0
- package/package.json +130 -7
|
@@ -0,0 +1,416 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2025, Salesforce, Inc.
|
|
3
|
+
* SPDX-License-Identifier: Apache-2
|
|
4
|
+
* For full license text, see the license.txt file in the repo root or http://www.apache.org/licenses/LICENSE-2.0
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* @fileoverview MRT (Managed Runtime) Middleware for Express.js applications.
|
|
8
|
+
*
|
|
9
|
+
* This module provides middleware functions for handling requests in a managed runtime environment,
|
|
10
|
+
* including request processing, proxy configuration, static asset serving, and local development
|
|
11
|
+
* utilities. It's designed to work with Salesforce Commerce Cloud's managed runtime platform.
|
|
12
|
+
*
|
|
13
|
+
* @author Salesforce Commerce Cloud
|
|
14
|
+
* @version 0.0.1
|
|
15
|
+
*/
|
|
16
|
+
import { Headers } from '../utils/ssr-proxying.js';
|
|
17
|
+
import { configureProxying, } from '../utils/configure-proxying.js';
|
|
18
|
+
import express from 'express';
|
|
19
|
+
import fs from 'fs';
|
|
20
|
+
import path from 'path';
|
|
21
|
+
import mimeTypes from 'mime-types';
|
|
22
|
+
import qs from 'qs';
|
|
23
|
+
const MOBIFY_PATH = '/mobify';
|
|
24
|
+
const PROXY_PATH_BASE = `${MOBIFY_PATH}/proxy`;
|
|
25
|
+
const CACHING_PATH_BASE = `${MOBIFY_PATH}/caching`;
|
|
26
|
+
const BUNDLE_PATH_BASE = `${MOBIFY_PATH}/bundle`;
|
|
27
|
+
const proxyBasePath = PROXY_PATH_BASE;
|
|
28
|
+
const bundleBasePath = BUNDLE_PATH_BASE;
|
|
29
|
+
const X_HEADERS_TO_REMOVE_ORIGIN = [
|
|
30
|
+
'x-api-key',
|
|
31
|
+
'x-apigateway-event',
|
|
32
|
+
'x-apigateway-context',
|
|
33
|
+
'x-mobify-access-key',
|
|
34
|
+
'x-sfdc-access-control',
|
|
35
|
+
];
|
|
36
|
+
export const X_MOBIFY_REQUEST_CLASS = 'x-mobify-request-class';
|
|
37
|
+
export const X_MOBIFY_QUERYSTRING = 'x-mobify-querystring';
|
|
38
|
+
export const X_MOBIFY_REQUEST_PROCESSOR_LOCAL = 'x-mobify-rp-local';
|
|
39
|
+
const CONTENT_TYPE = 'content-type';
|
|
40
|
+
const NO_CACHE = 'max-age=0, nocache, nostore, must-revalidate';
|
|
41
|
+
/**
|
|
42
|
+
* Checks if a URL is for a bundle or proxy path that should be skipped by request processing.
|
|
43
|
+
*
|
|
44
|
+
* @param url - The URL to check
|
|
45
|
+
* @returns True if the URL starts with a proxy or bundle base path
|
|
46
|
+
* @private
|
|
47
|
+
*/
|
|
48
|
+
const _isBundleOrProxyPath = (url) => {
|
|
49
|
+
return url.startsWith(proxyBasePath) || url.startsWith(bundleBasePath);
|
|
50
|
+
};
|
|
51
|
+
/**
|
|
52
|
+
* Dynamically imports a request processor module if it exists.
|
|
53
|
+
*
|
|
54
|
+
* @param requestProcessorPath - The file path to the request processor module
|
|
55
|
+
* @returns The default export of the module, or null if the file doesn't exist
|
|
56
|
+
* @private
|
|
57
|
+
*/
|
|
58
|
+
const _getRequestProcessor = async (requestProcessorPath) => {
|
|
59
|
+
if (requestProcessorPath && fs.existsSync(requestProcessorPath)) {
|
|
60
|
+
const module = await import(requestProcessorPath);
|
|
61
|
+
return module;
|
|
62
|
+
}
|
|
63
|
+
return null;
|
|
64
|
+
};
|
|
65
|
+
/**
|
|
66
|
+
* Retrieves request processor parameters from environment variables with defaults.
|
|
67
|
+
*
|
|
68
|
+
* This function reads environment variables to determine the application hostname,
|
|
69
|
+
* deployment target, and environment. It provides sensible defaults for local development.
|
|
70
|
+
*
|
|
71
|
+
* @returns Object containing appHostname, deployTarget, and environment
|
|
72
|
+
* @private
|
|
73
|
+
*/
|
|
74
|
+
const getRequestProcessorParameters = () => {
|
|
75
|
+
return {
|
|
76
|
+
appHostname: process.env.EXTERNAL_DOMAIN_NAME || 'localhost:2401',
|
|
77
|
+
deployTarget: process.env.DEPLOY_TARGET || 'local-target',
|
|
78
|
+
environment: process.env.ENVIRONMENT || 'development',
|
|
79
|
+
};
|
|
80
|
+
};
|
|
81
|
+
/**
|
|
82
|
+
* Updates the request's path and querystring, and parses the query parameters.
|
|
83
|
+
*
|
|
84
|
+
* This function updates the Express request object's originalUrl and query properties.
|
|
85
|
+
* It handles both cases where a querystring is present and where it's not. For Express 5
|
|
86
|
+
* compatibility, it uses Object.defineProperty to update the query object since direct
|
|
87
|
+
* modification is no longer allowed.
|
|
88
|
+
*
|
|
89
|
+
* @param req - Express request object to update
|
|
90
|
+
* @param updatedPath - The new path to set
|
|
91
|
+
* @param updatedQuerystring - The new querystring (optional, if undefined the querystring is removed)
|
|
92
|
+
* @private
|
|
93
|
+
*/
|
|
94
|
+
const updatePathAndQueryString = (req, updatedPath, updatedQuerystring) => {
|
|
95
|
+
let newQuery = {};
|
|
96
|
+
if (updatedQuerystring) {
|
|
97
|
+
newQuery = qs.parse(updatedQuerystring);
|
|
98
|
+
req.originalUrl = `${updatedPath}?${updatedQuerystring}`;
|
|
99
|
+
}
|
|
100
|
+
else {
|
|
101
|
+
req.originalUrl = updatedPath;
|
|
102
|
+
}
|
|
103
|
+
// Express 5 no longer allows direct modification of the query property
|
|
104
|
+
Object.defineProperty(req, 'query', {
|
|
105
|
+
value: { ...newQuery },
|
|
106
|
+
writable: true,
|
|
107
|
+
enumerable: true,
|
|
108
|
+
configurable: true,
|
|
109
|
+
});
|
|
110
|
+
};
|
|
111
|
+
/**
|
|
112
|
+
* Removes internal MRT headers and API Gateway headers from the request.
|
|
113
|
+
*
|
|
114
|
+
* This function cleans up headers that should not be forwarded to downstream services.
|
|
115
|
+
* It removes API Gateway-specific headers and internal MRT headers. When called from
|
|
116
|
+
* the cleanup middleware, it also removes the X_MOBIFY_REQUEST_PROCESSOR_LOCAL header
|
|
117
|
+
* to indicate that cleanup has been performed.
|
|
118
|
+
*
|
|
119
|
+
* @param req - Express request object to clean up
|
|
120
|
+
* @param cleanupLocalRequestProcessorHeader - If true, removes X_MOBIFY_REQUEST_PROCESSOR_LOCAL header
|
|
121
|
+
* @private
|
|
122
|
+
*/
|
|
123
|
+
const cleanUpHeaders = (req, cleanupLocalRequestProcessorHeader = false) => {
|
|
124
|
+
// If the cleanup is happening in the local request processor
|
|
125
|
+
// we don't want to remove the X_MOBIFY_REQUEST_PROCESSOR_LOCAL header
|
|
126
|
+
// because we need to not overwrite it in the cleanup middleware
|
|
127
|
+
if (cleanupLocalRequestProcessorHeader) {
|
|
128
|
+
delete req.headers[X_MOBIFY_REQUEST_PROCESSOR_LOCAL];
|
|
129
|
+
}
|
|
130
|
+
X_HEADERS_TO_REMOVE_ORIGIN.forEach((key) => {
|
|
131
|
+
delete req.headers[key];
|
|
132
|
+
});
|
|
133
|
+
};
|
|
134
|
+
/**
|
|
135
|
+
* Retrieves and processes the querystring from the x-mobify-querystring header.
|
|
136
|
+
*
|
|
137
|
+
* This function checks for the x-mobify-querystring header and uses it as the
|
|
138
|
+
* definitive querystring if present and non-empty. This header is used in production
|
|
139
|
+
* environments to override the URL querystring, but is also handled in local development
|
|
140
|
+
* to allow for testing. After processing, the header is removed from the request.
|
|
141
|
+
*
|
|
142
|
+
* If the header is present but empty, or if it's not present at all, the original
|
|
143
|
+
* querystring is returned unchanged.
|
|
144
|
+
*
|
|
145
|
+
* @param req - Express request object containing the headers
|
|
146
|
+
* @param originalQuerystring - The original querystring from the URL (may be undefined)
|
|
147
|
+
* @returns The querystring to use (from header if present and non-empty, otherwise original)
|
|
148
|
+
* @private
|
|
149
|
+
*/
|
|
150
|
+
const getMobifyQueryString = (req, originalQuerystring) => {
|
|
151
|
+
// If there's an x-querystring header, use that as the definitive
|
|
152
|
+
// querystring. This header is used in production, not in local dev,
|
|
153
|
+
// but we always handle it here to allow for testing.
|
|
154
|
+
let updatedQuerystring = originalQuerystring;
|
|
155
|
+
const xQueryString = req.headers[X_MOBIFY_QUERYSTRING];
|
|
156
|
+
if (xQueryString && xQueryString !== '') {
|
|
157
|
+
updatedQuerystring = xQueryString;
|
|
158
|
+
}
|
|
159
|
+
delete req.headers[X_MOBIFY_QUERYSTRING];
|
|
160
|
+
return updatedQuerystring;
|
|
161
|
+
};
|
|
162
|
+
/**
|
|
163
|
+
* Creates a middleware function that processes incoming requests using a custom request processor.
|
|
164
|
+
*
|
|
165
|
+
* This middleware handles:
|
|
166
|
+
* - Skipping processing for proxy and bundle paths
|
|
167
|
+
* - Loading and executing custom request processors
|
|
168
|
+
* - Processing custom query strings from headers
|
|
169
|
+
* - Removing API Gateway headers
|
|
170
|
+
* - Enforcing HTTP method restrictions for root path
|
|
171
|
+
* - Updating request paths and query strings when paths change
|
|
172
|
+
*
|
|
173
|
+
* @param requestProcessorPath - Path to the request processor module file
|
|
174
|
+
* @param proxyConfigs - Array of proxy configurations
|
|
175
|
+
* @returns Express middleware function
|
|
176
|
+
*
|
|
177
|
+
* @example
|
|
178
|
+
* ```typescript
|
|
179
|
+
* const middleware = createMRTRequestProcessorMiddleware(
|
|
180
|
+
* '/path/to/processor.js',
|
|
181
|
+
* [{ host: 'https://api.example.com', path: 'api' }]
|
|
182
|
+
* );
|
|
183
|
+
* app.use(middleware);
|
|
184
|
+
* ```
|
|
185
|
+
*/
|
|
186
|
+
export const createMRTRequestProcessorMiddleware = (requestProcessorPath, proxyConfigs) => {
|
|
187
|
+
const processIncomingRequest = async (req, res) => {
|
|
188
|
+
// If the request is for a proxy or bundle path, do nothing
|
|
189
|
+
if (_isBundleOrProxyPath(req.originalUrl)) {
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
const requestProcessor = await _getRequestProcessor(requestProcessorPath);
|
|
193
|
+
const originalQuerystring = req.originalUrl.split('?')[1];
|
|
194
|
+
// If there's no querystring the value will be undefined
|
|
195
|
+
// but TypeScript will complain if we don't explicitly set it to undefined.
|
|
196
|
+
let updatedQuerystring = originalQuerystring || undefined;
|
|
197
|
+
let updatedPath = req.originalUrl.split('?')[0];
|
|
198
|
+
updatedQuerystring = getMobifyQueryString(req, updatedQuerystring);
|
|
199
|
+
if (requestProcessor) {
|
|
200
|
+
// Allow the processor to handle this request. Because this code
|
|
201
|
+
// runs only in the local development server, we intentionally do
|
|
202
|
+
// not swallow errors - we want them to happen and show up on the
|
|
203
|
+
// console because that's how developers can test the processor.
|
|
204
|
+
const headers = new Headers(req.headers, 'http');
|
|
205
|
+
const { appHostname, deployTarget, environment } = getRequestProcessorParameters();
|
|
206
|
+
const processed = requestProcessor.processRequest({
|
|
207
|
+
headers,
|
|
208
|
+
path: req.path,
|
|
209
|
+
querystring: updatedQuerystring,
|
|
210
|
+
getRequestClass: () => headers.getHeader(X_MOBIFY_REQUEST_CLASS),
|
|
211
|
+
setRequestClass: (value) => headers.setHeader(X_MOBIFY_REQUEST_CLASS, value),
|
|
212
|
+
// This matches the set of parameters passed in the
|
|
213
|
+
// Lambda@Edge context.
|
|
214
|
+
parameters: {
|
|
215
|
+
deployTarget,
|
|
216
|
+
appHostname,
|
|
217
|
+
proxyConfigs: proxyConfigs || [],
|
|
218
|
+
environment,
|
|
219
|
+
},
|
|
220
|
+
});
|
|
221
|
+
// Aid debugging by checking the return value
|
|
222
|
+
console.assert(processed && 'path' in processed && 'querystring' in processed, 'Expected processRequest to return an object with ' +
|
|
223
|
+
'"path" and "querystring" properties, ' +
|
|
224
|
+
`but got ${JSON.stringify(processed, null, 2)}`);
|
|
225
|
+
// Update the request.
|
|
226
|
+
updatedQuerystring = processed.querystring;
|
|
227
|
+
updatedPath = processed.path;
|
|
228
|
+
if (headers.modified) {
|
|
229
|
+
req.headers = headers.toObject();
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
// Update the request.
|
|
233
|
+
if (updatedQuerystring !== originalQuerystring) {
|
|
234
|
+
updatePathAndQueryString(req, updatedPath, updatedQuerystring);
|
|
235
|
+
}
|
|
236
|
+
// Get the request class and store it for general use. We
|
|
237
|
+
// must do this AFTER the request-processor, because that's
|
|
238
|
+
// what may set the request class.
|
|
239
|
+
res.locals.requestClass = req.headers[X_MOBIFY_REQUEST_CLASS];
|
|
240
|
+
req.headers[X_MOBIFY_REQUEST_PROCESSOR_LOCAL] = 'true'; // Mark the request as processed by the request processor
|
|
241
|
+
};
|
|
242
|
+
const ssrRequestProcessorMiddleware = (req, res, next) => {
|
|
243
|
+
// If the path is /, we enforce that the only methods
|
|
244
|
+
// allowed are GET, HEAD or OPTIONS. This is a restriction
|
|
245
|
+
// imposed by API Gateway: we enforce it here so that the
|
|
246
|
+
// local dev server has the same behaviour.
|
|
247
|
+
if (req.path === '/' && !['GET', 'HEAD', 'OPTIONS'].includes(req.method)) {
|
|
248
|
+
res.sendStatus(405);
|
|
249
|
+
return;
|
|
250
|
+
}
|
|
251
|
+
// Apply custom query parameter parsing and forward errors via next()
|
|
252
|
+
processIncomingRequest(req, res)
|
|
253
|
+
.then(() => {
|
|
254
|
+
// Strip out API Gateway headers from the incoming request. We
|
|
255
|
+
// do that now so that the rest of the code don't have to deal
|
|
256
|
+
// with these headers, which can be large and may be accidentally
|
|
257
|
+
// forwarded to other servers.
|
|
258
|
+
cleanUpHeaders(req, false);
|
|
259
|
+
// Hand off to the next middleware
|
|
260
|
+
next();
|
|
261
|
+
})
|
|
262
|
+
.catch((err) => {
|
|
263
|
+
next(err);
|
|
264
|
+
});
|
|
265
|
+
};
|
|
266
|
+
return ssrRequestProcessorMiddleware;
|
|
267
|
+
};
|
|
268
|
+
/**
|
|
269
|
+
* Creates proxy middleware functions for the specified proxy configurations.
|
|
270
|
+
*
|
|
271
|
+
* This function creates Express middleware functions that handle proxying requests
|
|
272
|
+
* to external services. It can optionally create both regular proxy and caching
|
|
273
|
+
* proxy middlewares for each configuration. The app hostname is automatically
|
|
274
|
+
* retrieved from environment variables (EXTERNAL_DOMAIN_NAME or defaults to 'localhost:2401').
|
|
275
|
+
*
|
|
276
|
+
* @param proxyConfigs - Array of proxy configurations
|
|
277
|
+
* @param appProtocol - The protocol to use for the app (defaults to 'http')
|
|
278
|
+
* @param includeCaching - Whether to include caching proxy middlewares (defaults to false)
|
|
279
|
+
* @returns Array of proxy middleware results with their paths
|
|
280
|
+
*
|
|
281
|
+
* @example
|
|
282
|
+
* ```typescript
|
|
283
|
+
* const proxyMiddlewares = createMRTProxyMiddlewares(
|
|
284
|
+
* [{ host: 'https://api.example.com', path: 'api' }],
|
|
285
|
+
* 'https',
|
|
286
|
+
* true // Include caching middlewares
|
|
287
|
+
* );
|
|
288
|
+
*
|
|
289
|
+
* proxyMiddlewares.forEach(({ fn, path }) => {
|
|
290
|
+
* app.use(path, fn);
|
|
291
|
+
* });
|
|
292
|
+
* ```
|
|
293
|
+
*/
|
|
294
|
+
export const createMRTProxyMiddlewares = (proxyConfigs, appProtocol = 'http', includeCaching = false, createProxyFn) => {
|
|
295
|
+
if (!proxyConfigs) {
|
|
296
|
+
return [];
|
|
297
|
+
}
|
|
298
|
+
const { appHostname } = getRequestProcessorParameters();
|
|
299
|
+
const proxies = configureProxying(proxyConfigs, appHostname, appProtocol, createProxyFn);
|
|
300
|
+
const middlewares = [];
|
|
301
|
+
proxies.forEach((proxy) => {
|
|
302
|
+
const proxyPath = `${PROXY_PATH_BASE}/${proxy.path}`;
|
|
303
|
+
const cachingProxyPath = `${CACHING_PATH_BASE}/${proxy.path}`;
|
|
304
|
+
middlewares.push({ fn: proxy.fn, path: proxyPath });
|
|
305
|
+
if (includeCaching) {
|
|
306
|
+
middlewares.push({ fn: proxy.fn, path: cachingProxyPath });
|
|
307
|
+
}
|
|
308
|
+
});
|
|
309
|
+
return middlewares;
|
|
310
|
+
};
|
|
311
|
+
/**
|
|
312
|
+
* Sets appropriate HTTP headers for local asset files.
|
|
313
|
+
*
|
|
314
|
+
* This function sets content-type, caching, and other headers for static assets
|
|
315
|
+
* served from the local filesystem. It uses the file's modification time for
|
|
316
|
+
* ETag and Last-Modified headers, and sets no-cache directives for local assets.
|
|
317
|
+
*
|
|
318
|
+
* @param res - Express response object
|
|
319
|
+
* @param assetPath - Path to the asset file
|
|
320
|
+
*
|
|
321
|
+
* @example
|
|
322
|
+
* ```typescript
|
|
323
|
+
* app.use('/static', express.static('public', {
|
|
324
|
+
* setHeaders: setLocalAssetHeaders
|
|
325
|
+
* }));
|
|
326
|
+
* ```
|
|
327
|
+
*/
|
|
328
|
+
export const setLocalAssetHeaders = (res, assetPath) => {
|
|
329
|
+
const base = path.basename(assetPath);
|
|
330
|
+
const contentType = mimeTypes.lookup(base) || 'application/octet-stream';
|
|
331
|
+
res.set(CONTENT_TYPE, contentType);
|
|
332
|
+
// Stat the file and return the last-modified Date
|
|
333
|
+
// in RFC1123 format. Also use that value as the ETag
|
|
334
|
+
// and Last-Modified
|
|
335
|
+
const mtime = fs.statSync(assetPath).mtime;
|
|
336
|
+
const mtimeRFC1123 = mtime.toUTCString();
|
|
337
|
+
res.set('date', mtimeRFC1123);
|
|
338
|
+
res.set('last-modified', mtimeRFC1123);
|
|
339
|
+
res.set('etag', mtime.getTime().toString());
|
|
340
|
+
// We don't cache local bundle assets
|
|
341
|
+
res.set('cache-control', NO_CACHE);
|
|
342
|
+
};
|
|
343
|
+
/**
|
|
344
|
+
* Creates an Express static middleware configured for MRT asset serving.
|
|
345
|
+
*
|
|
346
|
+
* This function creates a static file serving middleware with MRT-specific
|
|
347
|
+
* configurations including custom header setting and security options.
|
|
348
|
+
*
|
|
349
|
+
* @param staticAssetDir - Directory path containing static assets
|
|
350
|
+
* @returns Express static middleware function
|
|
351
|
+
*
|
|
352
|
+
* @example
|
|
353
|
+
* ```typescript
|
|
354
|
+
* const staticMiddleware = createMRTStaticAssetServingMiddleware('/path/to/assets');
|
|
355
|
+
* app.use('/static', staticMiddleware);
|
|
356
|
+
* ```
|
|
357
|
+
*/
|
|
358
|
+
export const createMRTStaticAssetServingMiddleware = (staticAssetDir) => {
|
|
359
|
+
return express.static(staticAssetDir, {
|
|
360
|
+
dotfiles: 'deny',
|
|
361
|
+
setHeaders: setLocalAssetHeaders,
|
|
362
|
+
fallthrough: false,
|
|
363
|
+
});
|
|
364
|
+
};
|
|
365
|
+
/**
|
|
366
|
+
* Creates a common middleware function that sets the host header based on environment variables.
|
|
367
|
+
*
|
|
368
|
+
* The host header is set to EXTERNAL_DOMAIN_NAME if available, otherwise defaults to 'localhost:2401'.
|
|
369
|
+
* Use this middleware in all environments (local and deployed), at the top of your middleware stack.
|
|
370
|
+
*
|
|
371
|
+
* @returns Express middleware function
|
|
372
|
+
*
|
|
373
|
+
* @example
|
|
374
|
+
* ```typescript
|
|
375
|
+
* const middleware = createMRTCommonMiddleware();
|
|
376
|
+
* app.use(middleware);
|
|
377
|
+
* ```
|
|
378
|
+
*/
|
|
379
|
+
export const createMRTCommonMiddleware = () => {
|
|
380
|
+
return (req, res, next) => {
|
|
381
|
+
req.headers.host = process.env.EXTERNAL_DOMAIN_NAME || 'localhost:2401';
|
|
382
|
+
next();
|
|
383
|
+
};
|
|
384
|
+
};
|
|
385
|
+
/**
|
|
386
|
+
* Creates a cleanup middleware function that removes internal headers and cleans up request state.
|
|
387
|
+
*
|
|
388
|
+
* This middleware performs cleanup operations on requests:
|
|
389
|
+
* - Removes internal MRT headers (X_MOBIFY_REQUEST_PROCESSOR_LOCAL, X_MOBIFY_QUERYSTRING)
|
|
390
|
+
* - Removes API Gateway headers that shouldn't be forwarded
|
|
391
|
+
* - Optionally updates the path and querystring if the request wasn't processed by the request processor
|
|
392
|
+
*
|
|
393
|
+
* Use this middleware in all environments (local and deployed), at the end of the middleware chain,
|
|
394
|
+
* to ensure all internal headers are removed before the request is handled by the application.
|
|
395
|
+
*
|
|
396
|
+
* @returns Express middleware function
|
|
397
|
+
*
|
|
398
|
+
* @example
|
|
399
|
+
* ```typescript
|
|
400
|
+
* const cleanupMiddleware = createMRTCleanUpMiddleware();
|
|
401
|
+
* app.use(cleanupMiddleware);
|
|
402
|
+
* ```
|
|
403
|
+
*/
|
|
404
|
+
export const createMRTCleanUpMiddleware = () => {
|
|
405
|
+
return (req, res, next) => {
|
|
406
|
+
if (!req.headers[X_MOBIFY_REQUEST_PROCESSOR_LOCAL]) {
|
|
407
|
+
const originalQuerystring = req.originalUrl.split('?')[1] || undefined;
|
|
408
|
+
const updatedQuerystring = getMobifyQueryString(req, originalQuerystring);
|
|
409
|
+
const updatedPath = req.originalUrl.split('?')[0];
|
|
410
|
+
updatePathAndQueryString(req, updatedPath, updatedQuerystring);
|
|
411
|
+
}
|
|
412
|
+
cleanUpHeaders(req, true);
|
|
413
|
+
next();
|
|
414
|
+
};
|
|
415
|
+
};
|
|
416
|
+
//# sourceMappingURL=middleware.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"middleware.js","sourceRoot":"","sources":["../../../src/middleware/middleware.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"type":"commonjs"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { type ZlibOptions, type BrotliOptions, type ZstdOptions } from 'node:zlib';
|
|
2
|
+
import type { APIGatewayProxyEvent, Context } from 'aws-lambda';
|
|
3
|
+
import type { Express, Request, Response } from 'express';
|
|
4
|
+
import type { Writable } from 'stream';
|
|
5
|
+
interface ExpressRequest extends Request {
|
|
6
|
+
apiGateway?: {
|
|
7
|
+
event: APIGatewayProxyEvent;
|
|
8
|
+
context: Context;
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
interface ExpressResponse extends Response {
|
|
12
|
+
flushable?: boolean;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Configuration options for response compression.
|
|
16
|
+
*
|
|
17
|
+
* @property enabled - Whether compression is enabled. Set to false to disable compression entirely.
|
|
18
|
+
* Defaults to true (compression enabled).
|
|
19
|
+
* @property encoding - The compression encoding to use ('br', 'zstd', 'gzip', 'deflate').
|
|
20
|
+
* If not specified, the best encoding will be negotiated based on Accept-Encoding header.
|
|
21
|
+
* @property options - Compression library options. This can include any of the options accepted by
|
|
22
|
+
* zlib, Brotli, or Zstd, as defined in the zlib library, and will be passed
|
|
23
|
+
* directly to the corresponding compression library.
|
|
24
|
+
*/
|
|
25
|
+
export interface CompressionConfig {
|
|
26
|
+
enabled: boolean;
|
|
27
|
+
encoding?: 'br' | 'zstd' | 'gzip' | 'deflate';
|
|
28
|
+
options?: ZlibOptions | BrotliOptions | ZstdOptions;
|
|
29
|
+
}
|
|
30
|
+
type AsyncHandlerFunction = (event: APIGatewayProxyEvent, context: Context) => Promise<void>;
|
|
31
|
+
/**
|
|
32
|
+
* Creates a Lambda Adapter that wraps an Express app and supports response streaming
|
|
33
|
+
* for API Gateway v1 proxy integration using AWS Lambda response streaming
|
|
34
|
+
*
|
|
35
|
+
* @param app - Express application instance
|
|
36
|
+
* @param responseStream - AWS Lambda response stream
|
|
37
|
+
* @param compressionConfig - Optional compression configuration
|
|
38
|
+
* @returns Lambda handler function
|
|
39
|
+
*/
|
|
40
|
+
export declare function createStreamingLambdaAdapter(app: Express, responseStream: Writable, compressionConfig?: CompressionConfig): AsyncHandlerFunction;
|
|
41
|
+
/**
|
|
42
|
+
* Converts API Gateway event to Express-compatible request object
|
|
43
|
+
* Creates a proper IncomingMessage-like object with stream properties
|
|
44
|
+
*/
|
|
45
|
+
export declare function createExpressRequest(event: APIGatewayProxyEvent, context: Context): ExpressRequest;
|
|
46
|
+
/**
|
|
47
|
+
* Creates Express-compatible response object that properly extends ServerResponse
|
|
48
|
+
*
|
|
49
|
+
* This function creates a response object that:
|
|
50
|
+
* - Supports AWS Lambda response streaming via HttpResponseStream
|
|
51
|
+
* - Automatically compresses responses based on Accept-Encoding header
|
|
52
|
+
* - Uses negotiator to select the best available encoding (br, zstd if available, gzip, deflate)
|
|
53
|
+
* - Uses compressible package to determine if content should be compressed
|
|
54
|
+
*
|
|
55
|
+
* Compression flow:
|
|
56
|
+
* 1. Check Accept-Encoding header and select best encoding
|
|
57
|
+
* 2. Create HttpResponseStream with metadata
|
|
58
|
+
* 3. If compression is applicable, create compression stream and pipe to httpResponseStream
|
|
59
|
+
* 4. Write data to compression stream (or httpResponseStream if no compression)
|
|
60
|
+
* 5. End compression stream, which automatically ends httpResponseStream
|
|
61
|
+
*
|
|
62
|
+
* @param responseStream - The AWS Lambda response stream
|
|
63
|
+
* @param method - The HTTP method (GET, POST, etc.)
|
|
64
|
+
* @param request - Optional Express request object (used to check Accept-Encoding header)
|
|
65
|
+
* @returns Express-compatible response object
|
|
66
|
+
*/
|
|
67
|
+
export declare function createExpressResponse(responseStream: Writable, event: APIGatewayProxyEvent, context: Context, request?: ExpressRequest, compressionConfig?: CompressionConfig): ExpressResponse;
|
|
68
|
+
export {};
|