@lowdefy/server-e2e 6.0.0 → 7.0.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/client/App.jsx +24 -14
- package/client/Page.jsx +53 -16
- package/client/getShownPage.js +28 -0
- package/client/getShownPage.test.mjs +52 -0
- package/lib/client/auth/Auth.jsx +30 -4
- package/lib/server/auth/{session.js → getUser.js} +8 -7
- package/lib/server/log/createLogger.js +3 -0
- package/lib/server/log/logRequest.js +1 -3
- package/lib/server/scrubSecrets.js +25 -0
- package/lowdefy/build.mjs +1 -0
- package/lowdefy/build.test.mjs +65 -0
- package/lowdefy/createCustomPluginTypesMap.mjs +3 -2
- package/lowdefy/createCustomPluginTypesMap.test.mjs +5 -0
- package/package.json +38 -39
- package/package.original.json +38 -39
- package/src/app.js +12 -5
- package/src/html/getAssets.js +3 -1
- package/src/html/getHomePath.js +29 -0
- package/src/html/renderPage.js +29 -17
- package/src/html/renderPage.test.mjs +162 -0
- package/src/html/template.js +16 -6
- package/src/index.js +23 -0
- package/src/lib/getRequestPath.js +29 -0
- package/src/middleware/apiContext.js +22 -3
- package/src/middleware/apiContext.test.mjs +120 -0
- package/src/middleware/errorHandler.js +63 -4
- package/src/middleware/errorHandler.test.mjs +402 -0
- package/src/routes/apiPage.js +14 -9
- package/src/routes/apiPage.test.mjs +92 -0
- package/src/routes/clientError.js +6 -12
- package/src/routes/e2eIdentity.js +28 -0
- package/src/routes/e2eIdentity.test.mjs +43 -0
- package/src/routes/endpoints.js +5 -3
- package/src/routes/mountPageRoutes.js +29 -0
- package/src/routes/mountPageRoutes.test.mjs +56 -0
- package/src/routes/request.js +5 -3
- package/src/routes/requestBody.test.mjs +69 -0
- package/src/routes/sessionMock.js +4 -1
- package/src/routes/usage.js +6 -2
- package/src/routes/user.js +27 -0
- package/src/routes/websocket.js +23 -3
- package/src/routes/websocket.test.mjs +73 -0
- package/vite.config.js +57 -1
- package/lib/server/apiWrapper.js +0 -73
package/vite.config.js
CHANGED
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
import fs from 'node:fs';
|
|
18
18
|
import { defineConfig } from 'vite';
|
|
19
19
|
import react from '@vitejs/plugin-react';
|
|
20
|
+
import { Features } from 'lightningcss';
|
|
20
21
|
|
|
21
22
|
// basePath from the Lowdefy build — assets are served under it.
|
|
22
23
|
let basePath = '';
|
|
@@ -27,14 +28,53 @@ try {
|
|
|
27
28
|
// No build yet (e.g. editor tooling) — default base.
|
|
28
29
|
}
|
|
29
30
|
|
|
31
|
+
// The @lowdefy packages this server depends on. A linked plugin pinned to
|
|
32
|
+
// another release brings its own copies, and the client would then mix
|
|
33
|
+
// versions: the dev server pre-bundles one copy per package for every
|
|
34
|
+
// importer (whichever its scan meets first, so the server's own code can get
|
|
35
|
+
// a plugin's older @lowdefy/helpers without an export it imports), and a
|
|
36
|
+
// production build bundles both, so blocks read module state the client never
|
|
37
|
+
// filled (the HTML enhancements it registers in @lowdefy/block-utils). The
|
|
38
|
+
// server's copies are the ones its client and blocks were released with.
|
|
39
|
+
const lowdefyDependencies = Object.keys(
|
|
40
|
+
JSON.parse(fs.readFileSync(new URL('./package.json', import.meta.url), 'utf8')).dependencies ?? {}
|
|
41
|
+
).filter((name) => name.startsWith('@lowdefy/'));
|
|
42
|
+
|
|
43
|
+
// Vite 8 tree-shakes a `.module.css` imported only for its side effects
|
|
44
|
+
// (`import './style.module.css'`), and its CSS goes with it: `:global(...)` rules in block and
|
|
45
|
+
// plugin stylesheets never reach the built client. Marking CSS modules as side-effectful keeps
|
|
46
|
+
// them, whatever the import style.
|
|
47
|
+
function keepCssModuleSideEffects() {
|
|
48
|
+
return {
|
|
49
|
+
name: 'lowdefy-keep-css-module-side-effects',
|
|
50
|
+
enforce: 'post',
|
|
51
|
+
transform(code, id) {
|
|
52
|
+
if (/\.module\.css($|\?)/.test(id)) {
|
|
53
|
+
return { code, moduleSideEffects: 'no-treeshake' };
|
|
54
|
+
}
|
|
55
|
+
},
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
|
|
30
59
|
export default defineConfig(({ mode }) => ({
|
|
31
60
|
base: `${basePath}/`,
|
|
32
|
-
plugins: [react()],
|
|
61
|
+
plugins: [react(), keepCssModuleSideEffects()],
|
|
33
62
|
define: {
|
|
34
63
|
// Vite does not replace process.env.NODE_ENV inside dependencies —
|
|
35
64
|
// plugin and client code branch on it.
|
|
36
65
|
'process.env.NODE_ENV': JSON.stringify(mode === 'production' ? 'production' : 'development'),
|
|
37
66
|
},
|
|
67
|
+
css: {
|
|
68
|
+
// Vite minifies client CSS with Lightning CSS, which by default lowers
|
|
69
|
+
// light-dark() into --lightningcss-light/--lightningcss-dark variables that
|
|
70
|
+
// only a CSS color-scheme declaration defines. The client sets color-scheme
|
|
71
|
+
// from JavaScript (useDarkMode), so the lowered values never resolve and
|
|
72
|
+
// every light-dark() colour is dropped. Tailwind leaves light-dark()
|
|
73
|
+
// unlowered in its own Lightning CSS pass for the same reason.
|
|
74
|
+
lightningcss: {
|
|
75
|
+
exclude: Features.LightDark,
|
|
76
|
+
},
|
|
77
|
+
},
|
|
38
78
|
build: {
|
|
39
79
|
outDir: 'dist/client',
|
|
40
80
|
manifest: true,
|
|
@@ -42,4 +82,20 @@ export default defineConfig(({ mode }) => ({
|
|
|
42
82
|
input: 'client/main.jsx',
|
|
43
83
|
},
|
|
44
84
|
},
|
|
85
|
+
resolve: {
|
|
86
|
+
// Linked plugin packages (pnpm link: / workspace) resolve their own copies of
|
|
87
|
+
// shared libraries. They must share one React, the antd/X/cssinjs copies
|
|
88
|
+
// whose context providers (App, ConfigProvider, StyleProvider) the client
|
|
89
|
+
// renders, the dayjs whose global locale the client sets, and the server's
|
|
90
|
+
// @lowdefy packages (see lowdefyDependencies).
|
|
91
|
+
dedupe: [
|
|
92
|
+
'react',
|
|
93
|
+
'react-dom',
|
|
94
|
+
'antd',
|
|
95
|
+
'@ant-design/x',
|
|
96
|
+
'@ant-design/cssinjs',
|
|
97
|
+
'dayjs',
|
|
98
|
+
...lowdefyDependencies,
|
|
99
|
+
],
|
|
100
|
+
},
|
|
45
101
|
}));
|
package/lib/server/apiWrapper.js
DELETED
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
Copyright 2020-2026 Lowdefy, Inc
|
|
3
|
-
|
|
4
|
-
Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
-
you may not use this file except in compliance with the License.
|
|
6
|
-
You may obtain a copy of the License at
|
|
7
|
-
|
|
8
|
-
http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
-
|
|
10
|
-
Unless required by applicable law or agreed to in writing, software
|
|
11
|
-
distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
-
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
-
See the License for the specific language governing permissions and
|
|
14
|
-
limitations under the License.
|
|
15
|
-
*/
|
|
16
|
-
|
|
17
|
-
import path from 'path';
|
|
18
|
-
import { createApiContext, redactErrorResponse } from '@lowdefy/api';
|
|
19
|
-
import { v4 as uuid } from 'uuid';
|
|
20
|
-
|
|
21
|
-
import appMeta from '../build/appMeta.js';
|
|
22
|
-
import config from '../build/config.js';
|
|
23
|
-
import connections from '../../build/plugins/connections.js';
|
|
24
|
-
import createLogger from './log/createLogger.js';
|
|
25
|
-
import fileCache from './fileCache.js';
|
|
26
|
-
import getE2eSecrets from './getE2eSecrets.js';
|
|
27
|
-
import getServerSession from './auth/getServerSession.js';
|
|
28
|
-
import createHandleError from './log/createHandleError.js';
|
|
29
|
-
import logRequest from './log/logRequest.js';
|
|
30
|
-
import operators from '../../build/plugins/operators/server.js';
|
|
31
|
-
import jsMap from '../../build/plugins/operators/serverJsMap.js';
|
|
32
|
-
|
|
33
|
-
const secrets = getE2eSecrets();
|
|
34
|
-
|
|
35
|
-
function apiWrapper(handler) {
|
|
36
|
-
return async function wrappedHandler(req, res) {
|
|
37
|
-
const context = {
|
|
38
|
-
// Important to give absolute path so Next can trace build files
|
|
39
|
-
rid: uuid(),
|
|
40
|
-
appMeta,
|
|
41
|
-
buildDirectory: path.join(process.cwd(), 'build'),
|
|
42
|
-
configDirectory: process.env.LOWDEFY_DIRECTORY_CONFIG || process.cwd(),
|
|
43
|
-
config,
|
|
44
|
-
connections,
|
|
45
|
-
fileCache,
|
|
46
|
-
headers: req?.headers,
|
|
47
|
-
jsMap,
|
|
48
|
-
handleError: async (err) => {
|
|
49
|
-
console.error(err);
|
|
50
|
-
},
|
|
51
|
-
logger: console,
|
|
52
|
-
operators,
|
|
53
|
-
req,
|
|
54
|
-
res,
|
|
55
|
-
secrets,
|
|
56
|
-
};
|
|
57
|
-
try {
|
|
58
|
-
context.logger = createLogger({ rid: context.rid });
|
|
59
|
-
context.handleError = createHandleError({ context });
|
|
60
|
-
context.session = getServerSession(context);
|
|
61
|
-
createApiContext(context);
|
|
62
|
-
logRequest({ context });
|
|
63
|
-
// Await here so that if handler throws it is caught.
|
|
64
|
-
const response = await handler({ context, req, res });
|
|
65
|
-
return response;
|
|
66
|
-
} catch (error) {
|
|
67
|
-
await context.handleError(error);
|
|
68
|
-
res.status(500).json(redactErrorResponse(context, error));
|
|
69
|
-
}
|
|
70
|
-
};
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
export default apiWrapper;
|