@plitzi/sdk-shared 0.33.2 → 0.34.1
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 +64 -0
- package/dist/actions/cron.d.ts +34 -0
- package/dist/actions/cron.mjs +72 -0
- package/dist/actions/index.d.ts +6 -0
- package/dist/actions/index.mjs +5 -0
- package/dist/actions/triggerParams.d.ts +41 -0
- package/dist/actions/triggerParams.mjs +40 -0
- package/dist/actions/triggers.d.ts +29 -0
- package/dist/actions/triggers.mjs +4 -0
- package/dist/actions/validateDocument.d.ts +23 -0
- package/dist/actions/validateDocument.mjs +267 -0
- package/dist/auth/failureChannel.d.ts +9 -4
- package/dist/auth/failureChannel.mjs +3 -2
- package/dist/authoring/builder.d.ts +51 -0
- package/dist/authoring/builder.mjs +29 -0
- package/dist/authoring/declare.d.ts +64 -0
- package/dist/authoring/declare.mjs +4 -0
- package/dist/authoring/elementCallbacks.d.ts +13 -0
- package/dist/authoring/elementCallbacks.mjs +71 -0
- package/dist/authoring/index.d.ts +21 -0
- package/dist/authoring/index.mjs +6 -0
- package/dist/authoring/paramSpec.d.ts +51 -0
- package/dist/authoring/paramSpec.mjs +40 -0
- package/dist/authoring/spaceCallbacks.d.ts +10 -0
- package/dist/authoring/spaceCallbacks.mjs +51 -0
- package/dist/builder/contexts/BuilderContext.d.ts +2 -4
- package/dist/dataSource/getBindingsDetails.mjs +1 -1
- package/dist/dataSource/helpers/getSourceName.d.ts +1 -3
- package/dist/dataSource/helpers/getSourceName.mjs +1 -1
- package/dist/dataSource/index.d.ts +2 -0
- package/dist/dataSource/index.mjs +6 -5
- package/dist/dataSource/resolveVariables.d.ts +22 -0
- package/dist/dataSource/resolveVariables.mjs +16 -0
- package/dist/dataSource/utility/index.mjs +15 -13
- package/dist/dataSource/utility/not.d.ts +11 -0
- package/dist/dataSource/utility/not.mjs +15 -0
- package/dist/devTools/debugCookie.d.ts +16 -0
- package/dist/devTools/debugCookie.mjs +7 -0
- package/dist/devTools/index.d.ts +6 -2
- package/dist/devTools/index.mjs +4 -2
- package/dist/devTools/interactionLog.d.ts +14 -0
- package/dist/devTools/interactionLog.mjs +4 -0
- package/dist/helpers/index.d.ts +2 -0
- package/dist/helpers/index.mjs +11 -9
- package/dist/helpers/reducerOrigin.d.ts +15 -0
- package/dist/helpers/reducerOrigin.mjs +4 -0
- package/dist/helpers/ruleEvaluator.d.ts +14 -0
- package/dist/helpers/ruleEvaluator.mjs +5 -0
- package/dist/helpers/twigWrapper/AST.d.ts +12 -1
- package/dist/helpers/twigWrapper/AST.mjs +0 -0
- package/dist/helpers/twigWrapper/Evaluator/Evaluator.mjs +7 -0
- package/dist/helpers/twigWrapper/Parser/Cursor.d.ts +7 -0
- package/dist/helpers/twigWrapper/Parser/Cursor.mjs +5 -0
- package/dist/helpers/twigWrapper/Parser/ExpressionParser.mjs +46 -8
- package/dist/helpers/twigWrapper/Parser/types.mjs +0 -0
- package/dist/helpers/twigWrapper/charClass.d.ts +7 -0
- package/dist/helpers/twigWrapper/charClass.mjs +16 -12
- package/dist/helpers/twigWrapper/tokens/tokenPatterns.mjs +2 -2
- package/dist/helpers/utils.d.ts +0 -2
- package/dist/helpers/utils.mjs +16 -19
- package/dist/hooks/index.d.ts +2 -1
- package/dist/hooks/index.mjs +4 -3
- package/dist/hooks/useFontHead.d.ts +3 -0
- package/dist/hooks/useFontHead.mjs +23 -0
- package/dist/hooks/usePlitziServiceContext.d.ts +3 -2
- package/dist/index.mjs +61 -45
- package/dist/navigation/index.d.ts +1 -1
- package/dist/navigation/index.mjs +2 -2
- package/dist/navigation/routes.d.ts +8 -0
- package/dist/navigation/routes.mjs +39 -39
- package/dist/network/graphql/builder/Mutations/Segment/SegmentAddMutation.mjs +0 -1
- package/dist/network/graphql/builder/Mutations/Segment/SegmentAddTemplateMutation.mjs +0 -1
- package/dist/network/graphql/builder/Mutations/Segment/SegmentUpdateMutation.mjs +0 -1
- package/dist/network/graphql/builder/Mutations/Segment/space/elements/SegmentAddElementMutation.mjs +0 -1
- package/dist/network/graphql/builder/Mutations/Segment/space/elements/SegmentCloneElementMutation.mjs +0 -1
- package/dist/network/graphql/builder/Mutations/Segment/space/elements/SegmentMoveElementMutation.mjs +0 -1
- package/dist/network/graphql/builder/Mutations/Segment/space/elements/SegmentRemoveElementMutation.mjs +0 -1
- package/dist/network/graphql/builder/Mutations/Segment/space/elements/SegmentRenameElementMutation.d.ts +3 -0
- package/dist/network/graphql/builder/Mutations/Segment/space/elements/SegmentRenameElementMutation.mjs +9 -0
- package/dist/network/graphql/builder/Mutations/Segment/space/elements/SegmentUpdateElementMutation.mjs +0 -1
- package/dist/network/graphql/builder/Mutations/Segment/space/elements/SegmentUpdateElementsMutation.mjs +0 -1
- package/dist/network/graphql/builder/Mutations/Space/SpaceAddElementMutation.mjs +0 -1
- package/dist/network/graphql/builder/Mutations/Space/SpaceAddTemplateMutation.mjs +0 -1
- package/dist/network/graphql/builder/Mutations/Space/SpaceCloneElementMutation.mjs +0 -1
- package/dist/network/graphql/builder/Mutations/Space/SpaceMoveElementMutation.mjs +0 -1
- package/dist/network/graphql/builder/Mutations/Space/SpaceRemoveElementMutation.mjs +0 -1
- package/dist/network/graphql/builder/Mutations/Space/SpaceRenameElementMutation.d.ts +5 -0
- package/dist/network/graphql/builder/Mutations/Space/SpaceRenameElementMutation.mjs +9 -0
- package/dist/network/graphql/builder/Mutations/Space/SpaceUpdateElementMutation.mjs +0 -1
- package/dist/network/graphql/builder/Mutations/Space/SpaceUpdateElementsMutation.mjs +0 -1
- package/dist/network/graphql/builder/Mutations/Space/SpaceUpdateMutation.mjs +0 -1
- package/dist/network/graphql/builder/Mutations/Space/SpaceUpdateSchemaMutation.mjs +0 -1
- package/dist/network/graphql/builder/Mutations/Space/actions/SpaceAddActionMutation.d.ts +8 -0
- package/dist/network/graphql/builder/Mutations/Space/actions/SpaceAddActionMutation.mjs +16 -0
- package/dist/network/graphql/builder/Mutations/Space/actions/SpaceRemoveActionMutation.d.ts +4 -0
- package/dist/network/graphql/builder/Mutations/Space/actions/SpaceRemoveActionMutation.mjs +16 -0
- package/dist/network/graphql/builder/Mutations/Space/actions/SpaceRunActionMutation.d.ts +4 -0
- package/dist/network/graphql/builder/Mutations/Space/actions/SpaceRunActionMutation.mjs +14 -0
- package/dist/network/graphql/builder/Mutations/Space/actions/SpaceUpdateActionMutation.d.ts +4 -0
- package/dist/network/graphql/builder/Mutations/Space/actions/SpaceUpdateActionMutation.mjs +16 -0
- package/dist/network/graphql/builder/Mutations/Space/pages/SpaceAddPageMutation.mjs +2 -3
- package/dist/network/graphql/builder/Mutations/Space/pages/SpaceUpdatePageMutation.mjs +0 -1
- package/dist/network/graphql/builder/Mutations/Style/fonts/StyleAddFontMutation.d.ts +2 -0
- package/dist/network/graphql/builder/Mutations/Style/fonts/StyleAddFontMutation.mjs +11 -0
- package/dist/network/graphql/builder/Mutations/Style/fonts/StyleRemoveFontMutation.d.ts +2 -0
- package/dist/network/graphql/builder/Mutations/Style/fonts/StyleRemoveFontMutation.mjs +11 -0
- package/dist/network/graphql/builder/Mutations/Style/fonts/StyleUpdateFontMutation.d.ts +2 -0
- package/dist/network/graphql/builder/Mutations/Style/fonts/StyleUpdateFontMutation.mjs +11 -0
- package/dist/network/graphql/builder/Mutations/index.d.ts +24 -0
- package/dist/network/graphql/builder/Mutations/index.mjs +150 -132
- package/dist/network/graphql/builder/Queries/InitQuery.mjs +1 -2
- package/dist/network/graphql/builder/Queries/Segment/SegmentQuery.mjs +0 -1
- package/dist/network/graphql/builder/Queries/Segment/SegmentsQuery.mjs +0 -1
- package/dist/network/graphql/builder/Queries/Space/SpaceActionEventsQuery.d.ts +9 -0
- package/dist/network/graphql/builder/Queries/Space/SpaceActionEventsQuery.mjs +30 -0
- package/dist/network/graphql/builder/Queries/Space/SpaceActionTasksQuery.d.ts +6 -0
- package/dist/network/graphql/builder/Queries/Space/SpaceActionTasksQuery.mjs +16 -0
- package/dist/network/graphql/builder/Queries/Space/SpaceActionsQuery.d.ts +9 -0
- package/dist/network/graphql/builder/Queries/Space/SpaceActionsQuery.mjs +25 -0
- package/dist/network/graphql/builder/Queries/Space/SpaceCheckActionQuery.d.ts +6 -0
- package/dist/network/graphql/builder/Queries/Space/SpaceCheckActionQuery.mjs +17 -0
- package/dist/network/graphql/builder/Queries/Space/SpaceQuotaQuery.d.ts +30 -0
- package/dist/network/graphql/builder/Queries/Space/SpaceQuotaQuery.mjs +40 -0
- package/dist/network/graphql/builder/Queries/index.d.ts +16 -0
- package/dist/network/graphql/builder/Queries/index.mjs +24 -14
- package/dist/network/graphql/sdk/Queries/InitQuery.d.ts +4 -0
- package/dist/network/graphql/sdk/Queries/InitQuery.mjs +5 -2
- package/dist/network/graphql/sdk/Queries/Segment/SegmentQuery.mjs +0 -1
- package/dist/network/graphql/sdk/Queries/Segment/SegmentsQuery.mjs +0 -1
- package/dist/network/spaceEvents.d.ts +20 -1
- package/dist/network/spaceEvents.mjs +89 -74
- package/dist/schema/index.d.ts +1 -0
- package/dist/schema/index.mjs +2 -1
- package/dist/schema/serverElements.d.ts +16 -0
- package/dist/schema/serverElements.mjs +18 -0
- package/dist/server/actions/useActionsSync.d.ts +10 -0
- package/dist/server/actions/useActionsSync.mjs +7 -0
- package/dist/server/index.d.ts +2 -1
- package/dist/server/index.mjs +5 -4
- package/dist/server/rsc/refreshRsc.d.ts +11 -1
- package/dist/server/rsc/refreshRsc.mjs +30 -12
- package/dist/server/rsc/useRscSync.mjs +20 -13
- package/dist/state/runtimeStatePersist.mjs +4 -3
- package/dist/store/actionRuns/actionRunsRecorder.d.ts +36 -0
- package/dist/store/actionRuns/actionRunsRecorder.mjs +39 -0
- package/dist/store/actionRuns/actionRunsStore.d.ts +16 -0
- package/dist/store/actionRuns/actionRunsStore.mjs +5 -0
- package/dist/store/actionRuns/index.d.ts +6 -0
- package/dist/store/actionRuns/index.mjs +4 -0
- package/dist/store/actionRuns/useActionRuns.d.ts +13 -0
- package/dist/store/actionRuns/useActionRuns.mjs +10 -0
- package/dist/store/index.d.ts +46 -45
- package/dist/store/index.mjs +6 -3
- package/dist/store/renderSettings.d.ts +3 -0
- package/dist/store/renderSettings.mjs +17 -5
- package/dist/store/tracing/tracingCollector.d.ts +1 -1
- package/dist/store/tracing/tracingCollector.mjs +37 -35
- package/dist/store/tracing/tracingStore.d.ts +13 -0
- package/dist/store/tracing/tracingStore.mjs +3 -3
- package/dist/style/fontAssets.d.ts +12 -0
- package/dist/style/fontAssets.mjs +18 -0
- package/dist/style/fontValidation.d.ts +8 -0
- package/dist/style/fontValidation.mjs +107 -0
- package/dist/style/fonts.d.ts +74 -0
- package/dist/style/fonts.mjs +198 -0
- package/dist/style/fontsFromCss.d.ts +27 -0
- package/dist/style/fontsFromCss.mjs +43 -0
- package/dist/style/index.d.ts +4 -0
- package/dist/style/index.mjs +5 -1
- package/dist/style/styleConstants.d.ts +2 -2
- package/dist/style/styleConstants.mjs +1 -0
- package/dist/theme/ThemeProvider.d.ts +36 -6
- package/dist/theme/ThemeProvider.mjs +49 -35
- package/dist/theme/ThemeScope.d.ts +16 -0
- package/dist/theme/ThemeScope.mjs +6 -0
- package/dist/theme/index.d.ts +7 -1
- package/dist/theme/index.mjs +6 -2
- package/dist/theme/themeCookie.d.ts +30 -0
- package/dist/theme/themeCookie.mjs +24 -0
- package/dist/theme/themeStore.d.ts +40 -0
- package/dist/theme/themeStore.mjs +17 -0
- package/dist/theme/useTheme.d.ts +29 -0
- package/dist/theme/useTheme.mjs +20 -0
- package/dist/types/ActionTypes.d.ts +396 -0
- package/dist/types/ActionTypes.mjs +0 -0
- package/dist/types/AuthTypes.d.ts +23 -2
- package/dist/types/BuilderTypes.d.ts +0 -12
- package/dist/types/CommonTypes.d.ts +13 -0
- package/dist/types/DevToolsTypes.d.ts +57 -14
- package/dist/types/EventBridgeTypes.d.ts +1 -1
- package/dist/types/InteractionTypes.d.ts +23 -3
- package/dist/types/PluginTypes.d.ts +0 -3
- package/dist/types/SchemaTypes.d.ts +29 -4
- package/dist/types/ServerTypes.d.ts +390 -46
- package/dist/types/SpaceTypes.d.ts +16 -0
- package/dist/types/StoreTypes.d.ts +181 -3
- package/dist/types/StyleTypes.d.ts +83 -4
- package/dist/types/TemplateTypes.d.ts +20 -0
- package/dist/types/TemplateTypes.mjs +0 -0
- package/dist/types/ThemeTypes.d.ts +28 -1
- package/dist/types/index.d.ts +2 -0
- package/eslint.config.mjs +2 -0
- package/package.json +244 -29
- package/vite.config.ts +27 -7
|
@@ -1,8 +1,9 @@
|
|
|
1
|
+
import { ActionEntry, ActionLimits, ActionRejectReason, ActionRejectRecord, ActionRunRecord, ActionRunStatus, ActionTaskDescriptor, ActionTriggerType } from './ActionTypes';
|
|
1
2
|
import { Environment } from './CommonTypes';
|
|
2
3
|
import { ConnectorEntry } from './ConnectorTypes';
|
|
3
4
|
import { Schema } from './SchemaTypes';
|
|
4
5
|
import { AnalyticsConfig, OfflineDataRaw } from './SdkTypes';
|
|
5
|
-
import { Style } from './StyleTypes';
|
|
6
|
+
import { FontHead, Style } from './StyleTypes';
|
|
6
7
|
import { IncomingHttpHeaders } from 'node:http';
|
|
7
8
|
import { FC } from 'react';
|
|
8
9
|
export type ServerEnvironment = 'development' | 'production' | 'staging' | 'local';
|
|
@@ -33,7 +34,11 @@ export type SSRResponseHelpers = {
|
|
|
33
34
|
* several, and collapsing them into one string would produce a single malformed cookie. */
|
|
34
35
|
setHeader: (name: string, value: string | string[]) => void;
|
|
35
36
|
setStatus: (code: number) => void;
|
|
36
|
-
|
|
37
|
+
/**
|
|
38
|
+
* A `Buffer` is sent byte for byte and never compressed: it is how a binary reaches the wire — a font file, an
|
|
39
|
+
* image — and what it holds is usually compressed already. A string keeps the encoding negotiation.
|
|
40
|
+
*/
|
|
41
|
+
send: (body: string | Buffer) => void;
|
|
37
42
|
write: (chunk: string | Buffer) => void;
|
|
38
43
|
end: () => void;
|
|
39
44
|
};
|
|
@@ -46,7 +51,18 @@ export type SSRCredential = {
|
|
|
46
51
|
provider: string;
|
|
47
52
|
data: unknown;
|
|
48
53
|
};
|
|
49
|
-
|
|
54
|
+
/**
|
|
55
|
+
* How a plugin's build reaches the page.
|
|
56
|
+
*
|
|
57
|
+
* `copy`, `compile` and `download` all end with a file on this server's disk, which is also what lets the SSR
|
|
58
|
+
* render import the component and put its output in the HTML. `cdn` deliberately does not: the published URL is
|
|
59
|
+
* handed straight to the browser and the plugin renders on the client only.
|
|
60
|
+
*
|
|
61
|
+
* That trade is worth taking for a plugin this server did not build. Importing a third-party bundle into the
|
|
62
|
+
* render process means the bundle's own copy of React runs inside the renderer, and two copies of React is an
|
|
63
|
+
* invalid hook call — a crash that takes the whole page down rather than the one component.
|
|
64
|
+
*/
|
|
65
|
+
export type PluginAction = 'copy' | 'compile' | 'download' | 'cdn';
|
|
50
66
|
export type PluginSourceFile<T = Record<string, unknown>> = {
|
|
51
67
|
js: string;
|
|
52
68
|
css?: string;
|
|
@@ -74,9 +90,19 @@ export type PluginEntry = {
|
|
|
74
90
|
filePath?: string;
|
|
75
91
|
css?: string;
|
|
76
92
|
props: Record<string, unknown>;
|
|
93
|
+
/**
|
|
94
|
+
* Whether the SSR render actually included this plugin's own output.
|
|
95
|
+
*
|
|
96
|
+
* False for a plugin served straight from its CDN, and for one whose server-side import failed. Either way the
|
|
97
|
+
* client must not render it on the hydration pass: the markup would not be in the document React is hydrating
|
|
98
|
+
* against, and the mismatch throws away the whole tree it happens in.
|
|
99
|
+
*/
|
|
100
|
+
ssr?: boolean;
|
|
77
101
|
};
|
|
78
102
|
export type SSRTemplateProps = {
|
|
79
103
|
title?: string;
|
|
104
|
+
/** Meta description for the document, and the share-preview text derived from it. */
|
|
105
|
+
description?: string;
|
|
80
106
|
jsPath?: string;
|
|
81
107
|
cssPath?: string;
|
|
82
108
|
builderJsPath?: string;
|
|
@@ -90,15 +116,52 @@ export type SSRTemplateProps = {
|
|
|
90
116
|
/** When true the client-side <script> block is omitted — useful for inspecting raw SSR HTML. */
|
|
91
117
|
ssrOnly?: boolean;
|
|
92
118
|
debugMode?: boolean;
|
|
119
|
+
/**
|
|
120
|
+
* The theme class this document wears on `<html>` — `dark`, `light`, or nothing at all.
|
|
121
|
+
*
|
|
122
|
+
* The theme is kept in a cookie, so the server that renders the document already knows it: the page arrives
|
|
123
|
+
* painted correctly, with no blocking script in the head and no first paint in the other theme. Empty is not a
|
|
124
|
+
* failure — it is `system`, and the stylesheet's `prefers-color-scheme` queries answer it.
|
|
125
|
+
*/
|
|
126
|
+
themeClass?: string;
|
|
127
|
+
/**
|
|
128
|
+
* The document's web fonts: `fontsToHead(style.fonts, ...)` from this package.
|
|
129
|
+
*
|
|
130
|
+
* In the template rather than left to the SDK because a page paints before its JavaScript exists. A face
|
|
131
|
+
* requested at hydration arrives after the text it is for has already been drawn in a fallback, which is a
|
|
132
|
+
* reflow the visitor watches happen.
|
|
133
|
+
*/
|
|
134
|
+
fonts?: FontHead;
|
|
135
|
+
};
|
|
136
|
+
/**
|
|
137
|
+
* How a store-relative font path becomes a URL a browser can fetch.
|
|
138
|
+
*
|
|
139
|
+
* A space's manifest stores paths, never absolute URLs: the same space is rendered by Plitzi's cloud from a CDN,
|
|
140
|
+
* by a self-hosted server from its own disk, and by a static export from wherever it was published to. Baking one
|
|
141
|
+
* of those origins into the document would send every other deployment asking Plitzi for its customer's fonts.
|
|
142
|
+
*/
|
|
143
|
+
export type SSRFontsConfig = {
|
|
144
|
+
/** Prefix joined to each path, e.g. `/fonts` or `https://cdn.example.com/fonts`. Default: `/fonts`. */
|
|
145
|
+
baseUrl?: string;
|
|
146
|
+
/**
|
|
147
|
+
* A directory this server serves the uploaded files from, under `/fonts/*`.
|
|
148
|
+
*
|
|
149
|
+
* The self-hosting answer, and the reason `baseUrl` defaults to a path rather than an origin: with a directory
|
|
150
|
+
* here a deployment needs no object storage, no credentials and no network to serve its customers' fonts. A
|
|
151
|
+
* cloud deployment leaves it out and points `baseUrl` at its CDN instead.
|
|
152
|
+
*/
|
|
153
|
+
dir?: string;
|
|
93
154
|
};
|
|
94
155
|
export type SSRPlugin = {
|
|
95
156
|
component: FC;
|
|
96
157
|
props: Record<string, unknown>;
|
|
97
158
|
};
|
|
98
159
|
/** What a space token is worth. `render` is the public credential every published site embeds — it is readable
|
|
99
|
-
* by anyone who views the page, so it may only read
|
|
100
|
-
*
|
|
101
|
-
|
|
160
|
+
* by anyone who views the page, so it may only read, and only from the origins it declares. `host` is that same
|
|
161
|
+
* read access for a SERVER that renders the space as its own (self-hosting): secret rather than published, since
|
|
162
|
+
* a server has no browser origin for the allowlist to check. `agent` is the delegated grant an MCP connector
|
|
163
|
+
* receives after a member consents, and is the only bearer that may write without a session behind it. */
|
|
164
|
+
export type SpaceScope = 'render' | 'agent' | 'host';
|
|
102
165
|
/** A resolved space token: which space, what the bearer may do, and (for `agent`) the member who consented.
|
|
103
166
|
* `canWrite` is computed by the consumer from its own authorization model — the MCP never derives it. */
|
|
104
167
|
export type SSRGrant = {
|
|
@@ -220,9 +283,9 @@ export type SSRAdapters = {
|
|
|
220
283
|
/** Which space, environment and revision a request resolves to. Optional here for the same reason as
|
|
221
284
|
* `getOfflineData`: MCP resolves its space from the request token (`getGrant`), never from the host. */
|
|
222
285
|
getSpaceDeployment?: (req: SSRRequest) => Promise<SSRSpaceDeployment>;
|
|
223
|
-
/** Persist a space mutated by the mcp-ai `apply` tool
|
|
224
|
-
*
|
|
225
|
-
* `
|
|
286
|
+
/** Persist a space mutated by the mcp-ai `apply` tool — store it as given; derived caches (notably `style.cache`)
|
|
287
|
+
* arrive already compiled. When omitted, mcp-ai runs read/preview/validate only and `apply` reports
|
|
288
|
+
* `persisted: false`. */
|
|
226
289
|
saveOfflineData?: (spaceId: number, environment: string, data: OfflineDataRaw) => Promise<void>;
|
|
227
290
|
/** Resolve the grant the MCP request operates under, from the verified `Authorization` bearer. The consumer
|
|
228
291
|
* owns the JWT secret and the authorization model, so it decides here; the MCP service stays stateless.
|
|
@@ -249,10 +312,25 @@ export type SSRAdapters = {
|
|
|
249
312
|
saveConnector?: (spaceId: number, entry: ConnectorEntry) => Promise<void>;
|
|
250
313
|
/** Remove one connector by its identifier. Omitted alongside `saveConnector` for a read-only deployment. */
|
|
251
314
|
deleteConnector?: (spaceId: number, connectorId: string) => Promise<void>;
|
|
315
|
+
/** Read every server action configured for the space, so the MCP can list them and author flows against them.
|
|
316
|
+
* Space-level server-side state like connectors: the documents name credentials, connectors and steps, so this
|
|
317
|
+
* must never feed a browser payload. When omitted, the MCP's action resource is empty. */
|
|
318
|
+
getActions?: (spaceId: number) => Promise<ActionEntry[] | undefined>;
|
|
319
|
+
/** The server tasks a flow can be built from — what THIS deployment can run, which is the SDK's built-ins plus
|
|
320
|
+
* whatever tasks it registered. Shaped as `ActionTaskDescriptor` in `@plitzi/sdk-server/actions`. Without it an
|
|
321
|
+
* agent authoring an action is guessing at the step vocabulary. */
|
|
322
|
+
getActionTasks?: (spaceId: number) => Promise<ActionTaskDescriptor[] | undefined>;
|
|
323
|
+
/** Create or replace one action, keyed by `entry.id`. When omitted, action ops apply in memory only and `apply`
|
|
324
|
+
* reports `persisted: false`. */
|
|
325
|
+
saveAction?: (spaceId: number, entry: ActionEntry) => Promise<void>;
|
|
326
|
+
/** Remove one action by its identifier. Omitted alongside `saveAction` for a read-only deployment. */
|
|
327
|
+
deleteAction?: (spaceId: number, actionId: string) => Promise<void>;
|
|
252
328
|
/** Persist the element schema mutated by the MCP `apply` tool. When omitted, `apply` reports `persisted: false`. */
|
|
253
329
|
saveSchema?: (spaceId: number, environment: Environment, schema: Schema) => Promise<void>;
|
|
254
|
-
/** Persist the style document mutated by the MCP `apply` tool
|
|
255
|
-
*
|
|
330
|
+
/** Persist the style document mutated by the MCP `apply` tool — store it as given. `style.cache` arrives already
|
|
331
|
+
* compiled: the renderer serves that string and nothing else, so recomputing it is not a detail to delegate, and
|
|
332
|
+
* asking every deployment to remember it was one bug each of them could write alone. When omitted, `apply`
|
|
333
|
+
* reports `persisted: false`. */
|
|
256
334
|
saveStyle?: (spaceId: number, environment: Environment, style: Style) => Promise<void>;
|
|
257
335
|
/** Who this request carries, if anyone. The adapter reads the credential and resolves it; the cookie it arrived
|
|
258
336
|
* in was written by the server, from {@link SSRAuthCookie}. */
|
|
@@ -363,17 +441,130 @@ export interface SSRRscContext {
|
|
|
363
441
|
*/
|
|
364
442
|
loadOfflineData: () => Promise<OfflineDataRaw | undefined>;
|
|
365
443
|
}
|
|
444
|
+
/**
|
|
445
|
+
* Which published version of a space is asking.
|
|
446
|
+
*
|
|
447
|
+
* Absent means the live one — the document the builder edits. Present means a page PUBLISHED at that revision,
|
|
448
|
+
* which must read the private documents it was published against: a page shipped yesterday running whatever the
|
|
449
|
+
* action says today, or reading through a manifest since pointed at a different API, is the discrepancy
|
|
450
|
+
* versioning exists to remove.
|
|
451
|
+
*
|
|
452
|
+
* One type for actions and connectors, because it is one concept: a version of a space.
|
|
453
|
+
*/
|
|
454
|
+
export type SpaceRevision = {
|
|
455
|
+
environment: Environment;
|
|
456
|
+
revision: number;
|
|
457
|
+
};
|
|
458
|
+
/**
|
|
459
|
+
* How the server reaches a space's actions, and what it may run.
|
|
460
|
+
*
|
|
461
|
+
* Typed loosely for the same reason `ConnectorLookupsConfig` is — the document is executed by
|
|
462
|
+
* `@plitzi/sdk-server`'s actions module and the shared types stay free of its internals. Shaped as `ActionLookups`
|
|
463
|
+
* there.
|
|
464
|
+
*/
|
|
465
|
+
export type ActionLookupsConfig = {
|
|
466
|
+
getAction: (spaceId: number, actionId: string, at?: SpaceRevision) => Promise<unknown>;
|
|
467
|
+
listActions?: (spaceId: number, at?: SpaceRevision) => Promise<unknown[]>;
|
|
468
|
+
getCredential?: (spaceId: number, identifier: string) => Promise<Record<string, string> | undefined>;
|
|
469
|
+
getConnector?: (spaceId: number, connectorId: string, at?: SpaceRevision) => Promise<unknown>;
|
|
470
|
+
};
|
|
366
471
|
export type SSRActionConfig = {
|
|
367
|
-
/** URL path for the write endpoint. Defaults to '/_action'. */
|
|
472
|
+
/** URL path for the write endpoint, and the base for the action-addressed routes. Defaults to '/_action'. */
|
|
368
473
|
path?: string;
|
|
369
|
-
/**
|
|
370
|
-
*
|
|
371
|
-
*
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
474
|
+
/**
|
|
475
|
+
* Supplying these is what turns server actions on: without a way to read a document there is nothing to run, and
|
|
476
|
+
* the endpoint keeps answering element-addressed connector writes alone.
|
|
477
|
+
*/
|
|
478
|
+
lookups?: ActionLookupsConfig;
|
|
479
|
+
/** Deployment-owned tasks, shaped as `ActionTask` in `@plitzi/sdk-server/actions`. Validated at boot. */
|
|
480
|
+
tasks?: unknown[];
|
|
481
|
+
/** Ceilings for every run this server accepts. A document may tighten them, never widen them. */
|
|
482
|
+
limits?: ActionLimits;
|
|
483
|
+
/**
|
|
484
|
+
* Concurrency ceilings.
|
|
485
|
+
*
|
|
486
|
+
* `perSpace`/`perProcess` count CALLS — a click, a webhook, a schedule — where one run is somebody asking for
|
|
487
|
+
* work and one space's callers must not starve another's. A `render` is counted only by `renderPerProcess`,
|
|
488
|
+
* because it arrives because people are reading the page: a ceiling per space there would refuse the five
|
|
489
|
+
* hundredth visitor of a page that is simply doing well.
|
|
490
|
+
*/
|
|
491
|
+
concurrency?: {
|
|
492
|
+
perSpace?: number;
|
|
493
|
+
perProcess?: number;
|
|
494
|
+
renderPerProcess?: number;
|
|
495
|
+
};
|
|
496
|
+
/** Inbound webhooks are public by construction, so they are counted per caller per minute. Default 60. */
|
|
497
|
+
rateLimit?: {
|
|
498
|
+
webhookPerMinute?: number;
|
|
376
499
|
};
|
|
500
|
+
/**
|
|
501
|
+
* Database engines a flow may reach, shaped as `ActionDbDriver` in `@plitzi/sdk-server/actions`.
|
|
502
|
+
*
|
|
503
|
+
* Omitted leaves the `db.query` task unregistered entirely. What a driver connects to is always a database the
|
|
504
|
+
* SPACE declared as a credential — never this deployment's own, which no credential a space holds can name.
|
|
505
|
+
*/
|
|
506
|
+
dbDrivers?: unknown[];
|
|
507
|
+
/**
|
|
508
|
+
* Called once per run that STARTED — completed, failed or aborted — for a deployment that keeps a record.
|
|
509
|
+
* Shaped as `ActionRunRecord` in `@plitzi/sdk-server/actions`.
|
|
510
|
+
*
|
|
511
|
+
* A refused request is not a run and is not reported here; it goes to {@link SSRActionConfig.onReject}.
|
|
512
|
+
*/
|
|
513
|
+
onRun?: (record: ActionRunRecord) => void | Promise<void>;
|
|
514
|
+
/**
|
|
515
|
+
* Called once per request that was REFUSED before it became a run — a webhook whose signature did not verify, a
|
|
516
|
+
* caller over the rate limit, an action nobody may start. Shaped as `ActionRejectRecord`.
|
|
517
|
+
*
|
|
518
|
+
* Its own hook because it answers a different question from `onRun`: runs are history, refusals are a fault
|
|
519
|
+
* report, and the one that matters most — a signature that does not match — is otherwise indistinguishable
|
|
520
|
+
* from the integration simply never firing. Everything is reported; which refusals are worth keeping (a
|
|
521
|
+
* duplicate delivery is a polite retry, not a fault) is the deployment's to decide.
|
|
522
|
+
*/
|
|
523
|
+
onReject?: (record: ActionRejectRecord) => void | Promise<void>;
|
|
524
|
+
/**
|
|
525
|
+
* Replaying a finished run's answer to a caller that asks again with the same key, for this many milliseconds.
|
|
526
|
+
*
|
|
527
|
+
* Off unless set, and it only ever applies to a key the CALLER named — an `idempotencyKey` on the call or the
|
|
528
|
+
* delivery id a webhook sender stamps. Single-flight already refuses a retry that arrives while the first run
|
|
529
|
+
* is going; this is for the one that arrives after it finished, which is how every provider retries.
|
|
530
|
+
*/
|
|
531
|
+
idempotency?: {
|
|
532
|
+
replayTtlMs?: number;
|
|
533
|
+
};
|
|
534
|
+
/**
|
|
535
|
+
* Where the `kv` tasks keep things — shaped as `ActionKvAdapter` in `@plitzi/sdk-server/actions`.
|
|
536
|
+
*
|
|
537
|
+
* Five operations over strings, with no rule to obey: Redis, Memcached, a table, whatever this deployment
|
|
538
|
+
* already runs. How a counter BEHAVES — the key prefixing, the JSON round trip, and the rule that a window's
|
|
539
|
+
* lifetime is set once by whoever created it — belongs to the server, not to the thing it writes into.
|
|
540
|
+
*
|
|
541
|
+
* Omitted leaves an in-process Map, which counts only its own replica. That is fine for one; for a cluster it is
|
|
542
|
+
* a rate limit that multiplies by the number of them, so a multi-replica deployment supplies a shared one.
|
|
543
|
+
*/
|
|
544
|
+
kv?: {
|
|
545
|
+
get: (key: string) => Promise<string | undefined>;
|
|
546
|
+
set: (key: string, value: string, ttlSeconds?: number) => Promise<void>;
|
|
547
|
+
delete: (key: string) => Promise<void>;
|
|
548
|
+
increment: (key: string, amount: number) => Promise<number>;
|
|
549
|
+
expire: (key: string, ttlSeconds: number) => Promise<void>;
|
|
550
|
+
};
|
|
551
|
+
};
|
|
552
|
+
/**
|
|
553
|
+
* How the server reaches a space's connectors: the manifest that describes one, and the credential it authenticates
|
|
554
|
+
* with. Shaped as `ConnectorLookups` in `@plitzi/sdk-server`; typed loosely here so the shared types stay free of the
|
|
555
|
+
* server's internals.
|
|
556
|
+
*
|
|
557
|
+
* Top-level, and not under `action`, because BOTH directions need them. Supplying them is what makes the write
|
|
558
|
+
* endpoint able to authorize a write — a write can only be checked against a manifest — and it is also all the server
|
|
559
|
+
* needs to answer a server-driven element's READ, so `adapters.getRscData` is derived from them unless a deployment
|
|
560
|
+
* supplies its own. They lived under `action` when writes were the only caller, which left every deployment building
|
|
561
|
+
* that read half by hand out of `createConnectorResolver` and `resolveRscData` — from these very lookups, passed a
|
|
562
|
+
* second time.
|
|
563
|
+
*/
|
|
564
|
+
export type ConnectorLookupsConfig = {
|
|
565
|
+
getConnector: (spaceId: number, connectorId: string, at?: SpaceRevision) => Promise<unknown>;
|
|
566
|
+
getCredential?: (spaceId: number, identifier: string) => Promise<Record<string, string> | undefined>;
|
|
567
|
+
fetchImpl?: typeof fetch;
|
|
377
568
|
};
|
|
378
569
|
export type SSRHealthConfig = {
|
|
379
570
|
path?: string;
|
|
@@ -414,6 +605,18 @@ export type SSRRscConfig = {
|
|
|
414
605
|
path?: string;
|
|
415
606
|
/** Server-side cache TTL for RSC responses in milliseconds. Defaults to 30 000. Set to 0 to disable. */
|
|
416
607
|
cacheTtlMs?: number;
|
|
608
|
+
/**
|
|
609
|
+
* How long ONE server element may take before the page is answered without it. Defaults to 5 000.
|
|
610
|
+
*
|
|
611
|
+
* It is the page's ceiling, and it wins over the producer's own: an action may be allowed ten seconds of its
|
|
612
|
+
* own (`action.limits.timeoutMs`) and still be cut off here, because a section is worth waiting for only as
|
|
613
|
+
* long as the visitor is. Whichever is tighter decides, and now that the budget CANCELS what it stops waiting
|
|
614
|
+
* for, being cut here ends the run rather than leaving it to finish for nobody.
|
|
615
|
+
*
|
|
616
|
+
* Raise it for a deployment whose sections are genuinely slow and worth the wait; lower it to keep a page fast
|
|
617
|
+
* at the cost of showing more empty sections when a provider is having a bad day.
|
|
618
|
+
*/
|
|
619
|
+
elementTimeoutMs?: number;
|
|
417
620
|
};
|
|
418
621
|
/** What every log event carries, whatever layer it came from. */
|
|
419
622
|
type ServerLogEventBase = {
|
|
@@ -459,15 +662,59 @@ export type McpResourceLogEvent = ServerLogEventBase & {
|
|
|
459
662
|
/** The resource URI that was read, e.g. 'plitzi://element/hero_1'. */
|
|
460
663
|
name: string;
|
|
461
664
|
};
|
|
665
|
+
/** One server action run that STARTED — completed, failed or aborted.
|
|
666
|
+
*
|
|
667
|
+
* Its own event rather than a line on the request that triggered it, for the same reason a tool call is: the
|
|
668
|
+
* request is answered either way, and a run started by a schedule or a webhook has a request that says nothing
|
|
669
|
+
* about it. Where the request log answers "was this call served", this answers "what did the flow do".
|
|
670
|
+
*
|
|
671
|
+
* Carries the SHAPE of the run and never its data: which steps ran and how each ended, never what they
|
|
672
|
+
* returned. A refused run is absent by design — a 409 is not a run, and logging one buries the real ones under
|
|
673
|
+
* retries. */
|
|
674
|
+
export type ActionRunLogEvent = ServerLogEventBase & {
|
|
675
|
+
kind: 'run';
|
|
676
|
+
/** The action's identifier, as the space stores it. */
|
|
677
|
+
name: string;
|
|
678
|
+
spaceId: number;
|
|
679
|
+
environment: Environment;
|
|
680
|
+
/** What started it: a page call, a webhook, a schedule, a render, a trigger the deployment mounted. */
|
|
681
|
+
trigger: ActionTriggerType;
|
|
682
|
+
status: ActionRunStatus;
|
|
683
|
+
/** Who asked, when a session carried it. Absent for a webhook, a schedule or an anonymous visitor. */
|
|
684
|
+
userId?: number;
|
|
685
|
+
/** Each step as `action:status`, in order — enough to see where a flow stopped without keeping what it held. */
|
|
686
|
+
steps: string[];
|
|
687
|
+
};
|
|
688
|
+
/** One request that was REFUSED before it became a run — a webhook whose signature did not verify, a caller over
|
|
689
|
+
* its rate limit, an action nobody may start.
|
|
690
|
+
*
|
|
691
|
+
* Separate from {@link ActionRunLogEvent} because it is a different question: that one says what a flow did,
|
|
692
|
+
* this one says why a flow never happened. It is the only place an integration that is failing at the door
|
|
693
|
+
* shows up at all — the request log answers 401 and says nothing about which check refused it.
|
|
694
|
+
*
|
|
695
|
+
* `durationMs` is 0 and `ok` is always false: nothing ran, and a refusal is not a success on anybody's dashboard. */
|
|
696
|
+
export type ActionRejectLogEvent = ServerLogEventBase & {
|
|
697
|
+
kind: 'reject';
|
|
698
|
+
/** The action's identifier, as the request named it — it need not exist. */
|
|
699
|
+
name: string;
|
|
700
|
+
spaceId: number;
|
|
701
|
+
environment: Environment;
|
|
702
|
+
trigger: ActionTriggerType;
|
|
703
|
+
/** Which check refused it. */
|
|
704
|
+
reason: ActionRejectReason;
|
|
705
|
+
/** Who asked, as the transport identifies them — a session subject or an address. */
|
|
706
|
+
callerId?: string;
|
|
707
|
+
};
|
|
462
708
|
/** Everything a Plitzi server reports about the work it does, as ONE stream: the HTTP requests it answers, plus
|
|
463
|
-
* the MCP tool calls
|
|
464
|
-
* and switch on `kind` — a consumer can render it, ship it to a dashboard or drop the
|
|
709
|
+
* the MCP tool calls, resource reads and server-action runs that happen inside them. Wire a single sink via
|
|
710
|
+
* `SSRServerConfig.logger` and switch on `kind` — a consumer can render it, ship it to a dashboard or drop the
|
|
711
|
+
* kinds it does not want.
|
|
465
712
|
*
|
|
466
713
|
* Payload-free by construction: no headers, cookies, tokens nor request body ever reach an event, query values
|
|
467
|
-
* are stripped from paths
|
|
468
|
-
* consumer shipping these events must handle them accordingly: `clientIp` on a request event, and
|
|
469
|
-
* path, which is kept verbatim because it is what makes the log usable. */
|
|
470
|
-
export type ServerLogEvent = ServerRequestLogEvent | McpToolLogEvent | McpResourceLogEvent;
|
|
714
|
+
* are stripped from paths, tool arguments are reduced to their shape and a run to its steps. Two fields are NOT
|
|
715
|
+
* anonymous and a consumer shipping these events must handle them accordingly: `clientIp` on a request event, and
|
|
716
|
+
* the request path, which is kept verbatim because it is what makes the log usable. */
|
|
717
|
+
export type ServerLogEvent = ServerRequestLogEvent | McpToolLogEvent | McpResourceLogEvent | ActionRunLogEvent | ActionRejectLogEvent;
|
|
471
718
|
/** The sink a consumer provides to receive every {@link ServerLogEvent} (see `SSRServerConfig.logger`). */
|
|
472
719
|
export type ServerLogger = (event: ServerLogEvent) => void;
|
|
473
720
|
export type SSRServerConfig = {
|
|
@@ -502,6 +749,8 @@ export type SSRServerConfig = {
|
|
|
502
749
|
pluginsTtlMs?: number;
|
|
503
750
|
/** Auto-download and cache plugins declared in the schema's offlineData.plugins list. Default: true. */
|
|
504
751
|
autoLoadSchemaPlugins?: boolean;
|
|
752
|
+
/** Where this deployment serves the font files a space uploaded — see {@link SSRFontsConfig}. */
|
|
753
|
+
fonts?: SSRFontsConfig;
|
|
505
754
|
/** Omit client-side JS from the rendered page — useful for verifying SSR HTML without hydration. Default: false. */
|
|
506
755
|
ssrOnly?: boolean;
|
|
507
756
|
/** Stream HTML to the client as React renders, reducing TTFB. Default: false. */
|
|
@@ -516,6 +765,9 @@ export type SSRServerConfig = {
|
|
|
516
765
|
rsc?: SSRRscConfig;
|
|
517
766
|
/** Write endpoint for server-driven providers. Absent means the server serves reads only. */
|
|
518
767
|
action?: SSRActionConfig;
|
|
768
|
+
/** Connector manifest and credential lookups — see {@link ConnectorLookupsConfig}. They serve the RSC read path
|
|
769
|
+
* and the `/_action` write endpoint alike; without them neither can reach a connector. */
|
|
770
|
+
connectors?: ConnectorLookupsConfig;
|
|
519
771
|
/** Receives a {@link ServerLogEvent} for every HTTP request this server answers — whatever stage answered it
|
|
520
772
|
* and whatever the outcome — plus every MCP tool call and resource read inside those requests. Without it the
|
|
521
773
|
* server reports nothing per request (the MCP events still reach the console when `MCP_DEBUG=1`). */
|
|
@@ -630,14 +882,34 @@ export type OAuthGrantTarget = {
|
|
|
630
882
|
* for them. The SDK owns the protocol (discovery, registration, PKCE, code exchange); the consumer owns identity
|
|
631
883
|
* and issues a token its own `adapters.getGrant` will accept back. */
|
|
632
884
|
export type OAuthAdapters = {
|
|
633
|
-
/**
|
|
634
|
-
*
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
885
|
+
/**
|
|
886
|
+
* Who the browser making this request already is, from whatever session it carries.
|
|
887
|
+
*
|
|
888
|
+
* This server has no sign-in of its own: it reads an existing session and sends anyone it cannot identify to
|
|
889
|
+
* {@link OAuthConfig.signInUrl}, which brings them back. That is what lets a deployment have ONE sign-in screen
|
|
890
|
+
* for every surface — and it is what makes SSO somebody else's problem, because whatever established the
|
|
891
|
+
* session is no longer this flow's business.
|
|
892
|
+
*
|
|
893
|
+
* It replaced a username/password form this server used to render and check itself. Two sign-ins against one
|
|
894
|
+
* account store is two places to add a provider, to rate-limit, and to get a password check subtly wrong.
|
|
895
|
+
*
|
|
896
|
+
* Return undefined for "nobody is signed in". Never throw for that — an unreadable session is the ordinary
|
|
897
|
+
* first visit.
|
|
898
|
+
*/
|
|
899
|
+
identify: (req: SSRRequest) => Promise<OAuthUser | undefined>;
|
|
639
900
|
/** What this user may grant access to. An empty list ends the flow with `access_denied`. */
|
|
640
901
|
grantTargets: (user: OAuthUser) => Promise<OAuthGrantTarget[]>;
|
|
902
|
+
/**
|
|
903
|
+
* End whatever session {@link OAuthAdapters.identify} was reading, so the person can connect as somebody else.
|
|
904
|
+
*
|
|
905
|
+
* Optional, and its absence is what takes the offer off the grant screen: a deployment that cannot end a session
|
|
906
|
+
* from here should not show a button that pretends to. Clear the cookies on `res` and revoke at the source —
|
|
907
|
+
* forgetting the cookie alone leaves the credential working for anyone who already copied it.
|
|
908
|
+
*
|
|
909
|
+
* Whoever reaches that screen arrived from another application, so this is the only way out of the wrong account
|
|
910
|
+
* that does not mean abandoning the connection and starting over from the host.
|
|
911
|
+
*/
|
|
912
|
+
signOut?: (req: SSRRequest, res: SSRResponseHelpers) => void | Promise<void>;
|
|
641
913
|
/** Mint the bearer the client will send on every MCP request. Return undefined to deny the grant. */
|
|
642
914
|
issueToken: (user: OAuthUser, target: OAuthGrantTarget) => Promise<{
|
|
643
915
|
token: string;
|
|
@@ -657,7 +929,7 @@ export type OAuthGuestConfig = {
|
|
|
657
929
|
/** Who the grant is issued as. Defaults to `{ id: 'guest', label: 'Guest' }`. */
|
|
658
930
|
user?: OAuthUser;
|
|
659
931
|
};
|
|
660
|
-
/** What the
|
|
932
|
+
/** What the grant screen shows around the form. */
|
|
661
933
|
export type OAuthBranding = {
|
|
662
934
|
/** Shown as the heading, e.g. 'Plitzi'. Defaults to 'Plitzi'. */
|
|
663
935
|
productName?: string;
|
|
@@ -666,26 +938,46 @@ export type OAuthBranding = {
|
|
|
666
938
|
/** Extra CSS appended to the page's own, for a deployment that wants its own look without replacing the page. */
|
|
667
939
|
css?: string;
|
|
668
940
|
};
|
|
669
|
-
/**
|
|
670
|
-
*
|
|
941
|
+
/**
|
|
942
|
+
* Everything the GRANT screen needs to render itself.
|
|
943
|
+
*
|
|
944
|
+
* One screen, and deliberately only one: this server asks what to connect, never who somebody is. Signing in
|
|
945
|
+
* happens on {@link OAuthConfig.signInUrl}, wherever the deployment keeps it.
|
|
946
|
+
*/
|
|
671
947
|
export type OAuthConsentView = {
|
|
672
|
-
/** 'credentials' asks for username + password; 'target' asks which space to grant, after a successful login. */
|
|
673
|
-
step: 'credentials' | 'target';
|
|
674
948
|
/** Where the form must POST to (the authorize endpoint). */
|
|
675
949
|
action: string;
|
|
676
950
|
/** Hidden fields the form MUST round-trip verbatim, or the flow cannot be resumed. */
|
|
677
951
|
hidden: Record<string, string>;
|
|
678
|
-
/**
|
|
952
|
+
/** What this account may grant. Empty for a visitor who has not signed in, who is offered `guest` instead. */
|
|
679
953
|
targets: OAuthGrantTarget[];
|
|
680
|
-
/**
|
|
681
|
-
*
|
|
954
|
+
/**
|
|
955
|
+
* Offered when the deployment allows a guest connection. The form submits a `guest` field for it (any non-empty
|
|
956
|
+
* value), which is what tells the server to grant the guest target rather than a chosen one.
|
|
957
|
+
*
|
|
958
|
+
* It is the reason an unidentified visitor is shown this screen at all rather than being sent straight to
|
|
959
|
+
* sign-in: a guest has no session and never will, so a redirect they cannot come back from would take the
|
|
960
|
+
* option away entirely.
|
|
961
|
+
*/
|
|
682
962
|
guest?: {
|
|
683
963
|
label: string;
|
|
684
964
|
description?: string;
|
|
685
965
|
};
|
|
686
|
-
/** Who
|
|
966
|
+
/** Who is signed in. Absent for a visitor taking the guest connection. */
|
|
687
967
|
user?: OAuthUser;
|
|
688
|
-
/**
|
|
968
|
+
/** Where to send somebody who wants to sign in first. Shown when `user` is absent. */
|
|
969
|
+
signInUrl?: string;
|
|
970
|
+
/**
|
|
971
|
+
* Whether to offer "use another account" — shown only when the deployment can act on it, which means it supplied
|
|
972
|
+
* {@link OAuthAdapters.signOut}.
|
|
973
|
+
*
|
|
974
|
+
* A submit BUTTON in the same form rather than a link, and that is not decoration. Ending a session is a state
|
|
975
|
+
* change, so it may not hang off a URL anything can navigate to: a `<img src>` on any page on the internet would
|
|
976
|
+
* then be able to sign a visitor out. Posting it here keeps it a same-origin form submission carrying the request
|
|
977
|
+
* back, exactly like granting does.
|
|
978
|
+
*/
|
|
979
|
+
canSwitchUser?: boolean;
|
|
980
|
+
/** A message to show the user. */
|
|
689
981
|
error?: string;
|
|
690
982
|
branding: OAuthBranding;
|
|
691
983
|
};
|
|
@@ -715,16 +1007,60 @@ export type OAuthConfig = {
|
|
|
715
1007
|
/** Offer a connection that needs no account — see {@link OAuthGuestConfig}. Omit to require sign-in. */
|
|
716
1008
|
guest?: OAuthGuestConfig;
|
|
717
1009
|
branding?: OAuthBranding;
|
|
718
|
-
/**
|
|
719
|
-
|
|
1010
|
+
/**
|
|
1011
|
+
* The sign-in screen this server sends unidentified visitors to.
|
|
1012
|
+
*
|
|
1013
|
+
* The whole authorization request rides along as a `redirect` query param, so signing in is an ordinary
|
|
1014
|
+
* navigation that lands back on the `/authorize` it left — this server keeps no session of its own for a flow
|
|
1015
|
+
* that is one page long.
|
|
1016
|
+
*
|
|
1017
|
+
* Required, because {@link OAuthAdapters.identify} is: a server that does not check passwords and has nowhere
|
|
1018
|
+
* to send somebody who has not signed in cannot start the flow at all.
|
|
1019
|
+
*/
|
|
1020
|
+
signInUrl: string;
|
|
1021
|
+
/**
|
|
1022
|
+
* Hand the client the credential `issueToken` minted, instead of an opaque handle to it.
|
|
1023
|
+
*
|
|
1024
|
+
* Off by default, which is right whenever the credential is worth more than the connection — a space token
|
|
1025
|
+
* reaches the platform, and a client that never holds one cannot leak one. Turn it ON when the credential IS
|
|
1026
|
+
* what the client should hold: a native app granted the person's own session is holding exactly what a browser
|
|
1027
|
+
* holds, and wrapping it costs a store read on every request and gives a second thing to revoke.
|
|
1028
|
+
*/
|
|
1029
|
+
directTokens?: boolean;
|
|
720
1030
|
};
|
|
721
1031
|
/** A short-TTL, one-shot store for unsaved draft offline-data behind a preview token. The SDK ships an
|
|
722
1032
|
* in-memory default (fine for a single replica); a multi-replica deployment injects a shared (e.g. Redis)
|
|
723
1033
|
* implementation so a preview URL resolves on whichever replica the browser lands on. `take` consumes the
|
|
724
1034
|
* token so a preview URL is not replayable. */
|
|
1035
|
+
/**
|
|
1036
|
+
* How long a stashed draft lives, and whether looking at it uses it up.
|
|
1037
|
+
*
|
|
1038
|
+
* `reusable: false` is the capture path: one token, one render, gone — a URL that leaks buys nobody a second look.
|
|
1039
|
+
* `reusable: true` is somebody ITERATING: they reload, they open devtools, they navigate to the next page and back,
|
|
1040
|
+
* and a token consumed by the first of those turns the whole loop into "mint another one". Same store, same secret,
|
|
1041
|
+
* same expiry; the only difference is whether the read deletes it.
|
|
1042
|
+
*/
|
|
1043
|
+
export type DraftPutOptions = {
|
|
1044
|
+
ttlMs: number;
|
|
1045
|
+
reusable?: boolean;
|
|
1046
|
+
};
|
|
1047
|
+
/** A stashed draft, and whether the read that resolved it left it there. */
|
|
1048
|
+
export type DraftEntry = {
|
|
1049
|
+
data: OfflineDataRaw;
|
|
1050
|
+
reusable: boolean;
|
|
1051
|
+
};
|
|
725
1052
|
export type DraftStore = {
|
|
726
|
-
put: (token: string, data: OfflineDataRaw,
|
|
727
|
-
|
|
1053
|
+
put: (token: string, data: OfflineDataRaw, options: DraftPutOptions) => void | Promise<void>;
|
|
1054
|
+
/**
|
|
1055
|
+
* Resolves a draft, consuming it unless it was stored as reusable.
|
|
1056
|
+
*
|
|
1057
|
+
* It answers WHICH it was, rather than leaving the caller to infer it from a second read: the render that resolved
|
|
1058
|
+
* a session is the one that has to remember it for the rest of the visit, and "did this token survive" is a fact
|
|
1059
|
+
* the store holds and nobody else does.
|
|
1060
|
+
*/
|
|
1061
|
+
take: (token: string) => (DraftEntry | undefined) | Promise<DraftEntry | undefined>;
|
|
1062
|
+
/** Ends a reusable draft before its TTL — what "stop previewing" does. A token that is not there is not an error. */
|
|
1063
|
+
drop: (token: string) => void | Promise<void>;
|
|
728
1064
|
};
|
|
729
1065
|
/** Draft-preview config for the MCP visual-preview tools. When enabled, an internal endpoint at `path`
|
|
730
1066
|
* (guarded by `secret`) applies unsaved edits to a clone, stashes the resulting offline-data under a
|
|
@@ -735,7 +1071,15 @@ export type SSRPreviewConfig = {
|
|
|
735
1071
|
path?: string;
|
|
736
1072
|
/** Shared secret required in the `x-preview-secret` header; requests without it are rejected. */
|
|
737
1073
|
secret?: string;
|
|
738
|
-
/**
|
|
1074
|
+
/** One-shot token time-to-live in milliseconds. Default 60000. */
|
|
739
1075
|
ttlMs?: number;
|
|
1076
|
+
/**
|
|
1077
|
+
* How long a REUSABLE draft session lives, in milliseconds. Default 900000 (fifteen minutes).
|
|
1078
|
+
*
|
|
1079
|
+
* Longer than a one-shot token because it is measured against a person's attention rather than an HTTP round trip,
|
|
1080
|
+
* and short anyway: a draft is unsaved work that only its author should be looking at, and every minute it stays
|
|
1081
|
+
* resolvable is a minute a copied URL keeps working.
|
|
1082
|
+
*/
|
|
1083
|
+
sessionTtlMs?: number;
|
|
740
1084
|
};
|
|
741
1085
|
export {};
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { ActionDocument } from './ActionTypes';
|
|
1
2
|
import { Environment } from './CommonTypes';
|
|
2
3
|
import { ConnectorManifestDraft } from './ConnectorTypes';
|
|
3
4
|
export type SpaceCredentialProvider = 's3' | 'r2' | 'ssr' | 'custom';
|
|
@@ -16,6 +17,21 @@ export type SpaceConnector = {
|
|
|
16
17
|
createdAt: number;
|
|
17
18
|
updatedAt: number;
|
|
18
19
|
};
|
|
20
|
+
/**
|
|
21
|
+
* A server action as the builder sees it.
|
|
22
|
+
*
|
|
23
|
+
* The document is server-side state — it names credentials, connectors and steps — so this shape exists for the
|
|
24
|
+
* editor and the API that maintains it, never for a published page. What reaches a visitor is the action's
|
|
25
|
+
* identifier and its input/output fields, derived server-side.
|
|
26
|
+
*/
|
|
27
|
+
export type SpaceAction = {
|
|
28
|
+
id: number;
|
|
29
|
+
identifier: string;
|
|
30
|
+
name: string;
|
|
31
|
+
document: ActionDocument;
|
|
32
|
+
createdAt: number;
|
|
33
|
+
updatedAt: number;
|
|
34
|
+
};
|
|
19
35
|
export type SpaceCredential = {
|
|
20
36
|
identifier: string;
|
|
21
37
|
name: string;
|