@salesforce/pwa-kit-runtime 3.8.0-preview.0-basepath → 3.8.0-preview.2-basepath
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 +6 -5
- package/ssr/server/build-remote-server.js +1159 -0
- package/ssr/server/build-remote-server.test.js +41 -0
- package/ssr/server/constants.js +37 -0
- package/ssr/server/express.js +462 -0
- package/ssr/server/express.lambda.test.js +390 -0
- package/ssr/server/express.test.js +963 -0
- package/ssr/server/test_fixtures/favicon.ico +0 -0
- package/ssr/server/test_fixtures/loadable-stats.json +1 -0
- package/ssr/server/test_fixtures/localhost.pem +45 -0
- package/ssr/server/test_fixtures/main.js +7 -0
- package/ssr/server/test_fixtures/mobify.png +0 -0
- package/ssr/server/test_fixtures/server-renderer.js +12 -0
- package/ssr/server/test_fixtures/worker.js +7 -0
- package/ssr/server/test_fixtures/worker.js.map +1 -0
- package/utils/logger-factory.js +154 -0
- package/utils/logger-factory.test.js +71 -0
- package/utils/logger-instance.js +19 -0
- package/utils/middleware/index.js +16 -0
- package/utils/middleware/security.js +111 -0
- package/utils/middleware/security.test.js +110 -0
- package/utils/morgan-stream.js +28 -0
- package/utils/ssr-cache.js +177 -0
- package/utils/ssr-cache.test.js +64 -0
- package/utils/ssr-config.client.js +23 -0
- package/utils/ssr-config.client.test.js +25 -0
- package/utils/ssr-config.js +20 -0
- package/utils/ssr-config.server.js +98 -0
- package/utils/ssr-config.server.test.js +50 -0
- package/utils/ssr-namespace-paths.js +60 -0
- package/utils/ssr-namespace-paths.test.js +30 -0
- package/utils/ssr-paths.js +51 -0
- package/utils/ssr-paths.test.js +49 -0
- package/utils/ssr-proxying.js +859 -0
- package/utils/ssr-proxying.test.js +593 -0
- package/utils/ssr-request-processing.js +164 -0
- package/utils/ssr-request-processing.test.js +95 -0
- package/utils/ssr-server/cached-response.js +116 -0
- package/utils/ssr-server/configure-proxy.js +304 -0
- package/utils/ssr-server/metrics-sender.js +204 -0
- package/utils/ssr-server/outgoing-request-hook.js +139 -0
- package/utils/ssr-server/parse-end-parameters.js +38 -0
- package/utils/ssr-server/process-express-response.js +56 -0
- package/utils/ssr-server/process-lambda-response.js +43 -0
- package/utils/ssr-server/update-global-agent-options.js +41 -0
- package/utils/ssr-server/update-global-agent-options.test.js +28 -0
- package/utils/ssr-server/utils.js +124 -0
- package/utils/ssr-server/utils.test.js +69 -0
- package/utils/ssr-server/wrap-response-write.js +40 -0
- package/utils/ssr-server.js +115 -0
- package/utils/ssr-server.test.js +869 -0
- package/utils/ssr-shared.js +183 -0
|
@@ -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(n, t, e, r, o, a, c) { try { var i = n[a](c), u = i.value; } catch (n) { return void e(n); } i.done ? t(u) : Promise.resolve(u).then(r, o); }
|
|
5
|
+
function _asyncToGenerator(n) { return function () { var t = this, e = arguments; return new Promise(function (r, o) { var a = n.apply(t, e); function _next(n) { asyncGeneratorStep(a, r, o, _next, _throw, "next", n); } function _throw(n) { asyncGeneratorStep(a, r, o, _next, _throw, "throw", n); } _next(void 0); }); }; } /*
|
|
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,98 @@
|
|
|
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
|
+
* The implementation of getConfig below is expensive as it performs a file lookup.
|
|
20
|
+
*
|
|
21
|
+
* Since the environment config will not change unless the bundle is redeployed,
|
|
22
|
+
* this global variable helps prevent unnecessary file lookups when the server calls getConfig multiple times.
|
|
23
|
+
*/
|
|
24
|
+
let memoizedConfig;
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Returns the express app configuration file in object form. The file will be resolved in the
|
|
28
|
+
* the following order:
|
|
29
|
+
*
|
|
30
|
+
* {deploy_target}.ext - When the DEPLOY_TARGET environment is set (predominantly on remote environments)
|
|
31
|
+
* a file aptly named after the environment will be loaded first. Examples of this are `production.json`, or
|
|
32
|
+
* `development.json`.
|
|
33
|
+
*
|
|
34
|
+
* local.ext - Only loaded on local development environments, this file is used if you want a custom
|
|
35
|
+
* configuration that will not be used on deployed remote environments.
|
|
36
|
+
*
|
|
37
|
+
* default.ext - If you have no requirement for environment specific configurations the `default`
|
|
38
|
+
* config file will be used.
|
|
39
|
+
*
|
|
40
|
+
* package.json - If none of the files after have been found the `mobify` object defined in the
|
|
41
|
+
* projects `package.json` file.
|
|
42
|
+
*
|
|
43
|
+
* Each file marked with `ext` can optionally be terminated with `js`, `yml|yaml` or
|
|
44
|
+
* `json`. The file loaded is also determined based on that precidence of file extension.
|
|
45
|
+
*
|
|
46
|
+
* @param {Object} opts.buildDirectory - Option path to the folder containing the configution. Byt default
|
|
47
|
+
* it is the `build` folder when running remotely and the project folder when developing locally.
|
|
48
|
+
* @returns - the application configuration object.
|
|
49
|
+
*/
|
|
50
|
+
/* istanbul ignore next */
|
|
51
|
+
const getConfig = (opts = {}) => {
|
|
52
|
+
var _process, _process$env;
|
|
53
|
+
if (memoizedConfig) return memoizedConfig;
|
|
54
|
+
const {
|
|
55
|
+
buildDirectory
|
|
56
|
+
} = opts;
|
|
57
|
+
const configDirBase = IS_REMOTE ? 'build' : '';
|
|
58
|
+
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) || '';
|
|
59
|
+
const targetSearchPlaces = SUPPORTED_FILE_TYPES.map(ext => `config/${targetName}.${ext}`);
|
|
60
|
+
const localeSearchPlaces = SUPPORTED_FILE_TYPES.map(ext => `config/local.${ext}`);
|
|
61
|
+
const defaultSearchPlaces = SUPPORTED_FILE_TYPES.map(ext => `config/default.${ext}`);
|
|
62
|
+
const searchFrom = buildDirectory || process.cwd() + '/' + configDirBase;
|
|
63
|
+
|
|
64
|
+
// Combined search places.
|
|
65
|
+
const searchPlaces = [...(targetName ? targetSearchPlaces : []), ...(!IS_REMOTE ? localeSearchPlaces : []), ...defaultSearchPlaces, 'package.json'];
|
|
66
|
+
|
|
67
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
68
|
+
const {
|
|
69
|
+
cosmiconfigSync
|
|
70
|
+
} = require('cosmiconfig');
|
|
71
|
+
|
|
72
|
+
// Match config files based on the specificity from most to most general.
|
|
73
|
+
const explorerSync = cosmiconfigSync(targetName, {
|
|
74
|
+
packageProp: 'mobify',
|
|
75
|
+
searchPlaces: searchPlaces,
|
|
76
|
+
loaders: {
|
|
77
|
+
'.js': filepath => {
|
|
78
|
+
// Because `require` is bootstrapped by webpack, the builtin
|
|
79
|
+
// loader for `.js` files doesn't work. We have to ensure we use
|
|
80
|
+
// the right `require`.
|
|
81
|
+
const _require = eval('require');
|
|
82
|
+
const result = _require(filepath);
|
|
83
|
+
return result;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
// Load the config synchronously using a custom "searchPlaces".
|
|
89
|
+
const {
|
|
90
|
+
config
|
|
91
|
+
} = explorerSync.search(searchFrom) || {};
|
|
92
|
+
if (!config) {
|
|
93
|
+
throw new Error(`Application configuration not found!\nPossible configuration file locations:\n${searchPlaces.join('\n')}`);
|
|
94
|
+
}
|
|
95
|
+
memoizedConfig = config;
|
|
96
|
+
return config;
|
|
97
|
+
};
|
|
98
|
+
exports.getConfig = getConfig;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _ssrConfig = require("./ssr-config.server");
|
|
4
|
+
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; }
|
|
5
|
+
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; }
|
|
6
|
+
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
|
|
7
|
+
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
|
|
8
|
+
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); } /*
|
|
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
|
+
test('config is cached', () => {
|
|
31
|
+
const mockConfig = {
|
|
32
|
+
test: 'test'
|
|
33
|
+
};
|
|
34
|
+
const mockConfigSearch = jest.fn().mockReturnValue({
|
|
35
|
+
config: mockConfig
|
|
36
|
+
});
|
|
37
|
+
jest.doMock('cosmiconfig', () => {
|
|
38
|
+
const originalModule = jest.requireActual('cosmiconfig');
|
|
39
|
+
return _objectSpread(_objectSpread({}, originalModule), {}, {
|
|
40
|
+
cosmiconfigSync: () => ({
|
|
41
|
+
search: mockConfigSearch
|
|
42
|
+
})
|
|
43
|
+
});
|
|
44
|
+
});
|
|
45
|
+
// Call getConfig multiple times
|
|
46
|
+
expect((0, _ssrConfig.getConfig)()).toBe(mockConfig);
|
|
47
|
+
expect((0, _ssrConfig.getConfig)()).toBe(mockConfig);
|
|
48
|
+
expect(mockConfigSearch).toHaveBeenCalledTimes(1);
|
|
49
|
+
});
|
|
50
|
+
});
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.ssrNamespace = exports.slasPrivateProxyPath = exports.proxyBasePath = exports.healthCheckPath = exports.cachingBasePath = exports.bundleBasePath = void 0;
|
|
7
|
+
/*
|
|
8
|
+
* Copyright (c) 2024, 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
|
+
* DO NOT ADD NEW CONTENT TO THIS FILE! THIS FILE IS DEPRECATED!
|
|
16
|
+
* For all paths related code, use the ssr-path.js file
|
|
17
|
+
*/
|
|
18
|
+
const MOBIFY_PATH = '/mobify';
|
|
19
|
+
const PROXY_PATH_BASE = `${MOBIFY_PATH}/proxy`;
|
|
20
|
+
const BUNDLE_PATH_BASE = `${MOBIFY_PATH}/bundle`;
|
|
21
|
+
const CACHING_PATH_BASE = `${MOBIFY_PATH}/caching`;
|
|
22
|
+
const HEALTHCHECK_PATH = `${MOBIFY_PATH}/ping`;
|
|
23
|
+
const SLAS_PRIVATE_CLIENT_PROXY_PATH = `${MOBIFY_PATH}/slas/private`;
|
|
24
|
+
|
|
25
|
+
// The following variables were introduced in v3.7,
|
|
26
|
+
// before the env base path feature was fully implemented.
|
|
27
|
+
// In v3.8, we added the env base path support and the implementation has
|
|
28
|
+
// changed from using static variables to functions.
|
|
29
|
+
// Thus, we deprecate the following variables to avoid breaking change.
|
|
30
|
+
// We will remove the deprecation in future major releases.
|
|
31
|
+
/**
|
|
32
|
+
* @deprecated Use getProxyPath() instead. Import from @salesforce/pwa-kit-runtime/utils/ssr-paths
|
|
33
|
+
*/
|
|
34
|
+
const proxyBasePath = exports.proxyBasePath = PROXY_PATH_BASE;
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* @deprecated Use getBundlePath() instead. Import from @salesforce/pwa-kit-runtime/utils/ssr-paths
|
|
38
|
+
*/
|
|
39
|
+
const bundleBasePath = exports.bundleBasePath = BUNDLE_PATH_BASE;
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* @deprecated Use getCachingPath() instead. Import from @salesforce/pwa-kit-runtime/utils/ssr-paths
|
|
43
|
+
*/
|
|
44
|
+
const cachingBasePath = exports.cachingBasePath = CACHING_PATH_BASE;
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* @deprecated Use getHealthCheckPath() instead. Import from @salesforce/pwa-kit-runtime/utils/ssr-paths
|
|
48
|
+
*/
|
|
49
|
+
const healthCheckPath = exports.healthCheckPath = HEALTHCHECK_PATH;
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* @deprecated Use getSlasPrivateProxyPath() instead. Import from @salesforce/pwa-kit-runtime/utils/ssr-paths
|
|
53
|
+
*/
|
|
54
|
+
const slasPrivateProxyPath = exports.slasPrivateProxyPath = SLAS_PRIVATE_CLIENT_PROXY_PATH;
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* @deprecated This variable is no longer used. This variable has always been an empty string.
|
|
58
|
+
* Use getEnvBasePath() instead. Import from @salesforce/pwa-kit-runtime/utils/ssr-paths
|
|
59
|
+
*/
|
|
60
|
+
const ssrNamespace = exports.ssrNamespace = '';
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _ssrNamespacePaths = require("./ssr-namespace-paths");
|
|
4
|
+
/*
|
|
5
|
+
* Copyright (c) 2024, 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
|
+
describe('ssr-namespace-paths tests', () => {
|
|
12
|
+
test('proxyBasePath is correctly set', () => {
|
|
13
|
+
expect(_ssrNamespacePaths.proxyBasePath).toBe('/mobify/proxy');
|
|
14
|
+
});
|
|
15
|
+
test('bundleBasePath is correctly set', () => {
|
|
16
|
+
expect(_ssrNamespacePaths.bundleBasePath).toBe('/mobify/bundle');
|
|
17
|
+
});
|
|
18
|
+
test('cachingBasePath is correctly set', () => {
|
|
19
|
+
expect(_ssrNamespacePaths.cachingBasePath).toBe('/mobify/caching');
|
|
20
|
+
});
|
|
21
|
+
test('healthCheckPath is correctly set', () => {
|
|
22
|
+
expect(_ssrNamespacePaths.healthCheckPath).toBe('/mobify/ping');
|
|
23
|
+
});
|
|
24
|
+
test('slasPrivateProxyPath is correctly set', () => {
|
|
25
|
+
expect(_ssrNamespacePaths.slasPrivateProxyPath).toBe('/mobify/slas/private');
|
|
26
|
+
});
|
|
27
|
+
test('ssrNamespace is an empty string', () => {
|
|
28
|
+
expect(_ssrNamespacePaths.ssrNamespace).toBe('');
|
|
29
|
+
});
|
|
30
|
+
});
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.getSlasPrivateProxyPath = exports.getProxyPath = exports.getHealthCheckPath = exports.getEnvBasePath = exports.getCachingPath = exports.getBundlePath = void 0;
|
|
7
|
+
var _ssrConfig = require("./ssr-config");
|
|
8
|
+
var _loggerInstance = _interopRequireDefault(require("./logger-instance"));
|
|
9
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
10
|
+
/*
|
|
11
|
+
* Copyright (c) 2024, salesforce.com, inc.
|
|
12
|
+
* All rights reserved.
|
|
13
|
+
* SPDX-License-Identifier: BSD-3-Clause
|
|
14
|
+
* For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* This file defines the /mobify paths used to set up our Express endpoints.
|
|
19
|
+
*
|
|
20
|
+
* If a base path for the /mobify paths is defined, the methods in here will return the
|
|
21
|
+
* basepath. ie. /basepath/mobify/...
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
// The MOBIFY_PATH is defined separately in preparation for the future eventual removal or
|
|
25
|
+
// replacement of the 'mobify' part of these paths
|
|
26
|
+
const MOBIFY_PATH = '/mobify';
|
|
27
|
+
const PROXY_PATH_BASE = `${MOBIFY_PATH}/proxy`;
|
|
28
|
+
const BUNDLE_PATH_BASE = `${MOBIFY_PATH}/bundle`;
|
|
29
|
+
const CACHING_PATH_BASE = `${MOBIFY_PATH}/caching`;
|
|
30
|
+
const HEALTHCHECK_PATH = `${MOBIFY_PATH}/ping`;
|
|
31
|
+
const SLAS_PRIVATE_CLIENT_PROXY_PATH = `${MOBIFY_PATH}/slas/private`;
|
|
32
|
+
const getEnvBasePath = () => {
|
|
33
|
+
const config = (0, _ssrConfig.getConfig)();
|
|
34
|
+
let basePath = (config === null || config === void 0 ? void 0 : config.envBasePath) || '';
|
|
35
|
+
if (typeof basePath !== 'string') {
|
|
36
|
+
_loggerInstance.default.warn('Invalid envBasePath configuration. No base path is applied.');
|
|
37
|
+
basePath = '';
|
|
38
|
+
}
|
|
39
|
+
return basePath.replace(/\/$/, '');
|
|
40
|
+
};
|
|
41
|
+
exports.getEnvBasePath = getEnvBasePath;
|
|
42
|
+
const getProxyPath = () => `${getEnvBasePath()}${PROXY_PATH_BASE}`;
|
|
43
|
+
exports.getProxyPath = getProxyPath;
|
|
44
|
+
const getBundlePath = () => `${getEnvBasePath()}${BUNDLE_PATH_BASE}`;
|
|
45
|
+
exports.getBundlePath = getBundlePath;
|
|
46
|
+
const getCachingPath = () => `${getEnvBasePath()}${CACHING_PATH_BASE}`;
|
|
47
|
+
exports.getCachingPath = getCachingPath;
|
|
48
|
+
const getHealthCheckPath = () => `${getEnvBasePath()}${HEALTHCHECK_PATH}`;
|
|
49
|
+
exports.getHealthCheckPath = getHealthCheckPath;
|
|
50
|
+
const getSlasPrivateProxyPath = () => `${getEnvBasePath()}${SLAS_PRIVATE_CLIENT_PROXY_PATH}`;
|
|
51
|
+
exports.getSlasPrivateProxyPath = getSlasPrivateProxyPath;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _ssrPaths = require("./ssr-paths");
|
|
4
|
+
var _ssrConfig = require("./ssr-config");
|
|
5
|
+
/*
|
|
6
|
+
* Copyright (c) 2024, Salesforce, 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
|
+
|
|
12
|
+
jest.mock('./ssr-config', () => {
|
|
13
|
+
return {
|
|
14
|
+
getConfig: jest.fn()
|
|
15
|
+
};
|
|
16
|
+
});
|
|
17
|
+
const mockConfig = {
|
|
18
|
+
envBasePath: '/test'
|
|
19
|
+
};
|
|
20
|
+
describe('environment base path tests', () => {
|
|
21
|
+
beforeEach(() => {
|
|
22
|
+
jest.resetModules();
|
|
23
|
+
jest.resetAllMocks();
|
|
24
|
+
});
|
|
25
|
+
test('basePath is returned from config', () => {
|
|
26
|
+
_ssrConfig.getConfig.mockImplementation(() => mockConfig);
|
|
27
|
+
expect((0, _ssrPaths.getEnvBasePath)()).toBe('/test');
|
|
28
|
+
});
|
|
29
|
+
test('basePath is included in proxy path', () => {
|
|
30
|
+
_ssrConfig.getConfig.mockImplementation(() => mockConfig);
|
|
31
|
+
expect((0, _ssrPaths.getProxyPath)()).toBe('/test/mobify/proxy');
|
|
32
|
+
});
|
|
33
|
+
test('basePath is included in bundle path', () => {
|
|
34
|
+
_ssrConfig.getConfig.mockImplementation(() => mockConfig);
|
|
35
|
+
expect((0, _ssrPaths.getBundlePath)()).toBe('/test/mobify/bundle');
|
|
36
|
+
});
|
|
37
|
+
test('basePath is set to empty string if there is no config', () => {
|
|
38
|
+
_ssrConfig.getConfig.mockImplementation(() => {});
|
|
39
|
+
expect((0, _ssrPaths.getEnvBasePath)()).toBe('');
|
|
40
|
+
});
|
|
41
|
+
test('basePath is set to empty string if envBasePath is not a string', () => {
|
|
42
|
+
_ssrConfig.getConfig.mockImplementation(() => {
|
|
43
|
+
return {
|
|
44
|
+
envBasePath: () => {}
|
|
45
|
+
};
|
|
46
|
+
});
|
|
47
|
+
expect((0, _ssrPaths.getEnvBasePath)()).toBe('');
|
|
48
|
+
});
|
|
49
|
+
});
|