@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/app.js
DELETED
|
@@ -1,188 +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 { Hono } from 'hono';
|
|
18
|
-
import { bodyLimit } from 'hono/body-limit';
|
|
19
|
-
import { serveStatic } from '@hono/node-server/serve-static';
|
|
20
|
-
|
|
21
|
-
import agentHandler from './routes/agent.js';
|
|
22
|
-
import apiContext from './middleware/apiContext.js';
|
|
23
|
-
import authJson from '../lib/build/auth.js';
|
|
24
|
-
import authMiddleware from './routes/auth.js';
|
|
25
|
-
import clientErrorHandler from './routes/clientError.js';
|
|
26
|
-
import createErrorHandler from './middleware/errorHandler.js';
|
|
27
|
-
import createLogger from '../lib/server/log/createLogger.js';
|
|
28
|
-
import cronHandler from './routes/cron.js';
|
|
29
|
-
import detachedHandler from './routes/detached.js';
|
|
30
|
-
import devInspectHandler from './routes/devInspect.js';
|
|
31
|
-
import devToolsHandler from './routes/devTools.js';
|
|
32
|
-
import feedbackHandler from './routes/feedback.js';
|
|
33
|
-
import docsAppMapHandler from './routes/docs/appMap.js';
|
|
34
|
-
import docsBuildStatusHandler from './routes/docs/buildStatus.js';
|
|
35
|
-
import docsCheckpointsCreateHandler from './routes/docs/checkpointsCreate.js';
|
|
36
|
-
import docsCheckpointsListHandler from './routes/docs/checkpointsList.js';
|
|
37
|
-
import docsCheckpointsRevertHandler from './routes/docs/checkpointsRevert.js';
|
|
38
|
-
import docsContentHandler from './routes/docs/content.js';
|
|
39
|
-
import docsEvalOperatorHandler from './routes/docs/evalOperator.js';
|
|
40
|
-
import docsExamplesHandler from './routes/docs/examples.js';
|
|
41
|
-
import docsFindHandler from './routes/docs/find.js';
|
|
42
|
-
import docsIndexHandler from './routes/docs/index.js';
|
|
43
|
-
import docsInspectStateHandler from './routes/docs/inspectState.js';
|
|
44
|
-
import docsLoadStateHandler from './routes/docs/loadState.js';
|
|
45
|
-
import docsMcpHandler from './routes/docs/mcp.js';
|
|
46
|
-
import docsPageConfigHandler from './routes/docs/pageConfig.js';
|
|
47
|
-
import docsRunRequestHandler from './routes/docs/runRequest.js';
|
|
48
|
-
import docsSnapshotStateHandler from './routes/docs/snapshotState.js';
|
|
49
|
-
import docsStateCheckpointsListHandler from './routes/docs/stateCheckpointsList.js';
|
|
50
|
-
import docsPluginDocHandler from './routes/docs/pluginDoc.js';
|
|
51
|
-
import docsPluginsHandler from './routes/docs/plugins.js';
|
|
52
|
-
import docsSchemaHandler from './routes/docs/schema.js';
|
|
53
|
-
import docsScreenshotHandler from './routes/docs/screenshot.js';
|
|
54
|
-
import docsSearchHandler from './routes/docs/search.js';
|
|
55
|
-
import docsTypesHandler from './routes/docs/types.js';
|
|
56
|
-
import endpointsHandler from './routes/endpoints.js';
|
|
57
|
-
import getAuth from '../lib/server/auth/getAuth.js';
|
|
58
|
-
import getStrategies from '../lib/server/auth/getStrategies.js';
|
|
59
|
-
import getMockUser from '../lib/server/auth/getMockUser.js';
|
|
60
|
-
import iconsDynamicHandler from './routes/iconsDynamic.js';
|
|
61
|
-
import jitPageHandler from './routes/jitPage.js';
|
|
62
|
-
import jsEnvHandler from './routes/jsEnv.js';
|
|
63
|
-
import lowdefyConfig from '../lib/build/config.js';
|
|
64
|
-
import pingHandler from './routes/ping.js';
|
|
65
|
-
import reloadHandler from './routes/reload.js';
|
|
66
|
-
import renderDevPage from './html/renderDevPage.js';
|
|
67
|
-
import requestHandler from './routes/request.js';
|
|
68
|
-
import rootHandler from './routes/root.js';
|
|
69
|
-
import usageHandler from './routes/usage.js';
|
|
70
|
-
import userHandler from './routes/user.js';
|
|
71
|
-
import websocketHandler from './routes/websocket.js';
|
|
72
|
-
|
|
73
|
-
const basePath = lowdefyConfig.basePath ?? '';
|
|
74
|
-
|
|
75
|
-
// Dev Hono app — mounted into Vite via @hono/vite-dev-server (Vite owns HTTP
|
|
76
|
-
// and serves /client/* modules with HMR; everything else lands here).
|
|
77
|
-
// No compression in dev (parity with the old next.config compress: false,
|
|
78
|
-
// and SSE must stay unbuffered).
|
|
79
|
-
function createApp() {
|
|
80
|
-
const app = basePath ? new Hono().basePath(basePath) : new Hono();
|
|
81
|
-
const logger = createLogger({ server: 'lowdefy-dev' });
|
|
82
|
-
|
|
83
|
-
// No api context: SSE/health/static-js routes had no apiWrapper before.
|
|
84
|
-
app.get('/api/reload', reloadHandler);
|
|
85
|
-
app.get('/api/ping', pingHandler);
|
|
86
|
-
app.get('/api/js/:env', jsEnvHandler);
|
|
87
|
-
app.get('/api/icons/dynamic', iconsDynamicHandler);
|
|
88
|
-
app.get('/api/dev-tools', devToolsHandler);
|
|
89
|
-
// Annotation helper: the in-page overlay (Cmd/Ctrl+/) POSTs annotation
|
|
90
|
-
// batches here and gets back the enriched agent-readable text, which the
|
|
91
|
-
// overlay copies to the clipboard. No api context needed.
|
|
92
|
-
// /lowdefy-feedback is a reserved page-path prefix in dev, like /lowdefy-docs.
|
|
93
|
-
app.post('/lowdefy-feedback', feedbackHandler);
|
|
94
|
-
|
|
95
|
-
const mockUser = getMockUser();
|
|
96
|
-
if (authJson.configured === true && !mockUser) {
|
|
97
|
-
// Construct the BetterAuth instance and strategy verifiers at startup so
|
|
98
|
-
// config errors fail boot instead of the first request, and so the
|
|
99
|
-
// process-memoized singletons capture the base logger rather than the
|
|
100
|
-
// first request's rid-scoped child.
|
|
101
|
-
getAuth({ logger });
|
|
102
|
-
getStrategies({ logger });
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
// Docs and MCP endpoint for AI coding agents — always on in dev. Serves
|
|
106
|
-
// schemas/examples/docs for every installed plugin (core and local) plus
|
|
107
|
-
// the extracted core docs (@lowdefy/docs-content). Mounted outside /api/*
|
|
108
|
-
// so it can't clash with user API endpoints; /lowdefy-docs is a reserved page
|
|
109
|
-
// prefix in dev. The handlers need no auth protection or api context —
|
|
110
|
-
// they read build artifacts and node_modules directly — but run-request
|
|
111
|
-
// and eval-operator build a full Lowdefy context (createLowdefyContext),
|
|
112
|
-
// which resolves the caller from the request headers via resolveAuthentication.
|
|
113
|
-
app.all('/lowdefy-docs/mcp', docsMcpHandler);
|
|
114
|
-
app.get('/lowdefy-docs', docsIndexHandler);
|
|
115
|
-
app.get('/lowdefy-docs/build-status', docsBuildStatusHandler);
|
|
116
|
-
app.get('/lowdefy-docs/page-config/:pageId', docsPageConfigHandler);
|
|
117
|
-
app.get('/lowdefy-docs/find/:id', docsFindHandler);
|
|
118
|
-
app.get('/lowdefy-docs/screenshot/:pageId', docsScreenshotHandler);
|
|
119
|
-
app.get('/lowdefy-docs/inspect-state/:pageId', docsInspectStateHandler);
|
|
120
|
-
app.post('/lowdefy-docs/eval-operator', docsEvalOperatorHandler);
|
|
121
|
-
app.post('/lowdefy-docs/run-request', docsRunRequestHandler);
|
|
122
|
-
app.get('/lowdefy-docs/app-map', docsAppMapHandler);
|
|
123
|
-
app.get('/lowdefy-docs/checkpoints', docsCheckpointsListHandler);
|
|
124
|
-
app.post('/lowdefy-docs/checkpoints', docsCheckpointsCreateHandler);
|
|
125
|
-
app.post('/lowdefy-docs/checkpoints/revert', docsCheckpointsRevertHandler);
|
|
126
|
-
app.get('/lowdefy-docs/state-checkpoints', docsStateCheckpointsListHandler);
|
|
127
|
-
app.post('/lowdefy-docs/state-checkpoints/snapshot', docsSnapshotStateHandler);
|
|
128
|
-
app.post('/lowdefy-docs/state-checkpoints/load', docsLoadStateHandler);
|
|
129
|
-
// Live-tab inspection channel: dev tabs (client/Inspector.jsx) answer
|
|
130
|
-
// targeted SSE events by posting results here; GET lists connected tabs
|
|
131
|
-
// and serves checkpoint parts for the ?_checkpoint bootstrap.
|
|
132
|
-
app.all('/api/dev-inspect', devInspectHandler);
|
|
133
|
-
app.all('/api/dev-inspect/*', devInspectHandler);
|
|
134
|
-
app.get('/lowdefy-docs/plugins', docsPluginsHandler);
|
|
135
|
-
app.get('/lowdefy-docs/schema/:kind/:type', docsSchemaHandler);
|
|
136
|
-
app.get('/lowdefy-docs/examples/:type', docsExamplesHandler);
|
|
137
|
-
app.get('/lowdefy-docs/search', docsSearchHandler);
|
|
138
|
-
app.get('/lowdefy-docs/plugin-doc/:package{.+}', docsPluginDocHandler);
|
|
139
|
-
app.get('/lowdefy-docs/content/:slug{.+}', docsContentHandler);
|
|
140
|
-
app.get('/lowdefy-docs/:kind', docsTypesHandler);
|
|
141
|
-
|
|
142
|
-
app.use('/api/*', apiContext());
|
|
143
|
-
// Unified dev get-session: createLowdefyContext resolves the mock or headless
|
|
144
|
-
// caller into context.user on every path, so read it here rather than
|
|
145
|
-
// re-deriving the precedence. context.user is only absent in the real-engine
|
|
146
|
-
// case (the developer's own browser), which must fall through to BetterAuth.
|
|
147
|
-
// Registered before the /api/auth/* mount so this exact path wins while every
|
|
148
|
-
// other auth route still reaches the engine.
|
|
149
|
-
app.get('/api/auth/get-session', async (c, next) => {
|
|
150
|
-
const context = c.get('lowdefyContext');
|
|
151
|
-
if (context.user) return c.json({ session: { id: 'dev' }, user: context.user });
|
|
152
|
-
return next();
|
|
153
|
-
});
|
|
154
|
-
app.use('/api/auth/*', authMiddleware({ logger }));
|
|
155
|
-
app.get('/api/root', rootHandler);
|
|
156
|
-
app.get('/api/page/*', jitPageHandler);
|
|
157
|
-
app.all('/api/request/*', requestHandler);
|
|
158
|
-
// Endpoint payloads may carry base64 file content (emitFileContent + CallAPI);
|
|
159
|
-
// cap bodies at 10 MiB to match the agent route.
|
|
160
|
-
app.all('/api/endpoints/*', bodyLimit({ maxSize: 10 * 1024 * 1024 }), endpointsHandler);
|
|
161
|
-
app.get('/api/cron/*', cronHandler);
|
|
162
|
-
app.post('/api/detached/*', detachedHandler);
|
|
163
|
-
app.all('/api/client-error', clientErrorHandler);
|
|
164
|
-
app.all('/api/usage', usageHandler);
|
|
165
|
-
app.all('/api/agent/*', bodyLimit({ maxSize: 10 * 1024 * 1024 }), agentHandler);
|
|
166
|
-
app.get('/api/websocket', websocketHandler);
|
|
167
|
-
app.get('/api/user', userHandler);
|
|
168
|
-
|
|
169
|
-
// User public assets (icons, images). Vite serves /client modules itself.
|
|
170
|
-
app.use(
|
|
171
|
-
'/*',
|
|
172
|
-
serveStatic({
|
|
173
|
-
root: './public',
|
|
174
|
-
rewriteRequestPath: basePath ? (path) => path.replace(basePath, '') : undefined,
|
|
175
|
-
})
|
|
176
|
-
);
|
|
177
|
-
|
|
178
|
-
// Every page path renders the same shell — the client fetches config and
|
|
179
|
-
// handles home/404 routing, exactly like the old dev pages router did.
|
|
180
|
-
app.get('/', (c) => renderDevPage(c, { basePath }));
|
|
181
|
-
app.get('/:rest{.+}', (c) => renderDevPage(c, { basePath }));
|
|
182
|
-
|
|
183
|
-
app.onError(createErrorHandler({ basePath, logger }));
|
|
184
|
-
|
|
185
|
-
return app;
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
export default createApp();
|
|
@@ -1,86 +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
|
-
import safeScriptJson from '../lib/safeScriptJson.js';
|
|
21
|
-
|
|
22
|
-
// Dev HTML shell — config-free: the client fetches root config and page
|
|
23
|
-
// config over the API (SWR), exactly like the old dev pages did. Theme and
|
|
24
|
-
// app config are read per request so a lowdefyBuild does not require a
|
|
25
|
-
// server restart for the pre-hydration values to update.
|
|
26
|
-
//
|
|
27
|
-
// @hono/vite-dev-server injects /@vite/client into this response; the
|
|
28
|
-
// react-refresh preamble must be inlined here for @vitejs/plugin-react.
|
|
29
|
-
const layerOrderScript = `(function(){var s=document.createElement("style");s.id="__lf-layer-order";s.textContent="@layer theme, base, antd, components, utilities;";document.head.prepend(s);new MutationObserver(function(){if(document.head.firstChild!==s)document.head.prepend(s)}).observe(document.head,{childList:true})})();`;
|
|
30
|
-
|
|
31
|
-
function readBuildJson(name) {
|
|
32
|
-
try {
|
|
33
|
-
return JSON.parse(fs.readFileSync(path.join(process.cwd(), 'build', `${name}.json`), 'utf8'));
|
|
34
|
-
} catch {
|
|
35
|
-
return {};
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
function renderDevPage(c, { basePath = '' }) {
|
|
40
|
-
const themeConfig = readBuildJson('theme');
|
|
41
|
-
const appJson = readBuildJson('app');
|
|
42
|
-
|
|
43
|
-
const VALID_COLOR_MODES = ['system', 'light', 'dark'];
|
|
44
|
-
const configColorMode = VALID_COLOR_MODES.includes(themeConfig.darkMode)
|
|
45
|
-
? themeConfig.darkMode
|
|
46
|
-
: 'system';
|
|
47
|
-
const darkBg = themeConfig?.antd?.darkToken?.colorBgLayout ?? '#000';
|
|
48
|
-
const lightBg = themeConfig?.antd?.lightToken?.colorBgLayout ?? '';
|
|
49
|
-
|
|
50
|
-
const darkModeScript = `(function(){var c=${safeScriptJson(
|
|
51
|
-
configColorMode
|
|
52
|
-
)};var db=${safeScriptJson(darkBg)};var lb=${safeScriptJson(
|
|
53
|
-
lightBg
|
|
54
|
-
)};var d;if(c==="dark")d=true;else if(c==="light")d=false;else{try{var p=localStorage.getItem("lowdefy_darkMode");if(p==="dark")d=true;else if(p==="light")d=false;else d=window.matchMedia("(prefers-color-scheme:dark)").matches}catch(e){d=window.matchMedia("(prefers-color-scheme:dark)").matches}}var bg=d?db:lb;if(bg)document.documentElement.style.backgroundColor=bg})();`;
|
|
55
|
-
|
|
56
|
-
const html = `<!DOCTYPE html>
|
|
57
|
-
<html class="lowdefy">
|
|
58
|
-
<head>
|
|
59
|
-
<meta charset="utf-8" />
|
|
60
|
-
<script>${layerOrderScript}</script>
|
|
61
|
-
<script>${darkModeScript}</script>
|
|
62
|
-
<link rel="manifest" href="${basePath}/manifest.webmanifest" />
|
|
63
|
-
<link rel="icon" type="image/svg+xml" href="${basePath}/icon.svg" />
|
|
64
|
-
<link rel="apple-touch-icon" href="${basePath}/apple-touch-icon.png" />
|
|
65
|
-
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
66
|
-
<script type="module">
|
|
67
|
-
import RefreshRuntime from '${basePath}/@react-refresh';
|
|
68
|
-
RefreshRuntime.injectIntoGlobalHook(window);
|
|
69
|
-
window.$RefreshReg$ = () => {};
|
|
70
|
-
window.$RefreshSig$ = () => (type) => type;
|
|
71
|
-
window.__vite_plugin_react_preamble_installed__ = true;
|
|
72
|
-
</script>
|
|
73
|
-
${appJson.html?.appendHead ?? ''}
|
|
74
|
-
</head>
|
|
75
|
-
<body>
|
|
76
|
-
<div id="root"></div>
|
|
77
|
-
<script id="__LOWDEFY_CONFIG__" type="application/json">${safeScriptJson({ basePath })}</script>
|
|
78
|
-
${appJson.html?.appendBody ?? ''}
|
|
79
|
-
<script type="module" src="${basePath}/client/main.jsx"></script>
|
|
80
|
-
</body>
|
|
81
|
-
</html>`;
|
|
82
|
-
|
|
83
|
-
return c.html(html);
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
export default renderDevPage;
|
|
@@ -1,25 +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
|
-
// Splits the rest of a catch-all route into decoded segments, independent of
|
|
18
|
-
// any configured basePath. Mirrors the Next.js [...param] query arrays —
|
|
19
|
-
// nested ids (slashes in pageId or endpointId) are real.
|
|
20
|
-
function getPathSegments(c, prefix) {
|
|
21
|
-
const rest = c.req.path.split(prefix)[1] ?? '';
|
|
22
|
-
return rest.split('/').filter(Boolean).map(decodeURIComponent);
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
export default getPathSegments;
|
|
@@ -1,38 +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
|
-
// Escape characters that could break out of the enclosing <script> tag or
|
|
18
|
-
// terminate a JS string literal. Used to defuse the js/bad-code-sanitization
|
|
19
|
-
// class of injection for values embedded into inline scripts and the
|
|
20
|
-
// application/json config script.
|
|
21
|
-
const SCRIPT_ESCAPES = {
|
|
22
|
-
'<': '\\u003C',
|
|
23
|
-
'>': '\\u003E',
|
|
24
|
-
'\b': '\\b',
|
|
25
|
-
'\f': '\\f',
|
|
26
|
-
'\n': '\\n',
|
|
27
|
-
'\r': '\\r',
|
|
28
|
-
'\t': '\\t',
|
|
29
|
-
'\0': '\\0',
|
|
30
|
-
'\u2028': '\\u2028',
|
|
31
|
-
'\u2029': '\\u2029',
|
|
32
|
-
};
|
|
33
|
-
|
|
34
|
-
function safeScriptJson(value) {
|
|
35
|
-
return JSON.stringify(value).replace(/[<>\b\f\n\r\t\0\u2028\u2029]/g, (c) => SCRIPT_ESCAPES[c]);
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
export default safeScriptJson;
|
|
@@ -1,32 +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 createLowdefyContext from '../../lib/server/createLowdefyContext.js';
|
|
18
|
-
|
|
19
|
-
// Replaces lib/server/apiWrapper.js. Errors thrown by handlers are routed by
|
|
20
|
-
// Hono to the app-level error handler (src/middleware/errorHandler.js).
|
|
21
|
-
function apiContext() {
|
|
22
|
-
return async function apiContextMiddleware(c, next) {
|
|
23
|
-
if (c.get('lowdefyContext')) {
|
|
24
|
-
return next();
|
|
25
|
-
}
|
|
26
|
-
const context = await createLowdefyContext({ c });
|
|
27
|
-
c.set('lowdefyContext', context);
|
|
28
|
-
return next();
|
|
29
|
-
};
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
export default apiContext;
|
|
@@ -1,55 +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 { serializer } from '@lowdefy/helpers';
|
|
18
|
-
|
|
19
|
-
// Hono routes every handler error to the app-level error handler — upstream
|
|
20
|
-
// middleware try/catch never sees them. API routes get the serialized error
|
|
21
|
-
// JSON the old apiWrapper returned; page routes get a plain 500.
|
|
22
|
-
function createErrorHandler({ basePath = '', logger }) {
|
|
23
|
-
return async function errorHandler(error, c) {
|
|
24
|
-
const path = basePath ? c.req.path.replace(basePath, '') : c.req.path;
|
|
25
|
-
// Unauthenticated requests to protected endpoints are expected traffic -
|
|
26
|
-
// one warning line and a 401, skipping the structured error log so
|
|
27
|
-
// probing cannot flood it. Keys strictly on the error name; the 500 path
|
|
28
|
-
// below is untouched.
|
|
29
|
-
if (error.name === 'AuthenticationError') {
|
|
30
|
-
logger.warn(`Unauthenticated request: ${c.req.method} ${c.req.path}`);
|
|
31
|
-
if (path.startsWith('/api/')) {
|
|
32
|
-
return c.json({ name: error.name, message: error.message }, 401);
|
|
33
|
-
}
|
|
34
|
-
return c.text('Unauthorized', 401);
|
|
35
|
-
}
|
|
36
|
-
const context = c.get('lowdefyContext');
|
|
37
|
-
if (context) {
|
|
38
|
-
await context.handleError(error);
|
|
39
|
-
} else {
|
|
40
|
-
logger.error(error);
|
|
41
|
-
}
|
|
42
|
-
if (path.startsWith('/api/')) {
|
|
43
|
-
const serialized = serializer.serialize(error);
|
|
44
|
-
if (serialized?.['~e']) {
|
|
45
|
-
delete serialized['~e'].received;
|
|
46
|
-
delete serialized['~e'].stack;
|
|
47
|
-
delete serialized['~e'].configKey;
|
|
48
|
-
}
|
|
49
|
-
return c.json(serialized, 500);
|
|
50
|
-
}
|
|
51
|
-
return c.text('Internal Server Error', 500);
|
|
52
|
-
};
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
export default createErrorHandler;
|
package/src/routes/agent.js
DELETED
|
@@ -1,64 +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 { callAgent } from '@lowdefy/api';
|
|
18
|
-
import { translate, type } from '@lowdefy/helpers';
|
|
19
|
-
|
|
20
|
-
import getPathSegments from '../lib/getPathSegments.js';
|
|
21
|
-
|
|
22
|
-
async function agentHandler(c) {
|
|
23
|
-
const context = c.get('lowdefyContext');
|
|
24
|
-
const t = (key, values) => translate({ key, values, i18n: context.i18n });
|
|
25
|
-
if (c.req.method !== 'POST') {
|
|
26
|
-
throw new Error(t('agent.runtime.methodNotAllowed'));
|
|
27
|
-
}
|
|
28
|
-
const segments = getPathSegments(c, '/api/agent/');
|
|
29
|
-
if (segments.length < 2) {
|
|
30
|
-
return c.json({ error: t('agent.runtime.invalidPath') }, 400);
|
|
31
|
-
}
|
|
32
|
-
const agentId = segments[segments.length - 1];
|
|
33
|
-
const pageId = segments.slice(0, -1).join('/');
|
|
34
|
-
context.logger.info({ event: 'call_agent', agentId, pageId });
|
|
35
|
-
const { conversationId } = c.req.query();
|
|
36
|
-
const { messages, urlQuery, sharedState } = await c.req.json();
|
|
37
|
-
if (!Array.isArray(messages)) {
|
|
38
|
-
return c.json({ error: t('agent.runtime.messagesMustBeArray') }, 400);
|
|
39
|
-
}
|
|
40
|
-
if (urlQuery != null && (typeof urlQuery !== 'object' || Array.isArray(urlQuery))) {
|
|
41
|
-
return c.json({ error: t('agent.runtime.urlQueryMustBeObject') }, 400);
|
|
42
|
-
}
|
|
43
|
-
if (sharedState != null && !type.isObject(sharedState)) {
|
|
44
|
-
return c.json({ error: t('agent.runtime.sharedStateMustBeObject') }, 400);
|
|
45
|
-
}
|
|
46
|
-
const { response: webResponse } = await callAgent(context, {
|
|
47
|
-
agentId,
|
|
48
|
-
pageId,
|
|
49
|
-
messages,
|
|
50
|
-
conversationId: conversationId ?? undefined,
|
|
51
|
-
sharedState: sharedState ?? undefined,
|
|
52
|
-
urlQuery: urlQuery ?? undefined,
|
|
53
|
-
});
|
|
54
|
-
|
|
55
|
-
// callAgent returns a Web Response — stream its body straight through.
|
|
56
|
-
return c.body(webResponse.body, 200, {
|
|
57
|
-
'Content-Type': 'text/event-stream',
|
|
58
|
-
'Cache-Control': 'no-cache',
|
|
59
|
-
Connection: 'keep-alive',
|
|
60
|
-
'Content-Encoding': 'none',
|
|
61
|
-
});
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
export default agentHandler;
|
package/src/routes/auth.js
DELETED
|
@@ -1,43 +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 authJson from '../../lib/build/auth.js';
|
|
18
|
-
import getAuth from '../../lib/server/auth/getAuth.js';
|
|
19
|
-
import getMockUser from '../../lib/server/auth/getMockUser.js';
|
|
20
|
-
|
|
21
|
-
// Mounts BetterAuth's Web Standard handler on /api/auth/*. Hono routes HEAD
|
|
22
|
-
// requests through GET handlers, so HEAD short-circuits before the handler -
|
|
23
|
-
// corporate email link-checkers pre-fetch magic-link and verification URLs
|
|
24
|
-
// with HEAD, and letting those reach the handler would consume the one-time
|
|
25
|
-
// token before the user clicks.
|
|
26
|
-
function authMiddleware({ logger }) {
|
|
27
|
-
return async function auth(c) {
|
|
28
|
-
if (authJson.configured !== true) {
|
|
29
|
-
return c.json({ message: 'Auth not configured' }, 404);
|
|
30
|
-
}
|
|
31
|
-
if (getMockUser()) {
|
|
32
|
-
// Mock user active - no auth engine runs; the get-session stub in
|
|
33
|
-
// app.js is the only auth endpoint.
|
|
34
|
-
return c.json({ message: 'Auth engine disabled while dev.mockUser is active' }, 404);
|
|
35
|
-
}
|
|
36
|
-
if (c.req.method === 'HEAD') {
|
|
37
|
-
return c.body(null, 200);
|
|
38
|
-
}
|
|
39
|
-
return getAuth({ logger }).handler(c.req.raw);
|
|
40
|
-
};
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
export default authMiddleware;
|
|
@@ -1,57 +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 { logClientError } from '@lowdefy/api';
|
|
18
|
-
|
|
19
|
-
import clientErrorStore from '../../lib/docs/clientErrorStore.js';
|
|
20
|
-
|
|
21
|
-
async function clientErrorHandler(c) {
|
|
22
|
-
if (c.req.method !== 'POST') {
|
|
23
|
-
throw new Error('Only POST requests are supported.');
|
|
24
|
-
}
|
|
25
|
-
const context = c.get('lowdefyContext');
|
|
26
|
-
|
|
27
|
-
const origin = c.req.header('origin');
|
|
28
|
-
if (!origin) {
|
|
29
|
-
return c.json({ error: 'Forbidden' }, 403);
|
|
30
|
-
}
|
|
31
|
-
try {
|
|
32
|
-
if (new URL(origin).host !== c.req.header('host')) {
|
|
33
|
-
return c.json({ error: 'Forbidden' }, 403);
|
|
34
|
-
}
|
|
35
|
-
} catch {
|
|
36
|
-
return c.json({ error: 'Forbidden' }, 403);
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
// Dev keeps `received` in the payload — it powers error tracing in dev tools.
|
|
40
|
-
const body = await c.req.json();
|
|
41
|
-
const { error, ...response } = await logClientError(context, body);
|
|
42
|
-
|
|
43
|
-
// Feed the agent-facing feedback loop (GET /lowdefy-docs/build-status) with a
|
|
44
|
-
// serializable summary — not the full error object, which may carry
|
|
45
|
-
// non-serializable `received` values.
|
|
46
|
-
clientErrorStore.push({
|
|
47
|
-
timestamp: new Date().toISOString(),
|
|
48
|
-
name: error?.name ?? 'Error',
|
|
49
|
-
message: error?.message ?? null,
|
|
50
|
-
source: response.source ?? null,
|
|
51
|
-
config: response.config ?? null,
|
|
52
|
-
});
|
|
53
|
-
|
|
54
|
-
return c.json(response);
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
export default clientErrorHandler;
|
package/src/routes/cron.js
DELETED
|
@@ -1,44 +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 { runScheduledEndpoint } from '@lowdefy/api';
|
|
18
|
-
|
|
19
|
-
import getPathSegments from '../lib/getPathSegments.js';
|
|
20
|
-
|
|
21
|
-
// Triggered by Vercel Cron in production: an HTTP GET to /api/cron/<endpointId>. Available in dev so
|
|
22
|
-
// scheduled endpoints can be triggered locally with curl. Vercel auto-sends the value of the project
|
|
23
|
-
// env var named exactly CRON_SECRET as `Authorization: Bearer <value>`, and the firing cron
|
|
24
|
-
// expression in the `x-vercel-cron-schedule` header. Fails closed if CRON_SECRET is unset.
|
|
25
|
-
async function cronHandler(c) {
|
|
26
|
-
if (c.req.method !== 'GET') {
|
|
27
|
-
throw new Error('Only GET requests are supported.');
|
|
28
|
-
}
|
|
29
|
-
const context = c.get('lowdefyContext');
|
|
30
|
-
|
|
31
|
-
const secret = process.env.CRON_SECRET;
|
|
32
|
-
if (!secret || c.req.header('authorization') !== `Bearer ${secret}`) {
|
|
33
|
-
context.logger.warn({ event: 'cron_unauthorized' });
|
|
34
|
-
return c.json({ error: 'Unauthorized' }, 401);
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
const endpointId = getPathSegments(c, '/api/cron/').join('/');
|
|
38
|
-
const cron = c.req.header('x-vercel-cron-schedule');
|
|
39
|
-
context.logger.info({ event: 'call_cron_endpoint', endpointId, cron });
|
|
40
|
-
const response = await runScheduledEndpoint(context, { endpointId, cron });
|
|
41
|
-
return c.json(response);
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
export default cronHandler;
|