@common-stack/generate-plugin 8.2.2-alpha.0 → 8.2.2-alpha.2
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 +8 -0
- package/lib/generators/add-backend/files/package.json +1 -1
- package/lib/generators/add-frontend/frameworks/tailwindui/src/entry.client.tsx.template +11 -15
- package/lib/generators/add-frontend/frameworks/tailwindui/src/entry.server.tsx.template +9 -10
- package/lib/generators/add-frontend/frameworks/tailwindui/src/root.tsx.template +68 -42
- package/lib/generators/add-frontend/frameworks/tailwindui/tailwind.config.ts.template +288 -9
- package/lib/generators/add-frontend/templates/package.json +3 -7
- package/lib/generators/add-frontend/templates/server.js +11 -10
- package/lib/generators/add-frontend/templates/src/routes.ts.template +38 -0
- package/lib/generators/add-frontend/templates/vite.config.ts.template +91 -48
- package/lib/generators/add-fullstack/files/package.json +3 -3
- package/lib/generators/add-moleculer/files/package.json +5 -5
- package/lib/generators/add-package/files/browser/package.json +1 -1
- package/lib/generators/add-package/files/server/package.json +3 -3
- package/package.json +3 -3
- package/src/generators/add-backend/files/package.json +1 -1
- package/src/generators/add-frontend/frameworks/tailwindui/src/entry.client.tsx.template +11 -15
- package/src/generators/add-frontend/frameworks/tailwindui/src/entry.server.tsx.template +9 -10
- package/src/generators/add-frontend/frameworks/tailwindui/src/root.tsx.template +68 -42
- package/src/generators/add-frontend/frameworks/tailwindui/tailwind.config.ts.template +288 -9
- package/src/generators/add-frontend/templates/package.json +3 -7
- package/src/generators/add-frontend/templates/server.js +11 -10
- package/src/generators/add-frontend/templates/src/routes.ts.template +38 -0
- package/src/generators/add-frontend/templates/vite.config.ts.template +91 -48
- package/src/generators/add-fullstack/files/package.json +3 -3
- package/src/generators/add-moleculer/files/package.json +5 -5
- package/src/generators/add-package/files/browser/package.json +1 -1
- package/src/generators/add-package/files/server/package.json +3 -3
|
@@ -1,14 +1,9 @@
|
|
|
1
1
|
import express from 'express';
|
|
2
2
|
import compression from 'compression';
|
|
3
3
|
import { createRequestHandler } from '@remix-run/express';
|
|
4
|
-
import { installGlobals } from '@remix-run/node';
|
|
5
4
|
import './env.js';
|
|
6
|
-
import {
|
|
7
|
-
|
|
8
|
-
} from '@common-stack/rollup-vite-utils/lib/preStartup/configLoader/configLoader.js';
|
|
9
|
-
import config from './app/cde-webconfig.json' assert { type: 'json' };
|
|
10
|
-
|
|
11
|
-
installGlobals();
|
|
5
|
+
import { performCopyOperations } from '@common-stack/rollup-vite-utils/lib/preStartup/configLoader/configLoader.js';
|
|
6
|
+
import config from './app/cde-webconfig.json' with { type: 'json' };
|
|
12
7
|
|
|
13
8
|
Object.keys(config.buildConfig).forEach((key) => {
|
|
14
9
|
global[key] = config.buildConfig[key];
|
|
@@ -17,9 +12,15 @@ Object.keys(config.buildConfig).forEach((key) => {
|
|
|
17
12
|
const startServer = async () => {
|
|
18
13
|
await performCopyOperations(config);
|
|
19
14
|
|
|
20
|
-
const { corsMiddleware } = await import(
|
|
21
|
-
|
|
22
|
-
|
|
15
|
+
const { corsMiddleware } = await import(
|
|
16
|
+
`./${config.commonPaths.appPath}/${config.commonPaths.frontendStackPath}/backend/middlewares/cors.js`
|
|
17
|
+
);
|
|
18
|
+
const { containerMiddleware } = await import(
|
|
19
|
+
`./${config.commonPaths.appPath}/${config.commonPaths.frontendStackPath}/backend/middlewares/container.js`
|
|
20
|
+
);
|
|
21
|
+
const { loadContext } = await import(
|
|
22
|
+
`./${config.commonPaths.appPath}/${config.commonPaths.frontendStackPath}/load-context.server.js`
|
|
23
|
+
);
|
|
23
24
|
|
|
24
25
|
const viteDevServer =
|
|
25
26
|
process.env.NODE_ENV === 'production'
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
// import { flatRoutes } from "@remix-run/fs-routes";
|
|
2
|
+
import { type RouteConfig } from '@remix-run/route-config';
|
|
3
|
+
import { remixRoutesOptionAdapter } from '@remix-run/routes-option-adapter';
|
|
4
|
+
import { dirname, resolve } from 'path';
|
|
5
|
+
import { fileURLToPath } from 'url';
|
|
6
|
+
import { defineRoutesConfig } from '@common-stack/rollup-vite-utils/lib/vite-wrappers/json-wrappers.js';
|
|
7
|
+
import { performCopyOperations } from '@common-stack/rollup-vite-utils/lib/preStartup/configLoader/configLoader.js';
|
|
8
|
+
import config from '../app/cde-webconfig.json' with { type: 'json' };
|
|
9
|
+
|
|
10
|
+
const directoryName = dirname(fileURLToPath(import.meta.url));
|
|
11
|
+
|
|
12
|
+
export default remixRoutesOptionAdapter(async (defineRoutes) => {
|
|
13
|
+
if (process.env.NODE_ENV === 'production') {
|
|
14
|
+
await performCopyOperations(config);
|
|
15
|
+
}
|
|
16
|
+
let metaJson = null;
|
|
17
|
+
try {
|
|
18
|
+
metaJson = await import('../app/sync-meta.json');
|
|
19
|
+
} catch {
|
|
20
|
+
console.warn('No sync-meta.json found, continuing without metadata.');
|
|
21
|
+
}
|
|
22
|
+
return defineRoutes((routeFn) => {
|
|
23
|
+
defineRoutesConfig(
|
|
24
|
+
routeFn,
|
|
25
|
+
{
|
|
26
|
+
routesFileName: 'routes.json',
|
|
27
|
+
packages: config.modules,
|
|
28
|
+
paths: config.paths,
|
|
29
|
+
iconsRepository: config?.iconsRepository,
|
|
30
|
+
rootPath: resolve(directoryName, '../../..'),
|
|
31
|
+
settings: {
|
|
32
|
+
_useFutureCommonPackage: true,
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
metaJson,
|
|
36
|
+
);
|
|
37
|
+
});
|
|
38
|
+
}) satisfies RouteConfig;
|
|
@@ -1,23 +1,26 @@
|
|
|
1
|
-
import { defineConfig } from 'vite';
|
|
1
|
+
import { defineConfig, ConfigEnv, UserConfig } from 'vite';
|
|
2
2
|
import { vitePlugin as remix } from '@remix-run/dev';
|
|
3
3
|
import { dirname, resolve } from 'path';
|
|
4
|
-
import { installGlobals } from '@remix-run/node';
|
|
5
4
|
import { fileURLToPath } from 'url';
|
|
6
|
-
import {
|
|
5
|
+
// import { remixDevTools } from 'remix-development-tools';
|
|
7
6
|
import tsconfigPaths from 'vite-tsconfig-paths';
|
|
8
7
|
import { i18nInternationalizationPlugin } from '@common-stack/rollup-vite-utils/lib/vite-plugins/i18n-internationalization-plugin.js';
|
|
9
|
-
import {
|
|
8
|
+
// import { visualizer } from 'rollup-plugin-visualizer';
|
|
10
9
|
import { loadEnvConfig } from '@common-stack/rollup-vite-utils/lib/preStartup/configLoader/envLoader.js';
|
|
11
10
|
import { cjsInterop } from 'vite-plugin-cjs-interop';
|
|
12
11
|
import { mergeWith } from 'lodash-es';
|
|
13
|
-
import config from './app/cde-webconfig.json'
|
|
12
|
+
import config from './app/cde-webconfig.json' with { type: 'json' };
|
|
14
13
|
|
|
15
|
-
|
|
16
|
-
|
|
14
|
+
declare module '@remix-run/node' {
|
|
15
|
+
// or cloudflare, deno, etc.
|
|
16
|
+
interface Future {
|
|
17
|
+
v3_singleFetch: true;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
17
20
|
|
|
18
21
|
const directoryName = dirname(fileURLToPath(import.meta.url));
|
|
19
22
|
|
|
20
|
-
export default defineConfig(async ({ isSsrBuild }) => {
|
|
23
|
+
export default defineConfig(async ({ isSsrBuild }: ConfigEnv): Promise<UserConfig> => {
|
|
21
24
|
console.log('--- IS SSR BUILD:', isSsrBuild);
|
|
22
25
|
|
|
23
26
|
// Load environment variables from dotenv or other config
|
|
@@ -32,69 +35,105 @@ export default defineConfig(async ({ isSsrBuild }) => {
|
|
|
32
35
|
Object.entries(config.buildConfig).map(([key, value]) => [
|
|
33
36
|
key,
|
|
34
37
|
typeof value === 'string' ? `"${value.replace(/\\/g, '\\\\')}"` : value,
|
|
35
|
-
])
|
|
38
|
+
]),
|
|
36
39
|
),
|
|
37
40
|
};
|
|
38
41
|
|
|
39
|
-
// Define routes configuration
|
|
40
|
-
const routesConfig = async (defineRoutes) => {
|
|
41
|
-
// In production, perform required file copy operations
|
|
42
|
-
if (process.env.NODE_ENV === 'production') {
|
|
43
|
-
await performCopyOperations(config);
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
// Load metadata for routes
|
|
47
|
-
let metaJson = null;
|
|
48
|
-
try {
|
|
49
|
-
metaJson = await import('./app/sync-meta.json');
|
|
50
|
-
} catch {
|
|
51
|
-
console.warn('No sync-meta.json found, continuing without metadata.');
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
// Return routes definition
|
|
55
|
-
return defineRoutes((routeFn) =>
|
|
56
|
-
defineRoutesConfig(
|
|
57
|
-
routeFn,
|
|
58
|
-
{
|
|
59
|
-
routesFileName: 'routes.json',
|
|
60
|
-
packages: config.modules,
|
|
61
|
-
paths: config.paths,
|
|
62
|
-
iconsRepository: config?.iconsRepository,
|
|
63
|
-
rootPath: resolve(directoryName, '../..'),
|
|
64
|
-
settings: {
|
|
65
|
-
_useFutureCommonPackage: true,
|
|
66
|
-
},
|
|
67
|
-
},
|
|
68
|
-
metaJson
|
|
69
|
-
)
|
|
70
|
-
);
|
|
71
|
-
};
|
|
72
|
-
|
|
73
42
|
// Vite configuration
|
|
74
43
|
const viteConfig = {
|
|
75
44
|
define: envVariables,
|
|
45
|
+
ssr: {
|
|
46
|
+
// Keep small client-only libraries bundled, including all @radix-ui packages
|
|
47
|
+
// to ensure proper CommonJS to ESM interop handled by cjsInterop plugin
|
|
48
|
+
noExternal: [
|
|
49
|
+
'react-datepicker',
|
|
50
|
+
/^@radix-ui\//,
|
|
51
|
+
'@radix-ui/react-slot',
|
|
52
|
+
'@radix-ui/react-primitive',
|
|
53
|
+
'@radix-ui/react-compose-refs',
|
|
54
|
+
'@radix-ui/react-context',
|
|
55
|
+
'@radix-ui/react-collection',
|
|
56
|
+
'@radix-ui/react-separator',
|
|
57
|
+
],
|
|
58
|
+
},
|
|
76
59
|
plugins: [
|
|
60
|
+
// remixDevTools({
|
|
61
|
+
// server: {
|
|
62
|
+
// logs: {
|
|
63
|
+
// cookies: true,
|
|
64
|
+
// defer: true,
|
|
65
|
+
// actions: true,
|
|
66
|
+
// loaders: true,
|
|
67
|
+
// cache: true,
|
|
68
|
+
// siteClear: true,
|
|
69
|
+
// },
|
|
70
|
+
// },
|
|
71
|
+
// }),
|
|
77
72
|
i18nInternationalizationPlugin({
|
|
78
73
|
folderName: 'cdm-locales',
|
|
79
74
|
packages: [...config.modules, ...config.i18n.packages],
|
|
80
|
-
namespaceResolution: 'basename',
|
|
75
|
+
namespaceResolution: 'basename' as any,
|
|
81
76
|
}),
|
|
77
|
+
// visualizer({
|
|
78
|
+
// open: true,
|
|
79
|
+
// filename: 'bundle-analysis.html',
|
|
80
|
+
// }),
|
|
81
|
+
// cjsInterop({
|
|
82
|
+
// dependencies: ['@apollo/client', '@ant-design/pro-utils', '@rjsf/**',],
|
|
83
|
+
// }),
|
|
82
84
|
cjsInterop({
|
|
83
|
-
dependencies: [
|
|
85
|
+
dependencies: [
|
|
86
|
+
'@rjsf/**',
|
|
87
|
+
'react-timer-hook',
|
|
88
|
+
'rc-util/lib/hooks/useMergedState.js',
|
|
89
|
+
'@ant-design/icons',
|
|
90
|
+
'rc-picker',
|
|
91
|
+
'@monaco-editor/loader',
|
|
92
|
+
'react-google-calendar-api',
|
|
93
|
+
'@apollo/client',
|
|
94
|
+
],
|
|
84
95
|
}),
|
|
85
96
|
remix({
|
|
86
97
|
appDirectory: 'src',
|
|
87
|
-
routes: routesConfig,
|
|
98
|
+
// routes: routesConfig,
|
|
99
|
+
future: {
|
|
100
|
+
unstable_optimizeDeps: true,
|
|
101
|
+
v3_fetcherPersist: true,
|
|
102
|
+
v3_relativeSplatPath: true,
|
|
103
|
+
v3_throwAbortReason: true,
|
|
104
|
+
v3_lazyRouteDiscovery: true,
|
|
105
|
+
v3_singleFetch: true,
|
|
106
|
+
v3_routeConfig: true,
|
|
107
|
+
},
|
|
88
108
|
}),
|
|
89
109
|
tsconfigPaths({ ignoreConfigErrors: true }),
|
|
90
110
|
],
|
|
91
111
|
optimizeDeps: {
|
|
112
|
+
include: [
|
|
113
|
+
'@radix-ui/react-slot',
|
|
114
|
+
'@radix-ui/react-compose-refs',
|
|
115
|
+
'@radix-ui/react-primitive',
|
|
116
|
+
'@radix-ui/react-collection',
|
|
117
|
+
'@radix-ui/react-dialog',
|
|
118
|
+
'@radix-ui/react-select',
|
|
119
|
+
'@radix-ui/react-alert-dialog',
|
|
120
|
+
'@radix-ui/react-popover',
|
|
121
|
+
'@radix-ui/react-tooltip',
|
|
122
|
+
'@radix-ui/react-context-menu',
|
|
123
|
+
],
|
|
92
124
|
esbuildOptions: {
|
|
93
125
|
target: 'esnext',
|
|
94
126
|
},
|
|
127
|
+
force: true, // Force dependency optimization on every build
|
|
95
128
|
},
|
|
96
129
|
build: {
|
|
97
130
|
target: 'esnext',
|
|
131
|
+
rollupOptions: {
|
|
132
|
+
output: {
|
|
133
|
+
// Ensure that worker files are properly bundled
|
|
134
|
+
format: 'es',
|
|
135
|
+
},
|
|
136
|
+
},
|
|
98
137
|
},
|
|
99
138
|
resolve: {
|
|
100
139
|
alias: {
|
|
@@ -102,14 +141,18 @@ export default defineConfig(async ({ isSsrBuild }) => {
|
|
|
102
141
|
'@src': resolve(directoryName, 'src'),
|
|
103
142
|
},
|
|
104
143
|
},
|
|
144
|
+
worker: {
|
|
145
|
+
format: 'es', // Use ES modules format for workers
|
|
146
|
+
plugins: () => [], // Return an empty array of plugins
|
|
147
|
+
},
|
|
105
148
|
};
|
|
106
149
|
|
|
107
150
|
// Deep merge custom Vite config from config.json
|
|
108
|
-
// to merge Arrays properly need to concat.
|
|
151
|
+
// to merge Arrays properly need to concat.
|
|
109
152
|
const result = mergeWith(config.viteConfig, viteConfig, (objValue, srcValue) => {
|
|
110
153
|
if (Array.isArray(objValue)) {
|
|
111
154
|
return objValue.concat(srcValue);
|
|
112
155
|
}
|
|
113
156
|
});
|
|
114
|
-
return result;
|
|
157
|
+
return result as UserConfig;
|
|
115
158
|
});
|
|
@@ -136,9 +136,9 @@
|
|
|
136
136
|
"@babel/preset-typescript": "^7.18.6",
|
|
137
137
|
"@babel/register": "^7.18.9",
|
|
138
138
|
"@babel/runtime": "^7.20.1",
|
|
139
|
-
"@common-stack/env-list-loader": "
|
|
140
|
-
"@common-stack/generate-plugin": "
|
|
141
|
-
"@common-stack/rollup-vite-utils": "
|
|
139
|
+
"@common-stack/env-list-loader": "8.2.2-alpha.0",
|
|
140
|
+
"@common-stack/generate-plugin": "8.2.2-alpha.1",
|
|
141
|
+
"@common-stack/rollup-vite-utils": "8.2.2-alpha.1",
|
|
142
142
|
"@emotion/babel-plugin": "^11.11.0",
|
|
143
143
|
"@graphql-codegen/add": "^5.0.3",
|
|
144
144
|
"@graphql-codegen/cli": "^5.0.4",
|
|
@@ -29,11 +29,11 @@
|
|
|
29
29
|
"common": "link:./common"
|
|
30
30
|
},
|
|
31
31
|
"dependencies": {
|
|
32
|
-
"@common-stack/client-core": "
|
|
33
|
-
"@common-stack/core": "
|
|
34
|
-
"@common-stack/server-core": "
|
|
35
|
-
"@common-stack/server-stack": "
|
|
36
|
-
"@common-stack/store-mongo": "
|
|
32
|
+
"@common-stack/client-core": "8.2.2-alpha.1",
|
|
33
|
+
"@common-stack/core": "8.2.2-alpha.1",
|
|
34
|
+
"@common-stack/server-core": "8.2.2-alpha.1",
|
|
35
|
+
"@common-stack/server-stack": "8.2.2-alpha.1",
|
|
36
|
+
"@common-stack/store-mongo": "8.2.2-alpha.1",
|
|
37
37
|
"@container-stack/mailing-api": "5.2.1-alpha.1",
|
|
38
38
|
"helmet": "^3.21.2",
|
|
39
39
|
"react": "18.2.0",
|
|
@@ -62,9 +62,9 @@
|
|
|
62
62
|
"peerDependencies": {
|
|
63
63
|
"@apollo/client": ">=3.0.0",
|
|
64
64
|
"@cdm-logger/server": ">=9.0.3",
|
|
65
|
-
"@common-stack/core": "
|
|
66
|
-
"@common-stack/server-core": "
|
|
67
|
-
"@common-stack/store-mongo": "
|
|
65
|
+
"@common-stack/core": "8.2.2-alpha.1",
|
|
66
|
+
"@common-stack/server-core": "8.2.2-alpha.1",
|
|
67
|
+
"@common-stack/store-mongo": "8.2.2-alpha.1",
|
|
68
68
|
"@container-stack/mailing-api": ">=0.0.35-alpha.1",
|
|
69
69
|
"@vscode-alt/monaco-editor": "^0.21.4",
|
|
70
70
|
"inversify": "^5.0.1",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@common-stack/generate-plugin",
|
|
3
|
-
"version": "8.2.2-alpha.
|
|
3
|
+
"version": "8.2.2-alpha.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./lib/index.mjs",
|
|
6
6
|
"typings": "./lib/index.d.ts",
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
"watch": "yarn build:lib:watch"
|
|
19
19
|
},
|
|
20
20
|
"dependencies": {
|
|
21
|
-
"@common-stack/rollup-vite-utils": "8.2.2-alpha.
|
|
21
|
+
"@common-stack/rollup-vite-utils": "8.2.2-alpha.1",
|
|
22
22
|
"tslib": "^2.3.0"
|
|
23
23
|
},
|
|
24
24
|
"publishConfig": {
|
|
@@ -26,5 +26,5 @@
|
|
|
26
26
|
},
|
|
27
27
|
"executors": "./executors.json",
|
|
28
28
|
"generators": "./generators.json",
|
|
29
|
-
"gitHead": "
|
|
29
|
+
"gitHead": "221b5a2529f343d1bf43b7707f9efe00268f1e7b"
|
|
30
30
|
}
|
|
@@ -64,7 +64,7 @@
|
|
|
64
64
|
"dependencies": {
|
|
65
65
|
"@apollo/client": "^3.9.0",
|
|
66
66
|
"@babel/runtime": "^7.20.1",
|
|
67
|
-
"@common-stack/server-stack": "
|
|
67
|
+
"@common-stack/server-stack": "8.2.2-alpha.1",
|
|
68
68
|
"@remix-run/node": "~2.15.3",
|
|
69
69
|
"lodash": "^4.17.15",
|
|
70
70
|
"react": "18.2.0"
|
|
@@ -55,21 +55,17 @@ async function hydrate() {
|
|
|
55
55
|
startTransition(() => {
|
|
56
56
|
hydrateRoot(
|
|
57
57
|
document,
|
|
58
|
-
|
|
59
|
-
<
|
|
60
|
-
<
|
|
61
|
-
<
|
|
62
|
-
<
|
|
63
|
-
<
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
</ReduxProvider>
|
|
70
|
-
</StrictMode>
|
|
71
|
-
</I18nextProvider>
|
|
72
|
-
) as any,
|
|
58
|
+
<I18nextProvider i18n={i18next}>
|
|
59
|
+
<ReduxProvider store={store}>
|
|
60
|
+
<SlotFillProvider>
|
|
61
|
+
<InversifyProvider container={container} modules={clientModules}>
|
|
62
|
+
<ApolloProvider client={client}>
|
|
63
|
+
<RemixBrowser />
|
|
64
|
+
</ApolloProvider>
|
|
65
|
+
</InversifyProvider>
|
|
66
|
+
</SlotFillProvider>
|
|
67
|
+
</ReduxProvider>
|
|
68
|
+
</I18nextProvider>,
|
|
73
69
|
);
|
|
74
70
|
});
|
|
75
71
|
}
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* For more information, see https://remix.run/file-conventions/entry.server
|
|
5
5
|
*/
|
|
6
6
|
import * as React from 'react';
|
|
7
|
+
import 'reflect-metadata';
|
|
7
8
|
(global as any).__CLIENT__ = false;
|
|
8
9
|
(global as any).__SERVER__ = true;
|
|
9
10
|
import { PassThrough, Transform } from 'node:stream';
|
|
@@ -28,7 +29,8 @@ import config from '@app/cde-webconfig.json';
|
|
|
28
29
|
// @ts-ignore
|
|
29
30
|
import type { IAppLoadContext } from '@common-stack/client-core';
|
|
30
31
|
|
|
31
|
-
|
|
32
|
+
// Reject/cancel all pending promises after 5 seconds
|
|
33
|
+
export const streamTimeout = 5000;
|
|
32
34
|
|
|
33
35
|
class ConstantsTransform extends Transform {
|
|
34
36
|
_fills: string[];
|
|
@@ -120,7 +122,7 @@ function handleBotRequest(
|
|
|
120
122
|
let shellRendered = false;
|
|
121
123
|
const { pipe, abort } = renderToPipeableStream(
|
|
122
124
|
<I18nextProvider i18n={i18nInstance}>
|
|
123
|
-
<RemixServer context={remixContext} url={request.url}
|
|
125
|
+
<RemixServer context={remixContext} url={request.url} />
|
|
124
126
|
</I18nextProvider>,
|
|
125
127
|
{
|
|
126
128
|
onAllReady() {
|
|
@@ -154,7 +156,7 @@ function handleBotRequest(
|
|
|
154
156
|
},
|
|
155
157
|
);
|
|
156
158
|
|
|
157
|
-
setTimeout(abort,
|
|
159
|
+
setTimeout(abort, streamTimeout + 1000);
|
|
158
160
|
});
|
|
159
161
|
}
|
|
160
162
|
|
|
@@ -184,11 +186,7 @@ function handleBrowserRequest(
|
|
|
184
186
|
<SlotFillProvider context={slotFillContext}>
|
|
185
187
|
<InversifyProvider container={container} modules={clientModules as any}>
|
|
186
188
|
<ApolloProvider client={client}>
|
|
187
|
-
<RemixServer
|
|
188
|
-
context={remixContext}
|
|
189
|
-
url={request.url}
|
|
190
|
-
abortDelay={ABORT_DELAY}
|
|
191
|
-
/>
|
|
189
|
+
<RemixServer context={remixContext} url={request.url} />
|
|
192
190
|
</ApolloProvider>
|
|
193
191
|
</InversifyProvider>
|
|
194
192
|
</SlotFillProvider>
|
|
@@ -203,8 +201,9 @@ function handleBrowserRequest(
|
|
|
203
201
|
const apolloState = { ...client.extract() };
|
|
204
202
|
const reduxState = { ...store.getState() };
|
|
205
203
|
const fills = Object.keys(slotFillContext.fills);
|
|
204
|
+
const styleSheet = '';
|
|
206
205
|
|
|
207
|
-
const transform = new ConstantsTransform(fills, apolloState, reduxState,
|
|
206
|
+
const transform = new ConstantsTransform(fills, apolloState, reduxState, styleSheet);
|
|
208
207
|
|
|
209
208
|
responseHeaders.set('Content-Type', 'text/html');
|
|
210
209
|
|
|
@@ -233,6 +232,6 @@ function handleBrowserRequest(
|
|
|
233
232
|
},
|
|
234
233
|
);
|
|
235
234
|
|
|
236
|
-
setTimeout(abort,
|
|
235
|
+
setTimeout(abort, streamTimeout + 1000);
|
|
237
236
|
});
|
|
238
237
|
}
|
|
@@ -1,27 +1,38 @@
|
|
|
1
1
|
import 'reflect-metadata';
|
|
2
2
|
import * as React from 'react';
|
|
3
|
-
import {
|
|
4
|
-
|
|
3
|
+
import {
|
|
4
|
+
Links,
|
|
5
|
+
Meta,
|
|
6
|
+
Outlet,
|
|
7
|
+
Scripts,
|
|
8
|
+
ScrollRestoration,
|
|
9
|
+
useLoaderData,
|
|
10
|
+
useRouteError,
|
|
11
|
+
useRouteLoaderData,
|
|
12
|
+
data,
|
|
13
|
+
} from '@remix-run/react';
|
|
5
14
|
// @ts-ignore
|
|
6
15
|
import publicEnv from '@src/config/public-config';
|
|
7
16
|
import { PluginArea } from '@common-stack/client-react';
|
|
8
17
|
import { subscribeReduxRouter } from '@common-stack/remix-router-redux';
|
|
18
|
+
import { ApplicationErrorHandler, RemixErrorBoundary as ErrorBoundary } from '@admin-layout/tailwind-ui';
|
|
9
19
|
// @ts-ignore
|
|
10
20
|
import clientModules, { plugins } from '@app/frontend-stack-react/modules.js';
|
|
11
21
|
// @ts-ignore
|
|
12
22
|
import { useChangeLanguage } from 'remix-i18next/react';
|
|
13
23
|
import { useTranslation } from 'react-i18next';
|
|
24
|
+
// @ts-ignore
|
|
25
|
+
import { i18nextInstance as i18next } from '@app/frontend-stack-react/i18n-localization/i18next.server.js';
|
|
14
26
|
import { LayoutCookieProvider } from '@admin-layout/client';
|
|
15
27
|
import { settingsLoaderUtil } from '@admin-layout/client/lib/components/UpdateSettings/UpdateSettings.server';
|
|
16
|
-
import { IAppLoadContext
|
|
28
|
+
import type { IAppLoadContext } from '@common-stack/client-core';
|
|
29
|
+
import type { IResourceParams } from '@common-stack/core';
|
|
17
30
|
import { FillRenderProvider, PluginsLoader } from '@common-stack/components-pro';
|
|
18
|
-
// @ts-ignore
|
|
19
|
-
import { i18nextInstance as i18next } from '@app/frontend-stack-react/i18n-localization/i18next.server.js';
|
|
20
|
-
import stylesheet from "./tailwind.css?url";
|
|
21
31
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
32
|
+
// eslint-disable-next-line import/no-unresolved
|
|
33
|
+
import styles from '../tailwind.css?url';
|
|
34
|
+
|
|
35
|
+
export const links = () => [{ rel: 'stylesheet', href: styles }];
|
|
25
36
|
|
|
26
37
|
export const loader = async ({
|
|
27
38
|
request,
|
|
@@ -32,37 +43,49 @@ export const loader = async ({
|
|
|
32
43
|
context: IAppLoadContext;
|
|
33
44
|
params: IResourceParams;
|
|
34
45
|
}) => {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
46
|
+
// Fetch settings with error handling - don't let settings failures break the app
|
|
47
|
+
let settingsResponse: any = {};
|
|
48
|
+
try {
|
|
49
|
+
settingsResponse =
|
|
50
|
+
(await settingsLoaderUtil({
|
|
51
|
+
request,
|
|
52
|
+
context,
|
|
53
|
+
params,
|
|
54
|
+
})) || {};
|
|
55
|
+
} catch (error) {
|
|
56
|
+
console.error('❌ Failed to load settings, using defaults:', error);
|
|
57
|
+
// Continue without settings - the app should still work
|
|
58
|
+
}
|
|
38
59
|
|
|
39
|
-
|
|
60
|
+
const [locale] = await Promise.all([i18next.getLocale(request)]);
|
|
61
|
+
const loadedPlugins = await PluginsLoader(plugins, { request, context, params });
|
|
62
|
+
return data(
|
|
40
63
|
{
|
|
41
64
|
__ENV__: publicEnv,
|
|
42
65
|
locale,
|
|
43
|
-
settings: settingsResponse?.settings,
|
|
66
|
+
settings: settingsResponse?.settings || {},
|
|
44
67
|
loadedPlugins,
|
|
45
68
|
},
|
|
46
69
|
{
|
|
47
70
|
headers: [
|
|
48
71
|
['Cache-Control', 'max-age=300, s-maxage=600'],
|
|
49
|
-
['Set-Cookie', settingsResponse
|
|
50
|
-
],
|
|
72
|
+
settingsResponse?.setCookie ? ['Set-Cookie', settingsResponse.setCookie] : null,
|
|
73
|
+
].filter(Boolean) as [string, string][],
|
|
51
74
|
},
|
|
52
75
|
);
|
|
53
76
|
};
|
|
54
77
|
|
|
55
78
|
export const handle = {
|
|
56
|
-
i18n: 'common',
|
|
79
|
+
i18n: ['common', 'translations', 'projects'],
|
|
57
80
|
};
|
|
58
81
|
|
|
59
|
-
export
|
|
60
|
-
return params.defaultShouldRevalidate && params.currentUrl.pathname !== params.nextUrl.pathname;
|
|
61
|
-
}
|
|
82
|
+
export const shouldRevalidate = () => false;
|
|
62
83
|
|
|
63
84
|
export function Layout({ children }: { children: React.ReactNode }) {
|
|
64
|
-
|
|
65
|
-
|
|
85
|
+
// useLoaderData is for happy paths with Error boundary it will fail
|
|
86
|
+
// https://github.com/remix-run/remix/issues/8951#issuecomment-1973321870
|
|
87
|
+
const loaderData = useRouteLoaderData<{ locale: any; __ENV__?: any }>('root');
|
|
88
|
+
const locale = loaderData?.locale || 'en';
|
|
66
89
|
|
|
67
90
|
const { i18n } = useTranslation();
|
|
68
91
|
|
|
@@ -78,7 +101,7 @@ export function Layout({ children }: { children: React.ReactNode }) {
|
|
|
78
101
|
<>
|
|
79
102
|
<script
|
|
80
103
|
dangerouslySetInnerHTML={{
|
|
81
|
-
__html: `window.__ENV__ = ${JSON.stringify((
|
|
104
|
+
__html: `window.__ENV__ = ${JSON.stringify((loaderData as any)?.__ENV__ || {})}`,
|
|
82
105
|
}}
|
|
83
106
|
/>
|
|
84
107
|
<script
|
|
@@ -106,15 +129,28 @@ export function Layout({ children }: { children: React.ReactNode }) {
|
|
|
106
129
|
<head>
|
|
107
130
|
<meta charSet="utf-8" />
|
|
108
131
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
132
|
+
{/* CRITICAL: Load Symbol.observable polyfill BEFORE any other scripts */}
|
|
133
|
+
<script
|
|
134
|
+
dangerouslySetInnerHTML={{
|
|
135
|
+
__html: `
|
|
136
|
+
(function() {
|
|
137
|
+
if (typeof Symbol !== 'undefined' && typeof Symbol.for === 'function') {
|
|
138
|
+
if (!Symbol.observable) {
|
|
139
|
+
Symbol.observable = Symbol.for('observable');
|
|
140
|
+
}
|
|
141
|
+
console.log('[Symbol.observable polyfill] Loaded in head:', Symbol.observable);
|
|
142
|
+
}
|
|
143
|
+
})();
|
|
144
|
+
`,
|
|
145
|
+
}}
|
|
146
|
+
/>
|
|
109
147
|
<Meta />
|
|
110
148
|
<Links />
|
|
111
149
|
{typeof window === 'undefined' ? `[__STYLESHEET__]` : ''}
|
|
112
150
|
</head>
|
|
113
151
|
<body>
|
|
114
152
|
<PluginArea />
|
|
115
|
-
<FillRenderProvider>
|
|
116
|
-
{clientModules.getWrappedRoot(children)}
|
|
117
|
-
</FillRenderProvider>
|
|
153
|
+
<FillRenderProvider>{clientModules.getWrappedRoot(children)}</FillRenderProvider>
|
|
118
154
|
<ScrollRestoration />
|
|
119
155
|
<Scripts />
|
|
120
156
|
{getConstants()}
|
|
@@ -123,24 +159,14 @@ export function Layout({ children }: { children: React.ReactNode }) {
|
|
|
123
159
|
);
|
|
124
160
|
}
|
|
125
161
|
|
|
126
|
-
const TestComponent = () => {
|
|
127
|
-
return (
|
|
128
|
-
<div className="min-h-screen flex items-center justify-center bg-gray-100">
|
|
129
|
-
<div className="p-6 max-w-sm mx-auto bg-white rounded-xl shadow-md space-y-4">
|
|
130
|
-
<h1 className="text-2xl font-bold text-center">Hello, Tailwind CSS!</h1>
|
|
131
|
-
<p className="text-gray-500 text-center">This is a test page using React and Tailwind CSS.</p>
|
|
132
|
-
</div>
|
|
133
|
-
</div>
|
|
134
|
-
);
|
|
135
|
-
}
|
|
136
|
-
|
|
137
162
|
export default function App() {
|
|
138
163
|
return (
|
|
139
|
-
<
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
164
|
+
<ApplicationErrorHandler plugins={plugins}>
|
|
165
|
+
<LayoutCookieProvider>
|
|
166
|
+
<Outlet />
|
|
167
|
+
</LayoutCookieProvider>
|
|
168
|
+
</ApplicationErrorHandler>
|
|
143
169
|
);
|
|
144
170
|
}
|
|
145
171
|
|
|
146
|
-
|
|
172
|
+
export { ErrorBoundary };
|