@salesforce/pwa-kit-runtime 3.9.0-nightly-20241209080219 → 4.0.0-extensibility-preview.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.
Files changed (82) hide show
  1. package/package.json +9 -7
  2. package/ssr/server/build-remote-server.d.ts +211 -0
  3. package/ssr/server/build-remote-server.d.ts.map +1 -0
  4. package/ssr/server/build-remote-server.js +11 -78
  5. package/ssr/server/build-remote-server.test.js +139 -72
  6. package/ssr/server/constants.d.ts +18 -0
  7. package/ssr/server/constants.d.ts.map +1 -0
  8. package/ssr/server/constants.js +1 -2
  9. package/ssr/server/express.d.ts +17 -0
  10. package/ssr/server/express.d.ts.map +1 -0
  11. package/ssr/server/express.test.js +7 -91
  12. package/ssr/server/test_fixtures/extensions/another-extension/setup-server.d.ts +5 -0
  13. package/ssr/server/test_fixtures/extensions/another-extension/setup-server.d.ts.map +1 -0
  14. package/ssr/server/test_fixtures/extensions/another-extension/setup-server.js +19 -0
  15. package/ssr/server/test_fixtures/extensions/extension-with-bad-setup-server/setup-server.d.ts +5 -0
  16. package/ssr/server/test_fixtures/extensions/extension-with-bad-setup-server/setup-server.d.ts.map +1 -0
  17. package/ssr/server/test_fixtures/extensions/extension-with-bad-setup-server/setup-server.js +16 -0
  18. package/ssr/server/test_fixtures/extensions/extension-with-setup-server-no-default-export/setup-server.d.ts +2 -0
  19. package/ssr/server/test_fixtures/extensions/extension-with-setup-server-no-default-export/setup-server.d.ts.map +1 -0
  20. package/ssr/server/test_fixtures/extensions/extension-with-setup-server-no-default-export/setup-server.js +17 -0
  21. package/ssr/server/test_fixtures/extensions/extension-without-setup-server/random-file.d.ts +1 -0
  22. package/ssr/server/test_fixtures/extensions/extension-without-setup-server/random-file.d.ts.map +1 -0
  23. package/ssr/server/test_fixtures/extensions/extension-without-setup-server/random-file.js +7 -0
  24. package/ssr/server/test_fixtures/extensions/test-extension/setup-server.d.ts +5 -0
  25. package/ssr/server/test_fixtures/extensions/test-extension/setup-server.d.ts.map +1 -0
  26. package/ssr/server/test_fixtures/extensions/test-extension/setup-server.js +28 -0
  27. package/ssr/server/test_fixtures/main.d.ts +1 -0
  28. package/ssr/server/test_fixtures/main.d.ts.map +1 -0
  29. package/ssr/server/test_fixtures/server-renderer.d.ts +6 -0
  30. package/ssr/server/test_fixtures/server-renderer.d.ts.map +1 -0
  31. package/ssr/server/test_fixtures/worker.d.ts +1 -0
  32. package/ssr/server/test_fixtures/worker.d.ts.map +1 -0
  33. package/utils/logger-factory.d.ts +58 -0
  34. package/utils/logger-factory.d.ts.map +1 -0
  35. package/utils/logger-instance.d.ts +3 -0
  36. package/utils/logger-instance.d.ts.map +1 -0
  37. package/utils/middleware/index.d.ts +2 -0
  38. package/utils/middleware/index.d.ts.map +1 -0
  39. package/utils/middleware/security.d.ts +2 -0
  40. package/utils/middleware/security.d.ts.map +1 -0
  41. package/utils/morgan-stream.d.ts +11 -0
  42. package/utils/morgan-stream.d.ts.map +1 -0
  43. package/utils/ssr-cache.d.ts +112 -0
  44. package/utils/ssr-cache.d.ts.map +1 -0
  45. package/utils/ssr-config.client.d.ts +2 -0
  46. package/utils/ssr-config.client.d.ts.map +1 -0
  47. package/utils/ssr-config.client.test.js +4 -0
  48. package/utils/ssr-config.d.ts +3 -0
  49. package/utils/ssr-config.d.ts.map +1 -0
  50. package/utils/ssr-config.server.d.ts +2 -0
  51. package/utils/ssr-config.server.d.ts.map +1 -0
  52. package/utils/ssr-namespace-paths.d.ts +7 -0
  53. package/utils/ssr-namespace-paths.d.ts.map +1 -0
  54. package/utils/ssr-proxying.d.ts +173 -0
  55. package/utils/ssr-proxying.d.ts.map +1 -0
  56. package/utils/ssr-request-processing.d.ts +90 -0
  57. package/utils/ssr-request-processing.d.ts.map +1 -0
  58. package/utils/ssr-server/cached-response.d.ts +62 -0
  59. package/utils/ssr-server/cached-response.d.ts.map +1 -0
  60. package/utils/ssr-server/configure-proxy.d.ts +5 -0
  61. package/utils/ssr-server/configure-proxy.d.ts.map +1 -0
  62. package/utils/ssr-server/metrics-sender.d.ts +83 -0
  63. package/utils/ssr-server/metrics-sender.d.ts.map +1 -0
  64. package/utils/ssr-server/metrics-sender.js +1 -1
  65. package/utils/ssr-server/outgoing-request-hook.d.ts +2 -0
  66. package/utils/ssr-server/outgoing-request-hook.d.ts.map +1 -0
  67. package/utils/ssr-server/parse-end-parameters.d.ts +2 -0
  68. package/utils/ssr-server/parse-end-parameters.d.ts.map +1 -0
  69. package/utils/ssr-server/process-express-response.d.ts +3 -0
  70. package/utils/ssr-server/process-express-response.d.ts.map +1 -0
  71. package/utils/ssr-server/process-lambda-response.d.ts +2 -0
  72. package/utils/ssr-server/process-lambda-response.d.ts.map +1 -0
  73. package/utils/ssr-server/update-global-agent-options.d.ts +3 -0
  74. package/utils/ssr-server/update-global-agent-options.d.ts.map +1 -0
  75. package/utils/ssr-server/utils.d.ts +13 -0
  76. package/utils/ssr-server/utils.d.ts.map +1 -0
  77. package/utils/ssr-server/wrap-response-write.d.ts +2 -0
  78. package/utils/ssr-server/wrap-response-write.d.ts.map +1 -0
  79. package/utils/ssr-server.d.ts +11 -0
  80. package/utils/ssr-server.d.ts.map +1 -0
  81. package/utils/ssr-shared.d.ts +42 -0
  82. 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.9.0-nightly-20241209080219",
3
+ "version": "4.0.0-extensibility-preview.1",
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": "3.9.0-nightly-20241209080219",
49
+ "@salesforce/pwa-kit-dev": "4.0.0-extensibility-preview.1",
50
+ "@salesforce/pwa-kit-extension-sdk": "4.0.0-extensibility-preview.1",
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": "3.9.0-nightly-20241209080219",
55
+ "internal-lib-build": "4.0.0-extensibility-preview.1",
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": "3.9.0-nightly-20241209080219"
63
+ "@salesforce/pwa-kit-dev": "4.0.0-extensibility-preview.1"
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": "776e93dade65ec265428830940734a7714687fbf"
77
+ "gitHead": "5728f89cb53ab1b0c89418578f3e90c755efb0f8"
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, _incomingRequest$path2;
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
- if (options !== null && options !== void 0 && options.encodeNonAsciiHttpHeaders) {
667
- app.use(encodeNonAsciiMiddleware);
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
- console.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}`);
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
- console.warn('The SSR Server has _strictSSL turned off for https requests');
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, options) {
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, options);
952
- return this._createHandler(app, options);
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
- jest.mock('aws-serverless-express', () => {
18
- return {
19
- createServer: jest.fn(),
20
- proxy: jest.fn()
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
- // confirm ASCII headers are not modified
111
- res.setHeader(regularHeaderKey, regularHeaderValue);
112
- expect(res.getHeader(regularHeaderKey)).toEqual(regularHeaderValue);
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
+ // })