@salesforce/pwa-kit-runtime 3.9.0-nightly-20241206080208 → 4.0.0-extensibility-preview.0
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/package.json +9 -7
- package/ssr/server/build-remote-server.d.ts +211 -0
- package/ssr/server/build-remote-server.d.ts.map +1 -0
- package/ssr/server/build-remote-server.js +11 -78
- package/ssr/server/build-remote-server.test.js +139 -72
- package/ssr/server/constants.d.ts +18 -0
- package/ssr/server/constants.d.ts.map +1 -0
- package/ssr/server/constants.js +1 -2
- package/ssr/server/express.d.ts +17 -0
- package/ssr/server/express.d.ts.map +1 -0
- package/ssr/server/express.test.js +7 -91
- package/ssr/server/test_fixtures/extensions/another-extension/setup-server.d.ts +5 -0
- package/ssr/server/test_fixtures/extensions/another-extension/setup-server.d.ts.map +1 -0
- package/ssr/server/test_fixtures/extensions/another-extension/setup-server.js +19 -0
- package/ssr/server/test_fixtures/extensions/extension-with-bad-setup-server/setup-server.d.ts +5 -0
- package/ssr/server/test_fixtures/extensions/extension-with-bad-setup-server/setup-server.d.ts.map +1 -0
- package/ssr/server/test_fixtures/extensions/extension-with-bad-setup-server/setup-server.js +16 -0
- package/ssr/server/test_fixtures/extensions/extension-with-setup-server-no-default-export/setup-server.d.ts +2 -0
- package/ssr/server/test_fixtures/extensions/extension-with-setup-server-no-default-export/setup-server.d.ts.map +1 -0
- package/ssr/server/test_fixtures/extensions/extension-with-setup-server-no-default-export/setup-server.js +17 -0
- package/ssr/server/test_fixtures/extensions/extension-without-setup-server/random-file.d.ts +1 -0
- package/ssr/server/test_fixtures/extensions/extension-without-setup-server/random-file.d.ts.map +1 -0
- package/ssr/server/test_fixtures/extensions/extension-without-setup-server/random-file.js +7 -0
- package/ssr/server/test_fixtures/extensions/test-extension/setup-server.d.ts +5 -0
- package/ssr/server/test_fixtures/extensions/test-extension/setup-server.d.ts.map +1 -0
- package/ssr/server/test_fixtures/extensions/test-extension/setup-server.js +28 -0
- package/ssr/server/test_fixtures/main.d.ts +1 -0
- package/ssr/server/test_fixtures/main.d.ts.map +1 -0
- package/ssr/server/test_fixtures/server-renderer.d.ts +6 -0
- package/ssr/server/test_fixtures/server-renderer.d.ts.map +1 -0
- package/ssr/server/test_fixtures/worker.d.ts +1 -0
- package/ssr/server/test_fixtures/worker.d.ts.map +1 -0
- package/utils/logger-factory.d.ts +58 -0
- package/utils/logger-factory.d.ts.map +1 -0
- package/utils/logger-instance.d.ts +3 -0
- package/utils/logger-instance.d.ts.map +1 -0
- package/utils/middleware/index.d.ts +2 -0
- package/utils/middleware/index.d.ts.map +1 -0
- package/utils/middleware/security.d.ts +2 -0
- package/utils/middleware/security.d.ts.map +1 -0
- package/utils/morgan-stream.d.ts +11 -0
- package/utils/morgan-stream.d.ts.map +1 -0
- package/utils/ssr-cache.d.ts +112 -0
- package/utils/ssr-cache.d.ts.map +1 -0
- package/utils/ssr-config.client.d.ts +2 -0
- package/utils/ssr-config.client.d.ts.map +1 -0
- package/utils/ssr-config.client.test.js +4 -0
- package/utils/ssr-config.d.ts +3 -0
- package/utils/ssr-config.d.ts.map +1 -0
- package/utils/ssr-config.server.d.ts +2 -0
- package/utils/ssr-config.server.d.ts.map +1 -0
- package/utils/ssr-namespace-paths.d.ts +7 -0
- package/utils/ssr-namespace-paths.d.ts.map +1 -0
- package/utils/ssr-proxying.d.ts +173 -0
- package/utils/ssr-proxying.d.ts.map +1 -0
- package/utils/ssr-request-processing.d.ts +90 -0
- package/utils/ssr-request-processing.d.ts.map +1 -0
- package/utils/ssr-server/cached-response.d.ts +62 -0
- package/utils/ssr-server/cached-response.d.ts.map +1 -0
- package/utils/ssr-server/configure-proxy.d.ts +5 -0
- package/utils/ssr-server/configure-proxy.d.ts.map +1 -0
- package/utils/ssr-server/metrics-sender.d.ts +83 -0
- package/utils/ssr-server/metrics-sender.d.ts.map +1 -0
- package/utils/ssr-server/metrics-sender.js +1 -1
- package/utils/ssr-server/outgoing-request-hook.d.ts +2 -0
- package/utils/ssr-server/outgoing-request-hook.d.ts.map +1 -0
- package/utils/ssr-server/parse-end-parameters.d.ts +2 -0
- package/utils/ssr-server/parse-end-parameters.d.ts.map +1 -0
- package/utils/ssr-server/process-express-response.d.ts +3 -0
- package/utils/ssr-server/process-express-response.d.ts.map +1 -0
- package/utils/ssr-server/process-lambda-response.d.ts +2 -0
- package/utils/ssr-server/process-lambda-response.d.ts.map +1 -0
- package/utils/ssr-server/update-global-agent-options.d.ts +3 -0
- package/utils/ssr-server/update-global-agent-options.d.ts.map +1 -0
- package/utils/ssr-server/utils.d.ts +13 -0
- package/utils/ssr-server/utils.d.ts.map +1 -0
- package/utils/ssr-server/wrap-response-write.d.ts +2 -0
- package/utils/ssr-server/wrap-response-write.d.ts.map +1 -0
- package/utils/ssr-server.d.ts +11 -0
- package/utils/ssr-server.d.ts.map +1 -0
- package/utils/ssr-shared.d.ts +42 -0
- package/utils/ssr-shared.d.ts.map +1 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@salesforce/pwa-kit-runtime",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "4.0.0-extensibility-preview.0",
|
|
4
4
|
"description": "The PWAKit Runtime",
|
|
5
5
|
"homepage": "https://github.com/SalesforceCommerceCloud/pwa-kit/tree/develop/packages/pwa-kit-runtime#readme",
|
|
6
6
|
"bugs": {
|
|
@@ -19,8 +19,8 @@
|
|
|
19
19
|
"utils"
|
|
20
20
|
],
|
|
21
21
|
"scripts": {
|
|
22
|
-
"build": "cross-env NODE_ENV=production internal-lib-build build",
|
|
23
|
-
"build:watch": "nodemon --watch 'src/**' --exec 'npm run build'",
|
|
22
|
+
"build": "cross-env NODE_ENV=production internal-lib-build build && tsc",
|
|
23
|
+
"build:watch": "nodemon --watch 'src/**' --ext 'js,jsx,ts,tsx' --exec 'npm run build'",
|
|
24
24
|
"format": "internal-lib-build format \"**/*.{js,jsx}\"",
|
|
25
25
|
"lint": "npm run lint:js",
|
|
26
26
|
"lint:fix": "npm run lint:js -- --fix",
|
|
@@ -46,11 +46,13 @@
|
|
|
46
46
|
},
|
|
47
47
|
"devDependencies": {
|
|
48
48
|
"@loadable/component": "^5.15.3",
|
|
49
|
-
"@salesforce/pwa-kit-dev": "
|
|
49
|
+
"@salesforce/pwa-kit-dev": "4.0.0-extensibility-preview.0",
|
|
50
|
+
"@salesforce/pwa-kit-extension-sdk": "4.0.0-extensibility-preview.0",
|
|
50
51
|
"@serverless/event-mocks": "^1.1.1",
|
|
52
|
+
"@types/express": "^4.17.21",
|
|
51
53
|
"aws-lambda-mock-context": "^3.2.1",
|
|
52
54
|
"fs-extra": "^11.1.1",
|
|
53
|
-
"internal-lib-build": "
|
|
55
|
+
"internal-lib-build": "4.0.0-extensibility-preview.0",
|
|
54
56
|
"nock": "^13.3.0",
|
|
55
57
|
"nodemon": "^2.0.22",
|
|
56
58
|
"sinon": "^13.0.2",
|
|
@@ -58,7 +60,7 @@
|
|
|
58
60
|
"supertest": "^4.0.2"
|
|
59
61
|
},
|
|
60
62
|
"peerDependencies": {
|
|
61
|
-
"@salesforce/pwa-kit-dev": "
|
|
63
|
+
"@salesforce/pwa-kit-dev": "4.0.0-extensibility-preview.0"
|
|
62
64
|
},
|
|
63
65
|
"peerDependenciesMeta": {
|
|
64
66
|
"@salesforce/pwa-kit-dev": {
|
|
@@ -72,5 +74,5 @@
|
|
|
72
74
|
"publishConfig": {
|
|
73
75
|
"directory": "dist"
|
|
74
76
|
},
|
|
75
|
-
"gitHead": "
|
|
77
|
+
"gitHead": "16a2673cbdb9b22e3071435e8afbc2e89b2e37da"
|
|
76
78
|
}
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Environment variables that must be set for the Express app to run remotely.
|
|
3
|
+
*
|
|
4
|
+
* @private
|
|
5
|
+
*/
|
|
6
|
+
export const REMOTE_REQUIRED_ENV_VARS: string[];
|
|
7
|
+
export namespace RemoteServerFactory {
|
|
8
|
+
/**
|
|
9
|
+
* @private
|
|
10
|
+
*/
|
|
11
|
+
function _configure(options: any): any;
|
|
12
|
+
/**
|
|
13
|
+
* @private
|
|
14
|
+
*/
|
|
15
|
+
function _logStartupMessage(options: any): void;
|
|
16
|
+
/**
|
|
17
|
+
* @private
|
|
18
|
+
*/
|
|
19
|
+
function _getAllowCookies(options: any): boolean;
|
|
20
|
+
/**
|
|
21
|
+
* @private
|
|
22
|
+
*/
|
|
23
|
+
function _getProtocol(options: any): string;
|
|
24
|
+
/**
|
|
25
|
+
* @private
|
|
26
|
+
*/
|
|
27
|
+
function _getDefaultCacheControl(options: any): string;
|
|
28
|
+
/**
|
|
29
|
+
* @private
|
|
30
|
+
*/
|
|
31
|
+
function _strictSSL(options: any): boolean;
|
|
32
|
+
/**
|
|
33
|
+
* @private
|
|
34
|
+
*/
|
|
35
|
+
function _isBundleOrProxyPath(url: any): any;
|
|
36
|
+
/**
|
|
37
|
+
* @private
|
|
38
|
+
*/
|
|
39
|
+
function _getSlasEndpoint(options: any): string | undefined;
|
|
40
|
+
/**
|
|
41
|
+
* @private
|
|
42
|
+
*/
|
|
43
|
+
function _setCompression(app: any): void;
|
|
44
|
+
/**
|
|
45
|
+
* @private
|
|
46
|
+
*/
|
|
47
|
+
function _setupLogging(app: any): void;
|
|
48
|
+
/**
|
|
49
|
+
* Passing the correlation Id from MRT to locals
|
|
50
|
+
* @private
|
|
51
|
+
*/
|
|
52
|
+
function _setRequestId(app: any): void;
|
|
53
|
+
/**
|
|
54
|
+
* @private
|
|
55
|
+
*/
|
|
56
|
+
function _setupMetricsFlushing(app: any): void;
|
|
57
|
+
/**
|
|
58
|
+
* @private
|
|
59
|
+
*/
|
|
60
|
+
function _updatePackageMobify(options: any): void;
|
|
61
|
+
/**
|
|
62
|
+
* @private
|
|
63
|
+
*/
|
|
64
|
+
function _configureProxyConfigs(options: any): void;
|
|
65
|
+
/**
|
|
66
|
+
* @private
|
|
67
|
+
*/
|
|
68
|
+
function _createApp(options: any): import("express-serve-static-core").Express;
|
|
69
|
+
/**
|
|
70
|
+
* @private
|
|
71
|
+
*/
|
|
72
|
+
function _createExpressApp(options: any): import("express-serve-static-core").Express;
|
|
73
|
+
/**
|
|
74
|
+
* @private
|
|
75
|
+
*/
|
|
76
|
+
function _addSDKInternalHandlers(app: any): void;
|
|
77
|
+
/**
|
|
78
|
+
* @private
|
|
79
|
+
*/
|
|
80
|
+
function _setupSSRRequestProcessorMiddleware(app: any): void;
|
|
81
|
+
/**
|
|
82
|
+
* @private
|
|
83
|
+
*/
|
|
84
|
+
function _setupProxying(app: any, options: any): void;
|
|
85
|
+
/**
|
|
86
|
+
* @private
|
|
87
|
+
*/
|
|
88
|
+
function _handleMissingSlasPrivateEnvVar(app: any): void;
|
|
89
|
+
/**
|
|
90
|
+
* @private
|
|
91
|
+
*/
|
|
92
|
+
function _setupSlasPrivateClientProxy(app: any, options: any): void;
|
|
93
|
+
/**
|
|
94
|
+
* @private
|
|
95
|
+
*/
|
|
96
|
+
function _setupHealthcheck(app: any): void;
|
|
97
|
+
/**
|
|
98
|
+
* @private
|
|
99
|
+
*/
|
|
100
|
+
function _setupCommonMiddleware(app: any, options: any): void;
|
|
101
|
+
/**
|
|
102
|
+
* @private
|
|
103
|
+
*/
|
|
104
|
+
function _validateConfiguration(options: any): void;
|
|
105
|
+
/**
|
|
106
|
+
* @private
|
|
107
|
+
*/
|
|
108
|
+
function _addStaticAssetServing(): void;
|
|
109
|
+
/**
|
|
110
|
+
* @private
|
|
111
|
+
*/
|
|
112
|
+
function _addDevServerGarbageCollection(): void;
|
|
113
|
+
/**
|
|
114
|
+
* Serve the service worker at `req.path`
|
|
115
|
+
*
|
|
116
|
+
* For best results, serve the service worker at the root of the site and
|
|
117
|
+
* it must not be a redirect. We set a long value for s-maxage (to allow CDN
|
|
118
|
+
* caching), plus a strong etag (for CDN-only revalidation), and to set
|
|
119
|
+
* maxage to 0 to prevent browser caching.
|
|
120
|
+
*
|
|
121
|
+
* See https://developer.chrome.com/blog/fresher-sw/ for details on
|
|
122
|
+
* efficiently serving service workers.
|
|
123
|
+
*
|
|
124
|
+
*/
|
|
125
|
+
function serveServiceWorker(req: any, res: any): void;
|
|
126
|
+
/**
|
|
127
|
+
* Serve static files from the app's build directory and set default
|
|
128
|
+
* cache-control headers.
|
|
129
|
+
* @since v2.0.0
|
|
130
|
+
*
|
|
131
|
+
* @param {String} filePath - the location of the static file relative to the build directory
|
|
132
|
+
* @param {Object} opts - the options object to pass to the original `sendFile` method
|
|
133
|
+
*/
|
|
134
|
+
function serveStaticFile(filePath: string, opts?: Object): (req: any, res: any) => void;
|
|
135
|
+
/**
|
|
136
|
+
* @private
|
|
137
|
+
*/
|
|
138
|
+
function _serveStaticFile(req: any, res: any, baseDir: any, filePath: any, opts?: {}): void;
|
|
139
|
+
/**
|
|
140
|
+
* Server side rendering entry.
|
|
141
|
+
*
|
|
142
|
+
* @since v2.0.0
|
|
143
|
+
*
|
|
144
|
+
* This is a wrapper around the Express `res.sendFile` method.
|
|
145
|
+
*
|
|
146
|
+
* @param {Object} req - the req object
|
|
147
|
+
* @param {Object} req - the res object
|
|
148
|
+
* @param {function} next - the callback function for middleware chain
|
|
149
|
+
*/
|
|
150
|
+
function render(req: Object, res: any, next: Function): void;
|
|
151
|
+
/**
|
|
152
|
+
* Builds a Lambda handler function from an Express app.
|
|
153
|
+
*
|
|
154
|
+
* See: https://docs.aws.amazon.com/lambda/latest/dg/nodejs-prog-model-handler.html
|
|
155
|
+
*
|
|
156
|
+
* @param app {Express} - an Express App
|
|
157
|
+
* @private
|
|
158
|
+
*/
|
|
159
|
+
function _createHandler(app: Express): {
|
|
160
|
+
handler: (event: any, context: any, callback: any) => void;
|
|
161
|
+
server: any;
|
|
162
|
+
app: Express;
|
|
163
|
+
};
|
|
164
|
+
/**
|
|
165
|
+
* Create an SSR (Server-Side Rendering) Server.
|
|
166
|
+
*
|
|
167
|
+
* @constructor
|
|
168
|
+
* @param {Object} options
|
|
169
|
+
* @param {String} [options.buildDir] - The build directory path, either as an
|
|
170
|
+
* absolute path, or relative to the current working directory. Defaults
|
|
171
|
+
* to 'build'.
|
|
172
|
+
* @param {Number} [options.defaultCacheTimeSeconds=600] - The cache time
|
|
173
|
+
* for rendered pages and assets (not used in local development mode).
|
|
174
|
+
* @param {Object} options.mobify - The 'mobify' object from the project's
|
|
175
|
+
* package.json file, containing the SSR parameters.
|
|
176
|
+
* @param {Number} [options.port=3443] - the localhost port on which the local
|
|
177
|
+
* development Express app listens.
|
|
178
|
+
* @param {String} [options.protocol='https'] - the protocol on which the development
|
|
179
|
+
* Express app listens.
|
|
180
|
+
* @param {Boolean} [options.proxyKeepAliveAgent] - This boolean value indicates
|
|
181
|
+
* whether or not we are using a keep alive agent for proxy connections. Defaults
|
|
182
|
+
* to 'true'. NOTE: This keep alive agent will only be used on remote.
|
|
183
|
+
* @param {String} options.sslFilePath - the absolute path to a PEM format
|
|
184
|
+
* certificate file to be used by the local development server. This should
|
|
185
|
+
* contain both the certificate and the private key.
|
|
186
|
+
* @param {function} customizeApp - a callback that takes an express app
|
|
187
|
+
* as an argument. Use this to customize the server.
|
|
188
|
+
* @param {Boolean} [options.allowCookies] - This boolean value indicates
|
|
189
|
+
* whether or not we strip cookies from requests and block setting of cookies. Defaults
|
|
190
|
+
* to 'false'.
|
|
191
|
+
*/
|
|
192
|
+
function createHandler(options: {
|
|
193
|
+
buildDir?: string | undefined;
|
|
194
|
+
defaultCacheTimeSeconds?: number | undefined;
|
|
195
|
+
mobify: Object;
|
|
196
|
+
port?: number | undefined;
|
|
197
|
+
protocol?: string | undefined;
|
|
198
|
+
proxyKeepAliveAgent?: boolean | undefined;
|
|
199
|
+
sslFilePath: string;
|
|
200
|
+
}, customizeApp: Function): {
|
|
201
|
+
handler: (event: any, context: any, callback: any) => void;
|
|
202
|
+
server: any;
|
|
203
|
+
app: Express;
|
|
204
|
+
};
|
|
205
|
+
/**
|
|
206
|
+
* @private
|
|
207
|
+
*/
|
|
208
|
+
function _getRequestProcessor(req: any): null;
|
|
209
|
+
}
|
|
210
|
+
export function once(fn: any): (...args: any[]) => any;
|
|
211
|
+
//# sourceMappingURL=build-remote-server.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"build-remote-server.d.ts","sourceRoot":"","sources":["../../../src/ssr/server/build-remote-server.js"],"names":[],"mappings":"AAoEA;;;;GAIG;AACH,gDAKC;;IAWG;;OAEG;IACH,uCAgFC;IAED;;OAEG;IAEH,gDAEC;IAED;;OAEG;IAEH,iDAEC;IAED;;OAEG;IAEH,4CAEC;IAED;;OAEG;IACH,uDAEC;IAED;;OAEG;IAEH,2CAEC;IAED;;OAEG;IACH,6CAEC;IAED;;OAEG;IACH,4DAIC;IAED;;OAEG;IAEH,yCAEC;IAED;;OAEG;IAEH,uCA6CC;IAED;;;OAGG;IACH,uCAcC;IAED;;OAEG;IAEH,+CAEC;IAED;;OAEG;IACH,kDAEC;IAED;;OAEG;IACH,oDAEC;IAED;;OAEG;IACH,+EA0CC;IAED;;OAEG;IACH,sFAyDC;IAED;;OAEG;IAEH,iDAEC;IAED;;OAEG;IACH,6DAwLC;IAED;;OAEG;IAEH,sDAOC;IAED;;OAEG;IACH,yDAOC;IAED;;OAEG;IACH,oEAuEC;IAED;;OAEG;IACH,2CAIC;IAED;;OAEG;IACH,8DAaC;IAED;;OAEG;IACH,oDA0EC;IAED;;OAEG;IACH,wCAEC;IAED;;OAEG;IACH,gDAGC;IAED;;;;;;;;;;;OAWG;IACH,sDAwBC;IAED;;;;;;;OAOG;IACH,wFAKC;IAED;;OAEG;IACH,4FASC;IAED;;;;;;;;;;OAUG;IACH,6DAWC;IAED;;;;;;;OAOG;IACH;;;;MA8EC;IAED;;;;;;;;;;;;;;;;;;;;;;;;;;;OA2BG;IACH;;;;;;;;;;;;MAKC;IAED;;OAEG;IAEH,8CAEC;;AAyFE,uDASN"}
|
|
@@ -27,6 +27,7 @@ var _awsServerlessExpress = _interopRequireDefault(require("aws-serverless-expre
|
|
|
27
27
|
var _morgan = _interopRequireDefault(require("morgan"));
|
|
28
28
|
var _loggerInstance = _interopRequireDefault(require("../../utils/logger-instance"));
|
|
29
29
|
var _httpProxyMiddleware = require("http-proxy-middleware");
|
|
30
|
+
var _express3 = require("@salesforce/pwa-kit-extension-sdk/express");
|
|
30
31
|
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
31
32
|
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
32
33
|
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
@@ -296,7 +297,6 @@ const RemoteServerFactory = exports.RemoteServerFactory = {
|
|
|
296
297
|
// want request-processors applied to development views.
|
|
297
298
|
this._addSDKInternalHandlers(app);
|
|
298
299
|
this._setupSSRRequestProcessorMiddleware(app);
|
|
299
|
-
this._setForwardedHeaders(app, options);
|
|
300
300
|
this._setupLogging(app);
|
|
301
301
|
this._setupMetricsFlushing(app);
|
|
302
302
|
this._setupHealthcheck(app);
|
|
@@ -371,22 +371,6 @@ const RemoteServerFactory = exports.RemoteServerFactory = {
|
|
|
371
371
|
_addSDKInternalHandlers(app) {
|
|
372
372
|
// This method is used by the dev server, but is not needed here.
|
|
373
373
|
},
|
|
374
|
-
/**
|
|
375
|
-
* Set x-forward-* headers into locals, this is primarily used to facilitate react sdk hook `useOrigin`
|
|
376
|
-
* @private
|
|
377
|
-
*/
|
|
378
|
-
_setForwardedHeaders(app, options) {
|
|
379
|
-
app.use((req, res, next) => {
|
|
380
|
-
var _req$headers, _req$headers2;
|
|
381
|
-
const xForwardedHost = (_req$headers = req.headers) === null || _req$headers === void 0 ? void 0 : _req$headers['x-forwarded-host'];
|
|
382
|
-
const xForwardedProto = (_req$headers2 = req.headers) === null || _req$headers2 === void 0 ? void 0 : _req$headers2['x-forwarded-proto'];
|
|
383
|
-
if (xForwardedHost) {
|
|
384
|
-
// prettier-ignore
|
|
385
|
-
res.locals.xForwardedOrigin = `${xForwardedProto || options.protocol}://${xForwardedHost}`;
|
|
386
|
-
}
|
|
387
|
-
next();
|
|
388
|
-
});
|
|
389
|
-
},
|
|
390
374
|
/**
|
|
391
375
|
* @private
|
|
392
376
|
*/
|
|
@@ -600,7 +584,7 @@ const RemoteServerFactory = exports.RemoteServerFactory = {
|
|
|
600
584
|
[_ssrNamespacePaths.slasPrivateProxyPath]: ''
|
|
601
585
|
},
|
|
602
586
|
onProxyReq: (proxyRequest, incomingRequest) => {
|
|
603
|
-
var _incomingRequest$path
|
|
587
|
+
var _incomingRequest$path;
|
|
604
588
|
(0, _configureProxy.applyProxyRequestHeaders)({
|
|
605
589
|
proxyRequest,
|
|
606
590
|
incomingRequest,
|
|
@@ -619,11 +603,6 @@ const RemoteServerFactory = exports.RemoteServerFactory = {
|
|
|
619
603
|
if ((_incomingRequest$path = incomingRequest.path) !== null && _incomingRequest$path !== void 0 && _incomingRequest$path.match(options.applySLASPrivateClientToEndpoints)) {
|
|
620
604
|
proxyRequest.setHeader('Authorization', `Basic ${encodedSlasCredentials}`);
|
|
621
605
|
}
|
|
622
|
-
|
|
623
|
-
// /oauth2/trusted-agent/token endpoint requires a different auth header
|
|
624
|
-
if ((_incomingRequest$path2 = incomingRequest.path) !== null && _incomingRequest$path2 !== void 0 && _incomingRequest$path2.match(/\/oauth2\/trusted-agent\/token/)) {
|
|
625
|
-
proxyRequest.setHeader('_sfdc_client_auth', encodedSlasCredentials);
|
|
626
|
-
}
|
|
627
606
|
},
|
|
628
607
|
onProxyRes: (proxyRes, req) => {
|
|
629
608
|
if (proxyRes.statusCode && proxyRes.statusCode >= 400) {
|
|
@@ -663,9 +642,10 @@ const RemoteServerFactory = exports.RemoteServerFactory = {
|
|
|
663
642
|
// to add in their projects, like in any regular Express app.
|
|
664
643
|
app.use(ssrMiddleware);
|
|
665
644
|
app.use(errorHandlerMiddleware);
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
645
|
+
|
|
646
|
+
// NOTE: Think about changing the name of this function to `applyApplicationExtensions`. First look into
|
|
647
|
+
// what a common pattern is for application enhancement.
|
|
648
|
+
(0, _express3.applyApplicationExtensions)(app);
|
|
669
649
|
applyPatches(options);
|
|
670
650
|
},
|
|
671
651
|
/**
|
|
@@ -680,7 +660,7 @@ const RemoteServerFactory = exports.RemoteServerFactory = {
|
|
|
680
660
|
// A string like '8.10.0'
|
|
681
661
|
requiredNode)) {
|
|
682
662
|
/* istanbul ignore next */
|
|
683
|
-
|
|
663
|
+
_loggerInstance.default.warn(`Warning: You are using Node ${process.versions.node}. ` + `Your app may not work as expected when deployed to Managed ` + `Runtime servers which are compatible with Node ${requiredNode}`);
|
|
684
664
|
}
|
|
685
665
|
|
|
686
666
|
// Verify the remote environment
|
|
@@ -714,7 +694,7 @@ const RemoteServerFactory = exports.RemoteServerFactory = {
|
|
|
714
694
|
throw new Error('The sslFilePath option passed to the SSR server constructor ' + 'must be a path to an SSL certificate file ' + 'in PEM format, whose name ends with ".pem". ' + 'See the "cert" and "key" options on ' + 'https://nodejs.org/api/tls.html#tls_tls_createsecurecontext_options');
|
|
715
695
|
}
|
|
716
696
|
if (!options.strictSSL) {
|
|
717
|
-
|
|
697
|
+
_loggerInstance.default.warn('The SSR Server has _strictSSL turned off for https requests');
|
|
718
698
|
}
|
|
719
699
|
},
|
|
720
700
|
/**
|
|
@@ -824,29 +804,13 @@ const RemoteServerFactory = exports.RemoteServerFactory = {
|
|
|
824
804
|
* @param app {Express} - an Express App
|
|
825
805
|
* @private
|
|
826
806
|
*/
|
|
827
|
-
_createHandler(app
|
|
807
|
+
_createHandler(app) {
|
|
828
808
|
// This flag is initially false, and is set true on the first request
|
|
829
809
|
// handled by a Lambda. If it is true on entry to the handler function,
|
|
830
810
|
// it indicates that the Lambda container has been reused.
|
|
831
811
|
let lambdaContainerReused = false;
|
|
832
812
|
const server = _awsServerlessExpress.default.createServer(app, null, binaryMimeTypes);
|
|
833
813
|
const handler = (event, context, callback) => {
|
|
834
|
-
// encode non ASCII request headers
|
|
835
|
-
if (options !== null && options !== void 0 && options.encodeNonAsciiHttpHeaders) {
|
|
836
|
-
Object.keys(event.headers).forEach(key => {
|
|
837
|
-
if (!isASCII(event.headers[key])) {
|
|
838
|
-
event.headers[key] = encodeURIComponent(event.headers[key]);
|
|
839
|
-
// x-encoded-headers keeps track of which headers have been modified and encoded
|
|
840
|
-
if (event.headers[_constants.X_ENCODED_HEADERS]) {
|
|
841
|
-
// append header key
|
|
842
|
-
event.headers[_constants.X_ENCODED_HEADERS] = `${event.headers[_constants.X_ENCODED_HEADERS]},${key}`;
|
|
843
|
-
} else {
|
|
844
|
-
event.headers[_constants.X_ENCODED_HEADERS] = key;
|
|
845
|
-
}
|
|
846
|
-
}
|
|
847
|
-
});
|
|
848
|
-
}
|
|
849
|
-
|
|
850
814
|
// We don't want to wait for an empty event loop once the response
|
|
851
815
|
// has been sent. Setting this to false will "send the response
|
|
852
816
|
// right away when the callback executes", but any pending events
|
|
@@ -948,8 +912,8 @@ const RemoteServerFactory = exports.RemoteServerFactory = {
|
|
|
948
912
|
createHandler(options, customizeApp) {
|
|
949
913
|
process.on('unhandledRejection', _ssrServer.catchAndLog);
|
|
950
914
|
const app = this._createApp(options);
|
|
951
|
-
customizeApp(app
|
|
952
|
-
return this._createHandler(app
|
|
915
|
+
customizeApp(app);
|
|
916
|
+
return this._createHandler(app);
|
|
953
917
|
},
|
|
954
918
|
/**
|
|
955
919
|
* @private
|
|
@@ -1032,37 +996,6 @@ const errorHandlerMiddleware = (err, req, res, next) => {
|
|
|
1032
996
|
res.sendStatus(500);
|
|
1033
997
|
};
|
|
1034
998
|
|
|
1035
|
-
/**
|
|
1036
|
-
* Helper function that checks if a string is composed of ASCII characters
|
|
1037
|
-
* We only check printable ASCII characters and not special ASCII characters
|
|
1038
|
-
* such as NULL
|
|
1039
|
-
*
|
|
1040
|
-
* @private
|
|
1041
|
-
*/
|
|
1042
|
-
const isASCII = str => {
|
|
1043
|
-
return /^[\x20-\x7E]*$/.test(str);
|
|
1044
|
-
};
|
|
1045
|
-
|
|
1046
|
-
/**
|
|
1047
|
-
* Express Middleware applied to responses that encode any non ASCII headers
|
|
1048
|
-
*
|
|
1049
|
-
* @private
|
|
1050
|
-
*/
|
|
1051
|
-
const encodeNonAsciiMiddleware = (req, res, next) => {
|
|
1052
|
-
const originalSetHeader = res.setHeader;
|
|
1053
|
-
res.setHeader = function (key, value) {
|
|
1054
|
-
if (!isASCII(value)) {
|
|
1055
|
-
originalSetHeader.call(this, key, encodeURIComponent(value));
|
|
1056
|
-
let encodedHeaders = res.getHeader(_constants.X_ENCODED_HEADERS);
|
|
1057
|
-
encodedHeaders = encodedHeaders ? `${encodedHeaders},${key}` : key;
|
|
1058
|
-
originalSetHeader.call(this, _constants.X_ENCODED_HEADERS, encodedHeaders);
|
|
1059
|
-
} else {
|
|
1060
|
-
originalSetHeader.call(this, key, value);
|
|
1061
|
-
}
|
|
1062
|
-
};
|
|
1063
|
-
next();
|
|
1064
|
-
};
|
|
1065
|
-
|
|
1066
999
|
/**
|
|
1067
1000
|
* Wrap the function fn in such a way that it will be called at most once. Subsequent
|
|
1068
1001
|
* calls will always return the same value.
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
+
var _supertest = _interopRequireDefault(require("supertest"));
|
|
3
4
|
var _buildRemoteServer = require("./build-remote-server");
|
|
4
|
-
var _constants = require("./constants");
|
|
5
|
-
var _awsServerlessExpress = _interopRequireDefault(require("aws-serverless-express"));
|
|
6
5
|
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
7
6
|
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
8
7
|
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
@@ -14,12 +13,39 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
|
|
|
14
13
|
* SPDX-License-Identifier: BSD-3-Clause
|
|
15
14
|
* For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause
|
|
16
15
|
*/
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
16
|
+
const opts = (overrides = {}) => {
|
|
17
|
+
const defaults = {
|
|
18
|
+
buildDir: './src/ssr/server/test_fixtures',
|
|
19
|
+
mobify: {
|
|
20
|
+
app: {
|
|
21
|
+
extensions: ['test-extension', 'another-extension', 'extension-with-bad-setup-server', 'extension-with-setup-server-no-default-export', 'extension-without-setup-server']
|
|
22
|
+
},
|
|
23
|
+
ssrEnabled: true,
|
|
24
|
+
ssrOnly: ['main.js.map', 'ssr.js', 'ssr.js.map'],
|
|
25
|
+
ssrShared: ['main.js', 'ssr-loader.js', 'worker.js'],
|
|
26
|
+
ssrParameters: {
|
|
27
|
+
proxyConfigs: [{
|
|
28
|
+
protocol: 'https',
|
|
29
|
+
host: 'test.proxy.com',
|
|
30
|
+
path: 'base'
|
|
31
|
+
}, {
|
|
32
|
+
protocol: 'https',
|
|
33
|
+
// This is intentionally an unreachable host
|
|
34
|
+
host: '0.0.0.0',
|
|
35
|
+
path: 'base2'
|
|
36
|
+
}, {
|
|
37
|
+
protocol: 'https',
|
|
38
|
+
host: 'test.proxy.com',
|
|
39
|
+
path: 'base3',
|
|
40
|
+
caching: true
|
|
41
|
+
}]
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
sslFilePath: './src/ssr/server/test_fixtures/localhost.pem',
|
|
45
|
+
quiet: true
|
|
21
46
|
};
|
|
22
|
-
});
|
|
47
|
+
return _objectSpread(_objectSpread({}, defaults), overrides);
|
|
48
|
+
};
|
|
23
49
|
describe('the once function', () => {
|
|
24
50
|
test('should prevent a function being called more than once', () => {
|
|
25
51
|
const fn = jest.fn(() => ({
|
|
@@ -46,69 +72,110 @@ describe('remote server factory test coverage', () => {
|
|
|
46
72
|
expect(endpoint).toBeDefined();
|
|
47
73
|
});
|
|
48
74
|
});
|
|
49
|
-
describe('encodeNonAsciiHttpHeaders flag in options to createHandler', () => {
|
|
50
|
-
test('encodes request headers', () => {
|
|
51
|
-
const mockApp = {
|
|
52
|
-
sendMetric: jest.fn()
|
|
53
|
-
};
|
|
54
|
-
const mockOptions = {
|
|
55
|
-
encodeNonAsciiHttpHeaders: true
|
|
56
|
-
};
|
|
57
|
-
const originalHeaders = {
|
|
58
|
-
'x-non-ascii-header-one': 'テスト',
|
|
59
|
-
'x-non-ascii-header-two': '测试',
|
|
60
|
-
'x-regular-header': 'ascii-str'
|
|
61
|
-
};
|
|
62
|
-
const event = {
|
|
63
|
-
headers: _objectSpread({}, originalHeaders)
|
|
64
|
-
};
|
|
65
|
-
const expectedHeaders = {
|
|
66
|
-
'x-non-ascii-header-one': '%E3%83%86%E3%82%B9%E3%83%88',
|
|
67
|
-
'x-non-ascii-header-two': '%E6%B5%8B%E8%AF%95',
|
|
68
|
-
'x-encoded-headers': 'x-non-ascii-header-one,x-non-ascii-header-two',
|
|
69
|
-
'x-regular-header': 'ascii-str'
|
|
70
|
-
};
|
|
71
|
-
const {
|
|
72
|
-
handler
|
|
73
|
-
} = _buildRemoteServer.RemoteServerFactory._createHandler(mockApp, mockOptions);
|
|
74
|
-
expect(event.headers).toEqual(originalHeaders);
|
|
75
|
-
handler(event, {}, {});
|
|
76
|
-
expect(event.headers).toEqual(expectedHeaders);
|
|
77
|
-
expect(decodeURIComponent(event.headers['x-non-ascii-header-one'])).toEqual(originalHeaders['x-non-ascii-header-one']);
|
|
78
|
-
});
|
|
79
|
-
test('encodes response headers', () => {
|
|
80
|
-
const mockApp = {
|
|
81
|
-
use: jest.fn()
|
|
82
|
-
};
|
|
83
|
-
const mockOptions = {
|
|
84
|
-
encodeNonAsciiHttpHeaders: true
|
|
85
|
-
};
|
|
86
|
-
const res = {
|
|
87
|
-
headers: {},
|
|
88
|
-
setHeader: (key, value) => {
|
|
89
|
-
res.headers[key] = value;
|
|
90
|
-
},
|
|
91
|
-
getHeader: key => {
|
|
92
|
-
return res.headers[key];
|
|
93
|
-
}
|
|
94
|
-
};
|
|
95
|
-
const nonASCIIheader = 'x-non-ascii-header';
|
|
96
|
-
const nonASCIIstr = 'テスト';
|
|
97
|
-
const expectedEncoding = '%E3%83%86%E3%82%B9%E3%83%88';
|
|
98
|
-
const regularHeaderKey = 'x-regular-header';
|
|
99
|
-
const regularHeaderValue = 'ascii-str';
|
|
100
|
-
_buildRemoteServer.RemoteServerFactory._setupCommonMiddleware(mockApp, mockOptions);
|
|
101
|
-
const encodeNonAsciiMiddleware = mockApp.use.mock.calls[3][0];
|
|
102
|
-
res.setHeader(nonASCIIheader, nonASCIIstr);
|
|
103
|
-
expect(res.getHeader(nonASCIIheader)).toEqual(nonASCIIstr);
|
|
104
|
-
encodeNonAsciiMiddleware({}, res, () => {});
|
|
105
|
-
res.setHeader(nonASCIIheader, nonASCIIstr);
|
|
106
|
-
expect(res.getHeader(nonASCIIheader)).toEqual(expectedEncoding);
|
|
107
|
-
expect(decodeURI(expectedEncoding)).toEqual(nonASCIIstr);
|
|
108
|
-
expect(res.getHeader(_constants.X_ENCODED_HEADERS)).toEqual(nonASCIIheader);
|
|
109
75
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
76
|
+
// describe('extensions', () => {
|
|
77
|
+
// beforeEach(() => {
|
|
78
|
+
// jest.clearAllMocks()
|
|
79
|
+
// })
|
|
80
|
+
|
|
81
|
+
// test('can register extensions properly via _setupExtensions', () => {
|
|
82
|
+
// const app = RemoteServerFactory._createApp(opts())
|
|
83
|
+
// expect(app.__extensions).toBeDefined()
|
|
84
|
+
// return request(app)
|
|
85
|
+
// .get('/test-extension')
|
|
86
|
+
// .expect(200)
|
|
87
|
+
// .then((res) => {
|
|
88
|
+
// expect(res.text).toBe('test')
|
|
89
|
+
// })
|
|
90
|
+
// })
|
|
91
|
+
// test('can register multiple extensions', () => {
|
|
92
|
+
// const app = RemoteServerFactory._createApp(opts())
|
|
93
|
+
// expect(app.__extensions).toBeDefined()
|
|
94
|
+
// return request(app)
|
|
95
|
+
// .get('/another-extension')
|
|
96
|
+
// .expect(200)
|
|
97
|
+
// .then((res) => {
|
|
98
|
+
// expect(res.text).toBe('test')
|
|
99
|
+
// })
|
|
100
|
+
// })
|
|
101
|
+
|
|
102
|
+
// test('mixed types in extensions configuration', async () => {
|
|
103
|
+
// const options = opts({
|
|
104
|
+
// mobify: {app: {extensions: [['test-extension', {path: '/foo'}], 'another-extension']}}
|
|
105
|
+
// })
|
|
106
|
+
// const app = RemoteServerFactory._createApp(options)
|
|
107
|
+
// expect(app.__extensions).toBeDefined()
|
|
108
|
+
|
|
109
|
+
// await request(app)
|
|
110
|
+
// .get('/test-extension')
|
|
111
|
+
// .expect(200)
|
|
112
|
+
// .then((res) => {
|
|
113
|
+
// expect(res.text).toBe('test')
|
|
114
|
+
// })
|
|
115
|
+
|
|
116
|
+
// await request(app)
|
|
117
|
+
// .get('/another-extension')
|
|
118
|
+
// .expect(200)
|
|
119
|
+
// .then((res) => {
|
|
120
|
+
// expect(res.text).toBe('test')
|
|
121
|
+
// })
|
|
122
|
+
|
|
123
|
+
// await request(app)
|
|
124
|
+
// .get('/test-extension-config')
|
|
125
|
+
// .expect(200)
|
|
126
|
+
// .then((res) => {
|
|
127
|
+
// // The config should have {enabled: true} by default
|
|
128
|
+
// expect(res.text).toBe('{"enabled":true,"path":"/foo"}')
|
|
129
|
+
// })
|
|
130
|
+
// })
|
|
131
|
+
|
|
132
|
+
// test('disabled extension will not run', () => {
|
|
133
|
+
// const options = opts({mobify: {app: {extensions: [['test-extension', {enabled: false}]]}}})
|
|
134
|
+
// const app = RemoteServerFactory._createApp(options)
|
|
135
|
+
// expect(app.__extensions).toBeDefined()
|
|
136
|
+
// return request(app).get('/test-extension').expect(404)
|
|
137
|
+
// })
|
|
138
|
+
|
|
139
|
+
// test('logs warning when setup-server.js file is not found', () => {
|
|
140
|
+
// const warn = jest.spyOn(console, 'warn').mockImplementation(() => {})
|
|
141
|
+
// const app = RemoteServerFactory._createApp(
|
|
142
|
+
// opts({
|
|
143
|
+
// mobify: {app: {extensions: ['extension-without-setup-server']}}
|
|
144
|
+
// })
|
|
145
|
+
// )
|
|
146
|
+
// expect(warn.mock.calls).toEqual([
|
|
147
|
+
// [
|
|
148
|
+
// 'pwa-kit-runtime WARN No setup-server.js file found for extension-without-setup-server. Skipping.'
|
|
149
|
+
// ]
|
|
150
|
+
// ])
|
|
151
|
+
// })
|
|
152
|
+
|
|
153
|
+
// test('logs error when there is an error loading extension', () => {
|
|
154
|
+
// const errorlog = jest.spyOn(console, 'error').mockImplementation(() => {})
|
|
155
|
+
// const app = RemoteServerFactory._createApp(
|
|
156
|
+
// opts({
|
|
157
|
+
// mobify: {app: {extensions: ['extension-with-bad-setup-server']}}
|
|
158
|
+
// })
|
|
159
|
+
// )
|
|
160
|
+
// expect(errorlog.mock.calls).toEqual([
|
|
161
|
+
// [
|
|
162
|
+
// 'pwa-kit-runtime.RemoteServerFactory._setupExtensions ERROR Error setting extension extension-with-bad-setup-server: {"error":{}}'
|
|
163
|
+
// ]
|
|
164
|
+
// ])
|
|
165
|
+
// })
|
|
166
|
+
|
|
167
|
+
// test('logs error when instantiating extension throws an error', () => {
|
|
168
|
+
// const errorlog = jest.spyOn(console, 'error').mockImplementation(() => {})
|
|
169
|
+
// const app = RemoteServerFactory._createApp(
|
|
170
|
+
// opts({
|
|
171
|
+
// mobify: {app: {extensions: ['extension-with-setup-server-no-default-export']}}
|
|
172
|
+
// })
|
|
173
|
+
// )
|
|
174
|
+
|
|
175
|
+
// expect(errorlog.mock.calls).toEqual([
|
|
176
|
+
// [
|
|
177
|
+
// `pwa-kit-runtime.RemoteServerFactory._setupExtensions ERROR 'extension-with-setup-server-no-default-export' is not a valid PWA-Kit Application Extension, please ensure you are exporting a class of type 'ApplicationExtension'. Skipping.`
|
|
178
|
+
// ]
|
|
179
|
+
// ]).toF
|
|
180
|
+
// })
|
|
181
|
+
// })
|