@lowdefy/server-dev 0.0.0-experimental-20260720072521 → 0.0.0-experimental-20260720135014
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/.eslintrc.yaml +1 -0
- package/lib/build/app.js +1 -8
- package/lib/build/appMeta.js +1 -8
- package/lib/build/auth.js +1 -8
- package/lib/build/config.js +1 -8
- package/lib/build/i18n.js +1 -8
- package/lib/build/logger.js +1 -8
- package/lib/build/theme.js +1 -8
- package/lib/client/App.js +80 -0
- package/{client/Page.jsx → lib/client/Page.js} +5 -5
- package/{client/Reload.jsx → lib/client/Reload.js} +7 -5
- package/lib/client/auth/{Auth.jsx → Auth.js} +5 -12
- package/lib/client/auth/AuthConfigured.js +61 -0
- package/lib/client/auth/AuthNotConfigured.js +2 -22
- package/lib/client/setPageId.js +5 -6
- package/lib/client/utils/useMutateCache.js +1 -14
- package/lib/client/utils/usePageConfig.js +11 -31
- package/lib/server/apiWrapper.js +116 -0
- package/lib/server/auth/{getStrategies.js → getAuthOptions.js} +9 -14
- package/lib/server/auth/{getMockUser.js → getMockSession.js} +19 -10
- package/{src/routes/docs/checkpointsRevert.js → lib/server/auth/getServerSession.js} +13 -11
- package/lib/server/compileCss.js +39 -0
- package/lib/server/jitPageBuilder.js +11 -36
- package/lib/server/log/logRequest.js +3 -1
- package/manager/getContext.mjs +7 -3
- package/manager/processes/compileCss.mjs +54 -0
- package/manager/processes/initialBuild.mjs +2 -0
- package/manager/processes/installPlugins.mjs +11 -19
- package/manager/processes/lowdefyBuild.mjs +7 -29
- package/manager/processes/nextBuild.mjs +50 -0
- package/manager/processes/readDotEnv.mjs +1 -13
- package/manager/processes/shutdownServer.mjs +6 -6
- package/manager/processes/startServer.mjs +7 -8
- package/manager/processes/startWatchers.mjs +2 -2
- package/manager/run.mjs +0 -41
- package/manager/utils/createCustomPluginMessagesMap.mjs +1 -8
- package/manager/utils/createCustomPluginTypesMap.mjs +2 -3
- package/manager/utils/{getViteBin.mjs → getNextBin.mjs} +10 -7
- package/manager/utils/updatePageTailwindCss.mjs +1 -7
- package/manager/watchers/lowdefyBuildWatcher.mjs +1 -0
- package/manager/watchers/moduleBuildWatcher.mjs +1 -0
- package/manager/watchers/{serverArtifactWatcher.mjs → nextBuildWatcher.mjs} +22 -18
- package/next.config.js +25 -0
- package/package.json +47 -63
- package/package.original.json +55 -66
- package/{src/routes/devTools.js → pages/404.js} +2 -4
- package/{src/routes/docs/appMap.js → pages/[[...pageId]].js} +2 -6
- package/{client/App.jsx → pages/_app.js} +33 -21
- package/pages/_document.js +107 -0
- package/pages/api/agent/[...path].js +86 -0
- package/pages/api/auth/[...nextauth].js +48 -0
- package/pages/api/client-error.js +45 -0
- package/{src/routes/docs/buildStatus.js → pages/api/dev-tools.js} +4 -5
- package/{lib/docs/clientErrorStore.js → pages/api/endpoints/[...endpointId].js} +11 -15
- package/{src/lib/serveBuildJs.js → pages/api/icons/dynamic.js} +12 -8
- package/{src/routes/jsEnv.js → pages/api/js/[env].js} +20 -8
- package/pages/api/page/[...pageId].js +74 -0
- package/{src/routes → pages/api}/ping.js +2 -4
- package/pages/api/reload.js +53 -0
- package/pages/api/request/[...path].js +41 -0
- package/{src/routes → pages/api}/root.js +4 -4
- package/client/Inspector.jsx +0 -206
- package/client/Routing.jsx +0 -106
- package/client/feedback/FeedbackMount.jsx +0 -83
- package/client/feedback/FeedbackOverlay.jsx +0 -901
- package/client/feedback/captureTabScreenshot.js +0 -84
- package/client/feedback/copyToClipboard.js +0 -45
- package/client/feedback/drawAnnotationsSvg.js +0 -119
- package/client/feedback/elementInspect.js +0 -99
- package/client/feedback/feedbackStyles.js +0 -301
- package/client/feedback/pinResponsiveImages.js +0 -59
- package/client/feedback/sendFeedback.js +0 -39
- package/client/feedback/useFeedbackToggle.js +0 -70
- package/client/main.jsx +0 -42
- package/client/openInEditor/OpenInEditorListener.jsx +0 -261
- package/client/openInEditor/findBlockLocation.js +0 -51
- package/lib/client/auth/AuthConfigured.jsx +0 -155
- package/lib/docs/captureAnnotatedScreenshot.js +0 -88
- package/lib/docs/checkpointPaths.js +0 -91
- package/lib/docs/checkpointStore.js +0 -234
- package/lib/docs/checkpointToMocks.js +0 -65
- package/lib/docs/configCheckpoints.test.mjs +0 -156
- package/lib/docs/createConfigCheckpoint.js +0 -92
- package/lib/docs/createDocsMcpServer.js +0 -506
- package/lib/docs/createDocsMcpServer.test.mjs +0 -123
- package/lib/docs/devMockRegistry.js +0 -68
- package/lib/docs/docs.test.mjs +0 -448
- package/lib/docs/enrichFeedback.js +0 -71
- package/lib/docs/evalOperator.js +0 -39
- package/lib/docs/evalOperator.test.mjs +0 -112
- package/lib/docs/evalOperatorHeadless.js +0 -87
- package/lib/docs/evalOperatorHeadless.test.mjs +0 -72
- package/lib/docs/evalOperatorInTab.js +0 -48
- package/lib/docs/findConfig.js +0 -260
- package/lib/docs/formatFeedback.js +0 -121
- package/lib/docs/formatFeedback.test.mjs +0 -204
- package/lib/docs/getAppMap.js +0 -180
- package/lib/docs/getBrowser.js +0 -115
- package/lib/docs/getBuildStatus.js +0 -37
- package/lib/docs/getCoreDoc.js +0 -63
- package/lib/docs/getDocsManifest.js +0 -40
- package/lib/docs/getExamples.js +0 -58
- package/lib/docs/getOverview.js +0 -115
- package/lib/docs/getPageConfig.js +0 -53
- package/lib/docs/getPluginDoc.js +0 -55
- package/lib/docs/getSchema.js +0 -65
- package/lib/docs/inspectState.js +0 -41
- package/lib/docs/inspectState.test.mjs +0 -91
- package/lib/docs/inspectStateFromTab.js +0 -40
- package/lib/docs/inspectStateHeadless.js +0 -84
- package/lib/docs/inspectStateHeadless.test.mjs +0 -60
- package/lib/docs/isWriteRequestsAllowed.js +0 -50
- package/lib/docs/listConfigCheckpoints.js +0 -55
- package/lib/docs/listPlugins.js +0 -80
- package/lib/docs/listTypes.js +0 -105
- package/lib/docs/loadState.js +0 -139
- package/lib/docs/mapPageBuildErrors.js +0 -28
- package/lib/docs/normalizeTypeKind.js +0 -40
- package/lib/docs/readBuildArtifact.js +0 -35
- package/lib/docs/readPageArtifact.js +0 -26
- package/lib/docs/resolvePluginDir.js +0 -49
- package/lib/docs/revertConfigCheckpoint.js +0 -73
- package/lib/docs/runRequest.js +0 -141
- package/lib/docs/saveAnnotatedScreenshot.js +0 -43
- package/lib/docs/scaffoldPage.js +0 -75
- package/lib/docs/scaffoldPage.test.mjs +0 -97
- package/lib/docs/screenshotPage.js +0 -109
- package/lib/docs/screenshotPage.test.mjs +0 -59
- package/lib/docs/screenshotPageClip.test.mjs +0 -102
- package/lib/docs/searchDocs.js +0 -67
- package/lib/docs/setupTestFixtures.mjs +0 -335
- package/lib/docs/snapshotState.js +0 -59
- package/lib/docs/stateCheckpoints.test.mjs +0 -348
- package/lib/docs/tabAvailable.js +0 -28
- package/lib/docs/tabChannel.js +0 -119
- package/lib/docs/tabChannel.test.mjs +0 -130
- package/lib/server/auth/createSystemContext.js +0 -70
- package/lib/server/auth/getAuth.js +0 -46
- package/lib/server/auth/getHeadlessUser.js +0 -39
- package/lib/server/auth/headlessUser.js +0 -30
- package/lib/server/createLowdefyContext.js +0 -133
- package/lib/server/loadDynamicJsMap.js +0 -47
- package/manager/processes/lowdefyBuild.test.mjs +0 -102
- package/manager/utils/formatNoticeBox.mjs +0 -30
- package/manager/utils/writeBuildStatus.mjs +0 -39
- package/manager/utils/writeBuildStatus.test.mjs +0 -76
- package/postcss.config.cjs +0 -1
- package/src/app.js +0 -188
- package/src/html/renderDevPage.js +0 -86
- package/src/lib/getPathSegments.js +0 -25
- package/src/lib/safeScriptJson.js +0 -38
- package/src/middleware/apiContext.js +0 -32
- package/src/middleware/errorHandler.js +0 -55
- package/src/routes/agent.js +0 -64
- package/src/routes/auth.js +0 -43
- package/src/routes/clientError.js +0 -57
- package/src/routes/cron.js +0 -44
- package/src/routes/detached.js +0 -51
- package/src/routes/devInspect.js +0 -94
- package/src/routes/docs/checkpointsCreate.js +0 -28
- package/src/routes/docs/checkpointsList.js +0 -23
- package/src/routes/docs/content.js +0 -31
- package/src/routes/docs/evalOperator.js +0 -46
- package/src/routes/docs/examples.js +0 -33
- package/src/routes/docs/find.js +0 -30
- package/src/routes/docs/index.js +0 -23
- package/src/routes/docs/inspectState.js +0 -34
- package/src/routes/docs/loadState.js +0 -38
- package/src/routes/docs/mcp.js +0 -30
- package/src/routes/docs/pageConfig.js +0 -36
- package/src/routes/docs/pluginDoc.js +0 -33
- package/src/routes/docs/plugins.js +0 -23
- package/src/routes/docs/runRequest.js +0 -34
- package/src/routes/docs/schema.js +0 -37
- package/src/routes/docs/screenshot.js +0 -66
- package/src/routes/docs/search.js +0 -27
- package/src/routes/docs/snapshotState.js +0 -36
- package/src/routes/docs/stateCheckpointsList.js +0 -26
- package/src/routes/docs/types.js +0 -33
- package/src/routes/endpoints.js +0 -76
- package/src/routes/feedback.js +0 -110
- package/src/routes/feedback.test.mjs +0 -204
- package/src/routes/iconsDynamic.js +0 -25
- package/src/routes/jitPage.js +0 -99
- package/src/routes/reload.js +0 -81
- package/src/routes/request.js +0 -66
- package/src/routes/usage.js +0 -46
- package/src/routes/user.js +0 -27
- package/src/routes/websocket.js +0 -33
- package/src/websocket/devWebSocket.js +0 -78
- package/vite.config.js +0 -111
- /package/lib/client/{BuildErrorPage.jsx → BuildErrorPage.js} +0 -0
- /package/lib/client/{BuildingPage.jsx → BuildingPage.js} +0 -0
- /package/lib/client/{ErrorBar.jsx → ErrorBar.js} +0 -0
- /package/lib/client/{InstallingPluginsPage.jsx → InstallingPluginsPage.js} +0 -0
- /package/lib/client/{RestartingPage.jsx → RestartingPage.js} +0 -0
package/.eslintrc.yaml
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
extends: 'plugin:@next/next/core-web-vitals'
|
package/lib/build/app.js
CHANGED
|
@@ -13,14 +13,7 @@
|
|
|
13
13
|
See the License for the specific language governing permissions and
|
|
14
14
|
limitations under the License.
|
|
15
15
|
*/
|
|
16
|
-
|
|
17
|
-
// Build artifacts are read from disk because the Hono server runs as
|
|
18
|
-
// unbundled Node.js ESM — JSON imports would need import attributes, and
|
|
19
|
-
// client code imports the build JSON directly through Vite instead.
|
|
20
|
-
import fs from 'node:fs';
|
|
21
|
-
import path from 'node:path';
|
|
22
16
|
import { serializer } from '@lowdefy/helpers';
|
|
23
|
-
|
|
24
|
-
const raw = JSON.parse(fs.readFileSync(path.join(process.cwd(), 'build/app.json'), 'utf8'));
|
|
17
|
+
import raw from '../../build/app.json';
|
|
25
18
|
|
|
26
19
|
export default serializer.deserialize(raw);
|
package/lib/build/appMeta.js
CHANGED
|
@@ -13,14 +13,7 @@
|
|
|
13
13
|
See the License for the specific language governing permissions and
|
|
14
14
|
limitations under the License.
|
|
15
15
|
*/
|
|
16
|
-
|
|
17
|
-
// Build artifacts are read from disk because the Hono server runs as
|
|
18
|
-
// unbundled Node.js ESM — JSON imports would need import attributes, and
|
|
19
|
-
// client code imports the build JSON directly through Vite instead.
|
|
20
|
-
import fs from 'node:fs';
|
|
21
|
-
import path from 'node:path';
|
|
22
16
|
import { serializer } from '@lowdefy/helpers';
|
|
23
|
-
|
|
24
|
-
const raw = JSON.parse(fs.readFileSync(path.join(process.cwd(), 'build/appMeta.json'), 'utf8'));
|
|
17
|
+
import raw from '../../build/appMeta.json';
|
|
25
18
|
|
|
26
19
|
export default serializer.deserialize(raw);
|
package/lib/build/auth.js
CHANGED
|
@@ -13,14 +13,7 @@
|
|
|
13
13
|
See the License for the specific language governing permissions and
|
|
14
14
|
limitations under the License.
|
|
15
15
|
*/
|
|
16
|
-
|
|
17
|
-
// Build artifacts are read from disk because the Hono server runs as
|
|
18
|
-
// unbundled Node.js ESM — JSON imports would need import attributes, and
|
|
19
|
-
// client code imports the build JSON directly through Vite instead.
|
|
20
|
-
import fs from 'node:fs';
|
|
21
|
-
import path from 'node:path';
|
|
22
16
|
import { serializer } from '@lowdefy/helpers';
|
|
23
|
-
|
|
24
|
-
const raw = JSON.parse(fs.readFileSync(path.join(process.cwd(), 'build/auth.json'), 'utf8'));
|
|
17
|
+
import raw from '../../build/auth.json';
|
|
25
18
|
|
|
26
19
|
export default serializer.deserialize(raw);
|
package/lib/build/config.js
CHANGED
|
@@ -13,14 +13,7 @@
|
|
|
13
13
|
See the License for the specific language governing permissions and
|
|
14
14
|
limitations under the License.
|
|
15
15
|
*/
|
|
16
|
-
|
|
17
|
-
// Build artifacts are read from disk because the Hono server runs as
|
|
18
|
-
// unbundled Node.js ESM — JSON imports would need import attributes, and
|
|
19
|
-
// client code imports the build JSON directly through Vite instead.
|
|
20
|
-
import fs from 'node:fs';
|
|
21
|
-
import path from 'node:path';
|
|
22
16
|
import { serializer } from '@lowdefy/helpers';
|
|
23
|
-
|
|
24
|
-
const raw = JSON.parse(fs.readFileSync(path.join(process.cwd(), 'build/config.json'), 'utf8'));
|
|
17
|
+
import raw from '../../build/config.json';
|
|
25
18
|
|
|
26
19
|
export default serializer.deserialize(raw);
|
package/lib/build/i18n.js
CHANGED
|
@@ -13,14 +13,7 @@
|
|
|
13
13
|
See the License for the specific language governing permissions and
|
|
14
14
|
limitations under the License.
|
|
15
15
|
*/
|
|
16
|
-
|
|
17
|
-
// Build artifacts are read from disk because the Hono server runs as
|
|
18
|
-
// unbundled Node.js ESM — JSON imports would need import attributes, and
|
|
19
|
-
// client code imports the build JSON directly through Vite instead.
|
|
20
|
-
import fs from 'node:fs';
|
|
21
|
-
import path from 'node:path';
|
|
22
16
|
import { serializer } from '@lowdefy/helpers';
|
|
23
|
-
|
|
24
|
-
const raw = JSON.parse(fs.readFileSync(path.join(process.cwd(), 'build/i18n.json'), 'utf8'));
|
|
17
|
+
import raw from '../../build/i18n.json';
|
|
25
18
|
|
|
26
19
|
export default serializer.deserialize(raw);
|
package/lib/build/logger.js
CHANGED
|
@@ -13,14 +13,7 @@
|
|
|
13
13
|
See the License for the specific language governing permissions and
|
|
14
14
|
limitations under the License.
|
|
15
15
|
*/
|
|
16
|
-
|
|
17
|
-
// Build artifacts are read from disk because the Hono server runs as
|
|
18
|
-
// unbundled Node.js ESM — JSON imports would need import attributes, and
|
|
19
|
-
// client code imports the build JSON directly through Vite instead.
|
|
20
|
-
import fs from 'node:fs';
|
|
21
|
-
import path from 'node:path';
|
|
22
16
|
import { serializer } from '@lowdefy/helpers';
|
|
23
|
-
|
|
24
|
-
const raw = JSON.parse(fs.readFileSync(path.join(process.cwd(), 'build/logger.json'), 'utf8'));
|
|
17
|
+
import raw from '../../build/logger.json';
|
|
25
18
|
|
|
26
19
|
export default serializer.deserialize(raw);
|
package/lib/build/theme.js
CHANGED
|
@@ -13,14 +13,7 @@
|
|
|
13
13
|
See the License for the specific language governing permissions and
|
|
14
14
|
limitations under the License.
|
|
15
15
|
*/
|
|
16
|
-
|
|
17
|
-
// Build artifacts are read from disk because the Hono server runs as
|
|
18
|
-
// unbundled Node.js ESM — JSON imports would need import attributes, and
|
|
19
|
-
// client code imports the build JSON directly through Vite instead.
|
|
20
|
-
import fs from 'node:fs';
|
|
21
|
-
import path from 'node:path';
|
|
22
16
|
import { serializer } from '@lowdefy/helpers';
|
|
23
|
-
|
|
24
|
-
const raw = JSON.parse(fs.readFileSync(path.join(process.cwd(), 'build/theme.json'), 'utf8'));
|
|
17
|
+
import raw from '../../build/theme.json';
|
|
25
18
|
|
|
26
19
|
export default serializer.deserialize(raw);
|
|
@@ -0,0 +1,80 @@
|
|
|
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 React, { Suspense } from 'react';
|
|
18
|
+
|
|
19
|
+
import { useRouter } from 'next/router';
|
|
20
|
+
|
|
21
|
+
import Head from 'next/head';
|
|
22
|
+
import Link from 'next/link';
|
|
23
|
+
|
|
24
|
+
import BuildingPage from './BuildingPage.js';
|
|
25
|
+
import Reload from './Reload.js';
|
|
26
|
+
import Page from './Page.js';
|
|
27
|
+
import setPageId from './setPageId.js';
|
|
28
|
+
import { getReloadVersion } from './utils/useMutateCache.js';
|
|
29
|
+
import useRootConfig from './utils/useRootConfig.js';
|
|
30
|
+
|
|
31
|
+
import actions from '../../build/plugins/actions.js';
|
|
32
|
+
import blockMetas from '../../build/plugins/blockMetas.json';
|
|
33
|
+
import blocks from '../../build/plugins/blocks.js';
|
|
34
|
+
import icons from '../../build/plugins/icons.js';
|
|
35
|
+
import operators from '../../build/plugins/operators/client.js';
|
|
36
|
+
import staticJsMap from '../../build/plugins/operators/clientJsMap.js';
|
|
37
|
+
|
|
38
|
+
const App = ({ auth, lowdefy }) => {
|
|
39
|
+
const router = useRouter();
|
|
40
|
+
const { data: rootConfig } = useRootConfig(router.basePath);
|
|
41
|
+
|
|
42
|
+
if (rootConfig?.theme) {
|
|
43
|
+
lowdefy.theme = rootConfig.theme;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const { redirect, pageId } = setPageId(router, rootConfig);
|
|
47
|
+
if (redirect) {
|
|
48
|
+
router.push(`/${pageId}`);
|
|
49
|
+
return '';
|
|
50
|
+
}
|
|
51
|
+
return (
|
|
52
|
+
<Reload basePath={router.basePath} lowdefy={lowdefy}>
|
|
53
|
+
{(resetContext) => (
|
|
54
|
+
<Suspense key={`${pageId}_${getReloadVersion()}`} fallback={<BuildingPage />}>
|
|
55
|
+
<Page
|
|
56
|
+
auth={auth}
|
|
57
|
+
Components={{ Head, Link }}
|
|
58
|
+
config={{
|
|
59
|
+
rootConfig,
|
|
60
|
+
}}
|
|
61
|
+
jsMap={staticJsMap}
|
|
62
|
+
lowdefy={lowdefy}
|
|
63
|
+
pageId={pageId}
|
|
64
|
+
resetContext={resetContext}
|
|
65
|
+
router={router}
|
|
66
|
+
types={{
|
|
67
|
+
actions,
|
|
68
|
+
blockMetas,
|
|
69
|
+
blocks,
|
|
70
|
+
icons,
|
|
71
|
+
operators,
|
|
72
|
+
}}
|
|
73
|
+
/>
|
|
74
|
+
</Suspense>
|
|
75
|
+
)}
|
|
76
|
+
</Reload>
|
|
77
|
+
);
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
export default App;
|
|
@@ -18,10 +18,10 @@ import React, { useEffect, useRef } from 'react';
|
|
|
18
18
|
import { GenIcon } from 'react-icons/lib';
|
|
19
19
|
import Client from '@lowdefy/client';
|
|
20
20
|
|
|
21
|
-
import BuildErrorPage from '
|
|
22
|
-
import InstallingPluginsPage from '
|
|
23
|
-
import RestartingPage from '
|
|
24
|
-
import usePageConfig from '
|
|
21
|
+
import BuildErrorPage from './BuildErrorPage.js';
|
|
22
|
+
import InstallingPluginsPage from './InstallingPluginsPage.js';
|
|
23
|
+
import RestartingPage from './RestartingPage.js';
|
|
24
|
+
import usePageConfig from './utils/usePageConfig.js';
|
|
25
25
|
|
|
26
26
|
const Page = ({
|
|
27
27
|
auth,
|
|
@@ -48,7 +48,7 @@ const Page = ({
|
|
|
48
48
|
}, [pageConfig?._warnings, lowdefy]);
|
|
49
49
|
|
|
50
50
|
if (!pageConfig) {
|
|
51
|
-
router.replace(
|
|
51
|
+
router.replace(`/404`);
|
|
52
52
|
return '';
|
|
53
53
|
}
|
|
54
54
|
if (pageConfig.buildError) {
|
|
@@ -16,12 +16,9 @@
|
|
|
16
16
|
|
|
17
17
|
import React, { useEffect, useState } from 'react';
|
|
18
18
|
|
|
19
|
-
import useMutateCache from '
|
|
20
|
-
import waitForRestartedServer from '
|
|
19
|
+
import useMutateCache from './utils/useMutateCache.js';
|
|
20
|
+
import waitForRestartedServer from './utils/waitForRestartedServer.js';
|
|
21
21
|
|
|
22
|
-
// SSE listener — config rebuilds notify via /api/reload. Tailwind CSS updates
|
|
23
|
-
// arrive through Vite HMR now (globals.css is in the dev module graph), so
|
|
24
|
-
// the old tailwind-jit.css link cache-bust is gone.
|
|
25
22
|
const Reload = ({ children, basePath, lowdefy }) => {
|
|
26
23
|
const [reset, setReset] = useState(false);
|
|
27
24
|
const [restarting, setRestarting] = useState(false);
|
|
@@ -37,6 +34,11 @@ const Reload = ({ children, basePath, lowdefy }) => {
|
|
|
37
34
|
if (lowdefy._internal?.initialised) {
|
|
38
35
|
lowdefy._internal.initialised = false;
|
|
39
36
|
}
|
|
37
|
+
// Refresh JIT CSS link to pick up newly compiled Tailwind classes
|
|
38
|
+
const cssLink = document.getElementById('tailwind-jit-css');
|
|
39
|
+
if (cssLink) {
|
|
40
|
+
cssLink.href = `${basePath}/tailwind-jit.css?v=${Date.now()}`;
|
|
41
|
+
}
|
|
40
42
|
setReset(true);
|
|
41
43
|
console.log('Reloaded config.');
|
|
42
44
|
}, 600);
|
|
@@ -13,25 +13,18 @@
|
|
|
13
13
|
See the License for the specific language governing permissions and
|
|
14
14
|
limitations under the License.
|
|
15
15
|
*/
|
|
16
|
+
/* eslint-disable react/jsx-props-no-spreading */
|
|
16
17
|
|
|
17
18
|
import React from 'react';
|
|
18
|
-
import AuthConfigured from './AuthConfigured.
|
|
19
|
+
import AuthConfigured from './AuthConfigured.js';
|
|
19
20
|
import AuthNotConfigured from './AuthNotConfigured.js';
|
|
20
21
|
|
|
21
|
-
import
|
|
22
|
+
import authConfig from '../../build/auth.js';
|
|
22
23
|
|
|
23
|
-
|
|
24
|
-
// the lib/build/*.js wrappers are server-only (they read from disk).
|
|
25
|
-
// Deserialize to restore arrays from their ~arr build markers (providers
|
|
26
|
-
// must be a real array for provider lookups in createAuthMethods).
|
|
27
|
-
import rawAuthConfig from '../../../build/auth.json';
|
|
28
|
-
|
|
29
|
-
const authConfig = serializer.deserialize(rawAuthConfig);
|
|
30
|
-
|
|
31
|
-
function Auth({ children, user }) {
|
|
24
|
+
function Auth({ children, session }) {
|
|
32
25
|
if (authConfig.configured === true) {
|
|
33
26
|
return (
|
|
34
|
-
<AuthConfigured
|
|
27
|
+
<AuthConfigured serverSession={session} authConfig={authConfig}>
|
|
35
28
|
{(auth) => children(auth)}
|
|
36
29
|
</AuthConfigured>
|
|
37
30
|
);
|
|
@@ -0,0 +1,61 @@
|
|
|
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
|
+
/* eslint-disable react/jsx-props-no-spreading */
|
|
17
|
+
|
|
18
|
+
import React, { useEffect, useRef } from 'react';
|
|
19
|
+
import { getSession, SessionProvider, signIn, signOut, useSession } from 'next-auth/react';
|
|
20
|
+
|
|
21
|
+
import lowdefyConfig from '../../build/config.js';
|
|
22
|
+
|
|
23
|
+
function Session({ children }) {
|
|
24
|
+
const wasAuthenticated = useRef(false);
|
|
25
|
+
const { data: session, status } = useSession();
|
|
26
|
+
wasAuthenticated.current = wasAuthenticated.current || status === 'authenticated';
|
|
27
|
+
|
|
28
|
+
useEffect(() => {
|
|
29
|
+
if (wasAuthenticated.current && status === 'unauthenticated') {
|
|
30
|
+
window.location.reload();
|
|
31
|
+
}
|
|
32
|
+
}, [status]);
|
|
33
|
+
|
|
34
|
+
// If session is passed to SessionProvider from getServerSideProps
|
|
35
|
+
// we won't have a loading state here.
|
|
36
|
+
// But 404 uses getStaticProps so we have this for 404.
|
|
37
|
+
if (status === 'loading') {
|
|
38
|
+
return '';
|
|
39
|
+
}
|
|
40
|
+
return children(session);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function AuthConfigured({ authConfig, children, serverSession }) {
|
|
44
|
+
const auth = { authConfig, getSession, signIn, signOut };
|
|
45
|
+
let basePath = lowdefyConfig.basePath;
|
|
46
|
+
if (basePath) {
|
|
47
|
+
basePath = `${basePath}/api/auth`;
|
|
48
|
+
}
|
|
49
|
+
return (
|
|
50
|
+
<SessionProvider session={serverSession} basePath={basePath}>
|
|
51
|
+
<Session>
|
|
52
|
+
{(session) => {
|
|
53
|
+
auth.session = session;
|
|
54
|
+
return children(auth);
|
|
55
|
+
}}
|
|
56
|
+
</Session>
|
|
57
|
+
</SessionProvider>
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export default AuthConfigured;
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
See the License for the specific language governing permissions and
|
|
14
14
|
limitations under the License.
|
|
15
15
|
*/
|
|
16
|
+
/* eslint-disable react/jsx-props-no-spreading */
|
|
16
17
|
|
|
17
18
|
function authNotConfigured() {
|
|
18
19
|
throw new Error('Auth not configured.');
|
|
@@ -21,30 +22,9 @@ function authNotConfigured() {
|
|
|
21
22
|
function AuthNotConfigured({ authConfig, children }) {
|
|
22
23
|
const auth = {
|
|
23
24
|
authConfig,
|
|
24
|
-
user: null,
|
|
25
|
-
acceptInvitation: authNotConfigured,
|
|
26
|
-
addPasskey: authNotConfigured,
|
|
27
|
-
changePassword: authNotConfigured,
|
|
28
|
-
deletePasskey: authNotConfigured,
|
|
29
|
-
getResolvedUser: authNotConfigured,
|
|
30
25
|
getSession: authNotConfigured,
|
|
31
|
-
|
|
32
|
-
requestPasswordReset: authNotConfigured,
|
|
33
|
-
resetPassword: authNotConfigured,
|
|
34
|
-
revokeOtherSessions: authNotConfigured,
|
|
35
|
-
sendVerificationEmail: authNotConfigured,
|
|
36
|
-
setActiveOrganization: authNotConfigured,
|
|
37
|
-
signInEmail: authNotConfigured,
|
|
38
|
-
signInMagicLink: authNotConfigured,
|
|
39
|
-
signInOauth2: authNotConfigured,
|
|
40
|
-
signInSocial: authNotConfigured,
|
|
26
|
+
signIn: authNotConfigured,
|
|
41
27
|
signOut: authNotConfigured,
|
|
42
|
-
signUpEmail: authNotConfigured,
|
|
43
|
-
stopImpersonating: authNotConfigured,
|
|
44
|
-
twoFactorDisable: authNotConfigured,
|
|
45
|
-
twoFactorEnable: authNotConfigured,
|
|
46
|
-
twoFactorVerifyBackupCode: authNotConfigured,
|
|
47
|
-
twoFactorVerifyTotp: authNotConfigured,
|
|
48
28
|
};
|
|
49
29
|
|
|
50
30
|
return children(auth);
|
package/lib/client/setPageId.js
CHANGED
|
@@ -14,19 +14,18 @@
|
|
|
14
14
|
limitations under the License.
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
function setPageId(location, rootConfig) {
|
|
20
|
-
if (location.pageId === '404') {
|
|
17
|
+
function setPageId(router, rootConfig) {
|
|
18
|
+
if (router.pathname === `/404`) {
|
|
21
19
|
return { redirect: false, pageId: '404' };
|
|
22
20
|
}
|
|
23
|
-
|
|
21
|
+
const segments = router.query.pageId;
|
|
22
|
+
if (!segments || segments.length === 0) {
|
|
24
23
|
if (rootConfig.home.configured === false) {
|
|
25
24
|
return { redirect: true, pageId: rootConfig.home.pageId };
|
|
26
25
|
}
|
|
27
26
|
return { redirect: false, pageId: rootConfig.home.pageId };
|
|
28
27
|
}
|
|
29
|
-
return { redirect: false, pageId:
|
|
28
|
+
return { redirect: false, pageId: segments.join('/') };
|
|
30
29
|
}
|
|
31
30
|
|
|
32
31
|
export default setPageId;
|
|
@@ -16,25 +16,12 @@
|
|
|
16
16
|
|
|
17
17
|
import { useSWRConfig } from 'swr';
|
|
18
18
|
|
|
19
|
-
// Module-level counters that bust usePageConfig SWR keys: reloadVersion moves
|
|
20
|
-
// on config reloads (all pages), navVersion on client-side navigations
|
|
21
|
-
// (dynamic pages only — server-resolved content must re-resolve per
|
|
22
|
-
// navigation, never serve from the SWR cache).
|
|
23
19
|
let reloadVersion = 0;
|
|
24
|
-
let navVersion = 0;
|
|
25
20
|
|
|
26
21
|
function getReloadVersion() {
|
|
27
22
|
return reloadVersion;
|
|
28
23
|
}
|
|
29
24
|
|
|
30
|
-
function bumpNavVersion() {
|
|
31
|
-
navVersion += 1;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
function getNavVersion() {
|
|
35
|
-
return navVersion;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
25
|
function useMutateCache(basePath) {
|
|
39
26
|
const { mutate } = useSWRConfig();
|
|
40
27
|
return () => {
|
|
@@ -47,5 +34,5 @@ function useMutateCache(basePath) {
|
|
|
47
34
|
};
|
|
48
35
|
}
|
|
49
36
|
|
|
50
|
-
export {
|
|
37
|
+
export { getReloadVersion };
|
|
51
38
|
export default useMutateCache;
|
|
@@ -13,12 +13,7 @@
|
|
|
13
13
|
|
|
14
14
|
import useSWR from 'swr';
|
|
15
15
|
|
|
16
|
-
import {
|
|
17
|
-
|
|
18
|
-
// URLs whose config is server-resolved per request — learned from the fetched
|
|
19
|
-
// config's dynamic flag, so the first visit caches like a static page and
|
|
20
|
-
// every later navigation refetches.
|
|
21
|
-
const dynamicUrls = new Set();
|
|
16
|
+
import { getReloadVersion } from './useMutateCache.js';
|
|
22
17
|
|
|
23
18
|
function parseJsModule(text) {
|
|
24
19
|
const fn = new Function('exports', text.replace('export default', 'exports.default ='));
|
|
@@ -54,13 +49,6 @@ async function fetchPageConfig(url) {
|
|
|
54
49
|
if (res.status === 404) {
|
|
55
50
|
return null;
|
|
56
51
|
}
|
|
57
|
-
if (res.status === 401) {
|
|
58
|
-
// Logged-out navigation to a protected page - full load to the login
|
|
59
|
-
// page so it can return here after sign-in.
|
|
60
|
-
const { redirect } = await res.json();
|
|
61
|
-
window.location.assign(redirect ?? '/404');
|
|
62
|
-
return new Promise(() => {});
|
|
63
|
-
}
|
|
64
52
|
const data = await res.json();
|
|
65
53
|
if (data?.buildError) {
|
|
66
54
|
return data;
|
|
@@ -83,31 +71,23 @@ async function fetchPageConfig(url) {
|
|
|
83
71
|
data._jsEntries = jsEntries;
|
|
84
72
|
data._dynamicIcons = dynamicIcons;
|
|
85
73
|
|
|
86
|
-
|
|
87
|
-
|
|
74
|
+
// Bust CSS cache so the browser picks up newly compiled Tailwind classes
|
|
75
|
+
const cssLink = document.getElementById('tailwind-jit-css');
|
|
76
|
+
if (cssLink) {
|
|
77
|
+
cssLink.href = `${basePath}/tailwind-jit.css?v=${Date.now()}`;
|
|
88
78
|
}
|
|
89
79
|
|
|
90
80
|
return data;
|
|
91
81
|
}
|
|
92
82
|
|
|
93
83
|
function usePageConfig(pageId, basePath) {
|
|
94
|
-
|
|
95
|
-
// sees the same urlQuery as an initial HTML load. Including it in the SWR
|
|
96
|
-
// key also caches dynamic pages per query string.
|
|
97
|
-
const url = `${basePath}/api/page/${pageId}${window.location.search}`;
|
|
84
|
+
const url = `${basePath}/api/page/${pageId}`;
|
|
98
85
|
// Include reloadVersion in the SWR key so that after a config reload,
|
|
99
|
-
// previously cached page data is not reused.
|
|
100
|
-
//
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
const { data } = useSWR(
|
|
105
|
-
[url, getReloadVersion(), navVersion],
|
|
106
|
-
([fetchUrl]) => fetchPageConfig(fetchUrl),
|
|
107
|
-
{
|
|
108
|
-
suspense: true,
|
|
109
|
-
}
|
|
110
|
-
);
|
|
86
|
+
// previously cached page data is not reused. The fetcher receives
|
|
87
|
+
// [url, version] but only uses url — the version just busts the cache.
|
|
88
|
+
const { data } = useSWR([url, getReloadVersion()], ([fetchUrl]) => fetchPageConfig(fetchUrl), {
|
|
89
|
+
suspense: true,
|
|
90
|
+
});
|
|
111
91
|
return { data };
|
|
112
92
|
}
|
|
113
93
|
|
|
@@ -0,0 +1,116 @@
|
|
|
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
|
+
import fs from 'fs';
|
|
17
|
+
import path from 'path';
|
|
18
|
+
import { createApiContext } from '@lowdefy/api';
|
|
19
|
+
import { getSecretsFromEnv } from '@lowdefy/node-utils';
|
|
20
|
+
import { serializer } from '@lowdefy/helpers';
|
|
21
|
+
import { v4 as uuid } from 'uuid';
|
|
22
|
+
|
|
23
|
+
import agents from '../../build/plugins/agents.js';
|
|
24
|
+
import appMeta from '../build/appMeta.js';
|
|
25
|
+
import config from '../build/config.js';
|
|
26
|
+
import i18nConfig from '../build/i18n.js';
|
|
27
|
+
import connections from '../../build/plugins/connections.js';
|
|
28
|
+
import createLogger from './log/createLogger.js';
|
|
29
|
+
import fileCache from './fileCache.js';
|
|
30
|
+
import getServerSession from './auth/getServerSession.js';
|
|
31
|
+
import createHandleError from './log/createHandleError.js';
|
|
32
|
+
import logRequest from './log/logRequest.js';
|
|
33
|
+
import operators from '../../build/plugins/operators/server.js';
|
|
34
|
+
import staticJsMap from '../../build/plugins/operators/serverJsMap.js';
|
|
35
|
+
import getAuthOptions from './auth/getAuthOptions.js';
|
|
36
|
+
|
|
37
|
+
const secrets = getSecretsFromEnv();
|
|
38
|
+
|
|
39
|
+
// Dynamic JS map loading for JIT-built pages
|
|
40
|
+
let cachedJsMapMtime = null;
|
|
41
|
+
let cachedJsMap = staticJsMap;
|
|
42
|
+
|
|
43
|
+
function loadDynamicJsMap(buildDirectory) {
|
|
44
|
+
const jsMapPath = path.join(buildDirectory, 'plugins', 'operators', 'serverJsMap.js');
|
|
45
|
+
try {
|
|
46
|
+
const stat = fs.statSync(jsMapPath);
|
|
47
|
+
if (cachedJsMapMtime && stat.mtimeMs === cachedJsMapMtime) {
|
|
48
|
+
return cachedJsMap;
|
|
49
|
+
}
|
|
50
|
+
cachedJsMapMtime = stat.mtimeMs;
|
|
51
|
+
// For server-side, we can read and eval the JS file
|
|
52
|
+
const content = fs.readFileSync(jsMapPath, 'utf8');
|
|
53
|
+
const fn = new Function('exports', content.replace('export default', 'exports.default ='));
|
|
54
|
+
const exports = {};
|
|
55
|
+
fn(exports);
|
|
56
|
+
cachedJsMap = { ...staticJsMap, ...(exports.default ?? {}) };
|
|
57
|
+
return cachedJsMap;
|
|
58
|
+
} catch {
|
|
59
|
+
return cachedJsMap;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function apiWrapper(handler) {
|
|
64
|
+
return async function wrappedHandler(req, res) {
|
|
65
|
+
const buildDirectory = path.join(process.cwd(), 'build');
|
|
66
|
+
const jsMap = loadDynamicJsMap(buildDirectory);
|
|
67
|
+
|
|
68
|
+
const context = {
|
|
69
|
+
// Important to give absolute path so Next can trace build files
|
|
70
|
+
rid: uuid(),
|
|
71
|
+
agents,
|
|
72
|
+
appMeta,
|
|
73
|
+
buildDirectory,
|
|
74
|
+
configDirectory: process.env.LOWDEFY_DIRECTORY_CONFIG || process.cwd(),
|
|
75
|
+
config,
|
|
76
|
+
connections,
|
|
77
|
+
fileCache,
|
|
78
|
+
headers: req?.headers,
|
|
79
|
+
i18n: i18nConfig,
|
|
80
|
+
jsMap,
|
|
81
|
+
handleError: async (err) => {
|
|
82
|
+
console.error(err);
|
|
83
|
+
},
|
|
84
|
+
logger: console,
|
|
85
|
+
operators,
|
|
86
|
+
req,
|
|
87
|
+
res,
|
|
88
|
+
secrets,
|
|
89
|
+
};
|
|
90
|
+
try {
|
|
91
|
+
context.logger = createLogger();
|
|
92
|
+
context.handleError = createHandleError({ context });
|
|
93
|
+
context.authOptions = getAuthOptions(context);
|
|
94
|
+
if (!req.url.startsWith('/api/auth')) {
|
|
95
|
+
context.session = await getServerSession(context);
|
|
96
|
+
}
|
|
97
|
+
createApiContext(context);
|
|
98
|
+
logRequest({ context });
|
|
99
|
+
// Await here so that if handler throws it is caught.
|
|
100
|
+
const response = await handler({ context, req, res });
|
|
101
|
+
// TODO: Log response time?
|
|
102
|
+
return response;
|
|
103
|
+
} catch (error) {
|
|
104
|
+
await context.handleError(error);
|
|
105
|
+
const serialized = serializer.serialize(error);
|
|
106
|
+
if (serialized?.['~e']) {
|
|
107
|
+
delete serialized['~e'].received;
|
|
108
|
+
delete serialized['~e'].stack;
|
|
109
|
+
delete serialized['~e'].configKey;
|
|
110
|
+
}
|
|
111
|
+
res.status(500).json(serialized);
|
|
112
|
+
}
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
export default apiWrapper;
|