@plitzi/sdk-mcp 0.38.4 → 0.38.6
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 +358 -0
- package/README.md +38 -12
- package/dist/createServer.d.ts +1 -1
- package/dist/createServer.js +1 -1
- package/dist/index.d.ts +3 -4
- package/dist/index.js +1 -4
- package/dist/modules/mcp/apps/render/styles.d.ts +4 -8
- package/dist/modules/mcp/apps/render/styles.js +16 -47
- package/dist/modules/mcp/apps/render/view/index.tsx +1 -1
- package/dist/modules/mcp/catalogs/index.js +2 -2
- package/dist/modules/mcp/catalogs/pluginCatalog.js +2 -2
- package/dist/modules/mcp/e2e/mcpEndpoint.d.ts +2 -1
- package/dist/modules/mcp/handler.d.ts +2 -2
- package/dist/modules/mcp/helpers/callToolResult.d.ts +2 -0
- package/dist/modules/mcp/helpers/callToolResult.js +4 -0
- package/dist/modules/mcp/helpers/guide.js +27 -4
- package/dist/modules/mcp/helpers/index.d.ts +1 -1
- package/dist/modules/mcp/helpers/space.d.ts +4 -1
- package/dist/modules/mcp/helpers/space.js +1 -0
- package/dist/modules/mcp/helpers/uris.d.ts +2 -0
- package/dist/modules/mcp/helpers/uris.js +3 -1
- package/dist/modules/mcp/index.d.ts +1 -1
- package/dist/modules/mcp/resources/connectors.d.ts +1 -1
- package/dist/modules/mcp/resources/core.js +2 -2
- package/dist/modules/mcp/resources/data.d.ts +8 -0
- package/dist/modules/mcp/resources/data.js +46 -0
- package/dist/modules/mcp/resources/primer.js +3 -3
- package/dist/modules/mcp/resources/register.js +12 -2
- package/dist/modules/mcp/resources/renderGuide.js +6 -6
- package/dist/modules/mcp/resources/router.js +3 -1
- package/dist/modules/mcp/resources/schema.js +1 -1
- package/dist/modules/mcp/server.d.ts +3 -3
- package/dist/modules/mcp/server.js +12 -8
- package/dist/modules/mcp/tools/apply/dispatch.js +9 -1
- package/dist/modules/mcp/tools/apply/index.d.ts +11 -2
- package/dist/modules/mcp/tools/apply/index.js +27 -1
- package/dist/modules/mcp/tools/index.d.ts +2 -2
- package/dist/modules/mcp/tools/index.js +2 -2
- package/dist/modules/mcp/tools/operations/connectors/index.d.ts +2 -2
- package/dist/modules/mcp/tools/operations/connectors/manifest.d.ts +1 -1
- package/dist/modules/mcp/tools/operations/connectors/patchConnector.d.ts +1 -1
- package/dist/modules/mcp/tools/operations/connectors/upsertConnector.d.ts +1 -1
- package/dist/modules/mcp/tools/operations/data/data.test.d.ts +1 -0
- package/dist/modules/mcp/tools/operations/data/index.d.ts +32 -0
- package/dist/modules/mcp/tools/operations/data/index.js +54 -0
- package/dist/modules/mcp/tools/operations/index.d.ts +26 -4
- package/dist/modules/mcp/tools/operations/index.js +4 -1
- package/dist/modules/mcp/tools/operations/schema/interactions/patchInteractionNode.d.ts +1 -0
- package/dist/modules/mcp/tools/operations/schema/interactions/upsertInteractionFlow.d.ts +1 -0
- package/dist/modules/mcp/tools/operations/schema/operations.d.ts +2 -0
- package/dist/modules/mcp/tools/operations/schema/shared.d.ts +1 -0
- package/dist/modules/mcp/tools/operations/schema/shared.js +2 -5
- package/dist/modules/mcp/tools/operations/schema/translator.js +1 -1
- package/dist/modules/mcp/tools/operations/schema/write.js +1 -1
- package/dist/modules/mcp/tools/operations/schemaIds.js +1 -2
- package/dist/modules/mcp/tools/operations/style/write.js +1 -1
- package/dist/modules/mcp/tools/preview.d.ts +2 -0
- package/dist/modules/mcp/tools/render.d.ts +2 -0
- package/dist/modules/mcp/tools/screenshot.d.ts +11 -2
- package/dist/modules/mcp/tools/shared/newSuggestions.d.ts +2 -2
- package/dist/modules/mcp/tools/shared/newSuggestions.js +10 -5
- package/dist/modules/mcp/tools/shared/newSuggestions.test.d.ts +1 -0
- package/dist/modules/mcp/tools/shared/tool.d.ts +7 -6
- package/dist/modules/mcp/tools/shared/validator/index.js +2 -2
- package/dist/modules/mcp/tools/tryFunction.js +1 -1
- package/dist/modules/mcp/tools/validate.d.ts +11 -2
- package/dist/modules/mcp/types/appTypes.d.ts +2 -2
- package/dist/modules/mcp/types/toolTypes.d.ts +5 -1
- package/package.json +7 -9
- package/dist/modules/ai/AIEngine.d.ts +0 -20
- package/dist/modules/ai/AIEngine.js +0 -120
- package/dist/modules/ai/index.d.ts +0 -4
- package/dist/modules/ai/toolkit.d.ts +0 -17
- package/dist/modules/ai/toolkit.js +0 -59
- package/dist/modules/mcp/helpers/agentPrompt.d.ts +0 -4
- package/dist/modules/mcp/helpers/agentPrompt.js +0 -123
- /package/dist/modules/{ai/toolkit.test.d.ts → mcp/helpers/callToolResult.test.d.ts} +0 -0
|
@@ -2,53 +2,22 @@ import { require } from "../shared/resolve.js";
|
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import { readFileSync } from "node:fs";
|
|
4
4
|
//#region src/modules/mcp/apps/render/styles.ts
|
|
5
|
-
/** The SDK
|
|
5
|
+
/** The SDK's stylesheets, as a widget gets them.
|
|
6
6
|
*
|
|
7
7
|
* Everything the page shell inlines is paid for by EVERY widget: the host loads the ui:// page into a fresh
|
|
8
|
-
* sandboxed iframe and parses it whole before anything paints, which is the "Rendering…" the user waits through.
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
var
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
if (depth === 0) return at + 1;
|
|
23
|
-
}
|
|
24
|
-
return css.length;
|
|
25
|
-
};
|
|
26
|
-
/** Lifts every @font-face block out of a stylesheet. Brace counting rather than a CSS parser: a @font-face body is
|
|
27
|
-
* plain declarations, and base64 payloads and url() values carry no braces of their own. */
|
|
28
|
-
var splitFontFaces = (css) => {
|
|
29
|
-
const base = [];
|
|
30
|
-
const fonts = [];
|
|
31
|
-
let cursor = 0;
|
|
32
|
-
for (let at = css.indexOf("@font-face", cursor); at !== -1; at = css.indexOf("@font-face", cursor)) {
|
|
33
|
-
const open = css.indexOf("{", at);
|
|
34
|
-
if (open === -1) break;
|
|
35
|
-
const end = blockEnd(css, open);
|
|
36
|
-
base.push(css.slice(cursor, at));
|
|
37
|
-
fonts.push(css.slice(at, end));
|
|
38
|
-
cursor = end;
|
|
39
|
-
}
|
|
40
|
-
base.push(css.slice(cursor));
|
|
41
|
-
return {
|
|
42
|
-
base: base.join(""),
|
|
43
|
-
fonts: fonts.join("")
|
|
44
|
-
};
|
|
45
|
-
};
|
|
46
|
-
var stylesheet = () => readFileSync(path.join(path.dirname(require.resolve("@plitzi/plitzi-sdk")), "plitzi-sdk.css"), "utf-8");
|
|
47
|
-
var split;
|
|
48
|
-
var sdkStyles = () => split ??= splitFontFaces(stylesheet());
|
|
49
|
-
/** What the page shell inlines: the SDK stylesheet without the icon fonts. */
|
|
50
|
-
var widgetCss = () => sdkStyles().base;
|
|
51
|
-
/** The icon fonts, for the renders that draw one. */
|
|
52
|
-
var iconFontCss = () => sdkStyles().fonts;
|
|
8
|
+
* sandboxed iframe and parses it whole before anything paints, which is the "Rendering…" the user waits through. So
|
|
9
|
+
* the shell takes only `plitzi-sdk.css`, and Font Awesome — its rules in `plitzi-sdk-icons.css`, its fonts files
|
|
10
|
+
* beside it — travels in the tool result of the renders that actually draw an icon (see tools/render.ts). A widget
|
|
11
|
+
* without icons never downloads a glyph. */
|
|
12
|
+
var sdkDist = () => path.dirname(require.resolve("@plitzi/plitzi-sdk"));
|
|
13
|
+
var FONT_URL = /url\((webfonts\/[\w.-]+\.woff2)\)/g;
|
|
14
|
+
/** The icon sheet with each font it names inlined: the widget's sandbox reaches no origin to fetch one from. */
|
|
15
|
+
var inlineIconFonts = (css, readFont) => css.replace(FONT_URL, (_match, file) => `url(data:font/woff2;base64,${readFont(file).toString("base64")})`);
|
|
16
|
+
var base;
|
|
17
|
+
var icons;
|
|
18
|
+
/** What the page shell inlines. */
|
|
19
|
+
var widgetCss = () => base ??= readFileSync(path.join(sdkDist(), "plitzi-sdk.css"), "utf-8");
|
|
20
|
+
/** Font Awesome, fonts and all, for the renders that draw an icon. */
|
|
21
|
+
var iconFontCss = () => icons ??= inlineIconFonts(readFileSync(path.join(sdkDist(), "plitzi-sdk-icons.css"), "utf-8"), (file) => readFileSync(path.join(sdkDist(), file)));
|
|
53
22
|
//#endregion
|
|
54
|
-
export { iconFontCss,
|
|
23
|
+
export { iconFontCss, inlineIconFonts, widgetCss };
|
|
@@ -34,7 +34,7 @@ const ErrorPanel = ({ title, details }: { title: string; details: string }) => (
|
|
|
34
34
|
* wholesale when the result lands. A host that streams nothing paints none of this and keeps the static text. */
|
|
35
35
|
const SKELETON_BAR_WIDTHS = ['92%', '78%', '85%', '64%', '88%', '72%'];
|
|
36
36
|
|
|
37
|
-
// The deployment's own switch (
|
|
37
|
+
// The deployment's own switch (McpOptions.renderStreaming), handed over by the page. Absent means on: a page built
|
|
38
38
|
// before the setting existed carries none, and a host that streams no arguments paints the same either way.
|
|
39
39
|
const streamingEnabled =
|
|
40
40
|
(globalThis as { __PLITZI_VIEW__?: { streaming?: boolean } }).__PLITZI_VIEW__?.streaming !== false;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { buildDataSourceCatalog, buildInteractionCatalog, observedDataSources, observedInteractionActions } from "./observed.js";
|
|
2
2
|
import { buildTypeRegistry } from "./registry.js";
|
|
3
|
-
import {
|
|
4
|
-
export {
|
|
3
|
+
import { applyBuiltinCallback, applyElementCallback, applyUtility, cssProperties as cssProperties$1, cssShorthands, elementCatalog as elementCatalog$1, elementTypeNames, expandShorthand, expandShorthandPatch, getElementCallback, getGlobalCallback, getUtility, hiddenParams, isCssProperty, reconcileParams, suggestCssProperty } from "@plitzi/sdk-authoring";
|
|
4
|
+
export { applyBuiltinCallback, applyElementCallback, applyUtility, buildDataSourceCatalog, buildInteractionCatalog, buildTypeRegistry, cssProperties$1 as cssProperties, cssShorthands, elementCatalog$1 as elementCatalog, elementTypeNames, expandShorthand, expandShorthandPatch, getElementCallback, getGlobalCallback, getUtility, hiddenParams, isCssProperty, observedDataSources, observedInteractionActions, reconcileParams, suggestCssProperty };
|
|
@@ -10,8 +10,8 @@
|
|
|
10
10
|
*
|
|
11
11
|
* The BUILT-IN types are not here: their structural half (attributes, style selectors, default styles) comes from
|
|
12
12
|
* `@plitzi/sdk-elements`, which this package deliberately does not depend on — a React element library is the
|
|
13
|
-
* heaviest possible import for a server that renders nothing. Deployments merge those in themselves;
|
|
14
|
-
*
|
|
13
|
+
* heaviest possible import for a server that renders nothing. Deployments merge those in themselves; what each one is
|
|
14
|
+
* for is `elementCatalog`, read off the declarations by `@plitzi/sdk-authoring`.
|
|
15
15
|
*/
|
|
16
16
|
var MANIFEST_TTL_MS = 6e5;
|
|
17
17
|
var manifestCache = /* @__PURE__ */ new Map();
|
|
@@ -18,7 +18,8 @@ export interface McpEndpointOptions {
|
|
|
18
18
|
/** Attach a space to the connection, the way an authorized connector's token does — the server then offers its
|
|
19
19
|
* editing surface. Omitted, the endpoint is the guest one: no space, so only what works without one. */
|
|
20
20
|
spaceId?: number;
|
|
21
|
-
/** The deployment switch a consumer sets as `
|
|
21
|
+
/** The deployment switch a consumer sets as `McpOptions.renderStreaming`. Omitted, the server's own default
|
|
22
|
+
* stands. */
|
|
22
23
|
renderStreaming?: boolean;
|
|
23
24
|
}
|
|
24
25
|
/** Start the endpoint and connect a real MCP client to it, as a remote connector does. */
|
|
@@ -10,9 +10,9 @@ export type McpRequestOptions = {
|
|
|
10
10
|
preview?: PreviewClient;
|
|
11
11
|
screenshot?: ScreenshotClient;
|
|
12
12
|
logger?: ServerLogger;
|
|
13
|
-
/** Deployment switch for the plitzi_render view (see `
|
|
13
|
+
/** Deployment switch for the plitzi_render view (see `McpOptions.renderStreaming`). Defaults to true. */
|
|
14
14
|
renderStreaming?: boolean;
|
|
15
|
-
/** Where a rendered widget loads everything external from (see `
|
|
15
|
+
/** Where a rendered widget loads everything external from (see `McpOptions.proxy`). Absent → the URLs an agent
|
|
16
16
|
* authored travel to the host exactly as written. */
|
|
17
17
|
proxy?: ResourceProxy;
|
|
18
18
|
};
|
|
@@ -61,7 +61,8 @@ computed for you). Node types: \`callback\` (an element's own callback — \`ele
|
|
|
61
61
|
(category/key/value/revertOnFinish) ≠ global \`setState\` (source \`state\`, key/type/value). To turn a step off use
|
|
62
62
|
\`patchInteractionNode {enabled:false}\` — \`deleteInteraction\` removes it (destructive; confirm first). Any param
|
|
63
63
|
**value** can be a binding token \`{{ source }}\` (e.g. notification \`content: "{{ list_<name>.item.name }}"\`).
|
|
64
|
-
Steps read the page as it is when they run; a refiring trigger is ignored unless \`whileRunning: "queue"
|
|
64
|
+
Steps read the page as it is when they run; a refiring trigger is ignored unless \`whileRunning: "queue"\` (or
|
|
65
|
+
\`"latest"\`: the newest firing stops the running one); keyboard
|
|
65
66
|
shortcuts are the \`onKey\` trigger (\`keys: "shift+f, escape"\`).
|
|
66
67
|
|
|
67
68
|
**CMS / API integrations** (\`upsertConnector\`): a **connector** is a manifest declaring a provider's base URL,
|
|
@@ -178,6 +179,8 @@ Never download a whole tree you do not need.
|
|
|
178
179
|
action may be built from.
|
|
179
180
|
- \`plitzi://functions/{env}\` — the space's **functions**, its own server code: which files, and the tasks, routes and
|
|
180
181
|
hosts they declare. \`plitzi://functions/{env}/{+path}\` reads one file whole. See *Functions* below.
|
|
182
|
+
- \`plitzi://data/{env}\` — the space's **data**: JSON files its server providers read, never served.
|
|
183
|
+
\`plitzi://data/{env}/{+path}\` reads one, parsed. See *Data* below.
|
|
181
184
|
- \`plitzi://changes/{env}\` — the space's **change history**, read-only and newest first: who made each change (a
|
|
182
185
|
person in the builder, an agent, the autofix), when, and every element, class, token or font it touched, whole, before
|
|
183
186
|
and after. \`/{id}\` for the history of one of them — how you find what changed an element you are asked about, or
|
|
@@ -249,6 +252,11 @@ space already had is not repeated on every batch — and none of them blocks any
|
|
|
249
252
|
\`states\`/\`ancestors\`, the SDK (reduced motion, the theme toggle's icons) or the space's notification look says.
|
|
250
253
|
- \`heavy-animation\` — keyframes that animate a size, a position, a blur, a shadow, or a colour in a loop: they stutter
|
|
251
254
|
while the page loads. Lighter, not shorter — see **Motion — good practices**.
|
|
255
|
+
- \`unused-class\`, \`unused-token\`, \`unused-component\` — declared and read by nothing: remove it
|
|
256
|
+
(\`deleteDefinition\`, \`deleteStyleVariable\`, \`deleteComponent\`), or use it where it was meant to go. Said
|
|
257
|
+
when a batch leaves one behind.
|
|
258
|
+
- \`literal-colour\` — a class painted from the palette typing out a token's light value: \`var(--token)\` when it
|
|
259
|
+
should follow the scheme; a token of one value when it must stay the same in both.
|
|
252
260
|
\`plitzi://explain/<code>\` explains each. Take one unless the copies are about to diverge; one left on purpose is
|
|
253
261
|
quieted on an element it names — \`quiet: ["repeated-shape"]\` on \`upsertElement\`/\`patchElement\` (\`null\` removes it)
|
|
254
262
|
— and is not offered again, here, in the builder or in authoring. Suggestions' codes only.
|
|
@@ -424,7 +432,8 @@ fixed shape under *Connectors* — \`.records\` or \`.record\`, \`.pageInfo\`,
|
|
|
424
432
|
response: \`.data\` (the parsed body — an API answering \`{ "items": [...] }\` is read as
|
|
425
433
|
\`apiContainer_<name>.data.items\`) and \`.status\` (the HTTP status) — and a \`"server"\` provider with only a
|
|
426
434
|
\`query\` (a JSON file the deployment serves) answers in that same shape, so moving it to the server changes no
|
|
427
|
-
binding.
|
|
435
|
+
binding. Fed by a server **action**, it is the action's output at the root (\`apiContainer_<name>.items\`, never
|
|
436
|
+
\`.data.items\`). All add \`.isLoading\` (true while asked again too), \`.isEmpty\`,
|
|
428
437
|
\`.hasError\` and \`.errorMessage\`.
|
|
429
438
|
|
|
430
439
|
**Source scope — a source is visible to the provider's DESCENDANTS only.** An element source named
|
|
@@ -471,7 +480,8 @@ you — never wire them by hand. Each step also has an \`enabled\` flag (see dis
|
|
|
471
480
|
**Each step reads the page as it is when it runs**: a \`when\` or a \`{{ state.x }}\` after a \`setState\` sees the new
|
|
472
481
|
value, and one after a \`delay\` sees what changed meanwhile. To act on the value from BEFORE a write, put the reading
|
|
473
482
|
step first. **A trigger fired again while its flow runs is ignored** (no double submit); set \`"whileRunning": "queue"\`
|
|
474
|
-
on the trigger node for a stream of events that must each run in order (\`"parallel"\` runs them at once
|
|
483
|
+
on the trigger node for a stream of events that must each run in order (\`"parallel"\` runs them at once,
|
|
484
|
+
\`"latest"\` stops the running flow — its server action or request too — for a search as you type).
|
|
475
485
|
**Keyboard shortcuts** are a trigger every element has: \`onKey\` with param \`keys\` — \`"f"\`, \`"shift+f"\`,
|
|
476
486
|
\`"mod+k"\` (⌘ on a Mac, Ctrl elsewhere), \`"plus, ="\`, \`"escape"\`. Heard on the whole page while the element is
|
|
477
487
|
mounted, ignored while someone types in a field; the flow reads the key pressed as \`{{ <trigger id>.key }}\`.
|
|
@@ -673,7 +683,7 @@ returns **no records** rather than the whole collection — a URL that addressed
|
|
|
673
683
|
**Paging** is the \`pagination\` prop: \`"none"\`, \`"url"\` (the page number rides the query string, so pages are
|
|
674
684
|
shareable and indexable — prefer it) or \`"append"\` (a "load more" list). Give each list on a page its own
|
|
675
685
|
\`pageParam\` so two lists page independently. The provider also offers the \`loadMore\` and \`goToPage\` callbacks to
|
|
676
|
-
interaction flows, and \`
|
|
686
|
+
interaction flows, \`performQuery\` to refetch, and \`cancelQuery\` to drop a request in flight (a STOP).
|
|
677
687
|
|
|
678
688
|
**Writing back** (a form, a "delete" button): declare the endpoint under \`endpoints.write\`, then call the provider's
|
|
679
689
|
**\`writeRecord\`** callback from an interaction flow — nodeType \`callback\`, \`elementId\` the apiContainer's ref,
|
|
@@ -732,6 +742,19 @@ any other (\`<namespace>.<action>\`), listed in \`plitzi://actions/{env}/tasks\`
|
|
|
732
742
|
The live site runs what the space was last published with, never the draft. Running functions is part of the paid
|
|
733
743
|
plans: on another plan they save, and a run answers why it did not start — tell the user rather than work around it.
|
|
734
744
|
|
|
745
|
+
## Data
|
|
746
|
+
JSON the space's pages read on the server and never serve — a catalog, prices, a menu: what a page needs whole and
|
|
747
|
+
nobody edits element by element.
|
|
748
|
+
|
|
749
|
+
- **Read** it as a provider does: \`apiContainer\` with \`runtime: "server"\` and \`query: "/data/products.json"\` reads
|
|
750
|
+
\`products.json\` of \`plitzi://data/{env}\`, and the page arrives with it. A browser provider reading \`/data/…\` is
|
|
751
|
+
refused — the data is the server's.
|
|
752
|
+
- **Write** it with \`upsertDataFile { path, content }\` (the whole file, as JSON text; \`deleteDataFile { path }\`
|
|
753
|
+
removes one): a path of plain segments ending in \`.json\`. Saved whole, with the batch: a newer copy (somebody saved
|
|
754
|
+
since you read it) refuses it — read it again.
|
|
755
|
+
- **What a provider reads is in the page it renders**: data a page must not carry belongs in a server action, which
|
|
756
|
+
answers only what is shown. The live site reads what the space was last published with, never the draft.
|
|
757
|
+
|
|
735
758
|
## Realtime channels
|
|
736
759
|
Pages that see each other — cursors, presence, a shared board, a game. Three parts, all needed:
|
|
737
760
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { AIElementDetail } from '../types';
|
|
2
|
-
import { ActionEntry, ActionTaskDescriptor, ComponentCatalog, ConnectorEntry, Element, FunctionsDraft, PageFolder, Schema, Style } from '@plitzi/sdk-shared';
|
|
2
|
+
import { ActionEntry, ActionTaskDescriptor, ComponentCatalog, ConnectorEntry, DataDraft, Element, FunctionsDraft, PageFolder, Schema, Style } from '@plitzi/sdk-shared';
|
|
3
3
|
/** The working view the tools read and mutate: the two Plitzi schemas (elements + style), which the platform
|
|
4
4
|
* stores and persists as separate documents (Space model / Style model), plus the space's `connectors` — a third
|
|
5
5
|
* store (one row per connector) that a provider element points into by identifier. `catalog` is read-only
|
|
@@ -16,6 +16,9 @@ export interface Space {
|
|
|
16
16
|
/** The space's own functions — their source files, which copy of them this is, and what they declare. Absent when
|
|
17
17
|
* the deployment offers no functions: then there is nothing to read and every function op is refused. */
|
|
18
18
|
functions?: FunctionsDraft;
|
|
19
|
+
/** The space's own data — JSON its server providers read (`/data/<file>`), never served — and which copy of it this
|
|
20
|
+
* is. Absent when the deployment offers no data: then there is nothing to read and every data op is refused. */
|
|
21
|
+
data?: DataDraft;
|
|
19
22
|
catalog?: ComponentCatalog;
|
|
20
23
|
/**
|
|
21
24
|
* The whole document, when `schema` is a view of one tree of it — a component's, which an op addressed to a
|
|
@@ -6,6 +6,7 @@ var cloneSpace = (space) => ({
|
|
|
6
6
|
connectors: structuredClone(space.connectors),
|
|
7
7
|
actions: structuredClone(space.actions),
|
|
8
8
|
...space.functions ? { functions: structuredClone(space.functions) } : {},
|
|
9
|
+
...space.data ? { data: structuredClone(space.data) } : {},
|
|
9
10
|
...space.actionTasks ? { actionTasks: space.actionTasks } : {},
|
|
10
11
|
...space.catalog ? { catalog: space.catalog } : {}
|
|
11
12
|
});
|
|
@@ -28,6 +28,8 @@ export declare const actionUri: (env: Env, ref: string) => string;
|
|
|
28
28
|
export declare const actionTasksUri: (env: Env) => string;
|
|
29
29
|
export declare const functionsUri: (env: Env) => string;
|
|
30
30
|
export declare const functionFileUri: (env: Env, path: string) => string;
|
|
31
|
+
export declare const dataUri: (env: Env) => string;
|
|
32
|
+
export declare const dataFileUri: (env: Env, path: string) => string;
|
|
31
33
|
export declare const foldersUri: (env: Env) => string;
|
|
32
34
|
export declare const folderUri: (env: Env, ref: string) => string;
|
|
33
35
|
export declare const defsUri: (env: Env) => string;
|
|
@@ -28,6 +28,8 @@ var actionUri = (env, ref) => `plitzi://actions/${env}/${ref}`;
|
|
|
28
28
|
var actionTasksUri = (env) => `plitzi://actions/${env}/tasks`;
|
|
29
29
|
var functionsUri = (env) => `plitzi://functions/${env}`;
|
|
30
30
|
var functionFileUri = (env, path) => `plitzi://functions/${env}/${path}`;
|
|
31
|
+
var dataUri = (env) => `plitzi://data/${env}`;
|
|
32
|
+
var dataFileUri = (env, path) => `plitzi://data/${env}/${path}`;
|
|
31
33
|
var foldersUri = (env) => `plitzi://folders/${env}`;
|
|
32
34
|
var folderUri = (env, ref) => `plitzi://folders/${env}/${ref}`;
|
|
33
35
|
var defsUri = (env) => `plitzi://definitions/${env}`;
|
|
@@ -62,4 +64,4 @@ var itemTemplates = (env) => [
|
|
|
62
64
|
* family and extracts its ref in one step, without repeating the prefix string for both the startsWith and slice. */
|
|
63
65
|
var afterPrefix = (uri, prefix) => uri.startsWith(prefix) ? uri.slice(prefix.length) : void 0;
|
|
64
66
|
//#endregion
|
|
65
|
-
export { actionTasksUri, actionUri, actionsUri, afterPrefix, aliasedRoots, changesUri, componentsUri, connectorPresetsUri, connectorUri, connectorsUri, cssPropertiesUri, dataSourcesUri, defUri, defsUri, elementUri, flagsUri, folderUri, foldersUri, fontUri, fontsUri, functionFileUri, functionsUri, globalUri, globalsUri, guideUri, idUri, idsUri, interactionsUri, itemTemplates, layoutsUri, pageUri, pagesUri, primerUri, schemaVarsUri, settingsUri, styleVarUri, styleVarsUri, typesUri };
|
|
67
|
+
export { actionTasksUri, actionUri, actionsUri, afterPrefix, aliasedRoots, changesUri, componentsUri, connectorPresetsUri, connectorUri, connectorsUri, cssPropertiesUri, dataFileUri, dataSourcesUri, dataUri, defUri, defsUri, elementUri, flagsUri, folderUri, foldersUri, fontUri, fontsUri, functionFileUri, functionsUri, globalUri, globalsUri, guideUri, idUri, idsUri, interactionsUri, itemTemplates, layoutsUri, pageUri, pagesUri, primerUri, schemaVarsUri, settingsUri, styleVarUri, styleVarsUri, typesUri };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export { createMcpServer, handleMcp, serveMcp, readMcpBody } from './handler';
|
|
2
2
|
export { readResource, resourceVersion, registerResources, buildTypeRegistry, cssProperties } from './resources';
|
|
3
3
|
export { apply, validate, search, read, validateOperations, operation, tools } from './tools';
|
|
4
|
-
export { computeVersion
|
|
4
|
+
export { computeVersion } from './helpers';
|
|
5
5
|
export { createHttpPreviewClient } from './previewClient';
|
|
6
6
|
export { createLocalScreenshotClient, resolveLocalBrowser } from './localScreenshotClient';
|
|
7
7
|
export { createHttpScreenshotClient } from './screenshotClient';
|
|
@@ -10,7 +10,7 @@ export declare const connectorSummaries: (space: Space) => {
|
|
|
10
10
|
operators: string[];
|
|
11
11
|
pagination: import('@plitzi/sdk-shared').ConnectorPagination | undefined;
|
|
12
12
|
credential: string | undefined;
|
|
13
|
-
fields: Record<string, "number" | "file" | "text" | "color" | "
|
|
13
|
+
fields: Record<string, "number" | "file" | "text" | "color" | "image" | "switch" | "email" | "date" | "richText" | "multiImage" | "video" | "link" | "phone" | "option"> | undefined;
|
|
14
14
|
}[];
|
|
15
15
|
};
|
|
16
16
|
/** Connector reads: the space's connector listing and one full manifest. Undefined when the URI belongs to
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { buildTypeRegistry } from "../catalogs/registry.js";
|
|
2
|
-
import { cssProperties, cssShorthands } from "../catalogs/index.js";
|
|
3
1
|
import "../helpers/uris.js";
|
|
4
2
|
import { guideText } from "../helpers/guide.js";
|
|
3
|
+
import { buildTypeRegistry } from "../catalogs/registry.js";
|
|
4
|
+
import { cssProperties, cssShorthands } from "../catalogs/index.js";
|
|
5
5
|
import { envelope } from "./envelope.js";
|
|
6
6
|
//#region src/modules/mcp/resources/core.ts
|
|
7
7
|
/** Space-independent singletons: the usage guide, the observed type registry and the CSS property catalog.
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { Space } from '../helpers';
|
|
2
|
+
import { Env, ResourceEnvelope } from '../types';
|
|
3
|
+
/**
|
|
4
|
+
* The space's own data: JSON its server providers read (`query: '/data/<file>'`, `runtime: 'server'`), never served.
|
|
5
|
+
* The listing says which files there are, so an agent reads the one it needs; a file reads whole — parsed, so its
|
|
6
|
+
* shape is what a binding onto it reads.
|
|
7
|
+
*/
|
|
8
|
+
export declare const readDataResource: (space: Space, env: Env, uri: string) => ResourceEnvelope<unknown> | null | undefined;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { afterPrefix, dataFileUri, dataUri } from "../helpers/uris.js";
|
|
2
|
+
import { envelope } from "./envelope.js";
|
|
3
|
+
//#region src/modules/mcp/resources/data.ts
|
|
4
|
+
/**
|
|
5
|
+
* The space's own data: JSON its server providers read (`query: '/data/<file>'`, `runtime: 'server'`), never served.
|
|
6
|
+
* The listing says which files there are, so an agent reads the one it needs; a file reads whole — parsed, so its
|
|
7
|
+
* shape is what a binding onto it reads.
|
|
8
|
+
*/
|
|
9
|
+
var readDataResource = (space, env, uri) => {
|
|
10
|
+
if (uri === dataUri(env)) {
|
|
11
|
+
if (!space.data) return envelope({
|
|
12
|
+
available: false,
|
|
13
|
+
reason: "This deployment keeps no space data"
|
|
14
|
+
});
|
|
15
|
+
const { files, version } = space.data;
|
|
16
|
+
return envelope({
|
|
17
|
+
available: true,
|
|
18
|
+
version,
|
|
19
|
+
files: Object.entries(files).map(([path, content]) => ({
|
|
20
|
+
path,
|
|
21
|
+
query: `/data/${path}`,
|
|
22
|
+
bytes: content.length
|
|
23
|
+
}))
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
const path = afterPrefix(uri, dataFileUri(env, ""));
|
|
27
|
+
if (path === void 0) return;
|
|
28
|
+
const content = space.data && Object.hasOwn(space.data.files, path) ? space.data.files[path] : void 0;
|
|
29
|
+
if (content === void 0) return null;
|
|
30
|
+
try {
|
|
31
|
+
return envelope({
|
|
32
|
+
path,
|
|
33
|
+
query: `/data/${path}`,
|
|
34
|
+
content: JSON.parse(content)
|
|
35
|
+
});
|
|
36
|
+
} catch {
|
|
37
|
+
return envelope({
|
|
38
|
+
path,
|
|
39
|
+
query: `/data/${path}`,
|
|
40
|
+
text: content,
|
|
41
|
+
problem: "It is not JSON"
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
//#endregion
|
|
46
|
+
export { readDataResource };
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { buildDataSourceCatalog, buildInteractionCatalog } from "../catalogs/observed.js";
|
|
2
|
-
import { buildTypeRegistry } from "../catalogs/registry.js";
|
|
3
|
-
import { cssProperties, cssShorthands } from "../catalogs/index.js";
|
|
4
1
|
import { componentSummariesToAI } from "../helpers/components.js";
|
|
5
2
|
import { componentsUri, connectorsUri, dataSourcesUri, defsUri, flagsUri, foldersUri, fontsUri, interactionsUri, layoutsUri, pagesUri, primerUri, schemaVarsUri, settingsUri, styleVarsUri, typesUri } from "../helpers/uris.js";
|
|
6
3
|
import { guideQuickstart } from "../helpers/guide.js";
|
|
4
|
+
import { buildDataSourceCatalog, buildInteractionCatalog } from "../catalogs/observed.js";
|
|
5
|
+
import { buildTypeRegistry } from "../catalogs/registry.js";
|
|
6
|
+
import { cssProperties, cssShorthands } from "../catalogs/index.js";
|
|
7
7
|
import { envelope } from "./envelope.js";
|
|
8
8
|
import { connectorSummaries } from "./connectors.js";
|
|
9
9
|
import { definitionRefs, fontsToAI, styleVariablesToAI } from "../tools/operations/style/translator.js";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { cssProperties, cssShorthands } from "../catalogs/index.js";
|
|
2
1
|
import { changesUri } from "../helpers/uris.js";
|
|
3
2
|
import { guideText } from "../helpers/guide.js";
|
|
3
|
+
import { cssProperties, cssShorthands } from "../catalogs/index.js";
|
|
4
4
|
import { envelope, jsonContents } from "./envelope.js";
|
|
5
5
|
import { resourceErrorMessage } from "./canonical.js";
|
|
6
6
|
import { registerRenderResources } from "./renderGuide.js";
|
|
@@ -36,7 +36,7 @@ var registerResources = (server, getSpace, env, log, hasSpace, readChanges) => {
|
|
|
36
36
|
return result;
|
|
37
37
|
};
|
|
38
38
|
server.registerResource("Guide", "plitzi://guide", {
|
|
39
|
-
description: "How to read and write this space
|
|
39
|
+
description: "How to read and write this space through this server",
|
|
40
40
|
mimeType: "text/markdown"
|
|
41
41
|
}, () => emitStatic("plitzi://guide", () => ({ contents: [{
|
|
42
42
|
uri: "plitzi://guide",
|
|
@@ -157,6 +157,11 @@ var registerResources = (server, getSpace, env, log, hasSpace, readChanges) => {
|
|
|
157
157
|
`plitzi://functions/${env}`,
|
|
158
158
|
"The space’s own server code: which files it is, and the tasks, routes and hosts it declares — its tasks are steps like any server task"
|
|
159
159
|
],
|
|
160
|
+
[
|
|
161
|
+
"Data",
|
|
162
|
+
`plitzi://data/${env}`,
|
|
163
|
+
"The space’s own data: JSON files its server providers read as `/data/<file>`, never served — which files there are"
|
|
164
|
+
],
|
|
160
165
|
[
|
|
161
166
|
"Style definitions (schema alias)",
|
|
162
167
|
`plitzi://schema/${env}/definitions`,
|
|
@@ -237,6 +242,11 @@ var registerResources = (server, getSpace, env, log, hasSpace, readChanges) => {
|
|
|
237
242
|
`plitzi://functions/${env}/{+path}`,
|
|
238
243
|
"One file of the space’s functions, whole"
|
|
239
244
|
],
|
|
245
|
+
[
|
|
246
|
+
"Data file",
|
|
247
|
+
`plitzi://data/${env}/{+path}`,
|
|
248
|
+
"One file of the space’s data, parsed"
|
|
249
|
+
],
|
|
240
250
|
[
|
|
241
251
|
"Style definition",
|
|
242
252
|
`plitzi://definitions/${env}/{ref}`,
|
|
@@ -197,9 +197,9 @@ and \`patchDefinition\` still changes only some CSS of one class.
|
|
|
197
197
|
|
|
198
198
|
## Fit the panel — go wide, stay short
|
|
199
199
|
|
|
200
|
-
The widget renders in a **side panel** (Claude Desktop, ChatGPT
|
|
201
|
-
|
|
202
|
-
|
|
200
|
+
The widget renders in a **side panel** (Claude Desktop, ChatGPT), so it gets a usable width but very little
|
|
201
|
+
height: everything past the first screenful costs the user a scroll. Height is the scarce resource — spend width
|
|
202
|
+
instead.
|
|
203
203
|
|
|
204
204
|
Plain containers are blocks, so doing nothing stacks children **vertically** and produces exactly the tall,
|
|
205
205
|
half-empty widget to avoid. Choose the axis every time:
|
|
@@ -228,9 +228,9 @@ it — and reach for \`max-width\` only to stop one lone card from stretching ac
|
|
|
228
228
|
|
|
229
229
|
## Match the host theme — never hardcode a light palette
|
|
230
230
|
|
|
231
|
-
The widget is embedded in the host's own UI (Claude Desktop, ChatGPT
|
|
232
|
-
|
|
233
|
-
|
|
231
|
+
The widget is embedded in the host's own UI (Claude Desktop, ChatGPT), and that UI **may be in dark mode**. A
|
|
232
|
+
widget painted with fixed light colours is the most common way to ship something unusable: a white card in a dark
|
|
233
|
+
chat glares, and — worse — text left at a dark default disappears against the host's dark background.
|
|
234
234
|
|
|
235
235
|
The host publishes its palette as CSS variables on the page, so use them for every colour, with a
|
|
236
236
|
\`light-dark(<light>, <dark>)\` fallback for hosts that send none:
|
|
@@ -4,6 +4,7 @@ import { readActionResource } from "./actions.js";
|
|
|
4
4
|
import { canonicalUri } from "./canonical.js";
|
|
5
5
|
import { readConnectorResource } from "./connectors.js";
|
|
6
6
|
import { readCoreResource } from "./core.js";
|
|
7
|
+
import { readDataResource } from "./data.js";
|
|
7
8
|
import { readFunctionsResource } from "./functions.js";
|
|
8
9
|
import { readPrimerResource } from "./primer.js";
|
|
9
10
|
import { readRenderResource } from "./renderGuide.js";
|
|
@@ -18,7 +19,8 @@ var resolvers = [
|
|
|
18
19
|
readStyleResource,
|
|
19
20
|
readConnectorResource,
|
|
20
21
|
readActionResource,
|
|
21
|
-
readFunctionsResource
|
|
22
|
+
readFunctionsResource,
|
|
23
|
+
readDataResource
|
|
22
24
|
];
|
|
23
25
|
/** Resolve a resource URI to its versioned envelope, or null if unknown / not found. */
|
|
24
26
|
var readResource = (space, env, rawUri) => {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { buildDataSourceCatalog, buildInteractionCatalog } from "../catalogs/observed.js";
|
|
2
1
|
import { componentSummariesToAI, componentView, findComponentByRef } from "../helpers/components.js";
|
|
3
2
|
import { findElementByRef, findRootByRef } from "../helpers/space.js";
|
|
4
3
|
import { afterPrefix, componentsUri, dataSourcesUri, elementUri, flagsUri, folderUri, foldersUri, interactionsUri, layoutsUri, pageUri, pagesUri, schemaVarsUri, settingsUri } from "../helpers/uris.js";
|
|
4
|
+
import { buildDataSourceCatalog, buildInteractionCatalog } from "../catalogs/observed.js";
|
|
5
5
|
import { envelope } from "./envelope.js";
|
|
6
6
|
import { elementView, folderRefToAI, foldersToAI, layoutSummariesToAI, pageSkeletonToAI, pageStylesToAI, pageSummariesToAI, schemaVariablesToAI, settingsToAI } from "../tools/operations/schema/translator.js";
|
|
7
7
|
import { treeOf } from "@plitzi/sdk-schema/helpers/components";
|
|
@@ -20,10 +20,10 @@ export interface McpServerContext {
|
|
|
20
20
|
/** Structured request-log sink. When set, every tool call and resource read emits an McpLogEvent to it (the
|
|
21
21
|
* consumer renders them); otherwise logging falls back to the console when MCP_DEBUG=1. */
|
|
22
22
|
logger?: ServerLogger;
|
|
23
|
-
/** May the plitzi_render view paint from tool arguments the host is still streaming (see
|
|
24
|
-
* Defaults to true. */
|
|
23
|
+
/** May the plitzi_render view paint from tool arguments the host is still streaming (see
|
|
24
|
+
* `McpOptions.renderStreaming`)? Defaults to true. */
|
|
25
25
|
renderStreaming?: boolean;
|
|
26
|
-
/** Where a rendered widget loads everything external from (see `
|
|
26
|
+
/** Where a rendered widget loads everything external from (see `McpOptions.proxy`). It reaches two places: the render
|
|
27
27
|
* tool, which rewrites the URLs the agent authored, and the App's CSP, which declares the origin those URLs
|
|
28
28
|
* point at. Absent → neither happens, and a widget's resources load only where the host allows their origin. */
|
|
29
29
|
proxy?: ResourceProxy;
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { registerApps } from "./apps/index.js";
|
|
2
|
+
import { isCallToolResult } from "./helpers/callToolResult.js";
|
|
2
3
|
import { NoSpaceError, ReadOnlyGrantError, emptySpace, emptySpaceMessage, noSpaceErrorCode, readOnlyGrantErrorCode } from "./helpers/space.js";
|
|
3
4
|
import { serverInstructions, widgetsOnlyInstructions } from "./helpers/guide.js";
|
|
4
5
|
import { createMcpLog } from "./helpers/log.js";
|
|
5
6
|
import { proxyForTool } from "./proxy/config.js";
|
|
6
7
|
import { registerResources } from "./resources/register.js";
|
|
7
8
|
import { tools } from "./tools/index.js";
|
|
8
|
-
import { isCallToolResult } from "../ai/toolkit.js";
|
|
9
9
|
import { randomUUID } from "node:crypto";
|
|
10
10
|
import { registerAppTool } from "@modelcontextprotocol/ext-apps/server";
|
|
11
11
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
@@ -31,14 +31,15 @@ var createMcpServer = async ({ adapters, getGrant, preview, screenshot, logger,
|
|
|
31
31
|
};
|
|
32
32
|
const loadSpace = async () => {
|
|
33
33
|
const id = requireSpaceId();
|
|
34
|
-
const [schema, style, catalog, connectors, actions, actionTasks, functions] = await Promise.all([
|
|
34
|
+
const [schema, style, catalog, connectors, actions, actionTasks, functions, data] = await Promise.all([
|
|
35
35
|
adapters.getSchema?.(id, MCP_ENV),
|
|
36
36
|
adapters.getStyle?.(id, MCP_ENV),
|
|
37
37
|
adapters.getComponentCatalog?.(id, MCP_ENV).catch(() => void 0),
|
|
38
38
|
adapters.getConnectors?.(id).catch(() => void 0),
|
|
39
39
|
adapters.getActions?.(id).catch(() => void 0),
|
|
40
40
|
adapters.getActionTasks?.(id).catch(() => void 0),
|
|
41
|
-
adapters.getFunctions?.(id).catch(() => void 0)
|
|
41
|
+
adapters.getFunctions?.(id).catch(() => void 0),
|
|
42
|
+
adapters.getData?.(id).catch(() => void 0)
|
|
42
43
|
]);
|
|
43
44
|
if (!schema || !style) throw new Error(emptySpaceMessage);
|
|
44
45
|
return {
|
|
@@ -48,10 +49,11 @@ var createMcpServer = async ({ adapters, getGrant, preview, screenshot, logger,
|
|
|
48
49
|
connectors: connectors ?? [],
|
|
49
50
|
actions: actions ?? [],
|
|
50
51
|
actionTasks,
|
|
51
|
-
...functions ? { functions } : {}
|
|
52
|
+
...functions ? { functions } : {},
|
|
53
|
+
...data ? { data } : {}
|
|
52
54
|
};
|
|
53
55
|
};
|
|
54
|
-
const { saveSchema, saveStyle, saveConnector, deleteConnector, saveAction, deleteAction, saveFunctions, tryFunction } = adapters;
|
|
56
|
+
const { saveSchema, saveStyle, saveConnector, deleteConnector, saveAction, deleteAction, saveFunctions, tryFunction, saveData } = adapters;
|
|
55
57
|
const write = {
|
|
56
58
|
userId: grant?.userId,
|
|
57
59
|
batch: randomUUID()
|
|
@@ -63,13 +65,14 @@ var createMcpServer = async ({ adapters, getGrant, preview, screenshot, logger,
|
|
|
63
65
|
deleteConnector: deleteConnector ? (id) => deleteConnector(requireWritableSpaceId(), id) : void 0,
|
|
64
66
|
saveAction: saveAction ? (entry) => saveAction(requireWritableSpaceId(), entry) : void 0,
|
|
65
67
|
deleteAction: deleteAction ? (id) => deleteAction(requireWritableSpaceId(), id) : void 0,
|
|
66
|
-
saveFunctions: saveFunctions ? (files, base) => saveFunctions(requireWritableSpaceId(), files, base, write) : void 0
|
|
68
|
+
saveFunctions: saveFunctions ? (files, base) => saveFunctions(requireWritableSpaceId(), files, base, write) : void 0,
|
|
69
|
+
saveData: saveData ? (files, base) => saveData(requireWritableSpaceId(), files, base, write) : void 0
|
|
67
70
|
};
|
|
68
71
|
let spacePromise;
|
|
69
72
|
const getSpace = () => spacePromise ??= loadSpace();
|
|
70
73
|
const server = new McpServer({
|
|
71
74
|
name: "plitzi-mcp",
|
|
72
|
-
version: "0.38.
|
|
75
|
+
version: "0.38.6"
|
|
73
76
|
}, { instructions: hasSpace ? serverInstructions : widgetsOnlyInstructions });
|
|
74
77
|
const { getChanges } = adapters;
|
|
75
78
|
registerResources(server, getSpace, MCP_ENV, log, hasSpace, getChanges ? (query) => getChanges(requireSpaceId(), MCP_ENV, query) : void 0);
|
|
@@ -126,7 +129,8 @@ var createMcpServer = async ({ adapters, getGrant, preview, screenshot, logger,
|
|
|
126
129
|
const config = {
|
|
127
130
|
title: tool.title,
|
|
128
131
|
description: tool.description,
|
|
129
|
-
inputSchema: tool.inputShape
|
|
132
|
+
inputSchema: tool.inputShape,
|
|
133
|
+
annotations: { readOnlyHint: tool.access === "read" }
|
|
130
134
|
};
|
|
131
135
|
if (tool.ui) {
|
|
132
136
|
registerAppTool(server, tool.name, {
|
|
@@ -7,6 +7,7 @@ import { upsertAction } from "../operations/actions/upsertAction.js";
|
|
|
7
7
|
import { deleteConnector } from "../operations/connectors/deleteConnector.js";
|
|
8
8
|
import { patchConnector } from "../operations/connectors/patchConnector.js";
|
|
9
9
|
import { upsertConnector } from "../operations/connectors/upsertConnector.js";
|
|
10
|
+
import { deleteDataFile, upsertDataFile } from "../operations/data/index.js";
|
|
10
11
|
import { deleteFunctionFile, upsertFunctionFile } from "../operations/functions/index.js";
|
|
11
12
|
import { deleteBinding } from "../operations/schema/bindings/deleteBinding.js";
|
|
12
13
|
import { patchBinding } from "../operations/schema/bindings/patchBinding.js";
|
|
@@ -113,6 +114,8 @@ var executeOp = (space, env, op) => {
|
|
|
113
114
|
case "deleteAction": return deleteAction(space, env, op);
|
|
114
115
|
case "upsertFunctionFile": return upsertFunctionFile(space, env, op);
|
|
115
116
|
case "deleteFunctionFile": return deleteFunctionFile(space, env, op);
|
|
117
|
+
case "upsertDataFile": return upsertDataFile(space, env, op);
|
|
118
|
+
case "deleteDataFile": return deleteDataFile(space, env, op);
|
|
116
119
|
default: return fail("type", `Unknown operation "${op.type}"`, "See the Operation union");
|
|
117
120
|
}
|
|
118
121
|
};
|
|
@@ -132,7 +135,8 @@ var applyOperations = (space, env, ops) => {
|
|
|
132
135
|
deletedConnectors: [],
|
|
133
136
|
changedActions: [],
|
|
134
137
|
deletedActions: [],
|
|
135
|
-
changedFunctions: false
|
|
138
|
+
changedFunctions: false,
|
|
139
|
+
changedData: false
|
|
136
140
|
};
|
|
137
141
|
const stale = /* @__PURE__ */ new Set();
|
|
138
142
|
const elements = /* @__PURE__ */ new Set();
|
|
@@ -173,6 +177,10 @@ var applyOperations = (space, env, ops) => {
|
|
|
173
177
|
case "deleteFunctionFile":
|
|
174
178
|
outcome.changedFunctions = true;
|
|
175
179
|
break;
|
|
180
|
+
case "upsertDataFile":
|
|
181
|
+
case "deleteDataFile":
|
|
182
|
+
outcome.changedData = true;
|
|
183
|
+
break;
|
|
176
184
|
default: if (isStyleOp(op.type)) outcome.changedStyle = true;
|
|
177
185
|
else outcome.changedSchema = true;
|
|
178
186
|
}
|