@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/src/routes/jitPage.js
DELETED
|
@@ -1,99 +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 { getPageConfig } from '@lowdefy/api';
|
|
18
|
-
|
|
19
|
-
import authJson from '../../lib/build/auth.js';
|
|
20
|
-
import buildPageIfNeeded from '../../lib/server/jitPageBuilder.js';
|
|
21
|
-
import getPathSegments from '../lib/getPathSegments.js';
|
|
22
|
-
import lowdefyConfig from '../../lib/build/config.js';
|
|
23
|
-
|
|
24
|
-
const basePath = lowdefyConfig.basePath ?? '';
|
|
25
|
-
|
|
26
|
-
// JIT page build + config response. The response shapes are a frozen contract
|
|
27
|
-
// with the dev client:
|
|
28
|
-
// 200 { installing: true, packages } — plugin install in progress, client polls
|
|
29
|
-
// 500 { buildError: true, errors, message, source } — build failed
|
|
30
|
-
// 401 { redirect } — logged-out navigation to a protected page
|
|
31
|
-
// 404 'Page not found.'
|
|
32
|
-
// 200 pageConfig (+ _warnings)
|
|
33
|
-
async function jitPageHandler(c) {
|
|
34
|
-
const context = c.get('lowdefyContext');
|
|
35
|
-
const pageId = getPathSegments(c, '/api/page/').join('/');
|
|
36
|
-
|
|
37
|
-
let buildResult;
|
|
38
|
-
try {
|
|
39
|
-
buildResult = await buildPageIfNeeded({
|
|
40
|
-
pageId,
|
|
41
|
-
buildDirectory: context.buildDirectory,
|
|
42
|
-
configDirectory: context.configDirectory,
|
|
43
|
-
});
|
|
44
|
-
} catch (error) {
|
|
45
|
-
const rawErrors = error.buildErrors ?? [error];
|
|
46
|
-
const errors = [];
|
|
47
|
-
for (const err of rawErrors) {
|
|
48
|
-
await context.handleError(err);
|
|
49
|
-
errors.push({
|
|
50
|
-
type: err.name ?? 'Error',
|
|
51
|
-
message: err.message,
|
|
52
|
-
source: err.source ?? null,
|
|
53
|
-
stack: err.stack ?? null,
|
|
54
|
-
});
|
|
55
|
-
}
|
|
56
|
-
return c.json(
|
|
57
|
-
{
|
|
58
|
-
buildError: true,
|
|
59
|
-
errors,
|
|
60
|
-
// Keep top-level message/source for backward compatibility
|
|
61
|
-
message: error.message,
|
|
62
|
-
source: error.source ?? null,
|
|
63
|
-
},
|
|
64
|
-
500
|
|
65
|
-
);
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
if (buildResult && buildResult.installing) {
|
|
69
|
-
return c.json({
|
|
70
|
-
installing: true,
|
|
71
|
-
packages: buildResult.packages,
|
|
72
|
-
});
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
const result = await getPageConfig(context, { pageId, urlQuery: c.req.query() });
|
|
76
|
-
if (result.status === 'unauthenticated') {
|
|
77
|
-
// The client follows this redirect with a full page load, so the login
|
|
78
|
-
// page can return to the requested page after sign-in.
|
|
79
|
-
const callbackUrl = `${basePath}/${pageId}`;
|
|
80
|
-
return c.json(
|
|
81
|
-
{
|
|
82
|
-
redirect: `${basePath}${authJson.authPages.signIn}?callbackUrl=${encodeURIComponent(
|
|
83
|
-
callbackUrl
|
|
84
|
-
)}`,
|
|
85
|
-
},
|
|
86
|
-
401
|
|
87
|
-
);
|
|
88
|
-
}
|
|
89
|
-
if (result.status !== 'ok') {
|
|
90
|
-
return c.text('Page not found.', 404);
|
|
91
|
-
}
|
|
92
|
-
const pageConfig = result.pageConfig;
|
|
93
|
-
if (buildResult?.warnings?.length > 0) {
|
|
94
|
-
pageConfig._warnings = buildResult.warnings;
|
|
95
|
-
}
|
|
96
|
-
return c.json(pageConfig);
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
export default jitPageHandler;
|
package/src/routes/reload.js
DELETED
|
@@ -1,81 +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 { randomUUID } from 'node:crypto';
|
|
18
|
-
|
|
19
|
-
import chokidar from 'chokidar';
|
|
20
|
-
import { streamSSE } from 'hono/streaming';
|
|
21
|
-
|
|
22
|
-
import { registerTab, unregisterTab } from '../../lib/docs/tabChannel.js';
|
|
23
|
-
|
|
24
|
-
// SSE endpoint — notifies the client when build/reload is written so it can
|
|
25
|
-
// mutate the SWR cache and refetch config. Also doubles as the transport for
|
|
26
|
-
// the agent-state-xray tab channel (lib/docs/tabChannel.js): a connection
|
|
27
|
-
// that includes ?pageId=<id> is registered as an inspectable dev tab so an
|
|
28
|
-
// agent can push it inspect-request/eval-request SSE events.
|
|
29
|
-
//
|
|
30
|
-
// pageId tracking design: Inspector.jsx (not Reload.jsx) owns this query
|
|
31
|
-
// param, and re-opens its EventSource — new connection, new tab id — every
|
|
32
|
-
// time the developer navigates to a different page. That keeps tabChannel's
|
|
33
|
-
// view of "what page is this tab on" always correct without a separate
|
|
34
|
-
// ping route: Reload.jsx's own connection never sends pageId, so it is never
|
|
35
|
-
// registered as a tab and can't be mistaken for one by requestFromTab.
|
|
36
|
-
async function reloadHandler(c) {
|
|
37
|
-
return streamSSE(c, async (stream) => {
|
|
38
|
-
const watcher = chokidar.watch(['./build/reload'], {
|
|
39
|
-
persistent: true,
|
|
40
|
-
ignoreInitial: true,
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
const pageId = c.req.query('pageId');
|
|
44
|
-
const tabId = pageId === undefined ? undefined : randomUUID();
|
|
45
|
-
if (tabId) {
|
|
46
|
-
registerTab({
|
|
47
|
-
id: tabId,
|
|
48
|
-
pageId,
|
|
49
|
-
send: (event, data) => stream.writeSSE({ event, data: JSON.stringify(data) }),
|
|
50
|
-
});
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
let open = true;
|
|
54
|
-
stream.onAbort(() => {
|
|
55
|
-
open = false;
|
|
56
|
-
watcher.close();
|
|
57
|
-
if (tabId) {
|
|
58
|
-
unregisterTab({ id: tabId });
|
|
59
|
-
}
|
|
60
|
-
});
|
|
61
|
-
|
|
62
|
-
const reload = () => {
|
|
63
|
-
stream.writeSSE({ event: 'reload', data: JSON.stringify({}) });
|
|
64
|
-
};
|
|
65
|
-
watcher.on('add', () => reload());
|
|
66
|
-
watcher.on('change', () => reload());
|
|
67
|
-
// Do not reload on unlink — cleanBuildDirectory deletes build/reload during
|
|
68
|
-
// skeleton rebuilds, which would send a premature SSE event before the new
|
|
69
|
-
// build artifacts are written. The real reload comes via add/change when
|
|
70
|
-
// reloadClients() creates the file after the build completes.
|
|
71
|
-
|
|
72
|
-
while (open) {
|
|
73
|
-
await stream.sleep(15000);
|
|
74
|
-
if (open) {
|
|
75
|
-
await stream.writeSSE({ event: 'ping', data: '' });
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
});
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
export default reloadHandler;
|
package/src/routes/request.js
DELETED
|
@@ -1,66 +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 { callRequest } from '@lowdefy/api';
|
|
18
|
-
import { serializer } from '@lowdefy/helpers';
|
|
19
|
-
|
|
20
|
-
import getPathSegments from '../lib/getPathSegments.js';
|
|
21
|
-
import { getMock } from '../../lib/docs/devMockRegistry.js';
|
|
22
|
-
|
|
23
|
-
async function requestHandler(c) {
|
|
24
|
-
if (c.req.method !== 'POST') {
|
|
25
|
-
throw new Error('Only POST requests are supported.');
|
|
26
|
-
}
|
|
27
|
-
const context = c.get('lowdefyContext');
|
|
28
|
-
const segments = getPathSegments(c, '/api/request/');
|
|
29
|
-
if (segments.length < 2) {
|
|
30
|
-
return c.json({ error: 'Invalid request path' }, 400);
|
|
31
|
-
}
|
|
32
|
-
const requestId = segments[segments.length - 1];
|
|
33
|
-
const pageId = segments.slice(0, -1).join('/');
|
|
34
|
-
const { actionId, blockId, payload } = await c.req.json();
|
|
35
|
-
|
|
36
|
-
// Dev-only agent tooling: once a state checkpoint has been loaded
|
|
37
|
-
// (lib/docs/loadState.js), its recorded request/response pairs live in
|
|
38
|
-
// devMockRegistry keyed by (pageId, requestId). Short-circuit here, before
|
|
39
|
-
// ever touching the real connection, so a headless verification page, a
|
|
40
|
-
// human tester's browser tab, or an e2e test replays exactly what was
|
|
41
|
-
// recorded. The response shape mirrors @lowdefy/api's callRequest contract
|
|
42
|
-
// (see callRequestResolver.js / callRequest.js success shape, and
|
|
43
|
-
// middleware/errorHandler.js for the error shape) so the client's
|
|
44
|
-
// Requests.js can't tell the difference from a real request.
|
|
45
|
-
const mock = getMock({ pageId, requestId });
|
|
46
|
-
if (mock) {
|
|
47
|
-
context.logger.info({ event: 'dev_mock_request', pageId, requestId, blockId, actionId });
|
|
48
|
-
if (mock.error) {
|
|
49
|
-
const error = mock.error instanceof Error ? mock.error : new Error(mock.error);
|
|
50
|
-
const serialized = serializer.serialize(error);
|
|
51
|
-
if (serialized?.['~e']) {
|
|
52
|
-
delete serialized['~e'].received;
|
|
53
|
-
delete serialized['~e'].stack;
|
|
54
|
-
delete serialized['~e'].configKey;
|
|
55
|
-
}
|
|
56
|
-
return c.json(serialized, 500);
|
|
57
|
-
}
|
|
58
|
-
return c.json({ success: true, response: serializer.serialize(mock.response) });
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
context.logger.info({ event: 'call_request', pageId, requestId, blockId, actionId });
|
|
62
|
-
const response = await callRequest(context, { blockId, pageId, payload, requestId });
|
|
63
|
-
return c.json(response);
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
export default requestHandler;
|
package/src/routes/usage.js
DELETED
|
@@ -1,46 +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 fs from 'node:fs';
|
|
18
|
-
import path from 'node:path';
|
|
19
|
-
|
|
20
|
-
const packageJson = JSON.parse(fs.readFileSync(path.join(process.cwd(), 'package.json'), 'utf8'));
|
|
21
|
-
|
|
22
|
-
async function usageHandler(c) {
|
|
23
|
-
if (c.req.method !== 'POST') {
|
|
24
|
-
throw new Error('Only POST requests are supported.');
|
|
25
|
-
}
|
|
26
|
-
const context = c.get('lowdefyContext');
|
|
27
|
-
const { user, machine } = await c.req.json();
|
|
28
|
-
const host = c.req.header('host');
|
|
29
|
-
context.logger.info({ event: 'log_usage', user, machine });
|
|
30
|
-
|
|
31
|
-
const timestamp = Date.now();
|
|
32
|
-
|
|
33
|
-
return c.json({
|
|
34
|
-
offline: false,
|
|
35
|
-
data: {
|
|
36
|
-
gitSha: context.appMeta.gitSha,
|
|
37
|
-
host,
|
|
38
|
-
machine,
|
|
39
|
-
timestamp,
|
|
40
|
-
user,
|
|
41
|
-
version: packageJson.version,
|
|
42
|
-
},
|
|
43
|
-
});
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
export default usageHandler;
|
package/src/routes/user.js
DELETED
|
@@ -1,27 +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
|
-
// The resolved caller for the client - the same resolveAuthentication output
|
|
18
|
-
// the first page load embeds. The base session carries neither roles (read
|
|
19
|
-
// live from the active member row) nor the merged attributes bag, so the
|
|
20
|
-
// client re-syncs from here (UpdateSession) after a session change such as
|
|
21
|
-
// SetActiveOrganization.
|
|
22
|
-
async function userHandler(c) {
|
|
23
|
-
const context = c.get('lowdefyContext');
|
|
24
|
-
return c.json({ user: context.user ?? null });
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
export default userHandler;
|
package/src/routes/websocket.js
DELETED
|
@@ -1,33 +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 { setPendingWebSocketContext } from '../websocket/devWebSocket.js';
|
|
18
|
-
|
|
19
|
-
// In dev, Vite owns the HTTP server, so websocket upgrades can't flow through
|
|
20
|
-
// @hono/node-server. The Vite plugin (see vite.config.js) fetches this route
|
|
21
|
-
// with the upgrade request's headers to run the full middleware chain (auth
|
|
22
|
-
// session, apiContext), and this handler hands the built context back to the
|
|
23
|
-
// upgrade handler through a pending-context exchange keyed by request id.
|
|
24
|
-
function websocketHandler(c) {
|
|
25
|
-
const rid = c.req.header('x-lowdefy-websocket-rid');
|
|
26
|
-
if (!rid) {
|
|
27
|
-
return c.json({ message: 'WebSocket upgrade required.' }, 400);
|
|
28
|
-
}
|
|
29
|
-
setPendingWebSocketContext(rid, c.get('lowdefyContext'));
|
|
30
|
-
return c.json({ ok: true });
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
export default websocketHandler;
|
|
@@ -1,78 +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 { randomUUID } from 'node:crypto';
|
|
18
|
-
import { createChannelRegistry, createWebSocketConnection } from '@lowdefy/api';
|
|
19
|
-
|
|
20
|
-
import app from '../app.js';
|
|
21
|
-
|
|
22
|
-
// One registry per dev server process, shared by all websocket connections.
|
|
23
|
-
const registry = createChannelRegistry();
|
|
24
|
-
|
|
25
|
-
// Contexts built by the /api/websocket route (full middleware chain) are
|
|
26
|
-
// handed to the upgrade handler through this exchange, keyed by request id.
|
|
27
|
-
const pendingContexts = new Map();
|
|
28
|
-
|
|
29
|
-
function setPendingWebSocketContext(rid, context) {
|
|
30
|
-
pendingContexts.set(rid, context);
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
function takePendingWebSocketContext(rid) {
|
|
34
|
-
const context = pendingContexts.get(rid);
|
|
35
|
-
pendingContexts.delete(rid);
|
|
36
|
-
return context;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
// Called by the Vite plugin on an HTTP upgrade for /api/websocket. Runs the
|
|
40
|
-
// dev Hono app for the upgrade request (auth session + apiContext), then
|
|
41
|
-
// completes the websocket handshake and wires the connection to the registry.
|
|
42
|
-
async function handleWebSocketUpgrade({ request, socket, head, wss }) {
|
|
43
|
-
const rid = randomUUID();
|
|
44
|
-
const headers = new Headers();
|
|
45
|
-
Object.entries(request.headers).forEach(([key, value]) => {
|
|
46
|
-
if (value) {
|
|
47
|
-
headers.set(key, Array.isArray(value) ? value[0] : value);
|
|
48
|
-
}
|
|
49
|
-
});
|
|
50
|
-
headers.set('x-lowdefy-websocket-rid', rid);
|
|
51
|
-
|
|
52
|
-
const url = `http://${request.headers.host ?? 'localhost'}${request.url}`;
|
|
53
|
-
const response = await app.fetch(new Request(url, { headers }));
|
|
54
|
-
const context = takePendingWebSocketContext(rid);
|
|
55
|
-
|
|
56
|
-
if (!context || response.status !== 200) {
|
|
57
|
-
socket.end('HTTP/1.1 400 Bad Request\r\nConnection: close\r\n\r\n');
|
|
58
|
-
return;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
wss.handleUpgrade(request, socket, head, (ws) => {
|
|
62
|
-
const connection = createWebSocketConnection(context, {
|
|
63
|
-
registry,
|
|
64
|
-
send: (message) => ws.send(message),
|
|
65
|
-
});
|
|
66
|
-
ws.on('message', (data) => {
|
|
67
|
-
connection.handleMessage(data.toString());
|
|
68
|
-
});
|
|
69
|
-
ws.on('close', () => {
|
|
70
|
-
connection.close();
|
|
71
|
-
});
|
|
72
|
-
ws.on('error', (error) => {
|
|
73
|
-
context.logger.debug({ event: 'ws_error' }, String(error?.message ?? error));
|
|
74
|
-
});
|
|
75
|
-
});
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
export { handleWebSocketUpgrade, setPendingWebSocketContext };
|
package/vite.config.js
DELETED
|
@@ -1,111 +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 fs from 'node:fs';
|
|
18
|
-
import { defineConfig } from 'vite';
|
|
19
|
-
import react from '@vitejs/plugin-react';
|
|
20
|
-
import devServer from '@hono/vite-dev-server';
|
|
21
|
-
import { WebSocketServer } from 'ws';
|
|
22
|
-
|
|
23
|
-
// basePath from the Lowdefy build — assets and routes are served under it.
|
|
24
|
-
let basePath = '';
|
|
25
|
-
try {
|
|
26
|
-
const config = JSON.parse(fs.readFileSync('./build/config.json', 'utf8'));
|
|
27
|
-
basePath = config.basePath ?? '';
|
|
28
|
-
} catch (e) {
|
|
29
|
-
// No build yet — default base.
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
// Vite owns the HTTP server in dev, so /api/websocket upgrades are handled
|
|
33
|
-
// here instead of @hono/node-server. The upgrade handler module is loaded
|
|
34
|
-
// through Vite's SSR graph so it shares the Hono app and @lowdefy/api module
|
|
35
|
-
// instances with the dev server routes. Vite's own HMR websocket uses a
|
|
36
|
-
// different path and is untouched.
|
|
37
|
-
function lowdefyWebSocket() {
|
|
38
|
-
return {
|
|
39
|
-
name: 'lowdefy-websocket',
|
|
40
|
-
configureServer(server) {
|
|
41
|
-
const wss = new WebSocketServer({ noServer: true, maxPayload: 256 * 1024 });
|
|
42
|
-
server.httpServer?.on('upgrade', async (request, socket, head) => {
|
|
43
|
-
const { pathname } = new URL(request.url ?? '/', 'http://localhost');
|
|
44
|
-
if (pathname !== `${basePath}/api/websocket`) {
|
|
45
|
-
return;
|
|
46
|
-
}
|
|
47
|
-
try {
|
|
48
|
-
const { handleWebSocketUpgrade } = await server.ssrLoadModule(
|
|
49
|
-
'./src/websocket/devWebSocket.js'
|
|
50
|
-
);
|
|
51
|
-
await handleWebSocketUpgrade({ request, socket, head, wss });
|
|
52
|
-
} catch (error) {
|
|
53
|
-
console.error(error);
|
|
54
|
-
socket.destroy();
|
|
55
|
-
}
|
|
56
|
-
});
|
|
57
|
-
},
|
|
58
|
-
};
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
export default defineConfig(({ mode }) => ({
|
|
62
|
-
base: `${basePath}/`,
|
|
63
|
-
plugins: [
|
|
64
|
-
react(),
|
|
65
|
-
lowdefyWebSocket(),
|
|
66
|
-
devServer({
|
|
67
|
-
entry: './src/app.js',
|
|
68
|
-
// Vite serves these itself; everything else routes to the Hono app.
|
|
69
|
-
exclude: [
|
|
70
|
-
/^\/client\/.+/,
|
|
71
|
-
/^\/lib\/.+/,
|
|
72
|
-
/^\/build\/.+/,
|
|
73
|
-
/^\/@.+$/,
|
|
74
|
-
/^\/node_modules\/.*/,
|
|
75
|
-
/\?t=\d+$/,
|
|
76
|
-
/^\/favicon\.ico$/,
|
|
77
|
-
],
|
|
78
|
-
}),
|
|
79
|
-
],
|
|
80
|
-
define: {
|
|
81
|
-
// Vite does not replace process.env.NODE_ENV inside dependencies —
|
|
82
|
-
// plugin and client code branch on it.
|
|
83
|
-
'process.env.NODE_ENV': JSON.stringify(mode === 'production' ? 'production' : 'development'),
|
|
84
|
-
},
|
|
85
|
-
optimizeDeps: {
|
|
86
|
-
// There is no index.html in the root (the Hono app renders HTML), so the
|
|
87
|
-
// dependency scanner has nothing to crawl and would discover client deps
|
|
88
|
-
// lazily at first request — ending in a mid-session "optimized
|
|
89
|
-
// dependencies changed" full reload. The client entry reaches every
|
|
90
|
-
// plugin import statically (main.jsx → App → Routing → build/plugins/*),
|
|
91
|
-
// so a startup crawl discovers the full set. Linked workspace plugins are
|
|
92
|
-
// intentionally not pre-bundled (Vite default) so local plugin edits stay
|
|
93
|
-
// live.
|
|
94
|
-
entries: ['client/main.jsx'],
|
|
95
|
-
},
|
|
96
|
-
resolve: {
|
|
97
|
-
// linked plugin packages (pnpm link: / workspace) must share one React.
|
|
98
|
-
dedupe: ['react', 'react-dom'],
|
|
99
|
-
},
|
|
100
|
-
server: {
|
|
101
|
-
watch: {
|
|
102
|
-
// Tailwind scan inputs are rewritten by JIT page builds, and Vite
|
|
103
|
-
// full-reloads the browser on any watched .html change — killing
|
|
104
|
-
// in-flight requests on every first page visit. CSS recompilation does
|
|
105
|
-
// not need these events: globals.css imports build/tailwind-candidates.css,
|
|
106
|
-
// which the JIT builder touches whenever tailwind content changes (the
|
|
107
|
-
// sole recompile trigger — see writeGlobalsCss in @lowdefy/build).
|
|
108
|
-
ignored: ['**/lowdefy-build/tailwind/**'],
|
|
109
|
-
},
|
|
110
|
-
},
|
|
111
|
-
}));
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|