@plitzi/sdk-server 0.32.5 → 0.32.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 +10 -0
- package/dist/core/services/mcp.js +1 -1
- package/dist/helpers/buildServerInfo.js +3 -9
- package/dist/index.js +2 -1
- package/dist/modules/mcp/catalogs/builtinCallbacks.js +204 -0
- package/dist/modules/mcp/catalogs/builtinComponents.js +170 -0
- package/dist/modules/mcp/catalogs/builtinElementCallbacks.js +50 -0
- package/dist/modules/mcp/catalogs/builtinTransformers.js +148 -0
- package/dist/modules/mcp/catalogs/builtinUtilities.js +90 -0
- package/dist/modules/mcp/{tools/operations/style → catalogs}/cssCatalog.js +75 -2
- package/dist/modules/mcp/catalogs/observed.js +90 -0
- package/dist/modules/mcp/catalogs/paramSpec.js +69 -0
- package/dist/modules/mcp/catalogs/registry.js +89 -0
- package/dist/modules/mcp/handler.js +12 -2
- package/dist/modules/mcp/helpers/agentPrompt.js +104 -0
- package/dist/modules/mcp/helpers/guide.js +334 -15
- package/dist/modules/mcp/helpers/interactions.js +123 -0
- package/dist/modules/mcp/helpers/log.js +54 -0
- package/dist/modules/mcp/helpers/space.js +158 -33
- package/dist/modules/mcp/helpers/uris.js +44 -0
- package/dist/modules/mcp/resources/canonical.js +6 -21
- package/dist/modules/mcp/resources/core.js +4 -3
- package/dist/modules/mcp/resources/primer.js +13 -8
- package/dist/modules/mcp/resources/register.js +37 -5
- package/dist/modules/mcp/resources/schema.js +30 -20
- package/dist/modules/mcp/resources/style.js +18 -11
- package/dist/modules/mcp/server.js +21 -7
- package/dist/modules/mcp/tools/apply/dispatch.js +38 -18
- package/dist/modules/mcp/tools/apply/index.js +19 -4
- package/dist/modules/mcp/tools/apply/writeResult.js +2 -1
- package/dist/modules/mcp/tools/index.js +1 -1
- package/dist/modules/mcp/tools/operations/index.js +13 -2
- package/dist/modules/mcp/tools/operations/schema/bindings/deleteBinding.js +32 -0
- package/dist/modules/mcp/tools/operations/schema/bindings/patchBinding.js +36 -0
- package/dist/modules/mcp/tools/operations/schema/bindings/upsertBinding.js +47 -0
- package/dist/modules/mcp/tools/operations/schema/{deleteElement.js → elements/deleteElement.js} +10 -6
- package/dist/modules/mcp/tools/operations/schema/{moveElement.js → elements/moveElement.js} +8 -6
- package/dist/modules/mcp/tools/operations/schema/{patchElement.js → elements/patchElement.js} +19 -7
- package/dist/modules/mcp/tools/operations/schema/{upsertElement.js → elements/upsertElement.js} +11 -5
- package/dist/modules/mcp/tools/operations/schema/{deleteFolder.js → folders/deleteFolder.js} +4 -4
- package/dist/modules/mcp/tools/operations/schema/{upsertFolder.js → folders/upsertFolder.js} +4 -4
- package/dist/modules/mcp/tools/operations/schema/interactions/deleteInteraction.js +52 -0
- package/dist/modules/mcp/tools/operations/schema/interactions/patchInteractionNode.js +47 -0
- package/dist/modules/mcp/tools/operations/schema/interactions/upsertInteractionFlow.js +43 -0
- package/dist/modules/mcp/tools/operations/schema/operations.js +25 -11
- package/dist/modules/mcp/tools/operations/schema/{deletePage.js → pages/deletePage.js} +8 -5
- package/dist/modules/mcp/tools/operations/schema/pages/upsertPage.js +75 -0
- package/dist/modules/mcp/tools/operations/schema/settings/patchSettings.js +45 -0
- package/dist/modules/mcp/tools/operations/schema/shared.js +94 -2
- package/dist/modules/mcp/tools/operations/schema/translator.js +77 -10
- package/dist/modules/mcp/tools/operations/schema/{deleteVariable.js → variables/deleteVariable.js} +3 -3
- package/dist/modules/mcp/tools/operations/schema/{upsertVariable.js → variables/upsertVariable.js} +4 -4
- package/dist/modules/mcp/tools/operations/schema/write.js +78 -13
- package/dist/modules/mcp/tools/operations/style/{deleteDefinition.js → definitions/deleteDefinition.js} +4 -3
- package/dist/modules/mcp/tools/operations/style/{patchDefinition.js → definitions/patchDefinition.js} +6 -5
- package/dist/modules/mcp/tools/operations/style/{upsertDefinition.js → definitions/upsertDefinition.js} +5 -4
- package/dist/modules/mcp/tools/operations/style/{deleteGlobalStyle.js → globalStyles/deleteGlobalStyle.js} +4 -3
- package/dist/modules/mcp/tools/operations/style/{patchGlobalStyle.js → globalStyles/patchGlobalStyle.js} +6 -5
- package/dist/modules/mcp/tools/operations/style/{upsertGlobalStyle.js → globalStyles/upsertGlobalStyle.js} +5 -4
- package/dist/modules/mcp/tools/operations/style/idStyles/deleteIdStyle.js +21 -0
- package/dist/modules/mcp/tools/operations/style/idStyles/patchIdStyle.js +28 -0
- package/dist/modules/mcp/tools/operations/style/idStyles/upsertIdStyle.js +24 -0
- package/dist/modules/mcp/tools/operations/style/operations.js +14 -8
- package/dist/modules/mcp/tools/operations/style/translator.js +25 -1
- package/dist/modules/mcp/tools/operations/style/{deleteStyleVariable.js → variables/deleteStyleVariable.js} +4 -4
- package/dist/modules/mcp/tools/operations/style/{upsertStyleVariable.js → variables/upsertStyleVariable.js} +4 -4
- package/dist/modules/mcp/tools/operations/style/write.js +19 -11
- package/dist/modules/mcp/tools/read.js +1 -1
- package/dist/modules/mcp/tools/search.js +34 -27
- package/dist/modules/mcp/tools/shared/validator/audit.js +124 -0
- package/dist/modules/mcp/tools/shared/validator/batch.js +30 -0
- package/dist/modules/mcp/tools/shared/validator/bindings.js +70 -0
- package/dist/modules/mcp/tools/shared/validator/context.js +35 -0
- package/dist/modules/mcp/tools/shared/validator/css.js +47 -0
- package/dist/modules/mcp/tools/shared/validator/elements.js +55 -0
- package/dist/modules/mcp/tools/shared/validator/index.js +226 -0
- package/dist/modules/mcp/tools/shared/validator/interactions.js +106 -0
- package/dist/modules/mcp/tools/shared/validator/refs.js +28 -0
- package/dist/modules/mcp/tools/validate.js +23 -3
- package/dist/modules/ssr/preview.js +1 -1
- package/dist/modules/ssr/views/template.ejs +2 -0
- package/dist/src/index.d.ts +1 -1
- package/dist/src/modules/mcp/catalogs/builtinCallbacks.d.ts +23 -0
- package/dist/src/modules/mcp/catalogs/builtinComponents.d.ts +4 -0
- package/dist/src/modules/mcp/catalogs/builtinElementCallbacks.d.ts +20 -0
- package/dist/src/modules/mcp/catalogs/builtinTransformers.d.ts +28 -0
- package/dist/src/modules/mcp/catalogs/builtinTransformers.test.d.ts +1 -0
- package/dist/src/modules/mcp/catalogs/builtinUtilities.d.ts +18 -0
- package/dist/src/modules/mcp/{tools/operations/style → catalogs}/cssCatalog.d.ts +5 -1
- package/dist/src/modules/mcp/catalogs/index.d.ts +9 -0
- package/dist/src/modules/mcp/catalogs/observed.d.ts +48 -0
- package/dist/src/modules/mcp/catalogs/paramSpec.d.ts +42 -0
- package/dist/src/modules/mcp/catalogs/registry.d.ts +35 -0
- package/dist/src/modules/mcp/handler.d.ts +2 -2
- package/dist/src/modules/mcp/helpers/agentPrompt.d.ts +4 -0
- package/dist/src/modules/mcp/helpers/guide.d.ts +2 -1
- package/dist/src/modules/mcp/helpers/index.d.ts +4 -0
- package/dist/src/modules/mcp/helpers/interactions.d.ts +30 -0
- package/dist/src/modules/mcp/helpers/log.d.ts +8 -0
- package/dist/src/modules/mcp/helpers/log.test.d.ts +1 -0
- package/dist/src/modules/mcp/helpers/space.d.ts +67 -11
- package/dist/src/modules/mcp/helpers/uris.d.ts +28 -0
- package/dist/src/modules/mcp/index.d.ts +1 -1
- package/dist/src/modules/mcp/mcp.bench.d.ts +1 -0
- package/dist/src/modules/mcp/resources/canonical.d.ts +0 -1
- package/dist/src/modules/mcp/resources/index.d.ts +2 -3
- package/dist/src/modules/mcp/resources/primer.d.ts +2 -1
- package/dist/src/modules/mcp/resources/register.d.ts +2 -2
- package/dist/src/modules/mcp/server.d.ts +5 -2
- package/dist/src/modules/mcp/tools/apply/index.d.ts +191 -2
- package/dist/src/modules/mcp/tools/operations/index.d.ts +383 -4
- package/dist/src/modules/mcp/tools/operations/schema/bindings/deleteBinding.d.ts +17 -0
- package/dist/src/modules/mcp/tools/operations/schema/bindings/patchBinding.d.ts +25 -0
- package/dist/src/modules/mcp/tools/operations/schema/bindings/upsertBinding.d.ts +27 -0
- package/dist/src/modules/mcp/tools/operations/schema/{deleteElement.d.ts → elements/deleteElement.d.ts} +2 -2
- package/dist/src/modules/mcp/tools/operations/schema/{moveElement.d.ts → elements/moveElement.d.ts} +2 -2
- package/dist/src/modules/mcp/tools/operations/schema/{patchElement.d.ts → elements/patchElement.d.ts} +7 -2
- package/dist/src/modules/mcp/tools/operations/schema/{upsertElement.d.ts → elements/upsertElement.d.ts} +3 -3
- package/dist/src/modules/mcp/tools/operations/schema/{deleteFolder.d.ts → folders/deleteFolder.d.ts} +2 -2
- package/dist/src/modules/mcp/tools/operations/schema/{upsertFolder.d.ts → folders/upsertFolder.d.ts} +2 -2
- package/dist/src/modules/mcp/tools/operations/schema/index.d.ts +17 -11
- package/dist/src/modules/mcp/tools/operations/schema/interactions/deleteInteraction.d.ts +12 -0
- package/dist/src/modules/mcp/tools/operations/schema/interactions/patchInteractionNode.d.ts +18 -0
- package/dist/src/modules/mcp/tools/operations/schema/interactions/upsertInteractionFlow.d.ts +27 -0
- package/dist/src/modules/mcp/tools/operations/schema/operations.d.ts +131 -0
- package/dist/src/modules/mcp/tools/operations/schema/{deletePage.d.ts → pages/deletePage.d.ts} +2 -2
- package/dist/src/modules/mcp/tools/operations/schema/{upsertPage.d.ts → pages/upsertPage.d.ts} +3 -2
- package/dist/src/modules/mcp/tools/operations/schema/settings/patchSettings.d.ts +34 -0
- package/dist/src/modules/mcp/tools/operations/schema/shared.d.ts +53 -0
- package/dist/src/modules/mcp/tools/operations/schema/translator.d.ts +5 -2
- package/dist/src/modules/mcp/tools/operations/schema/{deleteVariable.d.ts → variables/deleteVariable.d.ts} +2 -2
- package/dist/src/modules/mcp/tools/operations/schema/{upsertVariable.d.ts → variables/upsertVariable.d.ts} +2 -2
- package/dist/src/modules/mcp/tools/operations/schema/write.d.ts +38 -8
- package/dist/src/modules/mcp/tools/operations/style/{deleteDefinition.d.ts → definitions/deleteDefinition.d.ts} +2 -2
- package/dist/src/modules/mcp/tools/operations/style/{patchDefinition.d.ts → definitions/patchDefinition.d.ts} +2 -2
- package/dist/src/modules/mcp/tools/operations/style/{upsertDefinition.d.ts → definitions/upsertDefinition.d.ts} +2 -2
- package/dist/src/modules/mcp/tools/operations/style/{deleteGlobalStyle.d.ts → globalStyles/deleteGlobalStyle.d.ts} +2 -2
- package/dist/src/modules/mcp/tools/operations/style/{patchGlobalStyle.d.ts → globalStyles/patchGlobalStyle.d.ts} +2 -2
- package/dist/src/modules/mcp/tools/operations/style/{upsertGlobalStyle.d.ts → globalStyles/upsertGlobalStyle.d.ts} +2 -2
- package/dist/src/modules/mcp/tools/operations/style/idStyles/deleteIdStyle.d.ts +9 -0
- package/dist/src/modules/mcp/tools/operations/style/idStyles/patchIdStyle.d.ts +37 -0
- package/dist/src/modules/mcp/tools/operations/style/idStyles/upsertIdStyle.d.ts +37 -0
- package/dist/src/modules/mcp/tools/operations/style/index.d.ts +11 -9
- package/dist/src/modules/mcp/tools/operations/style/operations.d.ts +70 -2
- package/dist/src/modules/mcp/tools/operations/style/shared.d.ts +1 -1
- package/dist/src/modules/mcp/tools/operations/style/translator.d.ts +4 -1
- package/dist/src/modules/mcp/tools/operations/style/{deleteStyleVariable.d.ts → variables/deleteStyleVariable.d.ts} +3 -3
- package/dist/src/modules/mcp/tools/operations/style/{upsertStyleVariable.d.ts → variables/upsertStyleVariable.d.ts} +3 -3
- package/dist/src/modules/mcp/tools/operations/style/write.d.ts +2 -7
- package/dist/src/modules/mcp/tools/preview.d.ts +191 -2
- package/dist/src/modules/mcp/tools/screenshot.d.ts +191 -2
- package/dist/src/modules/mcp/tools/shared/validator/audit.d.ts +4 -0
- package/dist/src/modules/mcp/tools/shared/validator/batch.d.ts +5 -0
- package/dist/src/modules/mcp/tools/shared/validator/bindings.d.ts +6 -0
- package/dist/src/modules/mcp/tools/shared/validator/context.d.ts +34 -0
- package/dist/src/modules/mcp/tools/shared/validator/css.d.ts +4 -0
- package/dist/src/modules/mcp/tools/shared/validator/elements.d.ts +6 -0
- package/dist/src/modules/mcp/tools/shared/validator/index.d.ts +8 -0
- package/dist/src/modules/mcp/tools/shared/validator/interactions.d.ts +3 -0
- package/dist/src/modules/mcp/tools/shared/validator/refs.d.ts +4 -0
- package/dist/src/modules/mcp/tools/validate.d.ts +191 -2
- package/dist/src/modules/mcp/types/aiSchema.d.ts +93 -1
- package/package.json +12 -10
- package/dist/modules/mcp/tools/operations/schema/registry.js +0 -55
- package/dist/modules/mcp/tools/operations/schema/upsertPage.js +0 -64
- package/dist/modules/mcp/tools/shared/validator.js +0 -262
- package/dist/src/modules/mcp/tools/operations/schema/registry.d.ts +0 -22
- package/dist/src/modules/mcp/tools/shared/validator.d.ts +0 -4
|
@@ -20,11 +20,14 @@ export interface AIPageSummary {
|
|
|
20
20
|
label: string;
|
|
21
21
|
slug: string;
|
|
22
22
|
default: boolean;
|
|
23
|
+
/** Whether the page is served by the published SDK runtime. A disabled page (`false`) is not routable/accessible
|
|
24
|
+
* to end users, but stays fully editable here. Defaults to true. */
|
|
25
|
+
enabled: boolean;
|
|
23
26
|
/** The ref of the folder this page lives in (a PageFolder id), or undefined for a root-level page. */
|
|
24
27
|
folder?: string;
|
|
25
28
|
elementCount: number;
|
|
26
29
|
}
|
|
27
|
-
/** A page folder in the sidebar tree. `ref` is the folder's id (there is no separate
|
|
30
|
+
/** A page folder in the sidebar tree. `ref` is the folder's id (there is no separate idRef); pages reference it
|
|
28
31
|
* by that id via their `folder`, and nested folders via `parentId`. */
|
|
29
32
|
export interface AIFolder {
|
|
30
33
|
ref: string;
|
|
@@ -37,6 +40,9 @@ export interface AISkeletonNode {
|
|
|
37
40
|
type: string;
|
|
38
41
|
label: string;
|
|
39
42
|
subType?: string;
|
|
43
|
+
/** This element's version — identical to the stateVersion a direct element read or search hit returns for it. Diff
|
|
44
|
+
* it against a version you already hold to re-read (plitzi_read) only the nodes that actually changed. */
|
|
45
|
+
stateVersion?: string;
|
|
40
46
|
/** The class refs this node attaches on its base selector — names only, no CSS. Lets an agent map element →
|
|
41
47
|
* class straight from the page skeleton, without a per-element read just to learn which class it uses. */
|
|
42
48
|
base?: string[];
|
|
@@ -50,6 +56,9 @@ export interface AIPageSkeleton {
|
|
|
50
56
|
label: string;
|
|
51
57
|
slug: string;
|
|
52
58
|
default: boolean;
|
|
59
|
+
/** Whether the page is served by the published SDK runtime. A disabled page (`false`) is not routable/accessible
|
|
60
|
+
* to end users, but stays fully editable here. Defaults to true. */
|
|
61
|
+
enabled: boolean;
|
|
53
62
|
/** Route params bound by the slug (e.g. ":spaceId" → ["spaceId"]). Valid as {{name}} references on this page,
|
|
54
63
|
* alongside the space-level plitzi://schema-variables. */
|
|
55
64
|
routeParams: string[];
|
|
@@ -63,6 +72,53 @@ export interface AIPageStyles {
|
|
|
63
72
|
definitions: AIDefinition[];
|
|
64
73
|
globalStyles: AIGlobalStyle[];
|
|
65
74
|
}
|
|
75
|
+
/** Which variant each attached class/selector currently uses on this element (element.definition.initialState
|
|
76
|
+
* .styleVariant). Outer key = class ref, inner key = selector (`base` or a slot), value = variant name(s). */
|
|
77
|
+
export type AIStyleVariantSelection = Record<string, Record<string, string | string[]>>;
|
|
78
|
+
/** The element's initial (default) state overrides. `styleVariant` picks which variant of its classes is active;
|
|
79
|
+
* `visibility` hides/shows it initially. Kept minimal — the two fields agents actually set. */
|
|
80
|
+
export interface AIInitialState {
|
|
81
|
+
styleVariant?: AIStyleVariantSelection;
|
|
82
|
+
visibility?: boolean;
|
|
83
|
+
}
|
|
84
|
+
/** One data binding: connect a data `source` to the element field named by `to` (a prop, a style value, or an
|
|
85
|
+
* initial-state key, per its category). `transformers` reshape the value; `when` gates the binding. */
|
|
86
|
+
export interface AIBinding {
|
|
87
|
+
id: string;
|
|
88
|
+
to: string;
|
|
89
|
+
source: string;
|
|
90
|
+
transformers?: Array<{
|
|
91
|
+
action: string;
|
|
92
|
+
params: Record<string, string>;
|
|
93
|
+
enabled?: boolean;
|
|
94
|
+
}>;
|
|
95
|
+
when?: unknown;
|
|
96
|
+
enabled?: boolean;
|
|
97
|
+
}
|
|
98
|
+
/** Data bindings on an element, grouped by what they feed: element props (`attributes`), style values (`style`),
|
|
99
|
+
* or initial-state keys (`initialState`). */
|
|
100
|
+
export type AIBindings = Partial<Record<'attributes' | 'style' | 'initialState', AIBinding[]>>;
|
|
101
|
+
export type AIInteractionNodeType = 'trigger' | 'globalCallback' | 'callback' | 'utility';
|
|
102
|
+
/** One step of an interaction flow, projected from the stored doubly-linked node. Order is conveyed by the
|
|
103
|
+
* position in `AIInteractionFlow.nodes`; the stored beforeNode/afterNode/flowId links are computed on write. */
|
|
104
|
+
export interface AIInteractionNode {
|
|
105
|
+
id: string;
|
|
106
|
+
title: string;
|
|
107
|
+
nodeType: AIInteractionNodeType;
|
|
108
|
+
action: string;
|
|
109
|
+
params?: Record<string, unknown>;
|
|
110
|
+
enabled?: boolean;
|
|
111
|
+
when?: unknown;
|
|
112
|
+
/** Source element the callback targets (globalCallback/utility). Defaults to this element on write. */
|
|
113
|
+
elementId?: string;
|
|
114
|
+
preview?: Record<string, unknown>;
|
|
115
|
+
}
|
|
116
|
+
/** One interaction flow on an element: a trigger (first node) followed by the callbacks/utilities it runs, in
|
|
117
|
+
* order. `flowId` equals the trigger node id. */
|
|
118
|
+
export interface AIInteractionFlow {
|
|
119
|
+
flowId: string;
|
|
120
|
+
nodes: AIInteractionNode[];
|
|
121
|
+
}
|
|
66
122
|
export interface AIElementDetail {
|
|
67
123
|
ref: string;
|
|
68
124
|
type: string;
|
|
@@ -81,6 +137,18 @@ export interface AIElementDetail {
|
|
|
81
137
|
/** Global (type 'element') styles that also affect this element because they target its type — every element of
|
|
82
138
|
* the type inherits them. Read-only here (not editable as definitions); shown so the effective CSS is complete. */
|
|
83
139
|
globalStyles?: AIGlobalStyle[];
|
|
140
|
+
/** Id rule (type 'id') targeting this element by its DOM `id` attribute (`#id`). Present only when the element
|
|
141
|
+
* carries an `id` that a rule matches. Edit it with the id-style tools (never as a definition). */
|
|
142
|
+
idStyle?: AIIdStyle;
|
|
143
|
+
/** Variant names each attached class exposes (deduped across its selectors), so the agent knows a class HAS a
|
|
144
|
+
* variant (e.g. a button class with "primary") before applying it via `initialState.styleVariant`. */
|
|
145
|
+
availableVariants?: Record<string, string[]>;
|
|
146
|
+
/** Which variant/visibility this element applies today (element.definition.initialState). */
|
|
147
|
+
initialState?: AIInitialState;
|
|
148
|
+
/** Data bindings on this element, grouped by category. */
|
|
149
|
+
bindings?: AIBindings;
|
|
150
|
+
/** Interaction flows on this element (event → ordered callbacks). */
|
|
151
|
+
interactions?: AIInteractionFlow[];
|
|
84
152
|
childRefs?: string[];
|
|
85
153
|
}
|
|
86
154
|
/** A global element style (a type 'element' StyleItem): its CSS applies to every element whose type equals
|
|
@@ -88,6 +156,12 @@ export interface AIElementDetail {
|
|
|
88
156
|
export interface AIGlobalStyle extends AIDefinition {
|
|
89
157
|
appliesToType: string;
|
|
90
158
|
}
|
|
159
|
+
/** An id rule (a type 'id' StyleItem): its CSS targets the single element whose DOM `id` equals `targetId`
|
|
160
|
+
* (the CSS equivalent of `#id { … }`). Style one element by giving it an `id` attribute and writing this rule;
|
|
161
|
+
* prefer a class definition when the styling could be reused. */
|
|
162
|
+
export interface AIIdStyle extends AIDefinition {
|
|
163
|
+
targetId: string;
|
|
164
|
+
}
|
|
91
165
|
export interface AIDefinitionSlot extends DisplayModeCss {
|
|
92
166
|
states?: Record<string, DisplayModeCss>;
|
|
93
167
|
variants?: Record<string, DisplayModeCss>;
|
|
@@ -118,6 +192,24 @@ export interface AISchemaVariable {
|
|
|
118
192
|
value: string | number | boolean;
|
|
119
193
|
}>;
|
|
120
194
|
}
|
|
195
|
+
/** Space-level settings: the arbitrary global CSS (`customCss`), state persistence, and the user/auth provider
|
|
196
|
+
* configuration. Every field is optional — a patch changes only the keys it sends. */
|
|
197
|
+
export interface AISettings {
|
|
198
|
+
customCss?: string;
|
|
199
|
+
keepState?: boolean;
|
|
200
|
+
stateStorage?: 'localStorage' | 'sessionStorage';
|
|
201
|
+
userProvider?: 'auth0' | 'basic' | 'custom' | '';
|
|
202
|
+
auth0Domain?: string;
|
|
203
|
+
auth0ClientId?: string;
|
|
204
|
+
tokenStorage?: 'localStorage' | 'sessionStorage' | '';
|
|
205
|
+
loginUrl?: string;
|
|
206
|
+
userUrl?: string;
|
|
207
|
+
refreshUrl?: string;
|
|
208
|
+
logoutUrl?: string;
|
|
209
|
+
detailsPath?: string;
|
|
210
|
+
tokenPath?: string;
|
|
211
|
+
expirationTimePath?: string;
|
|
212
|
+
}
|
|
121
213
|
export interface ValidationError {
|
|
122
214
|
path: string;
|
|
123
215
|
message: string;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@plitzi/sdk-server",
|
|
3
|
-
"version": "0.32.
|
|
3
|
+
"version": "0.32.6",
|
|
4
4
|
"license": "AGPL-3.0",
|
|
5
5
|
"files": [
|
|
6
6
|
"dist"
|
|
@@ -23,8 +23,9 @@
|
|
|
23
23
|
"sideEffects": false,
|
|
24
24
|
"dependencies": {
|
|
25
25
|
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
26
|
-
"@plitzi/plitzi-sdk": "0.32.
|
|
27
|
-
"@plitzi/sdk-
|
|
26
|
+
"@plitzi/plitzi-sdk": "0.32.6",
|
|
27
|
+
"@plitzi/sdk-schema": "0.32.6",
|
|
28
|
+
"@plitzi/sdk-shared": "0.32.6",
|
|
28
29
|
"ejs": "^6.0.1",
|
|
29
30
|
"esbuild": "^0.28.1",
|
|
30
31
|
"zod": "^4.4.3"
|
|
@@ -37,15 +38,15 @@
|
|
|
37
38
|
"@types/ejs": "^3.1.5",
|
|
38
39
|
"@types/node": "^26.1.1",
|
|
39
40
|
"@types/react": "^19.2.17",
|
|
40
|
-
"@vitejs/plugin-react": "^6.0.
|
|
41
|
+
"@vitejs/plugin-react": "^6.0.4",
|
|
41
42
|
"@vitest/coverage-v8": "^4.1.10",
|
|
42
|
-
"eslint": "^9.39.
|
|
43
|
+
"eslint": "^9.39.5",
|
|
43
44
|
"eslint-plugin-import": "^2.32.0",
|
|
44
|
-
"react": "^19.2.
|
|
45
|
-
"react-dom": "^19.2.
|
|
46
|
-
"tsx": "^4.23.
|
|
45
|
+
"react": "^19.2.8",
|
|
46
|
+
"react-dom": "^19.2.8",
|
|
47
|
+
"tsx": "^4.23.1",
|
|
47
48
|
"typescript": "^6.0.3",
|
|
48
|
-
"vite": "^8.1.
|
|
49
|
+
"vite": "^8.1.5",
|
|
49
50
|
"vite-plugin-dts": "^5.0.3",
|
|
50
51
|
"vitest": "^4.1.10"
|
|
51
52
|
},
|
|
@@ -59,6 +60,7 @@
|
|
|
59
60
|
"lint": "TIMING=1 eslint ./src",
|
|
60
61
|
"typecheck": "tsc -p tsconfig.app.json --noEmit",
|
|
61
62
|
"test": "vitest run",
|
|
62
|
-
"test:coverage": "vitest run --coverage"
|
|
63
|
+
"test:coverage": "vitest run --coverage",
|
|
64
|
+
"bench": "vitest bench --run"
|
|
63
65
|
}
|
|
64
66
|
}
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
import { cssProperties } from "../style/cssCatalog.js";
|
|
2
|
-
//#region src/modules/mcp/tools/operations/schema/registry.ts
|
|
3
|
-
var EXAMPLE_MAX_LENGTH = 80;
|
|
4
|
-
var isCompactExample = (value) => {
|
|
5
|
-
if (typeof value === "string") return value.length <= EXAMPLE_MAX_LENGTH;
|
|
6
|
-
return typeof value === "number" || typeof value === "boolean";
|
|
7
|
-
};
|
|
8
|
-
var NOTE = "Element types and their props/slots are observed from the elements that already exist in this space — they are ground truth, never inferred. Props list the attribute keys seen on each type with example values. Slots are the styleSelectors keys seen on each type (target them via element.style.slots). CSS in definitions must use the kebab-case keys in cssProperties. Reference schema variables in props via {{name}} and style variables in CSS via var(--name).";
|
|
9
|
-
var buildTypeRegistry = (schema) => {
|
|
10
|
-
const types = {};
|
|
11
|
-
for (const el of Object.values(schema.flat)) {
|
|
12
|
-
const typeName = el.definition.type;
|
|
13
|
-
const info = types[typeName] ??= {
|
|
14
|
-
count: 0,
|
|
15
|
-
subTypes: [],
|
|
16
|
-
slots: [],
|
|
17
|
-
props: {}
|
|
18
|
-
};
|
|
19
|
-
info.count += 1;
|
|
20
|
-
const subType = el.attributes.subType;
|
|
21
|
-
if (typeof subType === "string" && !info.subTypes.includes(subType)) info.subTypes.push(subType);
|
|
22
|
-
for (const slot of Object.keys(el.definition.styleSelectors)) if (!info.slots.includes(slot)) info.slots.push(slot);
|
|
23
|
-
for (const [key, value] of Object.entries(el.attributes)) {
|
|
24
|
-
if (key === "subType") continue;
|
|
25
|
-
const prop = info.props[key] ??= {
|
|
26
|
-
valueTypes: [],
|
|
27
|
-
examples: []
|
|
28
|
-
};
|
|
29
|
-
const valueType = value === null ? "null" : Array.isArray(value) ? "array" : typeof value;
|
|
30
|
-
if (!prop.valueTypes.includes(valueType)) prop.valueTypes.push(valueType);
|
|
31
|
-
if (prop.examples.length < 3 && isCompactExample(value) && value !== "" && !prop.examples.includes(value)) prop.examples.push(value);
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
for (const info of Object.values(types)) {
|
|
35
|
-
info.subTypes.sort();
|
|
36
|
-
info.slots.sort();
|
|
37
|
-
}
|
|
38
|
-
return {
|
|
39
|
-
note: NOTE,
|
|
40
|
-
cssProperties,
|
|
41
|
-
styleVariableCategories: [
|
|
42
|
-
"color",
|
|
43
|
-
"spacing",
|
|
44
|
-
"shadow",
|
|
45
|
-
"custom"
|
|
46
|
-
],
|
|
47
|
-
templateSyntax: {
|
|
48
|
-
schemaVariable: "{{name}}",
|
|
49
|
-
styleVariable: "var(--name)"
|
|
50
|
-
},
|
|
51
|
-
types
|
|
52
|
-
};
|
|
53
|
-
};
|
|
54
|
-
//#endregion
|
|
55
|
-
export { buildTypeRegistry };
|
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
import { findFolderByRef, findPageByRef, generateObjectId } from "../../../helpers/space.js";
|
|
2
|
-
import { empty, fail } from "../../../helpers/opResult.js";
|
|
3
|
-
import { pageUri, pagesUri } from "./write.js";
|
|
4
|
-
import { z } from "zod";
|
|
5
|
-
//#region src/modules/mcp/tools/operations/schema/upsertPage.ts
|
|
6
|
-
var upsertPageOp = z.object({
|
|
7
|
-
type: z.literal("upsertPage"),
|
|
8
|
-
ref: z.string().describe("Page id/slug to update, or a new id you choose to create one"),
|
|
9
|
-
label: z.string().optional(),
|
|
10
|
-
slug: z.string().optional(),
|
|
11
|
-
folder: z.string().nullable().optional().describe("Ref of an existing folder to place this page in; \"\" or null moves it to the root. Unknown → error"),
|
|
12
|
-
default: z.boolean().optional()
|
|
13
|
-
}).describe("Create a page, or update it when ref already exists (only the fields you pass change).");
|
|
14
|
-
var upsertPage = (space, env, op) => {
|
|
15
|
-
let folderValue;
|
|
16
|
-
if (op.folder !== void 0) if (op.folder === null || op.folder === "") folderValue = "";
|
|
17
|
-
else {
|
|
18
|
-
const resolved = findFolderByRef(space.schema, op.folder);
|
|
19
|
-
if (!resolved) return fail("folder", `Folder "${op.folder}" not found`, "Create it with upsertFolder, or read plitzi://folders");
|
|
20
|
-
folderValue = resolved.id;
|
|
21
|
-
}
|
|
22
|
-
const existing = findPageByRef(space.schema, op.ref);
|
|
23
|
-
if (existing) {
|
|
24
|
-
existing.attributes = {
|
|
25
|
-
...existing.attributes,
|
|
26
|
-
...op.slug !== void 0 ? { slug: op.slug } : {},
|
|
27
|
-
...op.label !== void 0 ? { name: op.label } : {},
|
|
28
|
-
...op.default !== void 0 ? { default: op.default } : {},
|
|
29
|
-
...folderValue !== void 0 ? { folder: folderValue } : {}
|
|
30
|
-
};
|
|
31
|
-
return {
|
|
32
|
-
...empty(),
|
|
33
|
-
updated: 1,
|
|
34
|
-
staleResources: [pageUri(env, op.ref), pagesUri(env)]
|
|
35
|
-
};
|
|
36
|
-
}
|
|
37
|
-
const id = generateObjectId();
|
|
38
|
-
const attributes = {
|
|
39
|
-
slug: op.slug ?? "",
|
|
40
|
-
name: op.label ?? op.ref,
|
|
41
|
-
default: op.default ?? false,
|
|
42
|
-
folder: folderValue ?? ""
|
|
43
|
-
};
|
|
44
|
-
space.schema.flat[id] = {
|
|
45
|
-
id,
|
|
46
|
-
attributes,
|
|
47
|
-
definition: {
|
|
48
|
-
rootId: id,
|
|
49
|
-
label: op.label ?? op.ref,
|
|
50
|
-
type: "page",
|
|
51
|
-
items: [],
|
|
52
|
-
styleSelectors: { base: "" },
|
|
53
|
-
aiRef: op.ref
|
|
54
|
-
}
|
|
55
|
-
};
|
|
56
|
-
space.schema.pages.push(id);
|
|
57
|
-
return {
|
|
58
|
-
...empty(),
|
|
59
|
-
created: 1,
|
|
60
|
-
staleResources: [pageUri(env, op.ref), pagesUri(env)]
|
|
61
|
-
};
|
|
62
|
-
};
|
|
63
|
-
//#endregion
|
|
64
|
-
export { upsertPage, upsertPageOp };
|
|
@@ -1,262 +0,0 @@
|
|
|
1
|
-
import { findFolderByRef, findPageByRef, folderAncestorIds, getPageElements, pageFoldersOf, pageRefOf, resolveRef, routeParamNames, slugRouteParams } from "../../helpers/space.js";
|
|
2
|
-
import { expandShorthand, isCssProperty, suggestCssProperty } from "../operations/style/cssCatalog.js";
|
|
3
|
-
import { buildTypeRegistry } from "../operations/schema/registry.js";
|
|
4
|
-
//#region src/modules/mcp/tools/shared/validator.ts
|
|
5
|
-
var REF_RE = /^[a-zA-Z0-9._-]+$/;
|
|
6
|
-
var MAX_OPS = 100;
|
|
7
|
-
var STYLE_CATEGORIES = [
|
|
8
|
-
"color",
|
|
9
|
-
"spacing",
|
|
10
|
-
"shadow",
|
|
11
|
-
"custom"
|
|
12
|
-
];
|
|
13
|
-
var VAR_REF = /\{\{\s*([A-Za-z_][\w.-]*)\s*\}\}/g;
|
|
14
|
-
var CSS_VAR = /var\(\s*--([A-Za-z_][\w-]*)\s*\)/g;
|
|
15
|
-
var RAW_CODE_TYPES = /* @__PURE__ */ new Set([
|
|
16
|
-
"blockJsx",
|
|
17
|
-
"blockHtml",
|
|
18
|
-
"custom"
|
|
19
|
-
]);
|
|
20
|
-
var warnOnce = (ctx, message) => {
|
|
21
|
-
if (!ctx.warned.has(message)) {
|
|
22
|
-
ctx.warned.add(message);
|
|
23
|
-
ctx.warnings.push(message);
|
|
24
|
-
}
|
|
25
|
-
};
|
|
26
|
-
var checkVarRefs = (text, path, ctx) => {
|
|
27
|
-
for (const match of text.matchAll(VAR_REF)) {
|
|
28
|
-
const name = match[1];
|
|
29
|
-
if (!ctx.schemaVars.has(name)) warnOnce(ctx, `Unknown variable {{${name}}} at ${path}: not a space schema variable or a page route param. Read plitzi://schema-variables, or use a route param from the page skeleton (routeParams).`);
|
|
30
|
-
}
|
|
31
|
-
};
|
|
32
|
-
var checkStyleVarRefs = (text, path, ctx) => {
|
|
33
|
-
for (const match of text.matchAll(CSS_VAR)) {
|
|
34
|
-
const name = match[1];
|
|
35
|
-
if (!ctx.styleVars.has(name)) {
|
|
36
|
-
const tokens = [...ctx.styleVars];
|
|
37
|
-
warnOnce(ctx, `Unknown style variable var(--${name}) at ${path}: not a design token in this space. ${tokens.length > 0 ? `Available tokens: ${tokens.slice(0, 30).join(", ")}${tokens.length > 30 ? ", …" : ""}.` : "Read plitzi://style-variables for the valid token names."}`);
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
};
|
|
41
|
-
var checkTypeProps = (type, props, path, ctx) => {
|
|
42
|
-
if (!props || RAW_CODE_TYPES.has(type)) return;
|
|
43
|
-
const known = ctx.typeProps.get(type);
|
|
44
|
-
if (!known || known.size === 0) return;
|
|
45
|
-
for (const key of Object.keys(props)) {
|
|
46
|
-
if (key === "subType" || known.has(key)) continue;
|
|
47
|
-
warnOnce(ctx, `Type "${type}" has no observed prop "${key}" at ${path} (observed: ${[...known].sort().join(", ")}). It may still be valid — verify against plitzi://types.`);
|
|
48
|
-
}
|
|
49
|
-
};
|
|
50
|
-
var checkRef = (ref, path, ctx) => {
|
|
51
|
-
if (!ref || ref.trim().length === 0) {
|
|
52
|
-
ctx.errors.push({
|
|
53
|
-
path,
|
|
54
|
-
message: "Ref must not be empty",
|
|
55
|
-
hint: "Use a semantic name like \"hero.title\""
|
|
56
|
-
});
|
|
57
|
-
return;
|
|
58
|
-
}
|
|
59
|
-
if (!REF_RE.test(ref)) ctx.errors.push({
|
|
60
|
-
path,
|
|
61
|
-
message: `Ref "${ref}" has invalid characters`,
|
|
62
|
-
hint: "Allowed characters: letters, numbers, dot, hyphen, underscore"
|
|
63
|
-
});
|
|
64
|
-
};
|
|
65
|
-
var checkCss = (css, path, ctx) => {
|
|
66
|
-
if (!css) return;
|
|
67
|
-
const declared = {};
|
|
68
|
-
for (const [key, value] of Object.entries(css)) if (value !== null) declared[key] = value;
|
|
69
|
-
for (const [key, value] of Object.entries(expandShorthand(declared))) {
|
|
70
|
-
if (!isCssProperty(key)) {
|
|
71
|
-
const suggestion = suggestCssProperty(key);
|
|
72
|
-
ctx.errors.push({
|
|
73
|
-
path: `${path}.${key}`,
|
|
74
|
-
message: `Unknown CSS property "${key}"`,
|
|
75
|
-
hint: suggestion ? `Use the kebab-case key "${suggestion}"` : "Read plitzi://css-properties for the valid property keys"
|
|
76
|
-
});
|
|
77
|
-
}
|
|
78
|
-
if (typeof value === "string") {
|
|
79
|
-
checkStyleVarRefs(value, `${path}.${key}`, ctx);
|
|
80
|
-
checkVarRefs(value, `${path}.${key}`, ctx);
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
};
|
|
84
|
-
var checkSlotCss = (slot, path, ctx) => {
|
|
85
|
-
checkCss(slot.desktop, `${path}.desktop`, ctx);
|
|
86
|
-
checkCss(slot.tablet, `${path}.tablet`, ctx);
|
|
87
|
-
checkCss(slot.mobile, `${path}.mobile`, ctx);
|
|
88
|
-
for (const [state, dm] of Object.entries(slot.states ?? {})) {
|
|
89
|
-
checkCss(dm.desktop, `${path}.states.${state}.desktop`, ctx);
|
|
90
|
-
checkCss(dm.tablet, `${path}.states.${state}.tablet`, ctx);
|
|
91
|
-
checkCss(dm.mobile, `${path}.states.${state}.mobile`, ctx);
|
|
92
|
-
}
|
|
93
|
-
for (const [name, dm] of Object.entries(slot.variants ?? {})) {
|
|
94
|
-
checkCss(dm.desktop, `${path}.variants.${name}.desktop`, ctx);
|
|
95
|
-
checkCss(dm.tablet, `${path}.variants.${name}.tablet`, ctx);
|
|
96
|
-
checkCss(dm.mobile, `${path}.variants.${name}.mobile`, ctx);
|
|
97
|
-
}
|
|
98
|
-
};
|
|
99
|
-
var checkElementProps = (element, path, ctx) => {
|
|
100
|
-
if (!element.props || RAW_CODE_TYPES.has(element.type)) return;
|
|
101
|
-
for (const [key, value] of Object.entries(element.props)) if (typeof value === "string") checkVarRefs(value, `${path}.props.${key}`, ctx);
|
|
102
|
-
checkTypeProps(element.type, element.props, path, ctx);
|
|
103
|
-
};
|
|
104
|
-
var checkElementInput = (element, path, ctx, seen) => {
|
|
105
|
-
checkRef(element.ref, `${path}.ref`, ctx);
|
|
106
|
-
if (seen.has(element.ref)) ctx.errors.push({
|
|
107
|
-
path: `${path}.ref`,
|
|
108
|
-
message: `Duplicate ref "${element.ref}" in this batch`,
|
|
109
|
-
hint: "Use a unique ref"
|
|
110
|
-
});
|
|
111
|
-
seen.add(element.ref);
|
|
112
|
-
if (!element.type) ctx.errors.push({
|
|
113
|
-
path: `${path}.type`,
|
|
114
|
-
message: "Element type is required",
|
|
115
|
-
hint: "Read plitzi://types for known types"
|
|
116
|
-
});
|
|
117
|
-
else if (!ctx.knownTypes.has(element.type)) ctx.warnings.push(`Type "${element.type}" was not seen in this space; ensure a plugin provides it (${path}.type).`);
|
|
118
|
-
checkElementProps(element, path, ctx);
|
|
119
|
-
element.children?.forEach((child, i) => checkElementInput(child, `${path}.children[${i}]`, ctx, seen));
|
|
120
|
-
};
|
|
121
|
-
var batchDeclaredVars = (ops) => {
|
|
122
|
-
const names = [];
|
|
123
|
-
for (const op of ops) if (op.type === "upsertVariable") names.push(op.name);
|
|
124
|
-
else if (op.type === "upsertPage" && typeof op.slug === "string") names.push(...slugRouteParams(op.slug));
|
|
125
|
-
return names;
|
|
126
|
-
};
|
|
127
|
-
var batchDeclaredPages = (ops) => {
|
|
128
|
-
const refs = /* @__PURE__ */ new Set();
|
|
129
|
-
for (const op of ops) if (op.type === "upsertPage") refs.add(op.ref);
|
|
130
|
-
return refs;
|
|
131
|
-
};
|
|
132
|
-
var batchDeclaredFolders = (ops) => {
|
|
133
|
-
const refs = /* @__PURE__ */ new Set();
|
|
134
|
-
for (const op of ops) if (op.type === "upsertFolder") refs.add(op.ref);
|
|
135
|
-
return refs;
|
|
136
|
-
};
|
|
137
|
-
var validateOperations = (space, ops) => {
|
|
138
|
-
const registry = buildTypeRegistry(space.schema);
|
|
139
|
-
const batchPages = batchDeclaredPages(ops);
|
|
140
|
-
const batchFolders = batchDeclaredFolders(ops);
|
|
141
|
-
const folderRefs = () => pageFoldersOf(space.schema).map((f) => f.id);
|
|
142
|
-
const ctx = {
|
|
143
|
-
errors: [],
|
|
144
|
-
warnings: [],
|
|
145
|
-
warned: /* @__PURE__ */ new Set(),
|
|
146
|
-
knownTypes: new Set(Object.keys(registry.types)),
|
|
147
|
-
typeProps: new Map(Object.entries(registry.types).map(([type, info]) => [type, new Set(Object.keys(info.props))])),
|
|
148
|
-
schemaVars: /* @__PURE__ */ new Set([
|
|
149
|
-
...space.schema.variables.map((v) => v.name),
|
|
150
|
-
...routeParamNames(space.schema),
|
|
151
|
-
...batchDeclaredVars(ops)
|
|
152
|
-
]),
|
|
153
|
-
styleVars: new Set(Object.values(space.style.variables).flatMap((group) => Object.keys(group)))
|
|
154
|
-
};
|
|
155
|
-
if (ops.length > MAX_OPS) ctx.errors.push({
|
|
156
|
-
path: "operations",
|
|
157
|
-
message: `Batch has ${ops.length} operations (max ${MAX_OPS})`,
|
|
158
|
-
hint: `Split into batches of at most ${MAX_OPS}`
|
|
159
|
-
});
|
|
160
|
-
ops.forEach((op, i) => {
|
|
161
|
-
const base = `operations[${i}]`;
|
|
162
|
-
if ((op.type === "upsertElement" || op.type === "patchElement" || op.type === "deleteElement" || op.type === "moveElement") && op.pageRef) {
|
|
163
|
-
if (!findPageByRef(space.schema, op.pageRef) && !batchPages.has(op.pageRef)) {
|
|
164
|
-
const validRefs = getPageElements(space.schema).map(pageRefOf);
|
|
165
|
-
ctx.errors.push({
|
|
166
|
-
path: `${base}.pageRef`,
|
|
167
|
-
message: `Page "${op.pageRef}" does not exist`,
|
|
168
|
-
hint: "Use an existing page ref, or create it with upsertPage earlier in the same batch",
|
|
169
|
-
validValues: validRefs
|
|
170
|
-
});
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
switch (op.type) {
|
|
174
|
-
case "upsertElement":
|
|
175
|
-
checkElementInput(op.element, `${base}.element`, ctx, /* @__PURE__ */ new Set());
|
|
176
|
-
break;
|
|
177
|
-
case "patchElement": {
|
|
178
|
-
checkRef(op.ref, `${base}.ref`, ctx);
|
|
179
|
-
const page = findPageByRef(space.schema, op.pageRef);
|
|
180
|
-
const target = page ? resolveRef(space.schema, page, op.ref) : void 0;
|
|
181
|
-
if (op.props) {
|
|
182
|
-
for (const [key, value] of Object.entries(op.props)) if (typeof value === "string") checkVarRefs(value, `${base}.props.${key}`, ctx);
|
|
183
|
-
if (target && target.id !== page?.id) checkTypeProps(target.definition.type, op.props, base, ctx);
|
|
184
|
-
}
|
|
185
|
-
break;
|
|
186
|
-
}
|
|
187
|
-
case "upsertDefinition":
|
|
188
|
-
case "patchDefinition": {
|
|
189
|
-
const { type, ref, slots, ...slot } = op;
|
|
190
|
-
checkRef(ref, `${base}.ref`, ctx);
|
|
191
|
-
checkSlotCss(slot, base, ctx);
|
|
192
|
-
for (const [slotName, slotDef] of Object.entries(slots ?? {})) checkSlotCss(slotDef, `${base}.slots.${slotName}`, ctx);
|
|
193
|
-
break;
|
|
194
|
-
}
|
|
195
|
-
case "upsertGlobalStyle":
|
|
196
|
-
case "patchGlobalStyle": {
|
|
197
|
-
const { type, componentType, slots, ...slot } = op;
|
|
198
|
-
checkRef(componentType, `${base}.componentType`, ctx);
|
|
199
|
-
checkSlotCss(slot, base, ctx);
|
|
200
|
-
for (const [slotName, slotDef] of Object.entries(slots ?? {})) checkSlotCss(slotDef, `${base}.slots.${slotName}`, ctx);
|
|
201
|
-
break;
|
|
202
|
-
}
|
|
203
|
-
case "deleteGlobalStyle":
|
|
204
|
-
checkRef(op.componentType, `${base}.componentType`, ctx);
|
|
205
|
-
break;
|
|
206
|
-
case "upsertPage":
|
|
207
|
-
checkRef(op.ref, `${base}.ref`, ctx);
|
|
208
|
-
if (typeof op.folder === "string" && op.folder !== "") {
|
|
209
|
-
if (!findFolderByRef(space.schema, op.folder) && !batchFolders.has(op.folder)) ctx.errors.push({
|
|
210
|
-
path: `${base}.folder`,
|
|
211
|
-
message: `Folder "${op.folder}" does not exist`,
|
|
212
|
-
hint: "Create it with upsertFolder earlier in the same batch, or read plitzi://folders for valid refs",
|
|
213
|
-
validValues: folderRefs()
|
|
214
|
-
});
|
|
215
|
-
}
|
|
216
|
-
break;
|
|
217
|
-
case "upsertFolder":
|
|
218
|
-
checkRef(op.ref, `${base}.ref`, ctx);
|
|
219
|
-
if (typeof op.parentId === "string") {
|
|
220
|
-
checkRef(op.parentId, `${base}.parentId`, ctx);
|
|
221
|
-
const parent = findFolderByRef(space.schema, op.parentId);
|
|
222
|
-
if (!parent && !batchFolders.has(op.parentId)) ctx.errors.push({
|
|
223
|
-
path: `${base}.parentId`,
|
|
224
|
-
message: `Parent folder "${op.parentId}" does not exist`,
|
|
225
|
-
hint: "Create the parent with upsertFolder first, or read plitzi://folders for valid refs",
|
|
226
|
-
validValues: folderRefs()
|
|
227
|
-
});
|
|
228
|
-
const selfId = findFolderByRef(space.schema, op.ref)?.id ?? op.ref;
|
|
229
|
-
if ((parent?.id ?? op.parentId) === selfId || parent && folderAncestorIds(pageFoldersOf(space.schema), parent.id).includes(selfId)) ctx.errors.push({
|
|
230
|
-
path: `${base}.parentId`,
|
|
231
|
-
message: `Folder "${op.ref}" cannot be nested under itself or one of its descendants`,
|
|
232
|
-
hint: "Choose a parent that is not this folder or below it"
|
|
233
|
-
});
|
|
234
|
-
}
|
|
235
|
-
break;
|
|
236
|
-
case "deleteDefinition":
|
|
237
|
-
case "deleteFolder":
|
|
238
|
-
case "deletePage":
|
|
239
|
-
case "upsertVariable":
|
|
240
|
-
case "deleteVariable":
|
|
241
|
-
checkRef("ref" in op ? op.ref : op.name, `${base}.${"ref" in op ? "ref" : "name"}`, ctx);
|
|
242
|
-
break;
|
|
243
|
-
case "upsertStyleVariable":
|
|
244
|
-
case "deleteStyleVariable":
|
|
245
|
-
if (!STYLE_CATEGORIES.includes(op.category)) ctx.errors.push({
|
|
246
|
-
path: `${base}.category`,
|
|
247
|
-
message: `Unknown style-variable category "${op.category}"`,
|
|
248
|
-
hint: "Use one of the valid categories",
|
|
249
|
-
validValues: STYLE_CATEGORIES
|
|
250
|
-
});
|
|
251
|
-
break;
|
|
252
|
-
default: break;
|
|
253
|
-
}
|
|
254
|
-
});
|
|
255
|
-
return {
|
|
256
|
-
valid: ctx.errors.length === 0,
|
|
257
|
-
errors: ctx.errors,
|
|
258
|
-
warnings: ctx.warnings
|
|
259
|
-
};
|
|
260
|
-
};
|
|
261
|
-
//#endregion
|
|
262
|
-
export { validateOperations };
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import { Schema } from '@plitzi/sdk-shared';
|
|
2
|
-
export interface TypePropInfo {
|
|
3
|
-
valueTypes: string[];
|
|
4
|
-
examples: unknown[];
|
|
5
|
-
}
|
|
6
|
-
export interface TypeInfo {
|
|
7
|
-
count: number;
|
|
8
|
-
subTypes: string[];
|
|
9
|
-
slots: string[];
|
|
10
|
-
props: Record<string, TypePropInfo>;
|
|
11
|
-
}
|
|
12
|
-
export interface TypeRegistry {
|
|
13
|
-
note: string;
|
|
14
|
-
cssProperties: string[];
|
|
15
|
-
styleVariableCategories: string[];
|
|
16
|
-
templateSyntax: {
|
|
17
|
-
schemaVariable: string;
|
|
18
|
-
styleVariable: string;
|
|
19
|
-
};
|
|
20
|
-
types: Record<string, TypeInfo>;
|
|
21
|
-
}
|
|
22
|
-
export declare const buildTypeRegistry: (schema: Schema) => TypeRegistry;
|