@salesforce/pwa-kit-react-sdk 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.
- package/CHANGELOG.md +86 -0
- package/LICENSE +14 -0
- package/README.md +37 -0
- package/package.json +82 -0
- package/scripts/file-utils.js +80 -0
- package/scripts/file-utils.test.js +189 -0
- package/scripts/setup-jsdom.js +20 -0
- package/scripts/version.js +22 -0
- package/ssr/browser/main.js +122 -0
- package/ssr/browser/main.test.js +54 -0
- package/ssr/server/react-rendering.js +405 -0
- package/ssr/server/react-rendering.test.js +708 -0
- package/ssr/universal/compatibility.js +31 -0
- package/ssr/universal/components/_app/index.js +35 -0
- package/ssr/universal/components/_app/index.test.js +20 -0
- package/ssr/universal/components/_app-config/index.js +88 -0
- package/ssr/universal/components/_app-config/index.test.js +21 -0
- package/ssr/universal/components/_document/index.js +93 -0
- package/ssr/universal/components/_document/index.test.js +58 -0
- package/ssr/universal/components/_error/index.js +56 -0
- package/ssr/universal/components/_error/index.test.js +28 -0
- package/ssr/universal/components/app-error-boundary/index.js +115 -0
- package/ssr/universal/components/app-error-boundary/index.test.js +109 -0
- package/ssr/universal/components/fetch-strategy/index.js +42 -0
- package/ssr/universal/components/route-component/index.js +409 -0
- package/ssr/universal/components/route-component/index.test.js +375 -0
- package/ssr/universal/components/switch/index.js +63 -0
- package/ssr/universal/components/throw-404/index.js +37 -0
- package/ssr/universal/components/throw-404/index.test.js +26 -0
- package/ssr/universal/components/with-correlation-id/index.js +36 -0
- package/ssr/universal/components/with-legacy-get-props/index.js +86 -0
- package/ssr/universal/components/with-legacy-get-props/index.test.js +35 -0
- package/ssr/universal/components/with-react-query/index.js +103 -0
- package/ssr/universal/components/with-react-query/index.test.js +44 -0
- package/ssr/universal/contexts/index.js +71 -0
- package/ssr/universal/contexts/index.test.js +101 -0
- package/ssr/universal/errors.js +34 -0
- package/ssr/universal/errors.test.js +20 -0
- package/ssr/universal/events.js +40 -0
- package/ssr/universal/events.test.js +39 -0
- package/ssr/universal/hooks/index.js +52 -0
- package/ssr/universal/routes.js +16 -0
- package/ssr/universal/utils.client.test.js +46 -0
- package/ssr/universal/utils.js +60 -0
- package/ssr/universal/utils.server.test.js +24 -0
- package/utils/assets.js +120 -0
- package/utils/assets.test.js +106 -0
- package/utils/url.js +39 -0
- package/utils/url.test.js +47 -0
- package/utils/uuidv4.client.js +21 -0
- package/utils/uuidv4.client.test.js +27 -0
- package/utils/warnings.js +81 -0
- package/utils/warnings.test.js +48 -0
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.withReactQuery = void 0;
|
|
7
|
+
var _react = _interopRequireDefault(require("react"));
|
|
8
|
+
var _hoistNonReactStatics = _interopRequireDefault(require("hoist-non-react-statics"));
|
|
9
|
+
var _reactSsrPrepass = _interopRequireDefault(require("react-ssr-prepass"));
|
|
10
|
+
var _reactQuery = require("@tanstack/react-query");
|
|
11
|
+
var _fetchStrategy = require("../fetch-strategy");
|
|
12
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
13
|
+
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); } }
|
|
14
|
+
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); }); }; } /*
|
|
15
|
+
* Copyright (c) 2022, Salesforce, Inc.
|
|
16
|
+
* All rights reserved.
|
|
17
|
+
* SPDX-License-Identifier: BSD-3-Clause
|
|
18
|
+
* For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause
|
|
19
|
+
*/
|
|
20
|
+
const STATE_KEY = '__reactQuery';
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* A HoC for adding React Query support to your application.
|
|
24
|
+
*
|
|
25
|
+
* @param {React.ReactElement} Wrapped The component to be wrapped
|
|
26
|
+
* @param {Object} options
|
|
27
|
+
* @param {Object} options.queryClientConfig The react query client configuration object to be used. By
|
|
28
|
+
* default the `retry` option will be set to false to ensure performant server rendering.
|
|
29
|
+
*
|
|
30
|
+
* @returns {React.ReactElement}
|
|
31
|
+
*/
|
|
32
|
+
const withReactQuery = (Wrapped, options = {}) => {
|
|
33
|
+
const isServerSide = typeof window === 'undefined';
|
|
34
|
+
/* istanbul ignore next */
|
|
35
|
+
const wrappedComponentName = Wrapped.displayName || Wrapped.name;
|
|
36
|
+
const queryClientConfig = options.queryClientConfig;
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* @private
|
|
40
|
+
*/
|
|
41
|
+
class WithReactQuery extends _fetchStrategy.FetchStrategy {
|
|
42
|
+
render() {
|
|
43
|
+
var _window$__PRELOADED_S;
|
|
44
|
+
this.props.locals.__queryClient = this.props.locals.__queryClient || new _reactQuery.QueryClient(queryClientConfig);
|
|
45
|
+
return /*#__PURE__*/_react.default.createElement(_reactQuery.QueryClientProvider, {
|
|
46
|
+
client: this.props.locals.__queryClient
|
|
47
|
+
}, /*#__PURE__*/_react.default.createElement(_reactQuery.Hydrate, {
|
|
48
|
+
state: isServerSide ? {} : (_window$__PRELOADED_S = window.__PRELOADED_STATE__) === null || _window$__PRELOADED_S === void 0 ? void 0 : _window$__PRELOADED_S[STATE_KEY]
|
|
49
|
+
}, /*#__PURE__*/_react.default.createElement(Wrapped, this.props)));
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* @private
|
|
54
|
+
*/
|
|
55
|
+
static doInitAppState({
|
|
56
|
+
res,
|
|
57
|
+
appJSX
|
|
58
|
+
}) {
|
|
59
|
+
return _asyncToGenerator(function* () {
|
|
60
|
+
const queryClient = res.locals.__queryClient = res.locals.__queryClient || new _reactQuery.QueryClient(queryClientConfig);
|
|
61
|
+
|
|
62
|
+
// Use `ssrPrepass` to collect all uses of `useQuery`.
|
|
63
|
+
yield (0, _reactSsrPrepass.default)(appJSX);
|
|
64
|
+
const queryCache = queryClient.getQueryCache();
|
|
65
|
+
const queries = queryCache.getAll().filter(q => q.options.enabled !== false);
|
|
66
|
+
yield Promise.all(queries.map(q =>
|
|
67
|
+
// If there's an error in this fetch, react-query will log the error
|
|
68
|
+
q.fetch().catch(() => {
|
|
69
|
+
// On our end, simply catch any error and move on to the next query
|
|
70
|
+
})));
|
|
71
|
+
return {
|
|
72
|
+
[STATE_KEY]: (0, _reactQuery.dehydrate)(queryClient)
|
|
73
|
+
};
|
|
74
|
+
})();
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* @private
|
|
79
|
+
*/
|
|
80
|
+
static getInitializers() {
|
|
81
|
+
var _Wrapped$getInitializ;
|
|
82
|
+
return [WithReactQuery.doInitAppState, ...(((_Wrapped$getInitializ = Wrapped.getInitializers) === null || _Wrapped$getInitializ === void 0 ? void 0 : _Wrapped$getInitializ.call(Wrapped)) ?? [])];
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* @private
|
|
87
|
+
*/
|
|
88
|
+
static getHOCsInUse() {
|
|
89
|
+
var _Wrapped$getHOCsInUse;
|
|
90
|
+
return [withReactQuery, ...(((_Wrapped$getHOCsInUse = Wrapped.getHOCsInUse) === null || _Wrapped$getHOCsInUse === void 0 ? void 0 : _Wrapped$getHOCsInUse.call(Wrapped)) ?? [])];
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
WithReactQuery.displayName = `withReactQuery(${wrappedComponentName})`;
|
|
94
|
+
const exclude = {
|
|
95
|
+
doInitAppState: true,
|
|
96
|
+
getInitializers: true,
|
|
97
|
+
initAppState: true,
|
|
98
|
+
getHOCsInUse: true
|
|
99
|
+
};
|
|
100
|
+
(0, _hoistNonReactStatics.default)(WithReactQuery, Wrapped, exclude);
|
|
101
|
+
return WithReactQuery;
|
|
102
|
+
};
|
|
103
|
+
exports.withReactQuery = withReactQuery;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _index = require("./index");
|
|
4
|
+
var _react = require("@testing-library/react");
|
|
5
|
+
var _react2 = _interopRequireDefault(require("react"));
|
|
6
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
7
|
+
/*
|
|
8
|
+
* Copyright (c) 2022, Salesforce, 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
|
+
describe('withReactQuery', function () {
|
|
15
|
+
let windowSpy;
|
|
16
|
+
beforeEach(() => {
|
|
17
|
+
windowSpy = jest.spyOn(window, 'window', 'get');
|
|
18
|
+
jest.spyOn(console, 'warn').mockImplementation(jest.fn());
|
|
19
|
+
});
|
|
20
|
+
afterEach(() => {
|
|
21
|
+
console.warn.mockRestore();
|
|
22
|
+
windowSpy.mockRestore();
|
|
23
|
+
});
|
|
24
|
+
test('Renders correctly', () => {
|
|
25
|
+
const Wrapped = () => /*#__PURE__*/_react2.default.createElement("p", null, "Hello world");
|
|
26
|
+
const Component = (0, _index.withReactQuery)(Wrapped);
|
|
27
|
+
(0, _react.render)( /*#__PURE__*/_react2.default.createElement(Component, {
|
|
28
|
+
locals: {}
|
|
29
|
+
}));
|
|
30
|
+
expect(_react.screen.getByText(/Hello world/i)).toBeInTheDocument();
|
|
31
|
+
});
|
|
32
|
+
test(`Has working getInitializers method`, () => {
|
|
33
|
+
expect((0, _index.withReactQuery)({}).getInitializers()).toHaveLength(1);
|
|
34
|
+
expect((0, _index.withReactQuery)({
|
|
35
|
+
getInitializers: () => ['xyz']
|
|
36
|
+
}).getInitializers()).toHaveLength(2);
|
|
37
|
+
});
|
|
38
|
+
test(`Has working getHOCsInUse method`, () => {
|
|
39
|
+
expect((0, _index.withReactQuery)({}).getHOCsInUse()).toHaveLength(1);
|
|
40
|
+
expect((0, _index.withReactQuery)({
|
|
41
|
+
getHOCsInUse: () => ['xyz']
|
|
42
|
+
}).getHOCsInUse()).toHaveLength(2);
|
|
43
|
+
});
|
|
44
|
+
});
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.ServerContext = exports.CorrelationIdProvider = exports.CorrelationIdContext = void 0;
|
|
7
|
+
var _react = _interopRequireWildcard(require("react"));
|
|
8
|
+
var _propTypes = _interopRequireDefault(require("prop-types"));
|
|
9
|
+
var _reactRouterDom = require("react-router-dom");
|
|
10
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
11
|
+
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
|
12
|
+
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
|
13
|
+
/*
|
|
14
|
+
* Copyright (c) 2021, salesforce.com, inc.
|
|
15
|
+
* All rights reserved.
|
|
16
|
+
* SPDX-License-Identifier: BSD-3-Clause
|
|
17
|
+
* For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause
|
|
18
|
+
*/
|
|
19
|
+
|
|
20
|
+
const CorrelationIdContext = /*#__PURE__*/_react.default.createContext();
|
|
21
|
+
exports.CorrelationIdContext = CorrelationIdContext;
|
|
22
|
+
const ServerContext = /*#__PURE__*/_react.default.createContext();
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* This provider initializes the correlation id,
|
|
26
|
+
* and will generate a new id whenever there is a location change
|
|
27
|
+
* @private
|
|
28
|
+
* @param children
|
|
29
|
+
* @param correlationId - default correlation id
|
|
30
|
+
* @param resetOnPageChange - a boolean to indicate if it needs to generate a new id when navigating to a new page
|
|
31
|
+
*/
|
|
32
|
+
exports.ServerContext = ServerContext;
|
|
33
|
+
const CorrelationIdProvider = ({
|
|
34
|
+
children,
|
|
35
|
+
correlationId,
|
|
36
|
+
resetOnPageChange = true
|
|
37
|
+
}) => {
|
|
38
|
+
const _correlationIdFn = typeof correlationId === 'function' && correlationId;
|
|
39
|
+
const _correlationId = typeof correlationId !== 'function' && correlationId;
|
|
40
|
+
if (resetOnPageChange && !_correlationIdFn) {
|
|
41
|
+
console.warn('correlationId needs to be a function returning a uuid string when resetOnPageChange is true');
|
|
42
|
+
}
|
|
43
|
+
const [id, setId] = _react.default.useState(_correlationId || _correlationIdFn());
|
|
44
|
+
const location = (0, _reactRouterDom.useLocation)();
|
|
45
|
+
const isFirstRun = (0, _react.useRef)(true);
|
|
46
|
+
(0, _react.useEffect)(() => {
|
|
47
|
+
// this hook only runs on client-side
|
|
48
|
+
// don't run this on first render
|
|
49
|
+
if (isFirstRun.current) {
|
|
50
|
+
isFirstRun.current = false;
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
if (resetOnPageChange && _correlationIdFn) {
|
|
54
|
+
// NOTE: the function needs to be an uuid v4.
|
|
55
|
+
const newId = _correlationIdFn();
|
|
56
|
+
setId(newId);
|
|
57
|
+
}
|
|
58
|
+
}, [location.pathname]);
|
|
59
|
+
return /*#__PURE__*/_react.default.createElement(CorrelationIdContext.Provider, {
|
|
60
|
+
value: {
|
|
61
|
+
correlationId: id
|
|
62
|
+
}
|
|
63
|
+
}, children);
|
|
64
|
+
};
|
|
65
|
+
exports.CorrelationIdProvider = CorrelationIdProvider;
|
|
66
|
+
CorrelationIdProvider.propTypes = {
|
|
67
|
+
children: _propTypes.default.element.isRequired,
|
|
68
|
+
resetOnPageChange: _propTypes.default.bool,
|
|
69
|
+
correlationId: _propTypes.default.oneOfType([_propTypes.default.string, _propTypes.default.func]).isRequired,
|
|
70
|
+
location: _propTypes.default.object
|
|
71
|
+
};
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _react = _interopRequireDefault(require("react"));
|
|
4
|
+
var _react2 = require("@testing-library/react");
|
|
5
|
+
var _reactRouterDom = require("react-router-dom");
|
|
6
|
+
var _history = require("history");
|
|
7
|
+
var _index = require("./index");
|
|
8
|
+
var _hooks = require("../hooks");
|
|
9
|
+
var _crypto = _interopRequireDefault(require("crypto"));
|
|
10
|
+
var _propTypes = _interopRequireDefault(require("prop-types"));
|
|
11
|
+
var _userEvent = _interopRequireDefault(require("@testing-library/user-event"));
|
|
12
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
13
|
+
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); } }
|
|
14
|
+
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); }); }; } /*
|
|
15
|
+
* Copyright (c) 2022, salesforce.com, inc.
|
|
16
|
+
* All rights reserved.
|
|
17
|
+
* SPDX-License-Identifier: BSD-3-Clause
|
|
18
|
+
* For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause
|
|
19
|
+
*/
|
|
20
|
+
const SampleProvider = props => {
|
|
21
|
+
const {
|
|
22
|
+
correlationId,
|
|
23
|
+
resetOnPageChange
|
|
24
|
+
} = props;
|
|
25
|
+
return /*#__PURE__*/_react.default.createElement(_index.CorrelationIdProvider, {
|
|
26
|
+
correlationId: correlationId,
|
|
27
|
+
resetOnPageChange: resetOnPageChange
|
|
28
|
+
}, props.children);
|
|
29
|
+
};
|
|
30
|
+
SampleProvider.propTypes = {
|
|
31
|
+
children: _propTypes.default.element.isRequired,
|
|
32
|
+
resetOnPageChange: _propTypes.default.bool,
|
|
33
|
+
correlationId: _propTypes.default.oneOfType([_propTypes.default.string, _propTypes.default.func]).isRequired
|
|
34
|
+
};
|
|
35
|
+
const Component = () => {
|
|
36
|
+
const {
|
|
37
|
+
correlationId
|
|
38
|
+
} = (0, _hooks.useCorrelationId)();
|
|
39
|
+
return /*#__PURE__*/_react.default.createElement("div", {
|
|
40
|
+
className: 'correlation-id'
|
|
41
|
+
}, correlationId);
|
|
42
|
+
};
|
|
43
|
+
describe('CorrelationIdProvider', function () {
|
|
44
|
+
test('Renders without errors', () => {
|
|
45
|
+
const history = (0, _history.createMemoryHistory)();
|
|
46
|
+
const id = _crypto.default.randomUUID();
|
|
47
|
+
(0, _react2.render)( /*#__PURE__*/_react.default.createElement(_reactRouterDom.Router, {
|
|
48
|
+
history: history
|
|
49
|
+
}, /*#__PURE__*/_react.default.createElement(SampleProvider, {
|
|
50
|
+
correlationId: () => id
|
|
51
|
+
}, /*#__PURE__*/_react.default.createElement(Component, null))));
|
|
52
|
+
expect(_react2.screen.getByText(id)).toBeInTheDocument();
|
|
53
|
+
});
|
|
54
|
+
test('renders when correlationId is passed as a function', () => {
|
|
55
|
+
const id = _crypto.default.randomUUID();
|
|
56
|
+
const history = (0, _history.createMemoryHistory)();
|
|
57
|
+
(0, _react2.render)( /*#__PURE__*/_react.default.createElement(_reactRouterDom.Router, {
|
|
58
|
+
history: history
|
|
59
|
+
}, /*#__PURE__*/_react.default.createElement(SampleProvider, {
|
|
60
|
+
correlationId: () => id
|
|
61
|
+
}, /*#__PURE__*/_react.default.createElement(Component, null))));
|
|
62
|
+
expect(_react2.screen.getByText(id)).toBeInTheDocument();
|
|
63
|
+
});
|
|
64
|
+
test('renders when correlationId is passed as a string', () => {
|
|
65
|
+
const id = _crypto.default.randomUUID();
|
|
66
|
+
const history = (0, _history.createMemoryHistory)();
|
|
67
|
+
(0, _react2.render)( /*#__PURE__*/_react.default.createElement(_reactRouterDom.Router, {
|
|
68
|
+
history: history
|
|
69
|
+
}, /*#__PURE__*/_react.default.createElement(SampleProvider, {
|
|
70
|
+
correlationId: id,
|
|
71
|
+
resetOnPageChange: false
|
|
72
|
+
}, /*#__PURE__*/_react.default.createElement(Component, null))));
|
|
73
|
+
expect(_react2.screen.getByText(id)).toBeInTheDocument();
|
|
74
|
+
});
|
|
75
|
+
test('generates a new id when changing page', /*#__PURE__*/_asyncToGenerator(function* () {
|
|
76
|
+
const user = _userEvent.default.setup();
|
|
77
|
+
const history = (0, _history.createMemoryHistory)();
|
|
78
|
+
const Component = () => {
|
|
79
|
+
const {
|
|
80
|
+
correlationId
|
|
81
|
+
} = (0, _hooks.useCorrelationId)();
|
|
82
|
+
return /*#__PURE__*/_react.default.createElement("div", null, /*#__PURE__*/_react.default.createElement("div", {
|
|
83
|
+
"data-testid": "correlation-id"
|
|
84
|
+
}, correlationId), /*#__PURE__*/_react.default.createElement("button", {
|
|
85
|
+
className: "button",
|
|
86
|
+
onClick: () => history.push('/page-1')
|
|
87
|
+
}, "Go to another page"));
|
|
88
|
+
};
|
|
89
|
+
(0, _react2.render)( /*#__PURE__*/_react.default.createElement(_reactRouterDom.Router, {
|
|
90
|
+
history: history
|
|
91
|
+
}, /*#__PURE__*/_react.default.createElement(SampleProvider, {
|
|
92
|
+
correlationId: () => _crypto.default.randomUUID()
|
|
93
|
+
}, /*#__PURE__*/_react.default.createElement(Component, null))));
|
|
94
|
+
const firstRenderedId = _react2.screen.getByTestId('correlation-id').innerHTML;
|
|
95
|
+
const button = _react2.screen.getByText(/go to another page/i);
|
|
96
|
+
yield user.click(button);
|
|
97
|
+
const secondRenderedId = _react2.screen.getByTestId('correlation-id').innerHTML;
|
|
98
|
+
// expecting the provider to have a different correlation id when a page navigation happens
|
|
99
|
+
expect(firstRenderedId).not.toEqual(secondRenderedId);
|
|
100
|
+
}));
|
|
101
|
+
});
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.HTTPNotFound = exports.HTTPError = 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
|
+
class HTTPError extends Error {
|
|
15
|
+
constructor(status, message) {
|
|
16
|
+
super(message);
|
|
17
|
+
this.constructor = HTTPError;
|
|
18
|
+
this.__proto__ = HTTPError.prototype;
|
|
19
|
+
this.message = message;
|
|
20
|
+
this.status = status;
|
|
21
|
+
}
|
|
22
|
+
toString() {
|
|
23
|
+
return `HTTPError ${this.status}: ${this.message}`;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
exports.HTTPError = HTTPError;
|
|
27
|
+
class HTTPNotFound extends HTTPError {
|
|
28
|
+
constructor(message) {
|
|
29
|
+
super(404, message);
|
|
30
|
+
this.constructor = HTTPNotFound;
|
|
31
|
+
this.__proto__ = HTTPNotFound.prototype;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
exports.HTTPNotFound = HTTPNotFound;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var errors = _interopRequireWildcard(require("./errors"));
|
|
4
|
+
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
|
5
|
+
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
|
6
|
+
/*
|
|
7
|
+
* Copyright (c) 2021, salesforce.com, inc.
|
|
8
|
+
* All rights reserved.
|
|
9
|
+
* SPDX-License-Identifier: BSD-3-Clause
|
|
10
|
+
* For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
describe('Errors', () => {
|
|
14
|
+
test('HTTP Errors should have a working toString()', () => {
|
|
15
|
+
const status = 400;
|
|
16
|
+
const msg = 'This is a bad request';
|
|
17
|
+
const err = new errors.HTTPError(status, msg);
|
|
18
|
+
expect(err.toString()).toBe(`HTTPError ${status}: ${msg}`);
|
|
19
|
+
});
|
|
20
|
+
});
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.pages = exports.PAGEEVENTS = void 0;
|
|
7
|
+
var _eventEmitter = _interopRequireDefault(require("event-emitter"));
|
|
8
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
9
|
+
/*
|
|
10
|
+
* Copyright (c) 2021, salesforce.com, inc.
|
|
11
|
+
* All rights reserved.
|
|
12
|
+
* SPDX-License-Identifier: BSD-3-Clause
|
|
13
|
+
* For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
const PAGEEVENTS = {
|
|
17
|
+
PAGELOAD: 'PAGELOAD',
|
|
18
|
+
ERROR: 'ERROR'
|
|
19
|
+
};
|
|
20
|
+
exports.PAGEEVENTS = PAGEEVENTS;
|
|
21
|
+
class Pages {
|
|
22
|
+
pageLoad(templateName, start, end) {
|
|
23
|
+
const payload = {
|
|
24
|
+
templateName,
|
|
25
|
+
start,
|
|
26
|
+
end
|
|
27
|
+
};
|
|
28
|
+
this.emit(PAGEEVENTS.PAGELOAD, payload);
|
|
29
|
+
}
|
|
30
|
+
error(name, content) {
|
|
31
|
+
const payload = {
|
|
32
|
+
name,
|
|
33
|
+
content
|
|
34
|
+
};
|
|
35
|
+
this.emit(PAGEEVENTS.ERROR, payload);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
(0, _eventEmitter.default)(Pages.prototype);
|
|
39
|
+
const pages = new Pages();
|
|
40
|
+
exports.pages = pages;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _events = require("./events");
|
|
4
|
+
/*
|
|
5
|
+
* Copyright (c) 2021, salesforce.com, 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('Page Events', () => {
|
|
12
|
+
test('emit and receive a PAGELOAD Page Event', () => {
|
|
13
|
+
expect.assertions(1);
|
|
14
|
+
return new Promise(resolve => {
|
|
15
|
+
_events.pages.on(_events.PAGEEVENTS.PAGELOAD, evt => {
|
|
16
|
+
expect(JSON.stringify(evt)).toEqual(JSON.stringify({
|
|
17
|
+
templateName: 'blah',
|
|
18
|
+
start: 123,
|
|
19
|
+
end: 456
|
|
20
|
+
}));
|
|
21
|
+
return resolve();
|
|
22
|
+
});
|
|
23
|
+
_events.pages.pageLoad('blah', 123, 456);
|
|
24
|
+
});
|
|
25
|
+
});
|
|
26
|
+
test('emit and receive a ERROR Page Event', () => {
|
|
27
|
+
expect.assertions(1);
|
|
28
|
+
return new Promise(resolve => {
|
|
29
|
+
_events.pages.on(_events.PAGEEVENTS.ERROR, evt => {
|
|
30
|
+
expect(JSON.stringify(evt)).toEqual(JSON.stringify({
|
|
31
|
+
name: 'blah',
|
|
32
|
+
content: 'more blah'
|
|
33
|
+
}));
|
|
34
|
+
return resolve();
|
|
35
|
+
});
|
|
36
|
+
_events.pages.error('blah', 'more blah');
|
|
37
|
+
});
|
|
38
|
+
});
|
|
39
|
+
});
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.useServerContext = exports.useCorrelationId = void 0;
|
|
7
|
+
var _react = _interopRequireWildcard(require("react"));
|
|
8
|
+
var _contexts = require("../contexts");
|
|
9
|
+
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
|
10
|
+
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
|
11
|
+
/*
|
|
12
|
+
* Copyright (c) 2022, salesforce.com, inc.
|
|
13
|
+
* All rights reserved.
|
|
14
|
+
* SPDX-License-Identifier: BSD-3-Clause
|
|
15
|
+
* For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause
|
|
16
|
+
*/
|
|
17
|
+
/* istanbul ignore file */
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Use this hook to get the correlation id value of the closest CorrelationIdProvider component.
|
|
21
|
+
*
|
|
22
|
+
* @returns {object} The correlation id
|
|
23
|
+
*/
|
|
24
|
+
const useCorrelationId = () => {
|
|
25
|
+
const context = _react.default.useContext(_contexts.CorrelationIdContext);
|
|
26
|
+
if (context === undefined) {
|
|
27
|
+
throw new Error('useCorrelationId needs to be used within CorrelationIdProvider');
|
|
28
|
+
}
|
|
29
|
+
return context;
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Server context
|
|
34
|
+
* @typedef {Object} ServerContext
|
|
35
|
+
* @property {Object} req - Request object
|
|
36
|
+
* @property {Object} res - Response object
|
|
37
|
+
*/
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Get the server context
|
|
41
|
+
* @returns {ServerContext} ServerContext object
|
|
42
|
+
*
|
|
43
|
+
* @example
|
|
44
|
+
* const {res} = useServerContext()
|
|
45
|
+
* if (res && query.error) { res.status(404) }
|
|
46
|
+
*/
|
|
47
|
+
exports.useCorrelationId = useCorrelationId;
|
|
48
|
+
const useServerContext = () => {
|
|
49
|
+
const serverContext = (0, _react.useContext)(_contexts.ServerContext);
|
|
50
|
+
return serverContext;
|
|
51
|
+
};
|
|
52
|
+
exports.useServerContext = useServerContext;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = 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
|
+
const routes = [];
|
|
15
|
+
var _default = routes;
|
|
16
|
+
exports.default = _default;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var utils = _interopRequireWildcard(require("./utils"));
|
|
4
|
+
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
|
5
|
+
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
|
6
|
+
/*
|
|
7
|
+
* Copyright (c) 2021, salesforce.com, inc.
|
|
8
|
+
* All rights reserved.
|
|
9
|
+
* SPDX-License-Identifier: BSD-3-Clause
|
|
10
|
+
* For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
describe('getProxyConfigs (client-side)', () => {
|
|
14
|
+
const configs = [{
|
|
15
|
+
foo: 'bar'
|
|
16
|
+
}];
|
|
17
|
+
beforeEach(() => {
|
|
18
|
+
global.Progressive = {
|
|
19
|
+
ssrOptions: {
|
|
20
|
+
proxyConfigs: configs
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
});
|
|
24
|
+
afterEach(() => {
|
|
25
|
+
delete global.Progressive;
|
|
26
|
+
});
|
|
27
|
+
test('should return proxy configs set on window.Progressive', () => {
|
|
28
|
+
expect(utils.getProxyConfigs()).toEqual(configs);
|
|
29
|
+
});
|
|
30
|
+
});
|
|
31
|
+
describe('getAssetUrl (client-side)', () => {
|
|
32
|
+
beforeEach(() => {
|
|
33
|
+
global.Progressive = {
|
|
34
|
+
buildOrigin: 'test.com'
|
|
35
|
+
};
|
|
36
|
+
});
|
|
37
|
+
afterEach(() => {
|
|
38
|
+
delete global.Progressive;
|
|
39
|
+
});
|
|
40
|
+
test('should return build origin when path is undefined', () => {
|
|
41
|
+
expect(utils.getAssetUrl()).toBe('test.com');
|
|
42
|
+
});
|
|
43
|
+
test('should return origin + path', () => {
|
|
44
|
+
expect(utils.getAssetUrl('/path')).toBe('test.com/path');
|
|
45
|
+
});
|
|
46
|
+
});
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.getProxyConfigs = exports.getAssetUrl = void 0;
|
|
7
|
+
var _ssrShared = require("@salesforce/pwa-kit-runtime/utils/ssr-shared");
|
|
8
|
+
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; }
|
|
9
|
+
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; }
|
|
10
|
+
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; }
|
|
11
|
+
function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return typeof key === "symbol" ? key : String(key); }
|
|
12
|
+
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); } /*
|
|
13
|
+
* Copyright (c) 2021, salesforce.com, inc.
|
|
14
|
+
* All rights reserved.
|
|
15
|
+
* SPDX-License-Identifier: BSD-3-Clause
|
|
16
|
+
* For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause
|
|
17
|
+
*/ /**
|
|
18
|
+
* @module progressive-web-sdk/ssr/universal/utils
|
|
19
|
+
*/
|
|
20
|
+
const onClient = typeof window !== 'undefined';
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Get the URL that should be used to load an asset from the bundle.
|
|
24
|
+
*
|
|
25
|
+
* @param {string} path - relative path from the build directory to the asset
|
|
26
|
+
* @function
|
|
27
|
+
* @returns {string}
|
|
28
|
+
*/
|
|
29
|
+
const getAssetUrl = path => {
|
|
30
|
+
/* istanbul ignore next */
|
|
31
|
+
const publicPath = onClient ? `${window.Progressive.buildOrigin}` : `/mobify/bundle/${process.env.BUNDLE_ID || 'development'}/`;
|
|
32
|
+
return path ? `${publicPath}${path}` : publicPath;
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* @typedef {Object} ProxyConfig
|
|
37
|
+
* @property {String} protocol - http or https
|
|
38
|
+
* @property {String} host - the hostname
|
|
39
|
+
* @property {String} path - the path element that follows "mobify/proxy"
|
|
40
|
+
*/
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Return the set of proxies configured for the app.
|
|
44
|
+
*
|
|
45
|
+
* The result is an array of objects, each of which has 'protocol'
|
|
46
|
+
* (either 'http' or 'https'), 'host' (the hostname) and 'path' (the
|
|
47
|
+
* path element that follows "/mobify/proxy/", defaulting to 'base' for
|
|
48
|
+
* the first proxy, and 'base2' for the next).
|
|
49
|
+
*
|
|
50
|
+
* @function
|
|
51
|
+
* @returns {Array<ProxyConfig>}
|
|
52
|
+
*/
|
|
53
|
+
exports.getAssetUrl = getAssetUrl;
|
|
54
|
+
const getProxyConfigs = () => {
|
|
55
|
+
const configs = onClient ? (window.Progressive.ssrOptions || {}).proxyConfigs || [] : _ssrShared.proxyConfigs;
|
|
56
|
+
|
|
57
|
+
// Clone to avoid accidental mutation of important configuration variables.
|
|
58
|
+
return configs.map(config => _objectSpread({}, config));
|
|
59
|
+
};
|
|
60
|
+
exports.getProxyConfigs = getProxyConfigs;
|