@salesforce/pwa-kit-runtime 3.0.0-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.
Files changed (45) hide show
  1. package/LICENSE +14 -0
  2. package/README.md +24 -0
  3. package/package.json +76 -0
  4. package/scripts/version.js +22 -0
  5. package/ssr/server/build-remote-server.js +1025 -0
  6. package/ssr/server/build-remote-server.test.js +24 -0
  7. package/ssr/server/constants.js +37 -0
  8. package/ssr/server/express.js +460 -0
  9. package/ssr/server/express.lambda.test.js +383 -0
  10. package/ssr/server/express.test.js +847 -0
  11. package/ssr/server/test_fixtures/favicon.ico +0 -0
  12. package/ssr/server/test_fixtures/loadable-stats.json +1 -0
  13. package/ssr/server/test_fixtures/localhost.pem +45 -0
  14. package/ssr/server/test_fixtures/main.js +7 -0
  15. package/ssr/server/test_fixtures/mobify.png +0 -0
  16. package/ssr/server/test_fixtures/server-renderer.js +12 -0
  17. package/ssr/server/test_fixtures/worker.js +7 -0
  18. package/ssr/server/test_fixtures/worker.js.map +1 -0
  19. package/utils/morgan-stream.js +26 -0
  20. package/utils/ssr-cache.js +177 -0
  21. package/utils/ssr-cache.test.js +64 -0
  22. package/utils/ssr-config.client.js +23 -0
  23. package/utils/ssr-config.client.test.js +25 -0
  24. package/utils/ssr-config.js +20 -0
  25. package/utils/ssr-config.server.js +88 -0
  26. package/utils/ssr-config.server.test.js +30 -0
  27. package/utils/ssr-proxying.js +804 -0
  28. package/utils/ssr-proxying.test.js +591 -0
  29. package/utils/ssr-request-processing.js +164 -0
  30. package/utils/ssr-request-processing.test.js +95 -0
  31. package/utils/ssr-server/cached-response.js +116 -0
  32. package/utils/ssr-server/configure-proxy.js +241 -0
  33. package/utils/ssr-server/metrics-sender.js +191 -0
  34. package/utils/ssr-server/outgoing-request-hook.js +139 -0
  35. package/utils/ssr-server/parse-end-parameters.js +38 -0
  36. package/utils/ssr-server/process-express-response.js +56 -0
  37. package/utils/ssr-server/process-lambda-response.js +36 -0
  38. package/utils/ssr-server/update-global-agent-options.js +42 -0
  39. package/utils/ssr-server/update-global-agent-options.test.js +28 -0
  40. package/utils/ssr-server/utils.js +119 -0
  41. package/utils/ssr-server/utils.test.js +64 -0
  42. package/utils/ssr-server/wrap-response-write.js +40 -0
  43. package/utils/ssr-server.js +115 -0
  44. package/utils/ssr-server.test.js +835 -0
  45. package/utils/ssr-shared.js +185 -0
@@ -0,0 +1,45 @@
1
+ -----BEGIN RSA PRIVATE KEY-----
2
+ MIIEowIBAAKCAQEA2jfc6QnD73JTV4HpxyC6IMhJfOGnPPx//ZZrcUEPEYe1M+cC
3
+ K471lvqWtl8TMJDcKwIlLPzC84JeoobUYHPjhfrbO4pt/8T4eMRGVn+L4UmEyIzG
4
+ /c9tXc9U9mtGEAiIeRplgcfwA0RiTG/gQ817qC8Oc2PLHzBupuGuuOBs90YrHGfI
5
+ Q9gvJ0RrEDym7u3NW++NKT4AzFk6NRL+CFlo4HG0Xb2y+oNmwDRU7L26TVyXRgn1
6
+ QiCIHJw5D6CB4jjXzZDD8Uj4N7hkfM8IjNv4Qs7gaRjS0yNLnqB2f0XEsQG8vn51
7
+ h2EtCPT36msgNz0RAYzDBl7c1aD5fAWyXDfPHQIDAQABAoIBABtWODRxZrxOZCZo
8
+ PfMWJHsK3Dnqwtqe/yGzgE41yj918rtHyzvNsvJw/gRmsK661voEUMfr+jgrMtPF
9
+ dEGJAw27uU8iLlmGQWJPpEgdvlZAsYO2Lw+Itrizyn78PVCw4Pfa2LCDbYvbOz08
10
+ Hqofycft7S+DZuTHWnVJfGvooX3wbx1eloLIeuvIk9uFLqnKb/CO64vey4OIR3Pk
11
+ kIxhSsjOQFjKWaiUpUZHR0iDMAjON4Y8k4fsiMOUC2KRu5G4hzmi8QQOyO4wvtjP
12
+ 48sL5K1UYf7G+ovEvOF3mioXNmRu0lYlDzv60oDH0Jea3ys5Vi90pjTghK6D7AuB
13
+ JV0tv3kCgYEA9kS1ziyZicGjp85pPufClIk45IvGm2dMbiEbcZkEAW+F7w0tt7Ik
14
+ wJSUjNXc/zvlhyg5tS4d3PWQ2JPS1au7h7eclgA8odg0Tg8CfMTC/8ALd9aQCLiE
15
+ 7giebyK54V9nv/DcvFwx7pOHGqPV6Y2V/k7OXOIgkRSdB8k+oNdqKNsCgYEA4tdk
16
+ hp07WZ4k+8FDZ4+lph1F1zzq+U86ulyOk/OMTz3ARJCmWxsFuVlxlZT2CrS5OEOa
17
+ MFjba7nSWNsvFFBOAx/tPKDLEy2CztmaA11Xh4iHr5FRroQoupARgZo+KywFajha
18
+ hi+MVjs8Dk+kZ+0tDBAjMCZnSDq6pnGyJlZ+zWcCgYBYG1cML2qzHWNGyxNeXR6B
19
+ c+K16cghm0B9+jxOVRdYyCSb1RQxL3v0pnPLO0x4yF4jD+ItjxVCE11CDwkURv+t
20
+ 26QbCnSm1qpH7xjNuLunMncn5czcQd/VJaJBUqQ8HJ0Kz8q5XSbEG2XvwwPqLiym
21
+ sl0kYAaUwVI5EeflNYyWlwKBgQCovnIZcX1k/S+l1+68ay9ekwgRRU/Ghhm56IBn
22
+ rxUBHX6ZgsE9pKxtZQwJqfYdoLLoF+HrdS5ExMalMueixNpDmMxx/WsTqRdVqKnZ
23
+ NuaV/ApzoDaTC90Aa4uaTZNRqj2c9q7ggx5yRz41pyk15klMX/TNLMRIBugySQGt
24
+ Y0qQoQKBgGOBAsRkJ5crQ2qff6K2oQvd99RPPX4EUKh/+oB3jrkSWR43DedtTC2I
25
+ dDPan/Z44RGErNFOwog4QWuC5h24D297ibW9Ri7lGzKlYt4wpJ2efXwW6YaMMrUt
26
+ TcvYTKeIYBLkQoNOvzNoClfylZ9Q+zwabH8bXuqzhD3YMYmvalGE
27
+ -----END RSA PRIVATE KEY-----
28
+ -----BEGIN CERTIFICATE-----
29
+ MIIC6TCCAdGgAwIBAgIJAIvnbrW0ATuCMA0GCSqGSIb3DQEBCwUAMCQxIjAgBgNV
30
+ BAMMGU1vYmlmeSBEZXZlbG9wbWVudCBTZXJ2ZXIwHhcNMTcwMzIxMDU1NTA4WhcN
31
+ MjcwMzE5MDU1NTA4WjAkMSIwIAYDVQQDDBlNb2JpZnkgRGV2ZWxvcG1lbnQgU2Vy
32
+ dmVyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2jfc6QnD73JTV4Hp
33
+ xyC6IMhJfOGnPPx//ZZrcUEPEYe1M+cCK471lvqWtl8TMJDcKwIlLPzC84JeoobU
34
+ YHPjhfrbO4pt/8T4eMRGVn+L4UmEyIzG/c9tXc9U9mtGEAiIeRplgcfwA0RiTG/g
35
+ Q817qC8Oc2PLHzBupuGuuOBs90YrHGfIQ9gvJ0RrEDym7u3NW++NKT4AzFk6NRL+
36
+ CFlo4HG0Xb2y+oNmwDRU7L26TVyXRgn1QiCIHJw5D6CB4jjXzZDD8Uj4N7hkfM8I
37
+ jNv4Qs7gaRjS0yNLnqB2f0XEsQG8vn51h2EtCPT36msgNz0RAYzDBl7c1aD5fAWy
38
+ XDfPHQIDAQABox4wHDAaBgNVHREEEzARgglsb2NhbGhvc3SHBH8AAAEwDQYJKoZI
39
+ hvcNAQELBQADggEBANnvxEsVQfgpo8Q6OCzts13elskuc/PGhiBAJhyPOq7Zrj63
40
+ +fzSYPac5u1B+MnNlWOT7lXjRywSK61H7zn4eGnE/cp6hDC6bL71In2BVMrzc9sX
41
+ Op3aVYOYYjOHuQxQccIfO970J8iw7Eq6BnJS4vfbxhf0a2bV3+Cv+HOjJPLHNS+O
42
+ SzggRD8O7uB6FOf0ni38j7ndvU8Z9ylYgtNOqsB2pGfQMyGjPObbY8NzUSbrHeWG
43
+ NJEdY8aW3q62elexs5y3y1t7epzfrmlrL3p4b/lQewLM5/Fn90qSF3St9baugF0m
44
+ hjHf9mKEV706lXDQvLkWt+sE/GwP2lsDa8czfZY=
45
+ -----END CERTIFICATE-----
@@ -0,0 +1,7 @@
1
+ /*
2
+ * Copyright (c) 2021, salesforce.com, inc.
3
+ * All rights reserved.
4
+ * SPDX-License-Identifier: BSD-3-Clause
5
+ * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause
6
+ */
7
+ // empty main.js
@@ -0,0 +1,12 @@
1
+ /*
2
+ * Copyright (c) 2022, Salesforce, Inc.
3
+ * All rights reserved.
4
+ * SPDX-License-Identifier: BSD-3-Clause
5
+ * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause
6
+ */
7
+
8
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
9
+ exports.default = ({clientStats, serverStats}) => {
10
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
11
+ return (req, res, next) => res.send('OK')
12
+ }
@@ -0,0 +1,7 @@
1
+ /*
2
+ * Copyright (c) 2021, salesforce.com, inc.
3
+ * All rights reserved.
4
+ * SPDX-License-Identifier: BSD-3-Clause
5
+ * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause
6
+ */
7
+ // empty worker.js
@@ -0,0 +1 @@
1
+ {}
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.morganStream = void 0;
7
+ var _stream = require("stream");
8
+ /*
9
+ * Copyright (c) 2022, salesforce.com, inc.
10
+ * All rights reserved.
11
+ * SPDX-License-Identifier: BSD-3-Clause
12
+ * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause
13
+ */
14
+
15
+ /**
16
+ * @private
17
+ * A stream that uses console.log to write log lines
18
+ */
19
+ class ConsoleLogStream extends _stream.Writable {
20
+ write(line) {
21
+ console.log(line);
22
+ }
23
+ }
24
+ // create new stream to be used in morgan stream
25
+ let morganStream = new ConsoleLogStream();
26
+ exports.morganStream = morganStream;
@@ -0,0 +1,177 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.PersistentCache = void 0;
7
+ /*
8
+ * Copyright (c) 2021, salesforce.com, inc.
9
+ * All rights reserved.
10
+ * SPDX-License-Identifier: BSD-3-Clause
11
+ * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause
12
+ */
13
+ /**
14
+ * @module progressive-web-sdk/utils/ssr-cache
15
+ */
16
+
17
+ /**
18
+ * A cache implementation.
19
+ *
20
+ * See the get, put and delete methods for more details.
21
+ */
22
+ class PersistentCache {
23
+ /**
24
+ * Initialize this cache module.
25
+ *
26
+ * Project code should never need to call this. The Express app
27
+ * provides an instance of this class.
28
+ *
29
+ * @param {Object} options - options to create cache
30
+ * @param {Boolean} options.useLocalCache - true to use a local disk cache,
31
+ * false to use a remote (S3) cache. A deployed Express app will use
32
+ * the remote S3 cache. The local development server will use the
33
+ * local disk cache.
34
+ * @param {String} [options.bucket] - for a remote cache, the name of the S3
35
+ * bucket to use.
36
+ * @param {String} [options.prefix] - for a remote cache, a prefix for the
37
+ * cache, within the S3 bucket.
38
+ * @param {String} [options.s3Endpoint] - for a remote cache, the S3 endpoint
39
+ * to use (allows for testing).
40
+ * @param {String} [options.accessKeyId] - for testing, override AWS access key id
41
+ * @param {String} [options.secretAccessKey] - for testing, override AWS
42
+ * secret key
43
+ * @param {Function} [options.sendMetric] - required function which will be
44
+ * called with performance metrics generated by the PersistentCache
45
+ * sendMetric takes a function with signature:
46
+ * (name: String, value: Number, unit: String,
47
+ * dimensions: Object) => undefined
48
+ */
49
+ constructor() {
50
+ this._cacheDeletePromise = Promise.resolve();
51
+ }
52
+
53
+ /**
54
+ * Provided for testing purposes. Calling close() will
55
+ * clean up any locally cached data.
56
+ * @private
57
+ */
58
+ close() {
59
+ // Doesn't do anything!
60
+ }
61
+
62
+ /**
63
+ * Return an object that represents an entry not found in the cache
64
+ * @param key
65
+ * @param namespace {String|string[]}
66
+ * @returns {Object}
67
+ * @private
68
+ */
69
+ _notFound(key, namespace) {
70
+ return {
71
+ key,
72
+ namespace,
73
+ found: false,
74
+ metadata: undefined,
75
+ data: undefined
76
+ };
77
+ }
78
+
79
+ /**
80
+ * Get a JavaScript object from the cache.
81
+ *
82
+ * The returned Promise will resolve either to null if there is no
83
+ * match in the cache, or to an object with the following
84
+ * properties: 'found' is a boolean that is true if the item was found
85
+ * in the cache, 'false' if not, 'data' is the data for the object
86
+ * (or undefined if the object was not found), 'metadata' is the metadata
87
+ * object passed to put() (or undefined if the object was not found),
88
+ * 'expiration' is a JS date/timestamp representing the time at which the
89
+ * item will expire from the cache, 'key' is the item's cache
90
+ * key, and 'namespace' is the item's cache namespace.
91
+ *
92
+ * If the value passed to 'put' was a Buffer, then 'data' will
93
+ * be a Buffer. If the value passed to 'put' was anything else,
94
+ * it will have been deserialized from JSON, and will be whatever
95
+ * type was originally passed in.
96
+ *
97
+ * If an object is in the cache under the given key, each call to this
98
+ * method will return a separate copy of the object.
99
+ *
100
+ * If the object is NOT in the cache, this method will return an object
101
+ * with 'found' set to false. This allows a then() handler to use object
102
+ * deconstruction on the result.
103
+ *
104
+ * Within the cache, items under the same key but in different namespaces
105
+ * are distinct. The default namespace is undefined.
106
+ *
107
+ * @param [namespace] {String|string[]} the cache namespace
108
+ * @param key {String} the cache key
109
+ * @returns {Promise<*>} A Promise that will resolve to the
110
+ * cache result, or null if there is no match in the cache.
111
+ */
112
+ get({
113
+ key,
114
+ namespace
115
+ }) {
116
+ return Promise.resolve(this._notFound(key, namespace));
117
+ }
118
+
119
+ /**
120
+ * Store a JavaScript object in the cache.
121
+ *
122
+ * If the data to be stored is a Buffer, it's stored as-is. If
123
+ * it's any other type, it's serialized to JSON and the JSON is
124
+ * stored. If the data is not JSON-serializable, then this method
125
+ * will throw an error.
126
+ *
127
+ * A primary use-case for this cache is storing HTTP responses,
128
+ * which include a status code, headers and a body. The body is
129
+ * typically most efficiently stored as a Buffer. Passing an object
130
+ * to 'data' that has a Buffer value will result in the Buffer being
131
+ * JSON-encoded, which is slow and takes up much more space than the
132
+ * origin data. The recommended way to store a response is to include
133
+ * the status and headers in the item's metadata, and to pass the body
134
+ * as a Buffer.
135
+ *
136
+ * If an expiration date/timestamp is given, the data will expire
137
+ * from the cache at that time. If no date/timestamp is given,
138
+ * the default expiration is one year from the time that the data is
139
+ * stored.
140
+ *
141
+ * Within the cache, items under the same key but in different namespaces
142
+ * are distinct. The default namespace is undefined.
143
+ *
144
+ * If put() is called to store metdata but no data, you should pass
145
+ * undefined for 'data'.
146
+ *
147
+ * @param key {String} the cache key.
148
+ * @param [namespace] {String|string[]} the cache namespace
149
+ * @param data {Buffer|*} the data to be stored.
150
+ * @param [metadata] {Object} a simple JS object with keys and values
151
+ * for metadata. This object MUST be JSON-seralizable.
152
+ * @param [expiration] {Number} the expiration date/time for the data,
153
+ * as a JS date/timestamp (the result of Date.getTime). If the expiration
154
+ * is less than PersistentCache.DELTA_THRESHOLD (midnight on January 1st, 1980)
155
+ * it is interpreted as a delta number of mS to be added to the current time.
156
+ * This allows for deltas up to ten years.
157
+ * @returns {Promise<*>} resolves when data has been stored, or rejects
158
+ * on an error
159
+ */
160
+ put() {
161
+ return Promise.resolve();
162
+ }
163
+
164
+ /**
165
+ * Remove a single entry from the cache.
166
+ * @param key {String} the cache key
167
+ * @param [namespace] {String|string[]} the cache namespace
168
+ * @returns {Promise.<*>} resolves when delete is complete
169
+ */
170
+ delete() {
171
+ return Promise.resolve();
172
+ }
173
+ }
174
+
175
+ // The timestamp value for 1980-01-01T00:00:00
176
+ exports.PersistentCache = PersistentCache;
177
+ PersistentCache.DELTA_THRESHOLD = 315561600000;
@@ -0,0 +1,64 @@
1
+ "use strict";
2
+
3
+ var _ssrCache = require("./ssr-cache");
4
+ function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
5
+ function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; } /*
6
+ * Copyright (c) 2021, salesforce.com, inc.
7
+ * All rights reserved.
8
+ * SPDX-License-Identifier: BSD-3-Clause
9
+ * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause
10
+ */
11
+ const localRemoteTestCases = [true, false];
12
+ localRemoteTestCases.forEach(useLocalCache => {
13
+ describe(`${useLocalCache ? 'Local' : 'Remote'} noop PersistentCache`, () => {
14
+ const testCache = new _ssrCache.PersistentCache({
15
+ useLocalCache,
16
+ bucket: 'TestBucket',
17
+ s3Endpoint: 'http://localhost:4568',
18
+ accessKeyId: 'S3RVER',
19
+ secretAccessKey: 'S3RVER',
20
+ sendMetric: () => {}
21
+ });
22
+ const key = 'key';
23
+ const namespace = 'namespace';
24
+ const buf = Buffer.alloc(8);
25
+ for (let i = 0; i <= 8; i++) {
26
+ buf[i] = i;
27
+ }
28
+ const expiration = Date.now() + 10000;
29
+ test('get', /*#__PURE__*/_asyncToGenerator(function* () {
30
+ const result = yield testCache.get({
31
+ key,
32
+ namespace
33
+ });
34
+ expect(result.data).toBeUndefined();
35
+ expect(result.metadata).toBeUndefined();
36
+ expect(result.found).toBe(false);
37
+ expect(result.key).toEqual(key);
38
+ expect(result.namespace).toEqual(namespace);
39
+ }));
40
+ test('put', /*#__PURE__*/_asyncToGenerator(function* () {
41
+ yield testCache.put({
42
+ key,
43
+ namespace,
44
+ data: buf,
45
+ expiration
46
+ });
47
+ const result = yield testCache.get({
48
+ key,
49
+ namespace
50
+ });
51
+ expect(result.data).toBeUndefined();
52
+ expect(result.metadata).toBeUndefined();
53
+ expect(result.found).toBe(false);
54
+ expect(result.key).toEqual(key);
55
+ expect(result.namespace).toEqual(namespace);
56
+ }));
57
+ test('delete', /*#__PURE__*/_asyncToGenerator(function* () {
58
+ yield expect(testCache.delete({
59
+ key,
60
+ namespace
61
+ })).resolves.not.toThrow();
62
+ }));
63
+ });
64
+ });
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.getConfig = void 0;
7
+ /*
8
+ * Copyright (c) 2021, salesforce.com, inc.
9
+ * All rights reserved.
10
+ * SPDX-License-Identifier: BSD-3-Clause
11
+ * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause
12
+ */
13
+
14
+ /**
15
+ * Returns the express app configuration file in object form that was serialized on the window object
16
+ *
17
+ * @returns - the application configuration object.
18
+ */
19
+ /* istanbul ignore next */
20
+ const getConfig = () => {
21
+ return window.__CONFIG__;
22
+ };
23
+ exports.getConfig = getConfig;
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+
3
+ var _ssrConfig = require("./ssr-config.client");
4
+ /*
5
+ * Copyright (c) 2023, Salesforce, Inc.
6
+ * All rights reserved.
7
+ * SPDX-License-Identifier: BSD-3-Clause
8
+ * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause
9
+ */
10
+
11
+ let windowSpy;
12
+ beforeEach(() => {
13
+ windowSpy = jest.spyOn(window, 'window', 'get');
14
+ });
15
+ afterEach(() => {
16
+ windowSpy.mockRestore();
17
+ });
18
+ describe('Client getConfig', () => {
19
+ test('returns window.__CONFIG__ value', () => {
20
+ windowSpy.mockImplementation(() => ({
21
+ __CONFIG__: {}
22
+ }));
23
+ expect((0, _ssrConfig.getConfig)()).toEqual({});
24
+ });
25
+ });
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+
3
+ /*
4
+ * Copyright (c) 2021, salesforce.com, inc.
5
+ * All rights reserved.
6
+ * SPDX-License-Identifier: BSD-3-Clause
7
+ * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause
8
+ */
9
+
10
+ // NOTE: This conditional export by default exports the named export `getConfig`
11
+ // for use in node environments. If specified by the `WEBPACK_TARGET` global
12
+ // this module will export a browser safe version.
13
+ /* global WEBPACK_TARGET */
14
+
15
+ /* istanbul ignore next */
16
+ if (typeof WEBPACK_TARGET !== 'undefined' && WEBPACK_TARGET === 'web') {
17
+ module.exports = require('./ssr-config.client.js');
18
+ } else {
19
+ module.exports = require('./ssr-config.server.js');
20
+ }
@@ -0,0 +1,88 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.getConfig = void 0;
7
+ /*
8
+ * Copyright (c) 2021, salesforce.com, inc.
9
+ * All rights reserved.
10
+ * SPDX-License-Identifier: BSD-3-Clause
11
+ * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause
12
+ */
13
+
14
+ /* istanbul ignore next */
15
+ const SUPPORTED_FILE_TYPES = ['js', 'yml', 'yaml', 'json'];
16
+ const IS_REMOTE = Object.prototype.hasOwnProperty.call(process.env, 'AWS_LAMBDA_FUNCTION_NAME');
17
+
18
+ /**
19
+ * Returns the express app configuration file in object form. The file will be resolved in the
20
+ * the following order:
21
+ *
22
+ * {deploy_target}.ext - When the DEPLOY_TARGET environment is set (predominantly on remote environments)
23
+ * a file aptly named after the environment will be loaded first. Examples of this are `production.json`, or
24
+ * `development.json`.
25
+ *
26
+ * local.ext - Only loaded on local development environments, this file is used if you want a custom
27
+ * configuration that will not be used on deployed remote environments.
28
+ *
29
+ * default.ext - If you have no requirement for environment specific configurations the `default`
30
+ * config file will be used.
31
+ *
32
+ * package.json - If none of the files after have been found the `mobify` object defined in the
33
+ * projects `package.json` file.
34
+ *
35
+ * Each file marked with `ext` can optionally be terminated with `js`, `yml|yaml` or
36
+ * `json`. The file loaded is also determined based on that precidence of file extension.
37
+ *
38
+ * @param {Object} opts.buildDirectory - Option path to the folder containing the configution. Byt default
39
+ * it is the `build` folder when running remotely and the project folder when developing locally.
40
+ * @returns - the application configuration object.
41
+ */
42
+ /* istanbul ignore next */
43
+ const getConfig = (opts = {}) => {
44
+ var _process, _process$env;
45
+ const {
46
+ buildDirectory
47
+ } = opts;
48
+ const configDirBase = IS_REMOTE ? 'build' : '';
49
+ let targetName = ((_process = process) === null || _process === void 0 ? void 0 : (_process$env = _process.env) === null || _process$env === void 0 ? void 0 : _process$env.DEPLOY_TARGET) || '';
50
+ const targetSearchPlaces = SUPPORTED_FILE_TYPES.map(ext => `config/${targetName}.${ext}`);
51
+ const localeSearchPlaces = SUPPORTED_FILE_TYPES.map(ext => `config/local.${ext}`);
52
+ const defaultSearchPlaces = SUPPORTED_FILE_TYPES.map(ext => `config/default.${ext}`);
53
+ const searchFrom = buildDirectory || process.cwd() + '/' + configDirBase;
54
+
55
+ // Combined search places.
56
+ const searchPlaces = [...(targetName ? targetSearchPlaces : []), ...(!IS_REMOTE ? localeSearchPlaces : []), ...defaultSearchPlaces, 'package.json'];
57
+
58
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
59
+ const {
60
+ cosmiconfigSync
61
+ } = require('cosmiconfig');
62
+
63
+ // Match config files based on the specificity from most to most general.
64
+ const explorerSync = cosmiconfigSync(targetName, {
65
+ packageProp: 'mobify',
66
+ searchPlaces: searchPlaces,
67
+ loaders: {
68
+ '.js': filepath => {
69
+ // Because `require` is bootstrapped by webpack, the builtin
70
+ // loader for `.js` files doesn't work. We have to ensure we use
71
+ // the right `require`.
72
+ const _require = eval('require');
73
+ const result = _require(filepath);
74
+ return result;
75
+ }
76
+ }
77
+ });
78
+
79
+ // Load the config synchronously using a custom "searchPlaces".
80
+ const {
81
+ config
82
+ } = explorerSync.search(searchFrom) || {};
83
+ if (!config) {
84
+ throw new Error(`Application configuration not found!\nPossible configuration file locations:\n${searchPlaces.join('\n')}`);
85
+ }
86
+ return config;
87
+ };
88
+ exports.getConfig = getConfig;
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+
3
+ var _ssrConfig = require("./ssr-config.server");
4
+ function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
5
+ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
6
+ function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
7
+ function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
8
+ function _toPrimitive(input, hint) { if (typeof input !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (typeof res !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); } /*
9
+ * Copyright (c) 2023, Salesforce, Inc.
10
+ * All rights reserved.
11
+ * SPDX-License-Identifier: BSD-3-Clause
12
+ * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause
13
+ */
14
+ describe('Server "getConfig"', () => {
15
+ const env = process.env;
16
+ beforeEach(() => {
17
+ jest.resetModules();
18
+ process.env = _objectSpread({}, env);
19
+ });
20
+ afterEach(() => {
21
+ process.env = env;
22
+ });
23
+ test('throws when no config files are found running remotely', () => {
24
+ expect(_ssrConfig.getConfig).toThrow();
25
+ });
26
+ test('throws when no config files are found running locally', () => {
27
+ process.env.AWS_LAMBDA_FUNCTION_NAME = '';
28
+ expect(_ssrConfig.getConfig).toThrow();
29
+ });
30
+ });