@plitzi/sdk-server 0.32.1 → 0.32.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +9 -0
- package/README.md +13 -11
- package/dist/core/mimeTypes.js +2 -2
- package/dist/core/requestHandler.js +22 -4
- package/dist/core/requestParser.js +16 -1
- package/dist/core/transports.js +1 -1
- package/dist/helpers/readCookie.js +11 -0
- package/dist/index.d.ts +1 -1
- package/dist/modules/mcp/handler.js +1 -1
- package/dist/modules/mcp/helpers.js +1 -1
- package/dist/modules/mcp/resources/index.js +1 -1
- package/dist/modules/mcp/tools/index.js +1 -1
- package/dist/modules/mcp/tools/space/schema/schemas.js +1 -1
- package/dist/modules/ssr/Component.js +4 -1
- package/dist/modules/ssr/applySSRResult.js +14 -0
- package/dist/modules/ssr/buildBody.js +10 -2
- package/dist/modules/ssr/handler.js +5 -3
- package/dist/modules/ssr/prepareRender.js +12 -4
- package/dist/modules/ssr/registerExternalPlugins.js +53 -3
- package/dist/modules/ssr/streamBody.js +11 -1
- package/dist/modules/ssr/views/template.ejs +1 -0
- package/dist/package.js +73 -58
- package/dist/package.json.d.ts +12 -12
- package/dist/src/core/requestParser.d.ts +1 -0
- package/dist/src/helpers/readCookie.d.ts +1 -0
- package/dist/src/modules/mcp/handler.d.ts +1 -1
- package/dist/src/modules/ssr/Component.d.ts +5 -2
- package/dist/src/modules/ssr/applySSRResult.d.ts +2 -0
- package/dist/src/modules/ssr/buildBody.d.ts +6 -2
- package/dist/src/standalone/alias-loader.d.mts +1 -0
- package/dist/src/standalone/plugins/ClientInfo.d.ts +1 -1
- package/dist/src/standalone/plugins/ServerInfo.d.ts +1 -1
- package/dist/src/standalone/plugins/SharedInfo.d.ts +1 -1
- package/dist/src/standalone/stubs/react-syntax-highlighter.d.mts +31 -0
- package/package.json +14 -14
package/CHANGELOG.md
CHANGED
package/README.md
CHANGED
|
@@ -72,8 +72,8 @@ type SSRAdapters = {
|
|
|
72
72
|
getOfflineData: (spaceId: number, environment: string, revision?: number) => Promise<OfflineDataRaw | undefined>;
|
|
73
73
|
getSpaceDeployment: (req: SSRRequest) => Promise<SSRSpaceDeployment>;
|
|
74
74
|
getUser?: (req: SSRRequest) => Promise<SSRUser | undefined>;
|
|
75
|
-
onLogin?: (req: SSRRequest) => Promise<boolean>;
|
|
76
|
-
onLogout?: (req: SSRRequest) => Promise<void>;
|
|
75
|
+
onLogin?: (req: SSRRequest, res: SSRResponseHelpers) => Promise<boolean>;
|
|
76
|
+
onLogout?: (req: SSRRequest, res: SSRResponseHelpers) => Promise<void>;
|
|
77
77
|
getRscData?: (
|
|
78
78
|
req: SSRRequest,
|
|
79
79
|
spaceId: number,
|
|
@@ -88,8 +88,8 @@ type SSRAdapters = {
|
|
|
88
88
|
- **`getOfflineData`** — returns the space snapshot (schema, plugins, styles, segments, collections) for SSR.
|
|
89
89
|
- **`getSpaceDeployment`** — resolves which space and environment to render for a given inbound request. Return `{ error: { code, message } }` to abort with an HTTP error. Optionally include `templateProps` to override template variables, or `pluginNames` to activate plugins for the space (see [Plugins](#plugins) and [Template props](#template-props)).
|
|
90
90
|
- **`getUser`** *(optional)* — resolves the authenticated user from the inbound request (e.g. via a session cookie or `Authorization` header). Called in parallel with `getOfflineData` on every cache miss. The returned user is forwarded to the SDK as `authenticated: true` and `user.details`, which controls page-level access for guest vs. registered users. Return `undefined` for unauthenticated requests.
|
|
91
|
-
- **`onLogin`** *(optional)* — called when `POST {loginPath}` is received. Responsible for establishing a session or issuing tokens. Return `true` if login succeeded; return `false` to
|
|
92
|
-
- **`onLogout`** *(optional)* — called when `POST {logoutPath}` is received. Responsible for invalidating any server-side user session or cache entry
|
|
91
|
+
- **`onLogin`** *(optional)* — called when `POST {loginPath}` is received. Responsible for establishing a session or issuing tokens. The raw request body is available on `req.body` (e.g. `JSON.stringify({ username, password })`), and `res` lets the adapter set the session cookie via `res.setHeader('Set-Cookie', …)`. Return `true` if login succeeded; return `false` to reject it. For a navigation (full-page form submit, `Sec-Fetch-Mode: navigate`) the server responds with a `303` redirect so the view re-renders via a GET; for a fetch it responds `200`/`401`.
|
|
92
|
+
- **`onLogout`** *(optional)* — called when `POST {logoutPath}` is received. Responsible for invalidating any server-side user session or cache entry, and may clear the session cookie via `res`. A navigation receives a `303` redirect; a fetch receives `204 No Content`.
|
|
93
93
|
- **`getRscData`** *(optional)* — called by the RSC endpoint (`/_rsc`) to fetch server-side data for schema elements with `runtime: 'server'`. Receives the full request, space context, and the resolved user so that authenticated operations can be performed. When `ids` is provided the adapter should return data only for those element IDs (partial refresh); omitting `ids` means a full fetch for all elements. Return `{}` when there is no server data for the current request (see [RSC](#react-server-components-rsc)).
|
|
94
94
|
|
|
95
95
|
## JSON adapters (offline mode)
|
|
@@ -614,15 +614,15 @@ createSSRServer({ adapters: { getOfflineData, getSpaceDeployment, getUser } });
|
|
|
614
614
|
|
|
615
615
|
### Login endpoint
|
|
616
616
|
|
|
617
|
-
The server exposes a built-in `POST /auth/login` endpoint. When hit, it calls `adapters.onLogin(req)` and
|
|
617
|
+
The server exposes a built-in `POST /auth/login` endpoint. When hit, it calls `adapters.onLogin(req, res)`. The raw request body is on `req.body`, and `res` is used to set the session cookie. A navigation (full-page form submit) gets a `303` redirect so the view re-renders; a fetch gets `200 OK` on success or `401 Unauthorized` when the adapter returns `false`:
|
|
618
618
|
|
|
619
619
|
```ts
|
|
620
|
-
const onLogin = async (req: SSRRequest): Promise<boolean> => {
|
|
620
|
+
const onLogin = async (req: SSRRequest, res: SSRResponseHelpers): Promise<boolean> => {
|
|
621
621
|
const { username, password } = JSON.parse(req.body ?? '{}');
|
|
622
|
-
const
|
|
623
|
-
if (!
|
|
622
|
+
const session = await db.users.authenticate(username, password);
|
|
623
|
+
if (!session) return false;
|
|
624
624
|
|
|
625
|
-
|
|
625
|
+
res.setHeader('Set-Cookie', `my_session=${session.token}; Path=/; HttpOnly; SameSite=Lax`);
|
|
626
626
|
return true;
|
|
627
627
|
};
|
|
628
628
|
|
|
@@ -641,14 +641,16 @@ createSSRServer({
|
|
|
641
641
|
|
|
642
642
|
### Logout endpoint
|
|
643
643
|
|
|
644
|
-
The server exposes a built-in `POST /auth/logout` endpoint. When hit, it calls `adapters.onLogout(req)`
|
|
644
|
+
The server exposes a built-in `POST /auth/logout` endpoint. When hit, it calls `adapters.onLogout(req, res)`. A navigation gets a `303` redirect so the view re-renders logged out; a fetch gets `204 No Content`. Implement `onLogout` to invalidate the session or cached user entry and clear the cookie:
|
|
645
645
|
|
|
646
646
|
```ts
|
|
647
|
-
const onLogout = async (req: SSRRequest): Promise<void> => {
|
|
647
|
+
const onLogout = async (req: SSRRequest, res: SSRResponseHelpers): Promise<void> => {
|
|
648
648
|
const token = parseCookies(req.headers['cookie'] ?? '')['my_session'];
|
|
649
649
|
if (token) {
|
|
650
650
|
await cache.delete(`user-${token}`);
|
|
651
651
|
}
|
|
652
|
+
|
|
653
|
+
res.setHeader('Set-Cookie', 'my_session=; Path=/; HttpOnly; SameSite=Lax; Max-Age=0');
|
|
652
654
|
};
|
|
653
655
|
|
|
654
656
|
createSSRServer({ adapters: { getOfflineData, getSpaceDeployment, getUser, onLogout } });
|
package/dist/core/mimeTypes.js
CHANGED
|
@@ -20,7 +20,7 @@ var MIME_TYPES = {
|
|
|
20
20
|
".txt": "text/plain; charset=utf-8",
|
|
21
21
|
".xml": "application/xml"
|
|
22
22
|
};
|
|
23
|
-
var IMMUTABLE_EXTS = new Set([
|
|
23
|
+
var IMMUTABLE_EXTS = /* @__PURE__ */ new Set([
|
|
24
24
|
".js",
|
|
25
25
|
".mjs",
|
|
26
26
|
".cjs",
|
|
@@ -38,4 +38,4 @@ var getCacheControl = (filePath) => {
|
|
|
38
38
|
return IMMUTABLE_EXTS.has(ext) ? "public, max-age=31536000, immutable" : "public, max-age=3600";
|
|
39
39
|
};
|
|
40
40
|
//#endregion
|
|
41
|
-
export { getCacheControl, getMimeType };
|
|
41
|
+
export { IMMUTABLE_EXTS, MIME_TYPES, getCacheControl, getMimeType };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { parseRequest } from "./requestParser.js";
|
|
1
|
+
import { parseRequest, readRawBody } from "./requestParser.js";
|
|
2
2
|
import { serveStatic } from "./staticFiles.js";
|
|
3
3
|
import { buildResponseHelpers } from "../helpers/buildResponseHelpers.js";
|
|
4
4
|
import { runMiddlewares } from "../helpers/runMiddlewares.js";
|
|
@@ -13,6 +13,10 @@ import { fileURLToPath } from "node:url";
|
|
|
13
13
|
//#region src/core/requestHandler.ts
|
|
14
14
|
var __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
15
15
|
var BUILTIN_PUBLIC_DIR = path.resolve(__dirname, "../public");
|
|
16
|
+
var safeRedirectTarget = (req) => {
|
|
17
|
+
const redirectParam = req.query["redirect"];
|
|
18
|
+
return redirectParam && redirectParam.startsWith("/") && !redirectParam.startsWith("//") ? redirectParam : "/";
|
|
19
|
+
};
|
|
16
20
|
var handleRequest = async (raw, rawRes, config, port, renderFn, caches, pluginManager) => {
|
|
17
21
|
const req = parseRequest(raw);
|
|
18
22
|
const res = buildResponseHelpers(rawRes, req.headers["accept-encoding"]);
|
|
@@ -54,14 +58,28 @@ var handleRequest = async (raw, rawRes, config, port, renderFn, caches, pluginMa
|
|
|
54
58
|
}
|
|
55
59
|
const loginPath = config.loginPath === false ? null : config.loginPath ?? "/auth/login";
|
|
56
60
|
if (loginPath && req.method === "POST" && req.path === loginPath) {
|
|
57
|
-
|
|
58
|
-
|
|
61
|
+
req.body = await readRawBody(raw);
|
|
62
|
+
const isLoggedIn = await config.adapters.onLogin?.(req, res);
|
|
63
|
+
if (req.headers["sec-fetch-mode"] === "navigate") {
|
|
64
|
+
res.setStatus(303);
|
|
65
|
+
res.setHeader("Location", isLoggedIn ? safeRedirectTarget(req) : loginPath);
|
|
66
|
+
res.end();
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
res.setStatus(isLoggedIn ? 200 : 401);
|
|
59
70
|
res.end();
|
|
60
71
|
return;
|
|
61
72
|
}
|
|
62
73
|
const logoutPath = config.logoutPath === false ? null : config.logoutPath ?? "/auth/logout";
|
|
63
74
|
if (logoutPath && req.method === "POST" && req.path === logoutPath) {
|
|
64
|
-
await
|
|
75
|
+
req.body = await readRawBody(raw);
|
|
76
|
+
await config.adapters.onLogout?.(req, res);
|
|
77
|
+
if (req.headers["sec-fetch-mode"] === "navigate") {
|
|
78
|
+
res.setStatus(303);
|
|
79
|
+
res.setHeader("Location", safeRedirectTarget(req));
|
|
80
|
+
res.end();
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
65
83
|
res.setStatus(204);
|
|
66
84
|
res.end();
|
|
67
85
|
return;
|
|
@@ -30,5 +30,20 @@ var parseRequest = (raw) => {
|
|
|
30
30
|
ctx: {}
|
|
31
31
|
};
|
|
32
32
|
};
|
|
33
|
+
var MAX_BODY_BYTES = 1024 * 1024;
|
|
34
|
+
var readRawBody = (raw) => new Promise((resolve, reject) => {
|
|
35
|
+
const chunks = [];
|
|
36
|
+
let size = 0;
|
|
37
|
+
raw.on("data", (chunk) => {
|
|
38
|
+
size += chunk.length;
|
|
39
|
+
if (size > MAX_BODY_BYTES) {
|
|
40
|
+
reject(/* @__PURE__ */ new Error("Request body too large"));
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
chunks.push(chunk);
|
|
44
|
+
});
|
|
45
|
+
raw.on("end", () => resolve(Buffer.concat(chunks).toString("utf8")));
|
|
46
|
+
raw.on("error", reject);
|
|
47
|
+
});
|
|
33
48
|
//#endregion
|
|
34
|
-
export { parseRequest };
|
|
49
|
+
export { parseRequest, readRawBody };
|
package/dist/core/transports.js
CHANGED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
//#region src/helpers/readCookie.ts
|
|
2
|
+
var readCookie = (cookieHeader, name) => {
|
|
3
|
+
if (!cookieHeader) return;
|
|
4
|
+
for (const part of cookieHeader.split(";")) {
|
|
5
|
+
const eq = part.indexOf("=");
|
|
6
|
+
if (eq === -1) continue;
|
|
7
|
+
if (part.slice(0, eq).trim() === name) return decodeURIComponent(part.slice(eq + 1).trim());
|
|
8
|
+
}
|
|
9
|
+
};
|
|
10
|
+
//#endregion
|
|
11
|
+
export { readCookie };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export * from './src/index'
|
|
1
|
+
export * from './src/index.js'
|
|
2
2
|
export {}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { createMcpServer } from "./server.js";
|
|
2
2
|
import AIEngine from "../ai/AIEngine.js";
|
|
3
|
-
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp
|
|
3
|
+
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp";
|
|
4
4
|
//#region src/modules/mcp/handler.ts
|
|
5
5
|
var readMcpBody = (req) => new Promise((resolve, reject) => {
|
|
6
6
|
let raw = "";
|
|
@@ -72,4 +72,4 @@ var adapterWrapper = (adapterName, handler) => {
|
|
|
72
72
|
};
|
|
73
73
|
};
|
|
74
74
|
//#endregion
|
|
75
|
-
export { bindTools, getAllowedModes, isToolActive, resolveToolHandler, toolResponseErr, toolResponseOk, zodToJsonSchema };
|
|
75
|
+
export { adapterWrapper, bindTools, getAllowedModes, isToolActive, resolveToolHandler, toolResponseErr, toolResponseOk, zodToJsonSchema };
|
|
@@ -68,4 +68,4 @@ var getResourceList = () => allResources.map(({ uri, name, description }) => ({
|
|
|
68
68
|
}));
|
|
69
69
|
var getResourceByUri = (uri) => allResources.find((r) => r.uri === uri);
|
|
70
70
|
//#endregion
|
|
71
|
-
export { getResourceByUri, getResourceList, registerResources };
|
|
71
|
+
export { allResources, getResourceByUri, getResourceList, registerResources };
|
|
@@ -147,4 +147,4 @@ var tools_exports = /* @__PURE__ */ __exportAll({
|
|
|
147
147
|
updateVariableTool: () => updateVariableTool
|
|
148
148
|
});
|
|
149
149
|
//#endregion
|
|
150
|
-
export { tools_exports };
|
|
150
|
+
export { addPluginTool, addResourceTool, applyPreviewTool, cloneElementTool, createCollectionRecordTool, createCollectionTool, createElementTool, createPageFolderTool, createPageTool, createSegmentElementTool, createSegmentStyleVariableTool, createSegmentTool, createSegmentVariableTool, createStyleSelectorTool, createStyleVariableTool, createVariableTool, deleteCollectionRecordTool, deleteCollectionTool, deleteElementTool, deletePageFolderTool, deletePageTool, deleteSegmentElementTool, deleteSegmentStyleVariableTool, deleteSegmentTool, deleteSegmentVariableTool, deleteStyleSelectorTool, deleteStyleVariableTool, deleteVariableTool, getCollectionRecordTool, getCollectionRecordsTool, getCollectionTool, getCollectionsTool, getElementTool, getElementsTool, getPageBySlugTool, getPageFolderTool, getPageFoldersTool, getPageTool, getPagesTool, getResourceTool, getResourcesTool, getSegmentTool, getSegmentsTool, getSpaceSettingsTool, getStyleSelectorsTool, getStyleVariableTool, getStyleVariablesTool, getVariableTool, getVariablesTool, listElementsTool, listPluginsTool, listResourcesTool, moveElementTool, moveResourceTool, moveSegmentElementTool, readResourceTool, removePluginTool, removeResourceTool, tools_exports, updateCollectionRecordTool, updateCollectionTool, updateElementTool, updatePageFolderTool, updatePageTool, updatePluginTool, updateSegmentElementTool, updateSegmentStyleVariableTool, updateSegmentTool, updateSegmentVariableTool, updateSpaceSettingsTool, updateStyleSelectorTool, updateStyleVariableTool, updateVariableTool };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import PlitziSdk from "@plitzi/plitzi-sdk";
|
|
2
2
|
import { jsx } from "react/jsx-runtime";
|
|
3
3
|
//#region src/modules/ssr/Component.tsx
|
|
4
|
-
var Component = ({ server, renderMode = "raw", previewMode = true, offlineData, environment = "main", plugins }) => {
|
|
4
|
+
var Component = ({ server, renderMode = "raw", previewMode = true, offlineData, environment = "main", plugins, ssrResult, sdkDevToolsStylePath, debugMode = false }) => {
|
|
5
5
|
return /* @__PURE__ */ jsx(PlitziSdk, {
|
|
6
6
|
environment,
|
|
7
7
|
server,
|
|
@@ -9,6 +9,9 @@ var Component = ({ server, renderMode = "raw", previewMode = true, offlineData,
|
|
|
9
9
|
renderMode,
|
|
10
10
|
offlineMode: !!offlineData && Object.keys(offlineData).length > 0,
|
|
11
11
|
offlineData,
|
|
12
|
+
ssrResult,
|
|
13
|
+
sdkDevToolsStylePath,
|
|
14
|
+
debugMode,
|
|
12
15
|
children: plugins && Object.keys(plugins).map((key) => /* @__PURE__ */ jsx(PlitziSdk.Plugin, {
|
|
13
16
|
renderType: key,
|
|
14
17
|
component: plugins[key].component,
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
//#region src/modules/ssr/applySSRResult.ts
|
|
2
|
+
var applySSRResult = (res, result) => {
|
|
3
|
+
if (result.headers) for (const [name, value] of Object.entries(result.headers)) res.setHeader(name, value);
|
|
4
|
+
if (result.redirect !== void 0) {
|
|
5
|
+
res.setStatus(result.status ?? 302);
|
|
6
|
+
res.setHeader("Location", result.redirect);
|
|
7
|
+
res.send("");
|
|
8
|
+
return true;
|
|
9
|
+
}
|
|
10
|
+
if (result.status !== void 0) res.setStatus(result.status);
|
|
11
|
+
return false;
|
|
12
|
+
};
|
|
13
|
+
//#endregion
|
|
14
|
+
export { applySSRResult };
|
|
@@ -5,16 +5,24 @@ import { jsx } from "react/jsx-runtime";
|
|
|
5
5
|
//#region src/modules/ssr/buildBody.tsx
|
|
6
6
|
var buildBody = async (req, config, spaceId, environment, revision, renderFn, pluginManager, offlineDataCache, metrics) => {
|
|
7
7
|
const prep = await prepareRender(req, config, spaceId, environment, revision, pluginManager, offlineDataCache, metrics);
|
|
8
|
+
const result = {};
|
|
8
9
|
const reactStart = metrics ? performance.now() : 0;
|
|
9
|
-
const html = renderToString(/* @__PURE__ */ jsx(Component, {
|
|
10
|
+
const html = renderToString(/* @__PURE__ */ jsx(Component, {
|
|
11
|
+
...prep.componentProps,
|
|
12
|
+
ssrResult: result
|
|
13
|
+
})).trim();
|
|
10
14
|
metrics?.record("react", Math.round(performance.now() - reactStart));
|
|
15
|
+
if (result.redirect !== void 0) return { result };
|
|
11
16
|
const templateStart = metrics ? performance.now() : 0;
|
|
12
17
|
const body = renderFn({
|
|
13
18
|
...prep.templateParams,
|
|
14
19
|
html
|
|
15
20
|
});
|
|
16
21
|
metrics?.record("template", Math.round(performance.now() - templateStart));
|
|
17
|
-
return
|
|
22
|
+
return {
|
|
23
|
+
body,
|
|
24
|
+
result
|
|
25
|
+
};
|
|
18
26
|
};
|
|
19
27
|
//#endregion
|
|
20
28
|
export { buildBody };
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { buildHtmlCacheKey } from "../../helpers/cache/keys.js";
|
|
2
|
+
import { applySSRResult } from "./applySSRResult.js";
|
|
2
3
|
import { buildBody } from "./buildBody.js";
|
|
3
4
|
import { streamBody } from "./streamBody.js";
|
|
4
5
|
import { RequestMetrics } from "../../helpers/metrics.js";
|
|
@@ -24,13 +25,14 @@ var renderSSR = async (req, res, config, renderFn, pluginManager, caches) => {
|
|
|
24
25
|
await streamBody(req, res, config, spaceId, environment, revision, renderFn, pluginManager, caches.offlineData, htmlCache, cacheKey, metrics);
|
|
25
26
|
return;
|
|
26
27
|
}
|
|
27
|
-
const body = await buildBody(req, config, spaceId, environment, revision, renderFn, pluginManager, caches.offlineData, metrics);
|
|
28
|
-
if (htmlCache && cacheKey) htmlCache.set(cacheKey, body);
|
|
28
|
+
const { body, result } = await buildBody(req, config, spaceId, environment, revision, renderFn, pluginManager, caches.offlineData, metrics);
|
|
29
29
|
if (metrics) {
|
|
30
30
|
res.setHeader("Server-Timing", metrics.toServerTimingHeader());
|
|
31
31
|
metrics.log(`${req.method} ${req.path}`);
|
|
32
32
|
}
|
|
33
|
-
res
|
|
33
|
+
if (applySSRResult(res, result)) return;
|
|
34
|
+
if (htmlCache && cacheKey && body !== void 0) htmlCache.set(cacheKey, body);
|
|
35
|
+
res.send(body ?? "");
|
|
34
36
|
};
|
|
35
37
|
//#endregion
|
|
36
38
|
export { renderSSR };
|
|
@@ -3,6 +3,7 @@ import { loadPluginComponents } from "./loadPluginComponents.js";
|
|
|
3
3
|
import { registerExternalPlugins } from "./registerExternalPlugins.js";
|
|
4
4
|
import { buildServerInfo } from "../../helpers/buildServerInfo.js";
|
|
5
5
|
import { escapeJson } from "../../helpers/escapeJson.js";
|
|
6
|
+
import { readCookie } from "../../helpers/readCookie.js";
|
|
6
7
|
//#region src/modules/ssr/prepareRender.tsx
|
|
7
8
|
var prepareRender = async (req, config, spaceId, environment, revision, pluginManager, offlineDataCache, metrics) => {
|
|
8
9
|
const m = (name, fn) => metrics ? metrics.measure(name, fn) : Promise.resolve(fn());
|
|
@@ -10,12 +11,17 @@ var prepareRender = async (req, config, spaceId, environment, revision, pluginMa
|
|
|
10
11
|
const cachedOfflineStr = offlineCacheKey ? offlineDataCache?.get(offlineCacheKey) : void 0;
|
|
11
12
|
const [offlineData, server] = await Promise.all([cachedOfflineStr ? JSON.parse(cachedOfflineStr) : m("schema", () => config.adapters.getOfflineData(spaceId, environment, revision)), m("rsc", () => buildServerInfo(req, config))]);
|
|
12
13
|
if (!cachedOfflineStr && offlineCacheKey && offlineData !== void 0) offlineDataCache?.set(offlineCacheKey, JSON.stringify(offlineData));
|
|
14
|
+
const v = config.assetVersion ? `?v=${config.assetVersion}` : "";
|
|
15
|
+
const sdkDevToolsStylePath = `/sdk-assets/plitzi-sdk-devtools.css${v}`;
|
|
16
|
+
const debugCookie = readCookie(req.headers.cookie, "plitzi_debug");
|
|
17
|
+
const debugMode = debugCookie === void 0 ? config.devMode : debugCookie === "true";
|
|
13
18
|
const offlineDataStr = escapeJson(JSON.stringify({
|
|
14
19
|
offlineData,
|
|
15
20
|
offlineMode: true,
|
|
16
21
|
environment,
|
|
17
22
|
renderMode: "raw",
|
|
18
|
-
server
|
|
23
|
+
server,
|
|
24
|
+
sdkDevToolsStylePath
|
|
19
25
|
}));
|
|
20
26
|
const pluginNames = req.ctx.spaceDeployment?.pluginNames ?? [];
|
|
21
27
|
const pluginSources = req.ctx.spaceDeployment?.pluginSources;
|
|
@@ -34,14 +40,15 @@ var prepareRender = async (req, config, spaceId, environment, revision, pluginMa
|
|
|
34
40
|
const entries = allPluginNames.length > 0 ? await pluginManager.getEntries(allPluginNames) : [];
|
|
35
41
|
const pluginComponents = await m("plugins", () => loadPluginComponents(entries, pluginManager.getComponents()));
|
|
36
42
|
const templatePlugins = entries.length > 0 ? entries : req.ctx.spaceDeployment?.templateProps?.plugins;
|
|
37
|
-
const v = config.assetVersion ? `?v=${config.assetVersion}` : "";
|
|
38
43
|
const vendorJs = (config.devMode ? "/sdk-assets/plitzi-sdk-dev-vendor.js" : "/sdk-assets/plitzi-sdk-vendor.js") + v;
|
|
39
44
|
return {
|
|
40
45
|
componentProps: {
|
|
41
46
|
plugins: Object.keys(pluginComponents).length > 0 ? pluginComponents : void 0,
|
|
42
47
|
offlineData,
|
|
43
48
|
server,
|
|
44
|
-
environment: req.ctx.spaceDeployment?.environment ?? environment
|
|
49
|
+
environment: req.ctx.spaceDeployment?.environment ?? environment,
|
|
50
|
+
debugMode,
|
|
51
|
+
sdkDevToolsStylePath
|
|
45
52
|
},
|
|
46
53
|
entries,
|
|
47
54
|
templateParams: {
|
|
@@ -52,9 +59,10 @@ var prepareRender = async (req, config, spaceId, environment, revision, pluginMa
|
|
|
52
59
|
reactJsx: vendorJs,
|
|
53
60
|
reactDom: vendorJs,
|
|
54
61
|
reactDomClient: vendorJs,
|
|
62
|
+
reactCompilerRuntime: vendorJs,
|
|
55
63
|
...req.ctx.spaceDeployment?.templateProps,
|
|
56
64
|
plugins: templatePlugins,
|
|
57
|
-
debugMode
|
|
65
|
+
debugMode,
|
|
58
66
|
ssrOnly: config.ssrOnly === true,
|
|
59
67
|
offlineData: offlineDataStr
|
|
60
68
|
}
|
|
@@ -1,5 +1,33 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import crypto from "node:crypto";
|
|
3
|
+
import fs from "node:fs/promises";
|
|
1
4
|
//#region src/modules/ssr/registerExternalPlugins.ts
|
|
2
|
-
var
|
|
5
|
+
var MANIFEST_TTL_MS = 600 * 1e3;
|
|
6
|
+
var manifestCache = /* @__PURE__ */ new Map();
|
|
7
|
+
var refreshing = /* @__PURE__ */ new Set();
|
|
8
|
+
var cacheDir;
|
|
9
|
+
var manifestCacheDir = (pluginManager) => {
|
|
10
|
+
cacheDir ??= path.join(pluginManager.outputDir, ".manifest-cache");
|
|
11
|
+
return cacheDir;
|
|
12
|
+
};
|
|
13
|
+
var cacheFilePath = (dir, resource) => path.join(dir, `${crypto.createHash("sha1").update(resource).digest("hex")}.json`);
|
|
14
|
+
var readDiskEntry = async (dir, resource) => {
|
|
15
|
+
try {
|
|
16
|
+
const raw = await fs.readFile(cacheFilePath(dir, resource), "utf-8");
|
|
17
|
+
return JSON.parse(raw);
|
|
18
|
+
} catch {
|
|
19
|
+
return null;
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
var writeDiskEntry = async (dir, resource, entry) => {
|
|
23
|
+
try {
|
|
24
|
+
await fs.mkdir(dir, { recursive: true });
|
|
25
|
+
await fs.writeFile(cacheFilePath(dir, resource), JSON.stringify(entry), "utf-8");
|
|
26
|
+
} catch (err) {
|
|
27
|
+
console.warn(`[SSR] Failed to persist plugin manifest cache for ${resource}:`, err);
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
var fetchAndStore = async (dir, resource) => {
|
|
3
31
|
try {
|
|
4
32
|
const url = `${resource}/plugin-manifest.json`;
|
|
5
33
|
const res = await fetch(url);
|
|
@@ -7,12 +35,34 @@ var fetchManifest = async (resource) => {
|
|
|
7
35
|
console.warn(`[SSR] Failed to fetch plugin manifest from ${url}: HTTP ${res.status}`);
|
|
8
36
|
return null;
|
|
9
37
|
}
|
|
10
|
-
|
|
38
|
+
const manifest = await res.json();
|
|
39
|
+
const entry = {
|
|
40
|
+
manifest,
|
|
41
|
+
expiresAt: Date.now() + MANIFEST_TTL_MS
|
|
42
|
+
};
|
|
43
|
+
manifestCache.set(resource, entry);
|
|
44
|
+
await writeDiskEntry(dir, resource, entry);
|
|
45
|
+
return manifest;
|
|
11
46
|
} catch (err) {
|
|
12
47
|
console.warn(`[SSR] Error fetching plugin manifest from ${resource}:`, err);
|
|
13
48
|
return null;
|
|
14
49
|
}
|
|
15
50
|
};
|
|
51
|
+
var revalidate = (dir, resource) => {
|
|
52
|
+
if (refreshing.has(resource)) return;
|
|
53
|
+
refreshing.add(resource);
|
|
54
|
+
fetchAndStore(dir, resource).finally(() => refreshing.delete(resource));
|
|
55
|
+
};
|
|
56
|
+
var fetchManifest = async (pluginManager, resource) => {
|
|
57
|
+
const dir = manifestCacheDir(pluginManager);
|
|
58
|
+
const cached = manifestCache.get(resource) ?? await readDiskEntry(dir, resource) ?? void 0;
|
|
59
|
+
if (cached) {
|
|
60
|
+
manifestCache.set(resource, cached);
|
|
61
|
+
if (cached.expiresAt <= Date.now()) revalidate(dir, resource);
|
|
62
|
+
return cached.manifest;
|
|
63
|
+
}
|
|
64
|
+
return fetchAndStore(dir, resource);
|
|
65
|
+
};
|
|
16
66
|
var resolveAssetUrl = (resource, asset) => {
|
|
17
67
|
if (asset.url) return asset.url;
|
|
18
68
|
if (asset.src) return `${resource}/${asset.src}`;
|
|
@@ -26,7 +76,7 @@ var findAsset = (manifest, type, resource) => {
|
|
|
26
76
|
var isAbsoluteUrl = (url) => url.startsWith("http://") || url.startsWith("https://");
|
|
27
77
|
var registerPlugin = async (pluginManager, plugin) => {
|
|
28
78
|
if (!plugin.resource || !isAbsoluteUrl(plugin.resource)) return null;
|
|
29
|
-
const manifest = await fetchManifest(plugin.resource);
|
|
79
|
+
const manifest = await fetchManifest(pluginManager, plugin.resource);
|
|
30
80
|
if (!manifest) return null;
|
|
31
81
|
const jsUrl = findAsset(manifest, "script", plugin.resource);
|
|
32
82
|
if (!jsUrl) {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { applySSRResult } from "./applySSRResult.js";
|
|
1
2
|
import Component from "./Component.js";
|
|
2
3
|
import { prepareRender } from "./prepareRender.js";
|
|
3
4
|
import { renderToPipeableStream } from "react-dom/server";
|
|
@@ -16,6 +17,7 @@ var streamBody = async (req, res, config, spaceId, environment, revision, render
|
|
|
16
17
|
const sentinelIdx = fullTemplate.indexOf(SSR_SENTINEL);
|
|
17
18
|
const head = sentinelIdx >= 0 ? fullTemplate.slice(0, sentinelIdx) : fullTemplate;
|
|
18
19
|
const tail = sentinelIdx >= 0 ? fullTemplate.slice(sentinelIdx + 18) : "";
|
|
20
|
+
const result = {};
|
|
19
21
|
await new Promise((resolve, reject) => {
|
|
20
22
|
const chunks = cacheKey && htmlCache ? [] : null;
|
|
21
23
|
const writable = new Writable({
|
|
@@ -34,13 +36,21 @@ var streamBody = async (req, res, config, spaceId, environment, revision, render
|
|
|
34
36
|
}
|
|
35
37
|
});
|
|
36
38
|
const reactStart = metrics ? performance.now() : 0;
|
|
37
|
-
const { pipe } = renderToPipeableStream(/* @__PURE__ */ jsx(Component, {
|
|
39
|
+
const { pipe, abort } = renderToPipeableStream(/* @__PURE__ */ jsx(Component, {
|
|
40
|
+
...prep.componentProps,
|
|
41
|
+
ssrResult: result
|
|
42
|
+
}), {
|
|
38
43
|
onShellReady() {
|
|
39
44
|
metrics?.record("react", Math.round(performance.now() - reactStart));
|
|
40
45
|
if (metrics) {
|
|
41
46
|
res.setHeader("Server-Timing", metrics.toServerTimingHeader());
|
|
42
47
|
metrics.log(`${req.method} ${req.path}`);
|
|
43
48
|
}
|
|
49
|
+
if (applySSRResult(res, result)) {
|
|
50
|
+
abort();
|
|
51
|
+
resolve();
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
44
54
|
res.write(Buffer.from(head, "utf-8"));
|
|
45
55
|
pipe(writable);
|
|
46
56
|
},
|
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
"react-dom": "<%= locals.reactDom || '' %>",
|
|
21
21
|
"react-dom/client": "<%= locals.reactDomClient || '' %>",
|
|
22
22
|
"react/jsx-runtime": "<%= locals.reactJsx || '' %>",
|
|
23
|
+
"react/compiler-runtime": "<%= locals.reactCompilerRuntime || locals.react || '' %>",
|
|
23
24
|
"@plitzi/plitzi-sdk": "<%= locals.jsPath || '' %>"
|
|
24
25
|
}
|
|
25
26
|
}
|
package/dist/package.js
CHANGED
|
@@ -1,62 +1,77 @@
|
|
|
1
|
+
//#region package.json
|
|
2
|
+
var name = "@plitzi/sdk-server";
|
|
3
|
+
var version = "0.32.2";
|
|
4
|
+
var license = "AGPL-3.0";
|
|
5
|
+
var files = ["dist"];
|
|
6
|
+
var main = "dist/index.js";
|
|
7
|
+
var module = "dist/index.js";
|
|
8
|
+
var types = "dist/index.d.ts";
|
|
9
|
+
var exports = { ".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.js",
|
|
12
|
+
"default": "./dist/index.js"
|
|
13
|
+
} };
|
|
14
|
+
var repository = {
|
|
15
|
+
"type": "https",
|
|
16
|
+
"url": "https://github.com/plitzi/plitzi-workspace.git"
|
|
17
|
+
};
|
|
18
|
+
var type = "module";
|
|
19
|
+
var dependencies = {
|
|
20
|
+
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
21
|
+
"@plitzi/plitzi-sdk": "workspace:*",
|
|
22
|
+
"@plitzi/sdk-shared": "workspace:*",
|
|
23
|
+
"ejs": "^6.0.1",
|
|
24
|
+
"esbuild": "^0.28.1",
|
|
25
|
+
"zod": "^4.4.3"
|
|
26
|
+
};
|
|
27
|
+
var peerDependencies = {
|
|
28
|
+
"react": "^19",
|
|
29
|
+
"react-dom": "^19"
|
|
30
|
+
};
|
|
31
|
+
var devDependencies = {
|
|
32
|
+
"@types/ejs": "^3.1.5",
|
|
33
|
+
"@types/node": "^26.0.0",
|
|
34
|
+
"@types/react": "^19.2.17",
|
|
35
|
+
"@vitejs/plugin-react": "^6.0.2",
|
|
36
|
+
"@vitest/coverage-v8": "^4.1.9",
|
|
37
|
+
"eslint": "^9.39.4",
|
|
38
|
+
"eslint-plugin-import": "^2.32.0",
|
|
39
|
+
"react": "^19.2.7",
|
|
40
|
+
"react-dom": "^19.2.7",
|
|
41
|
+
"tsx": "^4.22.4",
|
|
42
|
+
"typescript": "^6.0.3",
|
|
43
|
+
"vite": "^8.0.16",
|
|
44
|
+
"vite-plugin-dts": "^5.0.2",
|
|
45
|
+
"vitest": "^4.1.9"
|
|
46
|
+
};
|
|
47
|
+
var scripts = {
|
|
48
|
+
"start:dev": "node --import ./src/standalone/register-alias.mjs --watch src/standalone/server.ts",
|
|
49
|
+
"start": "TSX_TSCONFIG_PATH=tsconfig.app.json node --import tsx src/standalone/server.ts",
|
|
50
|
+
"start:watch": "TSX_TSCONFIG_PATH=tsconfig.app.json node --import tsx --watch src/standalone/server.ts",
|
|
51
|
+
"start:inspect": "TSX_TSCONFIG_PATH=tsconfig.app.json node --import tsx --inspect src/standalone/server.ts",
|
|
52
|
+
"build:dev": "vite build --mode development",
|
|
53
|
+
"build:prod": "vite build",
|
|
54
|
+
"lint": "TIMING=1 eslint ./src",
|
|
55
|
+
"typecheck": "tsc -p tsconfig.app.json --noEmit",
|
|
56
|
+
"test": "vitest run",
|
|
57
|
+
"test:coverage": "vitest run --coverage"
|
|
58
|
+
};
|
|
1
59
|
var package_default = {
|
|
2
|
-
name
|
|
3
|
-
version
|
|
4
|
-
license
|
|
5
|
-
files
|
|
6
|
-
main
|
|
7
|
-
module
|
|
8
|
-
types
|
|
9
|
-
exports
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
"default": "./dist/index.js"
|
|
13
|
-
} },
|
|
14
|
-
repository: {
|
|
15
|
-
"type": "https",
|
|
16
|
-
"url": "https://github.com/plitzi/plitzi-workspace.git"
|
|
17
|
-
},
|
|
18
|
-
type: "module",
|
|
60
|
+
name,
|
|
61
|
+
version,
|
|
62
|
+
license,
|
|
63
|
+
files,
|
|
64
|
+
main,
|
|
65
|
+
module,
|
|
66
|
+
types,
|
|
67
|
+
exports,
|
|
68
|
+
repository,
|
|
69
|
+
type,
|
|
19
70
|
sideEffects: false,
|
|
20
|
-
dependencies
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
"ejs": "^6.0.1",
|
|
25
|
-
"esbuild": "^0.28.0",
|
|
26
|
-
"zod": "^4.4.3"
|
|
27
|
-
},
|
|
28
|
-
peerDependencies: {
|
|
29
|
-
"react": "^19",
|
|
30
|
-
"react-dom": "^19"
|
|
31
|
-
},
|
|
32
|
-
devDependencies: {
|
|
33
|
-
"@types/ejs": "^3.1.5",
|
|
34
|
-
"@types/node": "^25.9.1",
|
|
35
|
-
"@types/react": "^19.2.15",
|
|
36
|
-
"@vitejs/plugin-react": "^6.0.2",
|
|
37
|
-
"@vitest/coverage-v8": "^4.1.7",
|
|
38
|
-
"eslint": "^9.39.4",
|
|
39
|
-
"eslint-plugin-import": "^2.32.0",
|
|
40
|
-
"react": "^19.2.6",
|
|
41
|
-
"react-dom": "^19.2.6",
|
|
42
|
-
"tsx": "^4.22.3",
|
|
43
|
-
"typescript": "^6.0.3",
|
|
44
|
-
"vite": "^8.0.14",
|
|
45
|
-
"vite-plugin-dts": "^5.0.1",
|
|
46
|
-
"vitest": "^4.1.7"
|
|
47
|
-
},
|
|
48
|
-
scripts: {
|
|
49
|
-
"start:dev": "TSX_TSCONFIG_PATH=tsconfig.app.json ALIAS_LOADER_DEBUG=1 node --import ./src/standalone/register-alias.mjs --import tsx --watch src/standalone/server.ts",
|
|
50
|
-
"start": "TSX_TSCONFIG_PATH=tsconfig.app.json node --import tsx src/standalone/server.ts",
|
|
51
|
-
"start:watch": "TSX_TSCONFIG_PATH=tsconfig.app.json node --import tsx --watch src/standalone/server.ts",
|
|
52
|
-
"start:inspect": "TSX_TSCONFIG_PATH=tsconfig.app.json node --import tsx --inspect src/standalone/server.ts",
|
|
53
|
-
"build:dev": "vite build --mode development",
|
|
54
|
-
"build:prod": "vite build",
|
|
55
|
-
"lint": "TIMING=1 eslint ./src",
|
|
56
|
-
"typecheck": "tsc -p tsconfig.app.json --noEmit",
|
|
57
|
-
"test": "vitest run",
|
|
58
|
-
"test:coverage": "vitest run --coverage"
|
|
59
|
-
}
|
|
71
|
+
dependencies,
|
|
72
|
+
peerDependencies,
|
|
73
|
+
devDependencies,
|
|
74
|
+
scripts
|
|
60
75
|
};
|
|
61
76
|
//#endregion
|
|
62
|
-
export { package_default as default };
|
|
77
|
+
export { package_default as default, dependencies, devDependencies, exports, files, license, main, module, name, peerDependencies, repository, scripts, type, types, version };
|
package/dist/package.json.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
declare const _default: {
|
|
2
2
|
"name": "@plitzi/sdk-server",
|
|
3
|
-
"version": "0.32.
|
|
3
|
+
"version": "0.32.2",
|
|
4
4
|
"license": "AGPL-3.0",
|
|
5
5
|
"files": [
|
|
6
6
|
"dist"
|
|
@@ -26,7 +26,7 @@ declare const _default: {
|
|
|
26
26
|
"@plitzi/plitzi-sdk": "workspace:*",
|
|
27
27
|
"@plitzi/sdk-shared": "workspace:*",
|
|
28
28
|
"ejs": "^6.0.1",
|
|
29
|
-
"esbuild": "^0.28.
|
|
29
|
+
"esbuild": "^0.28.1",
|
|
30
30
|
"zod": "^4.4.3"
|
|
31
31
|
},
|
|
32
32
|
"peerDependencies": {
|
|
@@ -35,22 +35,22 @@ declare const _default: {
|
|
|
35
35
|
},
|
|
36
36
|
"devDependencies": {
|
|
37
37
|
"@types/ejs": "^3.1.5",
|
|
38
|
-
"@types/node": "^
|
|
39
|
-
"@types/react": "^19.2.
|
|
38
|
+
"@types/node": "^26.0.0",
|
|
39
|
+
"@types/react": "^19.2.17",
|
|
40
40
|
"@vitejs/plugin-react": "^6.0.2",
|
|
41
|
-
"@vitest/coverage-v8": "^4.1.
|
|
41
|
+
"@vitest/coverage-v8": "^4.1.9",
|
|
42
42
|
"eslint": "^9.39.4",
|
|
43
43
|
"eslint-plugin-import": "^2.32.0",
|
|
44
|
-
"react": "^19.2.
|
|
45
|
-
"react-dom": "^19.2.
|
|
46
|
-
"tsx": "^4.22.
|
|
44
|
+
"react": "^19.2.7",
|
|
45
|
+
"react-dom": "^19.2.7",
|
|
46
|
+
"tsx": "^4.22.4",
|
|
47
47
|
"typescript": "^6.0.3",
|
|
48
|
-
"vite": "^8.0.
|
|
49
|
-
"vite-plugin-dts": "^5.0.
|
|
50
|
-
"vitest": "^4.1.
|
|
48
|
+
"vite": "^8.0.16",
|
|
49
|
+
"vite-plugin-dts": "^5.0.2",
|
|
50
|
+
"vitest": "^4.1.9"
|
|
51
51
|
},
|
|
52
52
|
"scripts": {
|
|
53
|
-
"start:dev": "
|
|
53
|
+
"start:dev": "node --import ./src/standalone/register-alias.mjs --watch src/standalone/server.ts",
|
|
54
54
|
"start": "TSX_TSCONFIG_PATH=tsconfig.app.json node --import tsx src/standalone/server.ts",
|
|
55
55
|
"start:watch": "TSX_TSCONFIG_PATH=tsconfig.app.json node --import tsx --watch src/standalone/server.ts",
|
|
56
56
|
"start:inspect": "TSX_TSCONFIG_PATH=tsconfig.app.json node --import tsx --inspect src/standalone/server.ts",
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const readCookie: (cookieHeader: string | undefined, name: string) => string | undefined;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp
|
|
1
|
+
import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp';
|
|
2
2
|
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp';
|
|
3
3
|
import { McpServerConfig, AiContext } from '@plitzi/sdk-shared';
|
|
4
4
|
import { IncomingMessage, ServerResponse } from 'node:http';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { OfflineDataRaw, Environment, RenderMode, Server, SSRPlugin } from '@plitzi/sdk-shared';
|
|
1
|
+
import { OfflineDataRaw, Environment, RenderMode, Server, SSRPlugin, SSRRenderResult } from '@plitzi/sdk-shared';
|
|
2
2
|
export type ComponentProps = {
|
|
3
3
|
server: Partial<Server>;
|
|
4
4
|
renderMode?: Extract<RenderMode, 'raw'>;
|
|
@@ -6,6 +6,9 @@ export type ComponentProps = {
|
|
|
6
6
|
previewMode?: boolean;
|
|
7
7
|
offlineData?: OfflineDataRaw;
|
|
8
8
|
plugins?: Record<string, SSRPlugin>;
|
|
9
|
+
ssrResult?: SSRRenderResult;
|
|
10
|
+
sdkDevToolsStylePath?: string;
|
|
11
|
+
debugMode?: boolean;
|
|
9
12
|
};
|
|
10
|
-
declare const Component: ({ server, renderMode, previewMode, offlineData, environment, plugins }: ComponentProps) => import("react
|
|
13
|
+
declare const Component: ({ server, renderMode, previewMode, offlineData, environment, plugins, ssrResult, sdkDevToolsStylePath, debugMode }: ComponentProps) => import("react").JSX.Element;
|
|
11
14
|
export default Component;
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
import { TtlCache } from '../../helpers/cache';
|
|
2
2
|
import { RequestMetrics } from '../../helpers/metrics';
|
|
3
3
|
import { PluginManager } from '../../plugins/manager';
|
|
4
|
-
import { Environment, SSRRequest, SSRServerConfig, SSRTemplateFn } from '@plitzi/sdk-shared';
|
|
5
|
-
export
|
|
4
|
+
import { Environment, SSRRenderResult, SSRRequest, SSRServerConfig, SSRTemplateFn } from '@plitzi/sdk-shared';
|
|
5
|
+
export type BuildBodyResult = {
|
|
6
|
+
body?: string;
|
|
7
|
+
result: SSRRenderResult;
|
|
8
|
+
};
|
|
9
|
+
export declare const buildBody: (req: SSRRequest, config: SSRServerConfig, spaceId: number, environment: Environment, revision: number, renderFn: SSRTemplateFn, pluginManager: PluginManager, offlineDataCache?: TtlCache<string>, metrics?: RequestMetrics) => Promise<BuildBodyResult>;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
declare const ClientInfo: () => import("react
|
|
1
|
+
declare const ClientInfo: () => import("react").JSX.Element;
|
|
2
2
|
export default ClientInfo;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
declare const ServerInfo: () => import("react
|
|
1
|
+
declare const ServerInfo: () => import("react").JSX.Element;
|
|
2
2
|
export default ServerInfo;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
declare const SharedInfo: () => import("react
|
|
1
|
+
declare const SharedInfo: () => import("react").JSX.Element;
|
|
2
2
|
export default SharedInfo;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
export function PrismLight({ children }: {
|
|
2
|
+
children: any;
|
|
3
|
+
}): import('react').ReactElement<unknown, string | import('react').JSXElementConstructor<any>>;
|
|
4
|
+
export namespace PrismLight {
|
|
5
|
+
function registerLanguage(): void;
|
|
6
|
+
}
|
|
7
|
+
export function PrismLight({ children }: {
|
|
8
|
+
children: any;
|
|
9
|
+
}): import('react').ReactElement<unknown, string | import('react').JSXElementConstructor<any>>;
|
|
10
|
+
export namespace PrismLight { }
|
|
11
|
+
export function PrismLight({ children }: {
|
|
12
|
+
children: any;
|
|
13
|
+
}): import('react').ReactElement<unknown, string | import('react').JSXElementConstructor<any>>;
|
|
14
|
+
export namespace PrismLight { }
|
|
15
|
+
export function PrismLight({ children }: {
|
|
16
|
+
children: any;
|
|
17
|
+
}): import('react').ReactElement<unknown, string | import('react').JSXElementConstructor<any>>;
|
|
18
|
+
export namespace PrismLight { }
|
|
19
|
+
export function PrismLight({ children }: {
|
|
20
|
+
children: any;
|
|
21
|
+
}): import('react').ReactElement<unknown, string | import('react').JSXElementConstructor<any>>;
|
|
22
|
+
export namespace PrismLight { }
|
|
23
|
+
export function PrismLight({ children }: {
|
|
24
|
+
children: any;
|
|
25
|
+
}): import('react').ReactElement<unknown, string | import('react').JSXElementConstructor<any>>;
|
|
26
|
+
export namespace PrismLight { }
|
|
27
|
+
export default SyntaxHighlighter;
|
|
28
|
+
declare function SyntaxHighlighter({ children }: {
|
|
29
|
+
children: any;
|
|
30
|
+
}): import('react').ReactElement<unknown, string | import('react').JSXElementConstructor<any>>;
|
|
31
|
+
declare namespace SyntaxHighlighter { }
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@plitzi/sdk-server",
|
|
3
|
-
"version": "0.32.
|
|
3
|
+
"version": "0.32.2",
|
|
4
4
|
"license": "AGPL-3.0",
|
|
5
5
|
"files": [
|
|
6
6
|
"dist"
|
|
@@ -23,10 +23,10 @@
|
|
|
23
23
|
"sideEffects": false,
|
|
24
24
|
"dependencies": {
|
|
25
25
|
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
26
|
-
"@plitzi/plitzi-sdk": "0.32.
|
|
27
|
-
"@plitzi/sdk-shared": "0.32.
|
|
26
|
+
"@plitzi/plitzi-sdk": "0.32.2",
|
|
27
|
+
"@plitzi/sdk-shared": "0.32.2",
|
|
28
28
|
"ejs": "^6.0.1",
|
|
29
|
-
"esbuild": "^0.28.
|
|
29
|
+
"esbuild": "^0.28.1",
|
|
30
30
|
"zod": "^4.4.3"
|
|
31
31
|
},
|
|
32
32
|
"peerDependencies": {
|
|
@@ -35,22 +35,22 @@
|
|
|
35
35
|
},
|
|
36
36
|
"devDependencies": {
|
|
37
37
|
"@types/ejs": "^3.1.5",
|
|
38
|
-
"@types/node": "^
|
|
39
|
-
"@types/react": "^19.2.
|
|
38
|
+
"@types/node": "^26.0.0",
|
|
39
|
+
"@types/react": "^19.2.17",
|
|
40
40
|
"@vitejs/plugin-react": "^6.0.2",
|
|
41
|
-
"@vitest/coverage-v8": "^4.1.
|
|
41
|
+
"@vitest/coverage-v8": "^4.1.9",
|
|
42
42
|
"eslint": "^9.39.4",
|
|
43
43
|
"eslint-plugin-import": "^2.32.0",
|
|
44
|
-
"react": "^19.2.
|
|
45
|
-
"react-dom": "^19.2.
|
|
46
|
-
"tsx": "^4.22.
|
|
44
|
+
"react": "^19.2.7",
|
|
45
|
+
"react-dom": "^19.2.7",
|
|
46
|
+
"tsx": "^4.22.4",
|
|
47
47
|
"typescript": "^6.0.3",
|
|
48
|
-
"vite": "^8.0.
|
|
49
|
-
"vite-plugin-dts": "^5.0.
|
|
50
|
-
"vitest": "^4.1.
|
|
48
|
+
"vite": "^8.0.16",
|
|
49
|
+
"vite-plugin-dts": "^5.0.2",
|
|
50
|
+
"vitest": "^4.1.9"
|
|
51
51
|
},
|
|
52
52
|
"scripts": {
|
|
53
|
-
"start:dev": "
|
|
53
|
+
"start:dev": "node --import ./src/standalone/register-alias.mjs --watch src/standalone/server.ts",
|
|
54
54
|
"start": "TSX_TSCONFIG_PATH=tsconfig.app.json node --import tsx src/standalone/server.ts",
|
|
55
55
|
"start:watch": "TSX_TSCONFIG_PATH=tsconfig.app.json node --import tsx --watch src/standalone/server.ts",
|
|
56
56
|
"start:inspect": "TSX_TSCONFIG_PATH=tsconfig.app.json node --import tsx --inspect src/standalone/server.ts",
|