@dr.pogodin/react-utils 1.47.0-alpha.2 → 1.47.0-alpha.4
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/babel.config.js +1 -1
- package/babel.module.config.js +11 -0
- package/bin/build.js +8 -4
- package/bin/setup.js +2 -3
- package/build/development/client/getInj.js +47 -45
- package/build/development/client/getInj.js.map +1 -1
- package/build/development/client/index.js +15 -21
- package/build/development/client/index.js.map +1 -1
- package/build/development/client/init.js +2 -6
- package/build/development/client/init.js.map +1 -1
- package/build/development/index.js +10 -179
- package/build/development/index.js.map +1 -1
- package/build/development/server/Cache.js +1 -8
- package/build/development/server/Cache.js.map +1 -1
- package/build/development/server/index.js +25 -50
- package/build/development/server/index.js.map +1 -1
- package/build/development/server/renderer.js +63 -92
- package/build/development/server/renderer.js.map +1 -1
- package/build/development/server/server.js +47 -58
- package/build/development/server/server.js.map +1 -1
- package/build/development/server/utils/errors.js +8 -31
- package/build/development/server/utils/errors.js.map +1 -1
- package/build/development/server/utils/index.js +2 -9
- package/build/development/server/utils/index.js.map +1 -1
- package/build/development/shared/components/Button/index.js +9 -16
- package/build/development/shared/components/Button/index.js.map +1 -1
- package/build/development/shared/components/Checkbox/index.js +6 -13
- package/build/development/shared/components/Checkbox/index.js.map +1 -1
- package/build/development/shared/components/GenericLink/index.js +4 -10
- package/build/development/shared/components/GenericLink/index.js.map +1 -1
- package/build/development/shared/components/Input/index.js +11 -18
- package/build/development/shared/components/Input/index.js.map +1 -1
- package/build/development/shared/components/Link.js +6 -13
- package/build/development/shared/components/Link.js.map +1 -1
- package/build/development/shared/components/Modal/index.js +16 -22
- package/build/development/shared/components/Modal/index.js.map +1 -1
- package/build/development/shared/components/NavLink.js +6 -13
- package/build/development/shared/components/NavLink.js.map +1 -1
- package/build/development/shared/components/PageLayout/index.js +7 -14
- package/build/development/shared/components/PageLayout/index.js.map +1 -1
- package/build/development/shared/components/TextArea/index.js +15 -22
- package/build/development/shared/components/TextArea/index.js.map +1 -1
- package/build/development/shared/components/Throbber/index.js +7 -14
- package/build/development/shared/components/Throbber/index.js.map +1 -1
- package/build/development/shared/components/WithTooltip/Tooltip.js +12 -18
- package/build/development/shared/components/WithTooltip/Tooltip.js.map +1 -1
- package/build/development/shared/components/WithTooltip/index.js +16 -23
- package/build/development/shared/components/WithTooltip/index.js.map +1 -1
- package/build/development/shared/components/YouTubeVideo/index.js +10 -17
- package/build/development/shared/components/YouTubeVideo/index.js.map +1 -1
- package/build/development/shared/components/index.js +16 -130
- package/build/development/shared/components/index.js.map +1 -1
- package/build/development/shared/components/selectors/CustomDropdown/Options/index.js +12 -19
- package/build/development/shared/components/selectors/CustomDropdown/Options/index.js.map +1 -1
- package/build/development/shared/components/selectors/CustomDropdown/index.js +20 -28
- package/build/development/shared/components/selectors/CustomDropdown/index.js.map +1 -1
- package/build/development/shared/components/selectors/NativeDropdown/index.js +13 -19
- package/build/development/shared/components/selectors/NativeDropdown/index.js.map +1 -1
- package/build/development/shared/components/selectors/Switch/index.js +10 -17
- package/build/development/shared/components/selectors/Switch/index.js.map +1 -1
- package/build/development/shared/components/selectors/common.js +1 -7
- package/build/development/shared/components/selectors/common.js.map +1 -1
- package/build/development/shared/components/selectors/index.js +3 -27
- package/build/development/shared/components/selectors/index.js.map +1 -1
- package/build/development/shared/utils/config.js +40 -20
- package/build/development/shared/utils/config.js.map +1 -1
- package/build/development/shared/utils/globalState.js +3 -8
- package/build/development/shared/utils/globalState.js.map +1 -1
- package/build/development/shared/utils/index.js +12 -89
- package/build/development/shared/utils/index.js.map +1 -1
- package/build/development/shared/utils/isomorphy/buildInfo.js +2 -9
- package/build/development/shared/utils/isomorphy/buildInfo.js.map +1 -1
- package/build/development/shared/utils/isomorphy/environment-check.js +2 -8
- package/build/development/shared/utils/isomorphy/environment-check.js.map +1 -1
- package/build/development/shared/utils/isomorphy/index.js +7 -32
- package/build/development/shared/utils/isomorphy/index.js.map +1 -1
- package/build/development/shared/utils/jest/E2eSsrEnv.js +20 -31
- package/build/development/shared/utils/jest/E2eSsrEnv.js.map +1 -1
- package/build/development/shared/utils/jest/global.js +1 -7
- package/build/development/shared/utils/jest/global.js.map +1 -1
- package/build/development/shared/utils/jest/index.js +20 -44
- package/build/development/shared/utils/jest/index.js.map +1 -1
- package/build/development/shared/utils/splitComponent.js +24 -30
- package/build/development/shared/utils/splitComponent.js.map +1 -1
- package/build/development/shared/utils/time.js +22 -31
- package/build/development/shared/utils/time.js.map +1 -1
- package/build/development/shared/utils/webpack.js +13 -16
- package/build/development/shared/utils/webpack.js.map +1 -1
- package/build/production/client/getInj.js +13 -11
- package/build/production/client/getInj.js.map +1 -1
- package/build/production/client/index.js +3 -3
- package/build/production/client/index.js.map +1 -1
- package/build/production/client/init.js +2 -2
- package/build/production/client/init.js.map +1 -1
- package/build/production/index.js +3 -2
- package/build/production/index.js.map +1 -1
- package/build/production/server/Cache.js +3 -3
- package/build/production/server/Cache.js.map +1 -1
- package/build/production/server/index.js +8 -8
- package/build/production/server/index.js.map +1 -1
- package/build/production/server/renderer.js +24 -25
- package/build/production/server/renderer.js.map +1 -1
- package/build/production/server/server.js +9 -9
- package/build/production/server/server.js.map +1 -1
- package/build/production/server/utils/errors.js +9 -9
- package/build/production/server/utils/errors.js.map +1 -1
- package/build/production/server/utils/index.js +2 -1
- package/build/production/server/utils/index.js.map +1 -1
- package/build/production/shared/components/Button/index.js +4 -4
- package/build/production/shared/components/Button/index.js.map +1 -1
- package/build/production/shared/components/Checkbox/index.js +1 -1
- package/build/production/shared/components/Checkbox/index.js.map +1 -1
- package/build/production/shared/components/GenericLink/index.js +4 -4
- package/build/production/shared/components/GenericLink/index.js.map +1 -1
- package/build/production/shared/components/Input/index.js +5 -5
- package/build/production/shared/components/Input/index.js.map +1 -1
- package/build/production/shared/components/Link.js +3 -3
- package/build/production/shared/components/Link.js.map +1 -1
- package/build/production/shared/components/Modal/index.js +7 -7
- package/build/production/shared/components/Modal/index.js.map +1 -1
- package/build/production/shared/components/NavLink.js +2 -2
- package/build/production/shared/components/NavLink.js.map +1 -1
- package/build/production/shared/components/PageLayout/index.js +2 -2
- package/build/production/shared/components/PageLayout/index.js.map +1 -1
- package/build/production/shared/components/TextArea/index.js +5 -5
- package/build/production/shared/components/TextArea/index.js.map +1 -1
- package/build/production/shared/components/Throbber/index.js +2 -2
- package/build/production/shared/components/Throbber/index.js.map +1 -1
- package/build/production/shared/components/WithTooltip/Tooltip.js +4 -4
- package/build/production/shared/components/WithTooltip/Tooltip.js.map +1 -1
- package/build/production/shared/components/WithTooltip/index.js +4 -4
- package/build/production/shared/components/WithTooltip/index.js.map +1 -1
- package/build/production/shared/components/YouTubeVideo/index.js +4 -4
- package/build/production/shared/components/YouTubeVideo/index.js.map +1 -1
- package/build/production/shared/components/index.js +3 -1
- package/build/production/shared/components/index.js.map +1 -1
- package/build/production/shared/components/selectors/CustomDropdown/Options/index.js +2 -2
- package/build/production/shared/components/selectors/CustomDropdown/Options/index.js.map +1 -1
- package/build/production/shared/components/selectors/CustomDropdown/index.js +2 -2
- package/build/production/shared/components/selectors/CustomDropdown/index.js.map +1 -1
- package/build/production/shared/components/selectors/NativeDropdown/index.js +4 -4
- package/build/production/shared/components/selectors/NativeDropdown/index.js.map +1 -1
- package/build/production/shared/components/selectors/Switch/index.js +1 -1
- package/build/production/shared/components/selectors/Switch/index.js.map +1 -1
- package/build/production/shared/components/selectors/common.js +2 -2
- package/build/production/shared/components/selectors/common.js.map +1 -1
- package/build/production/shared/components/selectors/index.js +1 -1
- package/build/production/shared/components/selectors/index.js.map +1 -1
- package/build/production/shared/utils/config.js +8 -4
- package/build/production/shared/utils/config.js.map +1 -1
- package/build/production/shared/utils/globalState.js +2 -2
- package/build/production/shared/utils/globalState.js.map +1 -1
- package/build/production/shared/utils/index.js +1 -1
- package/build/production/shared/utils/index.js.map +1 -1
- package/build/production/shared/utils/isomorphy/buildInfo.js +3 -3
- package/build/production/shared/utils/isomorphy/buildInfo.js.map +1 -1
- package/build/production/shared/utils/isomorphy/environment-check.js +3 -3
- package/build/production/shared/utils/isomorphy/environment-check.js.map +1 -1
- package/build/production/shared/utils/isomorphy/index.js +4 -4
- package/build/production/shared/utils/isomorphy/index.js.map +1 -1
- package/build/production/shared/utils/jest/E2eSsrEnv.js +14 -14
- package/build/production/shared/utils/jest/E2eSsrEnv.js.map +1 -1
- package/build/production/shared/utils/jest/global.js +1 -1
- package/build/production/shared/utils/jest/global.js.map +1 -1
- package/build/production/shared/utils/jest/index.js +11 -11
- package/build/production/shared/utils/jest/index.js.map +1 -1
- package/build/production/shared/utils/splitComponent.js +11 -11
- package/build/production/shared/utils/splitComponent.js.map +1 -1
- package/build/production/shared/utils/time.js +3 -3
- package/build/production/shared/utils/time.js.map +1 -1
- package/build/production/shared/utils/webpack.js +6 -6
- package/build/production/shared/utils/webpack.js.map +1 -1
- package/build/types-code/client/getInj.d.ts +1 -2
- package/build/types-code/client/index.d.ts +1 -1
- package/build/types-code/index.d.ts +1 -1
- package/build/types-code/server/index.d.ts +2 -2
- package/build/types-code/shared/utils/config.d.ts +4 -2
- package/build/types-code/shared/utils/index.d.ts +2 -2
- package/build/types-code/shared/utils/splitComponent.d.ts +6 -4
- package/build/web/client/getInj.js +48 -37
- package/build/web/client/getInj.js.map +1 -1
- package/build/web/client/index.js +3 -2
- package/build/web/client/index.js.map +1 -1
- package/build/web/index.js +3 -3
- package/build/web/index.js.map +1 -1
- package/build/web/server/index.js +9 -15
- package/build/web/server/index.js.map +1 -1
- package/build/web/server/renderer.js +24 -40
- package/build/web/server/renderer.js.map +1 -1
- package/build/web/server/server.js +2 -4
- package/build/web/server/server.js.map +1 -1
- package/build/web/shared/components/Modal/index.js +2 -2
- package/build/web/shared/components/Modal/index.js.map +1 -1
- package/build/web/shared/utils/config.js +36 -10
- package/build/web/shared/utils/config.js.map +1 -1
- package/build/web/shared/utils/index.js +2 -2
- package/build/web/shared/utils/index.js.map +1 -1
- package/build/web/shared/utils/jest/E2eSsrEnv.js +1 -2
- package/build/web/shared/utils/jest/E2eSsrEnv.js.map +1 -1
- package/build/web/shared/utils/splitComponent.js +2 -1
- package/build/web/shared/utils/splitComponent.js.map +1 -1
- package/build/web/shared/utils/webpack.js +11 -7
- package/build/web/shared/utils/webpack.js.map +1 -1
- package/config/babel/node-ssr.js +5 -5
- package/config/jest/default.js +1 -0
- package/config/jest/setup.js +8 -1
- package/config/webpack/app-base.js +13 -12
- package/config/webpack/app-development.js +3 -3
- package/config/webpack/lib-base.js +1 -2
- package/package.json +9 -9
- package/src/client/getInj.ts +60 -40
- package/src/client/index.tsx +5 -3
- package/src/index.ts +3 -3
- package/src/server/index.ts +9 -15
- package/src/server/renderer.tsx +27 -45
- package/src/server/server.ts +2 -4
- package/src/shared/components/Modal/index.tsx +2 -2
- package/src/shared/utils/config.ts +48 -12
- package/src/shared/utils/index.ts +2 -2
- package/src/shared/utils/jest/E2eSsrEnv.ts +1 -2
- package/src/shared/utils/splitComponent.tsx +14 -2
- package/src/shared/utils/webpack.ts +14 -8
- package/types.d.ts +1 -6
package/src/server/renderer.tsx
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
* ExpressJS middleware for server-side rendering of a ReactJS app.
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
+
import { Buffer } from 'node:buffer';
|
|
6
|
+
import { type Cipheriv, createCipheriv, randomBytes } from 'node:crypto';
|
|
5
7
|
import fs from 'node:fs';
|
|
6
8
|
import path from 'node:path';
|
|
7
9
|
import { Writable } from 'node:stream';
|
|
@@ -15,16 +17,14 @@ import winston from 'winston';
|
|
|
15
17
|
import { GlobalStateProvider, SsrContext } from '@dr.pogodin/react-global-state';
|
|
16
18
|
import { timer } from '@dr.pogodin/js-utils';
|
|
17
19
|
|
|
18
|
-
import
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
import omit from 'lodash/omit';
|
|
20
|
+
import {
|
|
21
|
+
cloneDeep,
|
|
22
|
+
defaults,
|
|
23
|
+
get,
|
|
24
|
+
mapValues,
|
|
25
|
+
} from 'lodash-es';
|
|
25
26
|
|
|
26
27
|
import config from 'config';
|
|
27
|
-
import forge from 'node-forge';
|
|
28
28
|
|
|
29
29
|
import { prerenderToNodeStream } from 'react-dom/static';
|
|
30
30
|
import { type HelmetDataContext, HelmetProvider } from '@dr.pogodin/react-helmet';
|
|
@@ -36,7 +36,9 @@ import type { ChunkGroupsT, SsrContextT } from 'utils/globalState';
|
|
|
36
36
|
|
|
37
37
|
import Cache from './Cache';
|
|
38
38
|
|
|
39
|
-
|
|
39
|
+
// @ts-expect-error "Property 'SECRET' does not exist on type 'IConfig'."
|
|
40
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
41
|
+
const { SECRET, ...sanitizedConfig } = config;
|
|
40
42
|
|
|
41
43
|
// Note: These type definitions for logger are copied from Winston logger,
|
|
42
44
|
// then simplified to make it easier to fit an alternative logger into this
|
|
@@ -133,26 +135,15 @@ function readChunkGroupsJson(buildDir: string) {
|
|
|
133
135
|
|
|
134
136
|
/**
|
|
135
137
|
* Prepares a new Cipher for data encryption.
|
|
136
|
-
* @param key Encryption key (32-bit random key is expected
|
|
137
|
-
*
|
|
138
|
-
* @return Resolves to the object with two fields:
|
|
138
|
+
* @param key Encryption key (32-bit random, Base64-encoded key is expected).
|
|
139
|
+
* @return Returns a tuple of:
|
|
139
140
|
* 1. cipher - a new Cipher, ready for encryption;
|
|
140
141
|
* 2. iv - initial vector used by the cipher.
|
|
141
142
|
*/
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
iv
|
|
145
|
-
|
|
146
|
-
return new Promise((resolve, reject) => {
|
|
147
|
-
forge.random.getBytes(32, (err, iv) => {
|
|
148
|
-
if (err) reject(err);
|
|
149
|
-
else {
|
|
150
|
-
const cipher = forge.cipher.createCipher('AES-CBC', key);
|
|
151
|
-
cipher.start({ iv });
|
|
152
|
-
resolve({ cipher, iv });
|
|
153
|
-
}
|
|
154
|
-
});
|
|
155
|
-
});
|
|
143
|
+
function prepareCipher(key: string): [cipher: Cipheriv, iv: Buffer] {
|
|
144
|
+
const iv = randomBytes(16);
|
|
145
|
+
const cipher = createCipheriv('AES-256-CBC', Buffer.from(key, 'base64'), iv);
|
|
146
|
+
return [cipher, iv];
|
|
156
147
|
}
|
|
157
148
|
|
|
158
149
|
/**
|
|
@@ -196,7 +187,7 @@ function groupExtraScripts(scripts: Array<string | ScriptT> = []) {
|
|
|
196
187
|
[SCRIPT_LOCATIONS.HEAD_OPEN]: '',
|
|
197
188
|
};
|
|
198
189
|
for (const script of scripts) {
|
|
199
|
-
if (
|
|
190
|
+
if (typeof script === 'string') {
|
|
200
191
|
if (script) res[SCRIPT_LOCATIONS.DEFAULT] += script;
|
|
201
192
|
} else if (script.code) {
|
|
202
193
|
if (script.location in res) res[script.location] += script.code;
|
|
@@ -312,7 +303,7 @@ export default function factory(
|
|
|
312
303
|
webpackConfig: Configuration,
|
|
313
304
|
options: OptionsT,
|
|
314
305
|
): RequestHandler {
|
|
315
|
-
const ops: OptionsT = defaults(
|
|
306
|
+
const ops: OptionsT = defaults({ ...options }, {
|
|
316
307
|
beforeRender: async () => Promise.resolve({}),
|
|
317
308
|
maxSsrRounds: 10,
|
|
318
309
|
ssrTimeout: 1000,
|
|
@@ -400,21 +391,9 @@ export default function factory(
|
|
|
400
391
|
}
|
|
401
392
|
|
|
402
393
|
const brr = ops.beforeRender!(req, sanitizedConfig as unknown as ConfigT);
|
|
394
|
+
const { configToInject, extraScripts, initialState } = await brr;
|
|
403
395
|
|
|
404
|
-
const [
|
|
405
|
-
configToInject,
|
|
406
|
-
extraScripts,
|
|
407
|
-
initialState,
|
|
408
|
-
}, {
|
|
409
|
-
cipher,
|
|
410
|
-
iv,
|
|
411
|
-
}] = await Promise.all([
|
|
412
|
-
// NOTE: Written this way to avoid triggering the "await-thenable"
|
|
413
|
-
// ESLint rule.
|
|
414
|
-
brr instanceof Promise ? brr : Promise.resolve(brr),
|
|
415
|
-
|
|
416
|
-
prepareCipher(buildInfo.key),
|
|
417
|
-
]);
|
|
396
|
+
const [cipher, iv] = prepareCipher(buildInfo.key);
|
|
418
397
|
|
|
419
398
|
let helmet: HelmetDataContext['helmet'];
|
|
420
399
|
|
|
@@ -553,9 +532,12 @@ export default function factory(
|
|
|
553
532
|
ignoreFunction: true,
|
|
554
533
|
unsafe: true,
|
|
555
534
|
});
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
535
|
+
|
|
536
|
+
const INJ = Buffer.concat([
|
|
537
|
+
iv,
|
|
538
|
+
cipher.update(payload, 'utf8'),
|
|
539
|
+
cipher.final(),
|
|
540
|
+
]).toString('base64');
|
|
559
541
|
|
|
560
542
|
const chunkSet = new Set<string>();
|
|
561
543
|
|
package/src/server/server.ts
CHANGED
|
@@ -5,9 +5,7 @@
|
|
|
5
5
|
import { sep } from 'node:path';
|
|
6
6
|
import { pathToFileURL } from 'node:url';
|
|
7
7
|
|
|
8
|
-
import cloneDeep from 'lodash
|
|
9
|
-
import mapValues from 'lodash/mapValues';
|
|
10
|
-
import pick from 'lodash/pick';
|
|
8
|
+
import { cloneDeep, mapValues, pick } from 'lodash-es';
|
|
11
9
|
|
|
12
10
|
import compression from 'compression';
|
|
13
11
|
import cookieParser from 'cookie-parser';
|
|
@@ -250,7 +248,7 @@ export default async function factory(
|
|
|
250
248
|
} as Location;
|
|
251
249
|
}
|
|
252
250
|
|
|
253
|
-
const { webpack } = await import(/* webpackChunkName: "server-side-code" */ 'webpack');
|
|
251
|
+
const { default: webpack } = await import(/* webpackChunkName: "server-side-code" */ 'webpack');
|
|
254
252
|
|
|
255
253
|
const { default: webpackDevMiddleware } = await import(
|
|
256
254
|
/* webpackChunkName: "server-side-code" */ 'webpack-dev-middleware'
|
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
useRef,
|
|
8
8
|
} from 'react';
|
|
9
9
|
|
|
10
|
-
import
|
|
10
|
+
import { createPortal } from 'react-dom';
|
|
11
11
|
import themed, { type Theme } from '@dr.pogodin/react-themes';
|
|
12
12
|
|
|
13
13
|
import baseTheme from './base-theme.scss';
|
|
@@ -96,7 +96,7 @@ const BaseModal: FunctionComponent<PropsT> = ({
|
|
|
96
96
|
/>
|
|
97
97
|
), []);
|
|
98
98
|
|
|
99
|
-
return
|
|
99
|
+
return createPortal(
|
|
100
100
|
(
|
|
101
101
|
<div>
|
|
102
102
|
{focusLast}
|
|
@@ -7,17 +7,53 @@ import clientGetInj from '../../client/getInj';
|
|
|
7
7
|
import { IS_CLIENT_SIDE } from './isomorphy/environment-check';
|
|
8
8
|
import { requireWeak } from './webpack';
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
10
|
+
type ConfigT = Record<string, unknown>;
|
|
11
|
+
|
|
12
|
+
let config: ConfigT | Promise<ConfigT> | undefined;
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Injects CSRF token into config (on client-side only).
|
|
16
|
+
*
|
|
17
|
+
* BEWARE: It mutates the argument, and also returns it as the result,
|
|
18
|
+
* for chaining.
|
|
19
|
+
*/
|
|
20
|
+
function injectCsrfToken(cfg: ConfigT): ConfigT {
|
|
21
|
+
// The safeguard for "document" is necessary because in non-Node environments,
|
|
22
|
+
// like React Native, IS_CLIENT_SIDE is "true", however "document" and a bunch
|
|
23
|
+
// of other browser-world features are not available.
|
|
24
|
+
if (IS_CLIENT_SIDE && typeof document !== 'undefined') {
|
|
25
|
+
// eslint-disable-next-line no-param-reassign
|
|
26
|
+
cfg.CSRF = parse(document.cookie).csrfToken;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
return cfg;
|
|
21
30
|
}
|
|
22
31
|
|
|
23
|
-
export
|
|
32
|
+
export function getConfig(sync: true): ConfigT;
|
|
33
|
+
|
|
34
|
+
export function getConfig(sync?: boolean): ConfigT | Promise<ConfigT>;
|
|
35
|
+
|
|
36
|
+
export function getConfig(sync?: boolean): ConfigT | Promise<ConfigT> {
|
|
37
|
+
if (!config) {
|
|
38
|
+
if (IS_CLIENT_SIDE) {
|
|
39
|
+
const inj = clientGetInj();
|
|
40
|
+
config = inj instanceof Promise
|
|
41
|
+
? inj.then((injection) => {
|
|
42
|
+
const res = injectCsrfToken(injection.CONFIG ?? {});
|
|
43
|
+
config = res;
|
|
44
|
+
return res;
|
|
45
|
+
})
|
|
46
|
+
: injectCsrfToken(inj.CONFIG ?? {});
|
|
47
|
+
} else {
|
|
48
|
+
const weak = requireWeak<ConfigT>('config');
|
|
49
|
+
if (!weak) throw Error('Internal error');
|
|
50
|
+
config = weak;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
if (sync && (config instanceof Promise)) {
|
|
55
|
+
throw Error('The config is not available yet');
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
return config;
|
|
59
|
+
}
|
|
@@ -5,7 +5,7 @@ import themedImpl, {
|
|
|
5
5
|
ThemeProvider,
|
|
6
6
|
} from '@dr.pogodin/react-themes';
|
|
7
7
|
|
|
8
|
-
import
|
|
8
|
+
import { getConfig } from './config';
|
|
9
9
|
import * as isomorphy from './isomorphy';
|
|
10
10
|
import time from './time';
|
|
11
11
|
import * as webpack from './webpack';
|
|
@@ -36,7 +36,7 @@ themed.PRIORITY = PRIORITY;
|
|
|
36
36
|
|
|
37
37
|
export {
|
|
38
38
|
type Theme,
|
|
39
|
-
|
|
39
|
+
getConfig,
|
|
40
40
|
isomorphy,
|
|
41
41
|
themed,
|
|
42
42
|
ThemeProvider,
|
|
@@ -20,8 +20,7 @@ import path from 'node:path';
|
|
|
20
20
|
|
|
21
21
|
import type { Request, Response } from 'express';
|
|
22
22
|
|
|
23
|
-
import defaults from 'lodash
|
|
24
|
-
import set from 'lodash/set';
|
|
23
|
+
import { defaults, set } from 'lodash-es';
|
|
25
24
|
|
|
26
25
|
import type { ReactNode } from 'react';
|
|
27
26
|
|
|
@@ -25,7 +25,9 @@ function getClientChunkGroups(): Promise<ChunkGroupsT> | undefined {
|
|
|
25
25
|
|
|
26
26
|
return (async () => {
|
|
27
27
|
const { default: getInj } = await import(/* webpackChunkName: "react-utils-client-side-code" */ '../../client/getInj');
|
|
28
|
-
|
|
28
|
+
|
|
29
|
+
const inj = await getInj();
|
|
30
|
+
return inj.CHUNK_GROUPS ?? {};
|
|
29
31
|
})();
|
|
30
32
|
}
|
|
31
33
|
|
|
@@ -171,6 +173,16 @@ type ComponentOrModule<PropsT> = ComponentType<PropsT> | {
|
|
|
171
173
|
default: ComponentType<PropsT>;
|
|
172
174
|
};
|
|
173
175
|
|
|
176
|
+
type GenericComponentPropsT = {
|
|
177
|
+
children?: ReactNode;
|
|
178
|
+
ref?: RefObject<unknown>;
|
|
179
|
+
|
|
180
|
+
// NOTE: This is necessary, as without it this type (with only optional
|
|
181
|
+
// fields) will be conisdered as "weak" by TypeScript, and it will be
|
|
182
|
+
// a error to assign to it any type that does not use "children", or "ref".
|
|
183
|
+
[propName: string]: unknown;
|
|
184
|
+
};
|
|
185
|
+
|
|
174
186
|
/**
|
|
175
187
|
* Given an async component retrieval function `getComponent()` it creates
|
|
176
188
|
* a special "code split" component, which uses <Suspense> to asynchronously
|
|
@@ -182,7 +194,7 @@ type ComponentOrModule<PropsT> = ComponentType<PropsT> | {
|
|
|
182
194
|
* @return {React.ElementType}
|
|
183
195
|
*/
|
|
184
196
|
export default function splitComponent<
|
|
185
|
-
ComponentPropsT extends
|
|
197
|
+
ComponentPropsT extends GenericComponentPropsT,
|
|
186
198
|
>({
|
|
187
199
|
chunkName,
|
|
188
200
|
getComponent,
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import type PathNS from 'node:path';
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
// eslint-disable-next-line import/enforce-node-protocol-usage
|
|
4
|
+
import { createRequire } from 'module';
|
|
5
|
+
|
|
6
|
+
import { IS_CLIENT_SIDE, IS_SERVER_SIDE } from './isomorphy';
|
|
4
7
|
|
|
5
8
|
type RequireWeakOptionsT = {
|
|
6
9
|
basePath?: string;
|
|
@@ -10,6 +13,10 @@ type RequireWeakResT<T> = T extends { default: infer D }
|
|
|
10
13
|
? (D extends null | undefined ? T : D & Omit<T, 'default'>)
|
|
11
14
|
: T;
|
|
12
15
|
|
|
16
|
+
let require: ((url: string) => unknown) | undefined;
|
|
17
|
+
|
|
18
|
+
if (IS_SERVER_SIDE) require = createRequire(import.meta.url);
|
|
19
|
+
|
|
13
20
|
/**
|
|
14
21
|
* Requires the specified module without including it into the bundle during
|
|
15
22
|
* Webpack build.
|
|
@@ -36,14 +43,12 @@ export function requireWeak<T extends object>(
|
|
|
36
43
|
({ basePath } = ops);
|
|
37
44
|
}
|
|
38
45
|
|
|
39
|
-
// eslint-disable-next-line no-eval
|
|
40
|
-
const req = eval('require') as (path: string) => unknown;
|
|
41
|
-
|
|
42
46
|
// eslint-disable-next-line @typescript-eslint/unbound-method
|
|
43
|
-
const { resolve } =
|
|
47
|
+
const { resolve } = require!('node:path') as typeof PathNS;
|
|
44
48
|
|
|
45
49
|
const path = basePath ? resolve(basePath, modulePath) : modulePath;
|
|
46
|
-
|
|
50
|
+
|
|
51
|
+
const module = require!(path) as T;
|
|
47
52
|
|
|
48
53
|
if (!('default' in module) || !module.default) return module as RequireWeakResT<T>;
|
|
49
54
|
|
|
@@ -53,8 +58,9 @@ export function requireWeak<T extends object>(
|
|
|
53
58
|
|
|
54
59
|
Object.entries(named).forEach(([name, value]) => {
|
|
55
60
|
const assigned = res[name as keyof RequireWeakResT<T>];
|
|
56
|
-
if (assigned
|
|
57
|
-
|
|
61
|
+
if (assigned === undefined) {
|
|
62
|
+
(res[name as keyof RequireWeakResT<T>] as unknown) = value;
|
|
63
|
+
} else if (assigned !== value) {
|
|
58
64
|
throw Error('Conflict between default and named exports');
|
|
59
65
|
}
|
|
60
66
|
});
|
package/types.d.ts
CHANGED
|
@@ -4,6 +4,7 @@ declare var IS_REACT_ACT_ENVIRONMENT: boolean | undefined;
|
|
|
4
4
|
declare var REACT_UTILS_WEBPACK_BUNDLE: boolean | undefined;
|
|
5
5
|
declare var REACT_UTILS_LIBRARY_LOADED: boolean | undefined;
|
|
6
6
|
declare var REACT_UTILS_FORCE_CLIENT_SIDE: boolean | undefined;
|
|
7
|
+
declare var SCENE_INIT_PROMISE: Promise<void> | undefined;
|
|
7
8
|
/* eslint-enable no-var */
|
|
8
9
|
|
|
9
10
|
declare module '@babel/register/experimental-worker' {
|
|
@@ -19,12 +20,6 @@ declare module '@babel/register/experimental-worker' {
|
|
|
19
20
|
export default register;
|
|
20
21
|
}
|
|
21
22
|
|
|
22
|
-
declare module 'node-forge/lib/forge' {
|
|
23
|
-
import F from 'node-forge';
|
|
24
|
-
|
|
25
|
-
export default F;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
23
|
declare module '*.png' {
|
|
29
24
|
const path: string;
|
|
30
25
|
export default path;
|