@plitzi/sdk-shared 0.37.2 → 0.37.3
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 +1146 -0
- package/dist/actions/access.d.ts +12 -0
- package/dist/actions/access.mjs +13 -0
- package/dist/actions/functions.d.ts +27 -0
- package/dist/actions/functions.mjs +18 -0
- package/dist/actions/index.d.ts +4 -0
- package/dist/actions/index.mjs +9 -7
- package/dist/auth/index.d.ts +2 -0
- package/dist/auth/index.mjs +2 -1
- package/dist/auth/visitorRoles.d.ts +27 -0
- package/dist/auth/visitorRoles.mjs +48 -0
- package/dist/authoring/builder.mjs +1 -0
- package/dist/authoring/declare.d.ts +53 -0
- package/dist/authoring/declare.mjs +2 -2
- package/dist/authoring/index.mjs +5 -5
- package/dist/authoring/paramSpec.d.ts +1 -1
- package/dist/authoring/paramSpec.mjs +1 -0
- package/dist/authoring/spaceCallbacks.mjs +2 -2
- package/dist/dataSource/computed.d.ts +21 -0
- package/dist/dataSource/computed.mjs +45 -0
- package/dist/dataSource/getBindingsDetails.mjs +35 -34
- package/dist/dataSource/index.d.ts +1 -0
- package/dist/dataSource/index.mjs +7 -6
- package/dist/dataSource/utility/not.mjs +4 -7
- package/dist/dataSource/utility/stringToArray.mjs +1 -1
- package/dist/dataSource/utility/truthiness.d.ts +1 -0
- package/dist/dataSource/utility/truthiness.mjs +8 -0
- package/dist/dataSource/utility/twigTemplate.d.ts +2 -1
- package/dist/dataSource/utility/twigTemplate.mjs +29 -17
- package/dist/devTools/utils/PlitziConsole.mjs +22 -22
- package/dist/helpers/cookies.d.ts +10 -0
- package/dist/helpers/cookies.mjs +19 -0
- package/dist/helpers/fetchManifest.d.ts +9 -0
- package/dist/helpers/fetchManifest.mjs +3 -6
- package/dist/helpers/formatDate.d.ts +5 -3
- package/dist/helpers/formatDate.mjs +34 -36
- package/dist/helpers/index.d.ts +2 -0
- package/dist/helpers/index.mjs +18 -14
- package/dist/helpers/isDate.d.ts +7 -0
- package/dist/helpers/isDate.mjs +15 -0
- package/dist/helpers/keys.d.ts +42 -0
- package/dist/helpers/keys.mjs +91 -0
- package/dist/helpers/twigWrapper/AST.d.ts +2 -2
- package/dist/helpers/twigWrapper/Evaluator/Evaluator.d.ts +12 -2
- package/dist/helpers/twigWrapper/Evaluator/Evaluator.mjs +57 -34
- package/dist/helpers/twigWrapper/Evaluator/index.d.ts +1 -1
- package/dist/helpers/twigWrapper/Evaluator/index.mjs +2 -2
- package/dist/helpers/twigWrapper/Parser/ExpressionParser.d.ts +2 -2
- package/dist/helpers/twigWrapper/Parser/ExpressionParser.mjs +147 -34
- package/dist/helpers/twigWrapper/Parser/Parser.d.ts +2 -1
- package/dist/helpers/twigWrapper/Parser/Parser.mjs +21 -20
- package/dist/helpers/twigWrapper/filters/filters.mjs +130 -112
- package/dist/helpers/twigWrapper/index.d.ts +5 -2
- package/dist/helpers/twigWrapper/index.mjs +7 -5
- package/dist/helpers/twigWrapper/inspectTemplate.d.ts +23 -0
- package/dist/helpers/twigWrapper/inspectTemplate.mjs +110 -0
- package/dist/helpers/twigWrapper/processTwig/helpers.d.ts +7 -0
- package/dist/helpers/twigWrapper/processTwig/helpers.mjs +2 -1
- package/dist/helpers/twigWrapper/processTwig/index.d.ts +2 -1
- package/dist/helpers/twigWrapper/processTwig/index.mjs +3 -2
- package/dist/helpers/twigWrapper/processTwig/processTwig.d.ts +28 -0
- package/dist/helpers/twigWrapper/processTwig/processTwig.mjs +73 -16
- package/dist/helpers/twigWrapper/processTwig/resolveStepParam.d.ts +17 -0
- package/dist/helpers/twigWrapper/processTwig/resolveStepParam.mjs +14 -0
- package/dist/helpers/twigWrapper/templateRoots.d.ts +11 -0
- package/dist/helpers/twigWrapper/templateRoots.mjs +4 -4
- package/dist/helpers/twigWrapper/tokens/hasTemplateSyntax.d.ts +1 -1
- package/dist/history/describe.d.ts +29 -0
- package/dist/history/describe.mjs +93 -0
- package/dist/history/diff.d.ts +33 -0
- package/dist/history/diff.mjs +73 -0
- package/dist/history/index.d.ts +3 -0
- package/dist/history/index.mjs +3 -0
- package/dist/history/types.d.ts +48 -0
- package/dist/history/types.mjs +0 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.mjs +77 -66
- package/dist/navigation/index.d.ts +1 -1
- package/dist/navigation/index.mjs +2 -2
- package/dist/navigation/routes.d.ts +11 -1
- package/dist/navigation/routes.mjs +15 -10
- package/dist/network/graphql/builder/Mutations/Space/SpaceFixIssuesMutation.d.ts +14 -0
- package/dist/network/graphql/builder/Mutations/Space/SpaceFixIssuesMutation.mjs +16 -0
- package/dist/network/graphql/builder/Mutations/Space/SpaceUpdatePluginMutation.d.ts +4 -0
- package/dist/network/graphql/builder/Mutations/Space/SpaceUpdatePluginMutation.mjs +2 -2
- package/dist/network/graphql/builder/Mutations/Space/actions/SpaceRunActionMutation.mjs +1 -0
- package/dist/network/graphql/builder/Mutations/Space/functions/SpaceRemoveFunctionsMutation.d.ts +3 -0
- package/dist/network/graphql/builder/Mutations/Space/functions/SpaceRemoveFunctionsMutation.mjs +9 -0
- package/dist/network/graphql/builder/Mutations/Space/functions/SpaceSaveFunctionsMutation.d.ts +11 -0
- package/dist/network/graphql/builder/Mutations/Space/functions/SpaceSaveFunctionsMutation.mjs +24 -0
- package/dist/network/graphql/builder/Mutations/Space/functions/SpaceTryFunctionMutation.d.ts +4 -0
- package/dist/network/graphql/builder/Mutations/Space/functions/SpaceTryFunctionMutation.mjs +15 -0
- package/dist/network/graphql/builder/Mutations/Space/runtime/SpaceRemoveRuntimeMutation.d.ts +2 -0
- package/dist/network/graphql/builder/Mutations/Space/runtime/SpaceRemoveRuntimeMutation.mjs +9 -0
- package/dist/network/graphql/builder/Mutations/Space/runtime/SpaceRemoveRuntimeVariableMutation.d.ts +2 -0
- package/dist/network/graphql/builder/Mutations/Space/runtime/SpaceRemoveRuntimeVariableMutation.mjs +9 -0
- package/dist/network/graphql/builder/Mutations/Space/runtime/SpaceSetRuntimeSizeMutation.d.ts +2 -0
- package/dist/network/graphql/builder/Mutations/Space/runtime/SpaceSetRuntimeSizeMutation.mjs +9 -0
- package/dist/network/graphql/builder/Mutations/Space/runtime/SpaceSetRuntimeVariableMutation.d.ts +2 -0
- package/dist/network/graphql/builder/Mutations/Space/runtime/SpaceSetRuntimeVariableMutation.mjs +9 -0
- package/dist/network/graphql/builder/Mutations/Space/runtime/SpaceStartRuntimeMutation.d.ts +2 -0
- package/dist/network/graphql/builder/Mutations/Space/runtime/SpaceStartRuntimeMutation.mjs +9 -0
- package/dist/network/graphql/builder/Mutations/Space/runtime/SpaceStopRuntimeMutation.d.ts +2 -0
- package/dist/network/graphql/builder/Mutations/Space/runtime/SpaceStopRuntimeMutation.mjs +9 -0
- package/dist/network/graphql/builder/Mutations/Space/visitors/SpaceAddVisitorMutation.d.ts +2 -0
- package/dist/network/graphql/builder/Mutations/Space/visitors/SpaceAddVisitorMutation.mjs +11 -0
- package/dist/network/graphql/builder/Mutations/Space/visitors/SpaceRemoveVisitorMutation.d.ts +2 -0
- package/dist/network/graphql/builder/Mutations/Space/visitors/SpaceRemoveVisitorMutation.mjs +11 -0
- package/dist/network/graphql/builder/Mutations/index.d.ts +28 -0
- package/dist/network/graphql/builder/Mutations/index.mjs +108 -84
- package/dist/network/graphql/builder/Queries/Space/SpaceChangesQuery.d.ts +23 -0
- package/dist/network/graphql/builder/Queries/Space/SpaceChangesQuery.mjs +49 -0
- package/dist/network/graphql/builder/Queries/Space/SpaceFunctionsQuery.d.ts +6 -0
- package/dist/network/graphql/builder/Queries/Space/SpaceFunctionsQuery.mjs +13 -0
- package/dist/network/graphql/builder/Queries/Space/SpaceIssuesQuery.d.ts +17 -0
- package/dist/network/graphql/builder/Queries/Space/SpaceIssuesQuery.mjs +22 -0
- package/dist/network/graphql/builder/Queries/Space/SpaceRuntimeQuery.d.ts +6 -0
- package/dist/network/graphql/builder/Queries/Space/SpaceRuntimeQuery.mjs +32 -0
- package/dist/network/graphql/builder/Queries/Space/SpaceVisitorsQuery.d.ts +6 -0
- package/dist/network/graphql/builder/Queries/Space/SpaceVisitorsQuery.mjs +16 -0
- package/dist/network/graphql/builder/Queries/index.d.ts +17 -3
- package/dist/network/graphql/builder/Queries/index.mjs +30 -22
- package/dist/network/graphql/sdk/Mutations/index.d.ts +1 -1
- package/dist/network/graphql/sdk/Queries/InitQuery.d.ts +1 -1
- package/dist/network/graphql/sdk/Queries/InitQuery.mjs +2 -91
- package/dist/network/graphql/sdk/Queries/Segment/SegmentQuery.d.ts +1 -1
- package/dist/network/graphql/sdk/Queries/Segment/SegmentQuery.mjs +2 -44
- package/dist/network/graphql/sdk/Queries/Segment/SegmentsQuery.d.ts +1 -1
- package/dist/network/graphql/sdk/Queries/Segment/SegmentsQuery.mjs +2 -55
- package/dist/network/graphql/sdk/Queries/index.d.ts +1 -5
- package/dist/network/index.mjs +7 -7
- package/dist/network/spaceEvents.d.ts +33 -3
- package/dist/network/spaceEvents.mjs +102 -89
- package/dist/realtime/client.d.ts +46 -0
- package/dist/realtime/client.mjs +192 -0
- package/dist/realtime/index.d.ts +6 -0
- package/dist/realtime/index.mjs +4 -0
- package/dist/realtime/presence.d.ts +38 -0
- package/dist/realtime/presence.mjs +70 -0
- package/dist/realtime/topics.d.ts +36 -0
- package/dist/realtime/topics.mjs +25 -0
- package/dist/server/actions/useRealtimeSync.d.ts +9 -0
- package/dist/server/actions/useRealtimeSync.mjs +7 -0
- package/dist/state/index.d.ts +1 -0
- package/dist/state/index.mjs +3 -2
- package/dist/state/paintedState.d.ts +52 -0
- package/dist/state/paintedState.mjs +37 -0
- package/dist/state/runtimeStatePersist.d.ts +8 -1
- package/dist/state/runtimeStatePersist.mjs +79 -29
- package/dist/store/index.d.ts +45 -45
- package/dist/store/renderSettings.d.ts +6 -3
- package/dist/store/tracing/index.d.ts +1 -0
- package/dist/store/tracing/tracingCollector.d.ts +17 -1
- package/dist/store/tracing/tracingCollector.mjs +5 -0
- package/dist/style/index.d.ts +1 -0
- package/dist/style/index.mjs +3 -2
- package/dist/style/runtimeStyle.d.ts +29 -0
- package/dist/style/runtimeStyle.mjs +7 -0
- package/dist/style/styleConstants.d.ts +3 -2
- package/dist/style/styleConstants.mjs +2 -0
- package/dist/style/styleStates.d.ts +14 -1
- package/dist/style/styleStates.mjs +10 -7
- package/dist/theme/ThemeProvider.mjs +35 -29
- package/dist/theme/themeCookie.mjs +11 -15
- package/dist/types/ActionTypes.d.ts +4 -0
- package/dist/types/AuthTypes.d.ts +11 -1
- package/dist/types/CommonTypes.d.ts +6 -0
- package/dist/types/FunctionTypes.d.ts +52 -0
- package/dist/types/FunctionTypes.mjs +0 -0
- package/dist/types/PluginTypes.d.ts +0 -1
- package/dist/types/RealtimeTypes.d.ts +94 -0
- package/dist/types/RealtimeTypes.mjs +0 -0
- package/dist/types/SchemaTypes.d.ts +54 -0
- package/dist/types/SchemaTypes.mjs +8 -0
- package/dist/types/ServerTypes.d.ts +259 -15
- package/dist/types/SpaceTypes.d.ts +53 -0
- package/dist/types/StateTypes.d.ts +6 -0
- package/dist/types/StoreTypes.d.ts +11 -0
- package/dist/types/index.d.ts +2 -0
- package/dist/types/index.mjs +3 -2
- package/package.json +172 -11
- package/vite.config.ts +0 -12
- package/dist/network/graphql/builder/Queries/PluginsQuery.d.ts +0 -9
- package/dist/network/graphql/builder/Queries/PluginsQuery.mjs +0 -54
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { InteractionCallbackParamValues, InteractionCallbackType } from './InteractionTypes';
|
|
2
|
+
import { ChannelDeclarations } from './RealtimeTypes';
|
|
2
3
|
import { Style } from './StyleTypes';
|
|
3
4
|
import { RuleGroup } from '@plitzi/plitzi-ui/QueryBuilder';
|
|
4
5
|
export type ElementRuntime = 'server' | 'client' | 'shared';
|
|
@@ -44,6 +45,15 @@ export type ElementBinding = {
|
|
|
44
45
|
enabled?: boolean;
|
|
45
46
|
to: string;
|
|
46
47
|
};
|
|
48
|
+
/**
|
|
49
|
+
* What a trigger does when it fires again while the flow it started is still running.
|
|
50
|
+
*
|
|
51
|
+
* - `skip` (the default): the new firing is ignored — what keeps a double click from submitting twice.
|
|
52
|
+
* - `parallel`: every firing runs its own flow, at the same time.
|
|
53
|
+
* - `queue`: every firing runs, one after another, in the order they came — none lost, none overlapping.
|
|
54
|
+
*/
|
|
55
|
+
export type WhileRunning = 'skip' | 'parallel' | 'queue';
|
|
56
|
+
export declare const WHILE_RUNNING_MODES: readonly WhileRunning[];
|
|
47
57
|
export type ElementInteraction<T extends Record<string, unknown> = Record<string, unknown>> = {
|
|
48
58
|
id: string;
|
|
49
59
|
title: string;
|
|
@@ -57,6 +67,8 @@ export type ElementInteraction<T extends Record<string, unknown> = Record<string
|
|
|
57
67
|
flowId: string;
|
|
58
68
|
enabled: boolean;
|
|
59
69
|
when?: RuleGroup;
|
|
70
|
+
/** On a trigger only: what a firing does while this flow is still running. `skip` when absent. */
|
|
71
|
+
whileRunning?: WhileRunning;
|
|
60
72
|
};
|
|
61
73
|
export type ElementDefinition = {
|
|
62
74
|
rootId: Element['id'];
|
|
@@ -123,7 +135,30 @@ export type Schema = {
|
|
|
123
135
|
settings: {
|
|
124
136
|
keepState?: boolean;
|
|
125
137
|
stateStorage?: 'localStorage' | 'sessionStorage';
|
|
138
|
+
/**
|
|
139
|
+
* Keys of `runtime.state` that are never kept, even with `keepState` on: they are not written, not brought back,
|
|
140
|
+
* and a value one of them already holds survives the moment the rest is restored. For state that must start fresh
|
|
141
|
+
* on every visit — a demo, a panel somebody left open, a step of a walkthrough. Top-level keys, as `setState`
|
|
142
|
+
* writes them.
|
|
143
|
+
*/
|
|
144
|
+
transientState?: string[];
|
|
145
|
+
/**
|
|
146
|
+
* Keys of `runtime.state` the first paint depends on — the tool a toolbar shows, a name in an avatar — kept in a
|
|
147
|
+
* cookie as well as in `stateStorage`, so the server renders with them and the page does not swap them in after
|
|
148
|
+
* hydration. Small values only: the cookie travels with every request and holds at most a few kilobytes. Needs
|
|
149
|
+
* `keepState`; a key cannot be both painted and transient. Top-level keys, as `setState` writes them.
|
|
150
|
+
*/
|
|
151
|
+
paintedState?: string[];
|
|
126
152
|
customCss: string;
|
|
153
|
+
/**
|
|
154
|
+
* The roles a signed-in visitor may hold in this space, each with the permissions it gives:
|
|
155
|
+
* `{ author: ['postPublish'] }`. They are what an action's `access: 'role'` and a page's `can()` are answered from
|
|
156
|
+
* — a visitor holds exactly the permissions of their roles here, never those of their account anywhere else.
|
|
157
|
+
*
|
|
158
|
+
* Declared by the space, so they are published, versioned and exported with it. WHO holds which is not: that is a
|
|
159
|
+
* list of people, kept by the platform the space runs on, and never part of a document anybody can read.
|
|
160
|
+
*/
|
|
161
|
+
visitorRoles?: Record<string, string[]>;
|
|
127
162
|
/** `basic` covers any HTTP+JSON backend by configuration; anything else is a name someone registered. */
|
|
128
163
|
userProvider?: 'basic' | 'custom' | '' | (string & {});
|
|
129
164
|
tokenStorage?: 'localStorage' | 'sessionStorage' | '';
|
|
@@ -151,6 +186,13 @@ export type Schema = {
|
|
|
151
186
|
* session itself, which is the case whenever `loginUrl` is your own API.
|
|
152
187
|
*/
|
|
153
188
|
sessionExchangeUrl?: string;
|
|
189
|
+
/**
|
|
190
|
+
* Where a sign-in that owed a second factor is completed: a password the backend answered with `mfaRequired` and
|
|
191
|
+
* an `mfaToken` resolves `auth.login` to `{ ok: false, reason: 'mfa', mfaToken }`, and `auth.login` with `mode:
|
|
192
|
+
* 'mfa'` posts `{ mfaToken, code }` here and adopts the session it answers with. Leave empty when the backend has
|
|
193
|
+
* no second factor.
|
|
194
|
+
*/
|
|
195
|
+
mfaUrl?: string;
|
|
154
196
|
/**
|
|
155
197
|
* What to do on a page that requires a session while the stored one is being re-checked. `optimistic` (the
|
|
156
198
|
* default) renders from the stored session and signs out if the check disagrees; `strict` waits for the answer,
|
|
@@ -167,6 +209,18 @@ export type Schema = {
|
|
|
167
209
|
* `false` there cannot be turned around from here. Never `devMode`, which makes a deployment a development server.
|
|
168
210
|
*/
|
|
169
211
|
debugMode?: boolean;
|
|
212
|
+
/**
|
|
213
|
+
* Values the space computes once and reads everywhere, by name: `{ xp: '{{ state.favourites|length * 10 }}' }` is
|
|
214
|
+
* read as `{{ computed.xp }}` in any binding, attribute or step. Each is a template over the global sources and the
|
|
215
|
+
* values declared before it (`computed.<earlier>`), re-evaluated when any of them changes. A template that is one
|
|
216
|
+
* `{{ expression }}` gives its value (a number, a list); anything else gives text.
|
|
217
|
+
*/
|
|
218
|
+
computed?: Record<string, string>;
|
|
219
|
+
/**
|
|
220
|
+
* The realtime channels the space offers, by topic pattern: `{ 'board:{id}': { access: { mode: 'public' } } }`.
|
|
221
|
+
* A page subscribes to and publishes on a topic one of them matches, and on nothing else.
|
|
222
|
+
*/
|
|
223
|
+
channels?: ChannelDeclarations;
|
|
170
224
|
};
|
|
171
225
|
rsc?: SchemaRsc;
|
|
172
226
|
pages: Element['id'][];
|
|
@@ -1,9 +1,12 @@
|
|
|
1
|
-
import { ActionEmailConfig, ActionEntry, ActionJobQueue, ActionLimits, ActionRejectReason, ActionRunSummary, ActionRejectRecord, ActionRunRecord, ActionRunStatus, ActionTaskDescriptor, ActionTriggerType } from './ActionTypes';
|
|
1
|
+
import { ActionEmailConfig, ActionEntry, ActionJobQueue, ActionLimits, ActionRejectReason, ActionRunSummary, ActionRejectRecord, ActionRunRecord, ActionRunReport, ActionRunStatus, ActionTaskDescriptor, ActionTriggerType } from './ActionTypes';
|
|
2
2
|
import { Environment } from './CommonTypes';
|
|
3
3
|
import { ConnectorEntry } from './ConnectorTypes';
|
|
4
|
+
import { FunctionsDraft, FunctionsSaveResult } from './FunctionTypes';
|
|
5
|
+
import { SSRRealtimeConfig } from './RealtimeTypes';
|
|
4
6
|
import { Schema } from './SchemaTypes';
|
|
5
7
|
import { AnalyticsConfig, OfflineDataRaw } from './SdkTypes';
|
|
6
8
|
import { FontHead, Style } from './StyleTypes';
|
|
9
|
+
import { SpaceChange } from '../history/types';
|
|
7
10
|
import { IncomingHttpHeaders } from 'node:http';
|
|
8
11
|
import { FC } from 'react';
|
|
9
12
|
export type ServerEnvironment = 'development' | 'production' | 'staging' | 'local';
|
|
@@ -24,8 +27,15 @@ export type SSRRequest = {
|
|
|
24
27
|
query: Record<string, string>;
|
|
25
28
|
/** Raw request body. Populated only for endpoints that consume it (e.g. the login/logout handlers). */
|
|
26
29
|
body?: string;
|
|
30
|
+
/**
|
|
31
|
+
* The client's address, when the host resolved one — through the proxies it sits behind. Forgeable by a direct
|
|
32
|
+
* client like every forwarded header, so it names things (a session in a device list) and never decides anything.
|
|
33
|
+
*/
|
|
34
|
+
ip?: string;
|
|
27
35
|
ctx: SSRContext;
|
|
28
36
|
};
|
|
37
|
+
/** A body's compressed forms, by content encoding — filled as they are first asked for. */
|
|
38
|
+
export type CompressedBodies = Partial<Record<'br' | 'gzip', Buffer>>;
|
|
29
39
|
export type SSRResponseHelpers = {
|
|
30
40
|
status: number;
|
|
31
41
|
/** Multi-valued for the headers that genuinely are, `Set-Cookie` above all — see `setHeader`. */
|
|
@@ -37,8 +47,18 @@ export type SSRResponseHelpers = {
|
|
|
37
47
|
/**
|
|
38
48
|
* A `Buffer` is sent byte for byte and never compressed: it is how a binary reaches the wire — a font file, an
|
|
39
49
|
* image — and what it holds is usually compressed already. A string keeps the encoding negotiation.
|
|
50
|
+
*
|
|
51
|
+
* `compressed` is where this body's compressed forms are kept, for a body that is sent again unchanged — a cached
|
|
52
|
+
* page, a static file. The first send of each encoding compresses and stores it; every later one sends the stored
|
|
53
|
+
* bytes. Without it a cache hit recompressed the same page on every request, which was nearly all the CPU a cached
|
|
54
|
+
* page cost.
|
|
55
|
+
*
|
|
56
|
+
* A function is a body read only when it is needed: when the stored form for this request's encoding is missing, or
|
|
57
|
+
* the client takes no compression. A static file is then read from disk once per encoding, not on every request.
|
|
40
58
|
*/
|
|
41
|
-
send: (body: string | Buffer) =>
|
|
59
|
+
send: (body: string | Buffer | (() => string), options?: {
|
|
60
|
+
compressed?: CompressedBodies;
|
|
61
|
+
}) => void;
|
|
42
62
|
write: (chunk: string | Buffer) => void;
|
|
43
63
|
end: () => void;
|
|
44
64
|
};
|
|
@@ -170,6 +190,23 @@ export type SSRGrant = {
|
|
|
170
190
|
userId?: number;
|
|
171
191
|
canWrite: boolean;
|
|
172
192
|
};
|
|
193
|
+
/** A page of a space's change history, newest first; `nextBefore` reads further back, null at the end. */
|
|
194
|
+
export type SSRChangePage = {
|
|
195
|
+
changes: SpaceChange[];
|
|
196
|
+
nextBefore: number | null;
|
|
197
|
+
};
|
|
198
|
+
/** What to read of the history: older than `before`, only the changes that touched `entityId`, `limit` at a time. */
|
|
199
|
+
export type SSRChangeQuery = {
|
|
200
|
+
before?: number;
|
|
201
|
+
entityId?: string;
|
|
202
|
+
limit: number;
|
|
203
|
+
};
|
|
204
|
+
/** Who a write is made for and which request made it, for a consumer that records its changes. Every document one
|
|
205
|
+
* request writes shares its `batch`: one `plitzi_apply`, read back as one change. */
|
|
206
|
+
export type SSRWriteContext = {
|
|
207
|
+
userId?: number;
|
|
208
|
+
batch: string;
|
|
209
|
+
};
|
|
173
210
|
/**
|
|
174
211
|
* A session, as the thing that issued it describes it. Deliberately free of transport: whoever mints one says what
|
|
175
212
|
* the credentials are and when they die, and the server decides how they are carried — which is what lets a
|
|
@@ -325,13 +362,25 @@ export type SSRAdapters = {
|
|
|
325
362
|
saveAction?: (spaceId: number, entry: ActionEntry) => Promise<void>;
|
|
326
363
|
/** Remove one action by its identifier. Omitted alongside `saveAction` for a read-only deployment. */
|
|
327
364
|
deleteAction?: (spaceId: number, actionId: string) => Promise<void>;
|
|
365
|
+
/** The space's own functions: the draft's source files, which copy of them it is and what they declare.
|
|
366
|
+
* Server-side code like the actions it serves — never a browser payload. When omitted, the MCP offers no functions
|
|
367
|
+
* resource and refuses the function ops. */
|
|
368
|
+
getFunctions?: (spaceId: number) => Promise<FunctionsDraft | undefined>;
|
|
369
|
+
/** Save the draft's functions, whole. The deployment builds and checks them and answers what is wrong where it is;
|
|
370
|
+
* `base` is the version the agent read, and a draft that moved on since is refused rather than overwritten. */
|
|
371
|
+
saveFunctions?: (spaceId: number, files: Record<string, string>, base: string, write: SSRWriteContext) => Promise<FunctionsSaveResult>;
|
|
372
|
+
/** Run one task of the draft's functions in the sandbox for the person behind the agent — the builder's Try. */
|
|
373
|
+
tryFunction?: (spaceId: number, task: string, params: Record<string, unknown>, write: SSRWriteContext) => Promise<ActionRunReport>;
|
|
328
374
|
/** Persist the element schema mutated by the MCP `apply` tool. When omitted, `apply` reports `persisted: false`. */
|
|
329
|
-
saveSchema?: (spaceId: number, environment: Environment, schema: Schema) => Promise<void>;
|
|
375
|
+
saveSchema?: (spaceId: number, environment: Environment, schema: Schema, write: SSRWriteContext) => Promise<void>;
|
|
330
376
|
/** Persist the style document mutated by the MCP `apply` tool — store it as given. `style.cache` arrives already
|
|
331
377
|
* compiled: the renderer serves that string and nothing else, so recomputing it is not a detail to delegate, and
|
|
332
378
|
* asking every deployment to remember it was one bug each of them could write alone. When omitted, `apply`
|
|
333
379
|
* reports `persisted: false`. */
|
|
334
|
-
saveStyle?: (spaceId: number, environment: Environment, style: Style) => Promise<void>;
|
|
380
|
+
saveStyle?: (spaceId: number, environment: Environment, style: Style, write: SSRWriteContext) => Promise<void>;
|
|
381
|
+
/** The space's change history, read-only: what every writer saved, and for whom. When omitted, the MCP offers no
|
|
382
|
+
* history resource. */
|
|
383
|
+
getChanges?: (spaceId: number, environment: Environment, query: SSRChangeQuery) => Promise<SSRChangePage>;
|
|
335
384
|
/** Who this request carries, if anyone. The adapter reads the credential and resolves it; the cookie it arrived
|
|
336
385
|
* in was written by the server, from {@link SSRAuthCookie}. */
|
|
337
386
|
getUser?: (req: SSRRequest) => Promise<SSRUser | undefined>;
|
|
@@ -469,6 +518,8 @@ export type ActionLookupsConfig = {
|
|
|
469
518
|
listScheduledSpaces?: () => Promise<number[]>;
|
|
470
519
|
getCredential?: (spaceId: number, identifier: string) => Promise<Record<string, string> | undefined>;
|
|
471
520
|
getConnector?: (spaceId: number, connectorId: string, at?: SpaceRevision) => Promise<unknown>;
|
|
521
|
+
/** The space's own functions as of that revision — `SpaceFunctions` in `@plitzi/sdk-server/functions`. */
|
|
522
|
+
getFunctions?: (spaceId: number, at?: SpaceRevision) => Promise<unknown>;
|
|
472
523
|
};
|
|
473
524
|
export type SSRActionConfig = {
|
|
474
525
|
/** URL path for the write endpoint, and the base for the action-addressed routes. Defaults to '/_action'. */
|
|
@@ -478,8 +529,6 @@ export type SSRActionConfig = {
|
|
|
478
529
|
* the endpoint keeps answering element-addressed connector writes alone.
|
|
479
530
|
*/
|
|
480
531
|
lookups?: ActionLookupsConfig;
|
|
481
|
-
/** Deployment-owned tasks, shaped as `ActionTask` in `@plitzi/sdk-server/actions`. Validated at boot. */
|
|
482
|
-
tasks?: unknown[];
|
|
483
532
|
/** Ceilings for every run this server accepts. A document may tighten them, never widen them. */
|
|
484
533
|
limits?: ActionLimits;
|
|
485
534
|
/**
|
|
@@ -539,10 +588,15 @@ export type SSRActionConfig = {
|
|
|
539
588
|
idempotency?: {
|
|
540
589
|
replayTtlMs?: number;
|
|
541
590
|
};
|
|
591
|
+
/**
|
|
592
|
+
* What each space's functions sign with (`ctx.sign` / `ctx.verify`): at least 32 characters, the same on every
|
|
593
|
+
* replica. Each space and environment signs with a key derived from it. Absent, spaces sign nothing.
|
|
594
|
+
*/
|
|
595
|
+
signingSecret?: string;
|
|
542
596
|
/**
|
|
543
597
|
* Where the `kv` tasks keep things — shaped as `ActionKvAdapter` in `@plitzi/sdk-server/actions`.
|
|
544
598
|
*
|
|
545
|
-
*
|
|
599
|
+
* Six operations over strings, with no rule to obey: Redis, Memcached, a table, whatever this deployment
|
|
546
600
|
* already runs. How a counter BEHAVES — the key prefixing, the JSON round trip, and the rule that a window's
|
|
547
601
|
* lifetime is set once by whoever created it — belongs to the server, not to the thing it writes into.
|
|
548
602
|
*
|
|
@@ -555,6 +609,8 @@ export type SSRActionConfig = {
|
|
|
555
609
|
delete: (key: string) => Promise<void>;
|
|
556
610
|
increment: (key: string, amount: number) => Promise<number>;
|
|
557
611
|
expire: (key: string, ttlSeconds: number) => Promise<void>;
|
|
612
|
+
/** Writes `next` only if the key holds `expected` (nothing, when undefined); answers whether it wrote. Atomic. */
|
|
613
|
+
swap: (key: string, expected: string | undefined, next: string, ttlSeconds?: number) => Promise<boolean>;
|
|
558
614
|
};
|
|
559
615
|
/**
|
|
560
616
|
* Scheduled runs: the durable queue they wait in, how many this replica runs at once, and whether it produces.
|
|
@@ -650,8 +706,18 @@ export type SSRCompressionConfig = {
|
|
|
650
706
|
encodings?: ('br' | 'gzip')[];
|
|
651
707
|
/** Responses smaller than this many bytes go out uncompressed. Default 1024. */
|
|
652
708
|
threshold?: number;
|
|
653
|
-
/**
|
|
709
|
+
/**
|
|
710
|
+
* Brotli quality, 0–11, for a body compressed on every request — a page rendered for this request alone. Default 2:
|
|
711
|
+
* measured on a quarter core, going to 4 cost a tenth of the pages a second to save half a kilobyte on each.
|
|
712
|
+
*/
|
|
654
713
|
brotliQuality?: number;
|
|
714
|
+
/**
|
|
715
|
+
* Brotli quality, 0–11, for a body compressed once and kept — a cached page, a static file such as the SDK bundle.
|
|
716
|
+
* Default 6: paid once, and every later response is that much smaller (the SDK bundle 10% under quality 4), for
|
|
717
|
+
* the same memory as 4. 9 needs ~40 MB more to compress the bundle, which a 128 MB server does not have; 10 and
|
|
718
|
+
* 11 cost seconds, which the request that fills the cache would wait for.
|
|
719
|
+
*/
|
|
720
|
+
keptBrotliQuality?: number;
|
|
655
721
|
/** Gzip level, 0–9. Default 6. */
|
|
656
722
|
gzipLevel?: number;
|
|
657
723
|
};
|
|
@@ -676,6 +742,12 @@ export type SSRRscConfig = {
|
|
|
676
742
|
elementTimeoutMs?: number;
|
|
677
743
|
};
|
|
678
744
|
/** What every log event carries, whatever layer it came from. */
|
|
745
|
+
/**
|
|
746
|
+
* How much a server says, from least to most: each level includes every one above it. `error` is what a production
|
|
747
|
+
* server shows unless told otherwise — something went wrong — and `warn`, `info` (every request answered, every
|
|
748
|
+
* plugin built) and `debug` are asked for. `silent` says nothing at all.
|
|
749
|
+
*/
|
|
750
|
+
export type LogLevel = 'error' | 'warn' | 'info' | 'debug';
|
|
679
751
|
type ServerLogEventBase = {
|
|
680
752
|
/** Wall-clock duration of the work the event describes, in milliseconds. */
|
|
681
753
|
durationMs: number;
|
|
@@ -771,7 +843,18 @@ export type ActionRejectLogEvent = ServerLogEventBase & {
|
|
|
771
843
|
* are stripped from paths, tool arguments are reduced to their shape and a run to its steps. Two fields are NOT
|
|
772
844
|
* anonymous and a consumer shipping these events must handle them accordingly: `clientIp` on a request event, and
|
|
773
845
|
* the request path, which is kept verbatim because it is what makes the log usable. */
|
|
774
|
-
|
|
846
|
+
/** Anything else the server has to say — a plugin rebuilt, a manifest that would not load — at its own level. */
|
|
847
|
+
export type ServerMessageLogEvent = {
|
|
848
|
+
kind: 'message';
|
|
849
|
+
level: LogLevel;
|
|
850
|
+
/** What is speaking: `SSR`, `RSC`, `Actions`, `auth`… — what a line used to start with in brackets. */
|
|
851
|
+
scope: string;
|
|
852
|
+
message: string;
|
|
853
|
+
ok: boolean;
|
|
854
|
+
error?: string;
|
|
855
|
+
timestamp: string;
|
|
856
|
+
};
|
|
857
|
+
export type ServerLogEvent = ServerRequestLogEvent | McpToolLogEvent | McpResourceLogEvent | ActionRunLogEvent | ActionRejectLogEvent | ServerMessageLogEvent;
|
|
775
858
|
/** The sink a consumer provides to receive every {@link ServerLogEvent} (see `SSRServerConfig.logger`). */
|
|
776
859
|
export type ServerLogger = (event: ServerLogEvent) => void;
|
|
777
860
|
export type SSRServerConfig = {
|
|
@@ -800,6 +883,11 @@ export type SSRServerConfig = {
|
|
|
800
883
|
/** Where a browser-obtained credential is handed over. Defaults to `/auth/exchange`; served only when the
|
|
801
884
|
* `exchangeCredential` adapter is supplied. */
|
|
802
885
|
exchangePath?: string | false;
|
|
886
|
+
/**
|
|
887
|
+
* Signing visitors in by redirect, through an OAuth 2.1 authorization server — see {@link SSRSignInConfig}. Served
|
|
888
|
+
* only with the `exchangeCredential` adapter, which is what turns what comes back into a session on this host.
|
|
889
|
+
*/
|
|
890
|
+
signIn?: SSRSignInConfig;
|
|
803
891
|
/** Naming and scope of the session cookies this server writes. See {@link SSRAuthCookie}. */
|
|
804
892
|
authCookie?: SSRAuthCookie;
|
|
805
893
|
templateFn?: SSRTemplateFn;
|
|
@@ -808,6 +896,13 @@ export type SSRServerConfig = {
|
|
|
808
896
|
pluginsTtlMs?: number;
|
|
809
897
|
/** Auto-download and cache plugins declared in the schema's offlineData.plugins list. Default: true. */
|
|
810
898
|
autoLoadSchemaPlugins?: boolean;
|
|
899
|
+
/**
|
|
900
|
+
* Whether a schema plugin may be read from a private address — `localhost`, the network this server runs in. A
|
|
901
|
+
* plugin's address is typed by whoever edits a space and read from inside this server, so it answers to the rule
|
|
902
|
+
* every authored request does and is refused there; turn this on only on a development machine whose bucket is on
|
|
903
|
+
* localhost. Default: false.
|
|
904
|
+
*/
|
|
905
|
+
allowPrivatePluginHosts?: boolean;
|
|
811
906
|
/** Where this deployment serves the font files a space uploaded — see {@link SSRFontsConfig}. */
|
|
812
907
|
fonts?: SSRFontsConfig;
|
|
813
908
|
/** Omit client-side JS from the rendered page — useful for verifying SSR HTML without hydration. Default: false. */
|
|
@@ -824,13 +919,34 @@ export type SSRServerConfig = {
|
|
|
824
919
|
rsc?: SSRRscConfig;
|
|
825
920
|
/** Write endpoint for server-driven providers. Absent means the server serves reads only. */
|
|
826
921
|
action?: SSRActionConfig;
|
|
922
|
+
/**
|
|
923
|
+
* Code of this server's own, and the sandbox for the spaces' — shaped as `FunctionsConfig` in
|
|
924
|
+
* `@plitzi/sdk-server/functions`. `native` is trusted code loaded in the process (a self-hosted server's tasks, or a
|
|
925
|
+
* platform's own); `runner` runs each space's functions, isolated.
|
|
926
|
+
*/
|
|
927
|
+
functions?: {
|
|
928
|
+
native?: unknown[];
|
|
929
|
+
runner?: unknown;
|
|
930
|
+
limits?: Record<string, number>;
|
|
931
|
+
};
|
|
932
|
+
/** Realtime channels the spaces declare — see {@link SSRRealtimeConfig}. On, in memory, when absent. */
|
|
933
|
+
realtime?: SSRRealtimeConfig;
|
|
827
934
|
/** Connector manifest and credential lookups — see {@link ConnectorLookupsConfig}. They serve the RSC read path
|
|
828
935
|
* and the `/_action` write endpoint alike; without them neither can reach a connector. */
|
|
829
936
|
connectors?: ConnectorLookupsConfig;
|
|
830
937
|
/** Receives a {@link ServerLogEvent} for every HTTP request this server answers — whatever stage answered it
|
|
831
938
|
* and whatever the outcome — plus every MCP tool call and resource read inside those requests. Without it the
|
|
832
|
-
* server reports nothing per request (the MCP events still reach the console when `MCP_DEBUG=1`).
|
|
939
|
+
* server reports nothing per request (the MCP events still reach the console when `MCP_DEBUG=1`). Everything
|
|
940
|
+
* else the server has to say — a failure, a plugin rebuilt — comes here too as a `message` event, and goes to the
|
|
941
|
+
* console when there is no logger. */
|
|
833
942
|
logger?: ServerLogger;
|
|
943
|
+
/**
|
|
944
|
+
* The least severe thing worth saying — see {@link LogLevel}. `error` by default, `info` with `devMode`: a server
|
|
945
|
+
* in production reports what went wrong and nothing else, unless asked. A request that was answered is `info`, one
|
|
946
|
+
* that failed `error`; a refused action is `warn`. Below the level nothing is built, so a quiet server pays nothing
|
|
947
|
+
* per request for the log it is not keeping.
|
|
948
|
+
*/
|
|
949
|
+
logLevel?: LogLevel | 'silent';
|
|
834
950
|
/**
|
|
835
951
|
* How responses are compressed. Omit for Brotli where the client takes it and gzip otherwise; `false` never
|
|
836
952
|
* compresses, which is what to use when a proxy or CDN in front already does it.
|
|
@@ -849,6 +965,32 @@ export type SSRServerConfig = {
|
|
|
849
965
|
host: string;
|
|
850
966
|
label: string;
|
|
851
967
|
}) => void;
|
|
968
|
+
/**
|
|
969
|
+
* How many processes serve this port. Node runs JavaScript on one thread, so one process renders on one core however
|
|
970
|
+
* many the machine has; each worker is a whole server of its own, and the connections are spread between them —
|
|
971
|
+
* more requests a second, and less time waiting behind another render.
|
|
972
|
+
*
|
|
973
|
+
* `true` / `'auto'`: one per core the process may actually use (a container's CPU quota included). `false`: one
|
|
974
|
+
* process. A number: that many, lowered to the cores there are (more only take turns on the same cores). Default: on
|
|
975
|
+
* under `NODE_ENV=production`, off otherwise — a development server and a test runner stay one process. The
|
|
976
|
+
* `SDK_SERVER_WORKERS` environment variable sets it when this does not.
|
|
977
|
+
*
|
|
978
|
+
* The workers are one server — one replica — and behave as one:
|
|
979
|
+
*
|
|
980
|
+
* - The stores kept in memory by default (an action's `kv`, the job queue, draft previews, the sign-in rate
|
|
981
|
+
* limit) are the primary's, and each worker reaches them over the cluster channel. A store the deployment
|
|
982
|
+
* supplies (Redis, a table) is used as it is.
|
|
983
|
+
* - The scheduler and the job consumers run in one worker only, so a schedule fires once and `jobs.workers` is the
|
|
984
|
+
* whole server's concurrency; if that worker dies, its replacement takes them over.
|
|
985
|
+
* - `server.cache.invalidate()`, `server.plugins.register()` and `server.plugins.invalidate()` reach every worker,
|
|
986
|
+
* whichever process calls them.
|
|
987
|
+
*
|
|
988
|
+
* Per worker: the rendered-page cache (each renders a page once), the plugin components, and the action run caps
|
|
989
|
+
* (`action.concurrency`: `perSpace`, `perProcess`, `renderPerProcess`), which a cluster of replicas already counts
|
|
990
|
+
* per replica. A plugin registered with a `component` stays in the process that registered it — register those
|
|
991
|
+
* where the server is created.
|
|
992
|
+
*/
|
|
993
|
+
workers?: boolean | number | 'auto';
|
|
852
994
|
adapters: SSRAdapters;
|
|
853
995
|
/** Which request-handling services this server mounts: `ssr` on by default, `rsc` whenever
|
|
854
996
|
* `adapters.getRscData` exists. Stages a companion package contributes are deliberately NOT flags here —
|
|
@@ -875,6 +1017,28 @@ export type SSRServerConfig = {
|
|
|
875
1017
|
* `createServer` from `@plitzi/sdk-server` takes and what the SSR stages are handed, so a page stage reaches
|
|
876
1018
|
* `getOfflineData` without asking whether it is there — while a stage typed to the bare context (anything from
|
|
877
1019
|
* `@plitzi/sdk-mcp`, which also runs in servers that have neither) still has to check. */
|
|
1020
|
+
/**
|
|
1021
|
+
* A visitor signs in somewhere else and comes back signed in HERE: `GET <path>?return=/somewhere` sends them to the
|
|
1022
|
+
* authorization server, and `GET <path>/callback` takes the code it answers with, redeems it server to server and
|
|
1023
|
+
* hands the token to `exchangeCredential` — which is what makes the session, on this host, for this space.
|
|
1024
|
+
*
|
|
1025
|
+
* This server registers itself with the authorization server (RFC 7591) as the host the visitor is on, and proves the
|
|
1026
|
+
* exchange with PKCE. The state travels in a `__Host-` cookie, which no sibling host can set: a sign-in somebody else
|
|
1027
|
+
* started cannot be finished in this browser.
|
|
1028
|
+
*/
|
|
1029
|
+
export type SSRSignInConfig = {
|
|
1030
|
+
/** What `exchangeCredential` knows the tokens by. */
|
|
1031
|
+
provider: string;
|
|
1032
|
+
/** Where the visitor's browser is sent: the authorization server's `/authorize`, as the public reaches it. */
|
|
1033
|
+
authorizeUrl: string;
|
|
1034
|
+
/** Where this server registers itself and redeems codes — reachable from here, which may be a private address. */
|
|
1035
|
+
registerUrl: string;
|
|
1036
|
+
tokenUrl: string;
|
|
1037
|
+
/** What to ask for, for the space being signed into. */
|
|
1038
|
+
scope: (spaceId: number) => string;
|
|
1039
|
+
/** Where the flow answers. Default `/auth/sign-in`; the authorization server sends people back to `<path>/callback`. */
|
|
1040
|
+
path?: string;
|
|
1041
|
+
};
|
|
878
1042
|
export type SSRPageServerConfig = SSRServerConfig & {
|
|
879
1043
|
adapters: SSRPageAdapters;
|
|
880
1044
|
};
|
|
@@ -961,8 +1125,15 @@ export type OAuthAdapters = {
|
|
|
961
1125
|
* first visit.
|
|
962
1126
|
*/
|
|
963
1127
|
identify: (req: SSRRequest) => Promise<OAuthUser | undefined>;
|
|
964
|
-
/**
|
|
965
|
-
|
|
1128
|
+
/**
|
|
1129
|
+
* What this user may grant access to. An empty list ends the flow with `access_denied`.
|
|
1130
|
+
*
|
|
1131
|
+
* `request.scope` is what the client asked for, so one deployment can offer different choices to different
|
|
1132
|
+
* clients — a native client signing in as the person, and the same client asking which space to work in.
|
|
1133
|
+
*/
|
|
1134
|
+
grantTargets: (user: OAuthUser, request: {
|
|
1135
|
+
scope?: string;
|
|
1136
|
+
}) => Promise<OAuthGrantTarget[]>;
|
|
966
1137
|
/**
|
|
967
1138
|
* End whatever session {@link OAuthAdapters.identify} was reading, so the person can connect as somebody else.
|
|
968
1139
|
*
|
|
@@ -974,13 +1145,53 @@ export type OAuthAdapters = {
|
|
|
974
1145
|
* that does not mean abandoning the connection and starting over from the host.
|
|
975
1146
|
*/
|
|
976
1147
|
signOut?: (req: SSRRequest, res: SSRResponseHelpers) => void | Promise<void>;
|
|
977
|
-
/** Mint the bearer the client will send on every
|
|
978
|
-
issueToken: (user: OAuthUser, target: OAuthGrantTarget) => Promise<{
|
|
1148
|
+
/** Mint the bearer the client will send on every request. Return undefined to deny the grant. */
|
|
1149
|
+
issueToken: (user: OAuthUser, target: OAuthGrantTarget, context: OAuthIssueContext) => Promise<{
|
|
979
1150
|
token: string;
|
|
980
1151
|
expiresInSeconds?: number;
|
|
981
1152
|
} | undefined>;
|
|
1153
|
+
/**
|
|
1154
|
+
* End a credential {@link OAuthAdapters.issueToken} minted, when its grant is revoked (RFC 7009).
|
|
1155
|
+
*
|
|
1156
|
+
* Optional, for a credential that ends on its own. Without it, revoking a grant stops it being RENEWED, and what
|
|
1157
|
+
* was already issued keeps working until it expires — which a person who just signed a device out reads as the
|
|
1158
|
+
* sign-out not having happened, because the device is still there in their list.
|
|
1159
|
+
*/
|
|
1160
|
+
revokeToken?: (credential: string) => Promise<void>;
|
|
982
1161
|
store: OAuthStore;
|
|
983
1162
|
};
|
|
1163
|
+
/**
|
|
1164
|
+
* Who a credential is being issued to, beyond the person: which application, from where, and — on a renewal — which
|
|
1165
|
+
* credential it takes the place of.
|
|
1166
|
+
*
|
|
1167
|
+
* This is what lets a deployment tell its user WHICH of their devices a credential lives on. The application names
|
|
1168
|
+
* itself when it registers (RFC 7591 `client_name`, `software_id`); the request is the one the credential is being
|
|
1169
|
+
* issued on — at consent, the person's browser, which for a loopback client is the same machine.
|
|
1170
|
+
*/
|
|
1171
|
+
export type OAuthIssueContext = {
|
|
1172
|
+
client: {
|
|
1173
|
+
clientId: string;
|
|
1174
|
+
/** What the application registered as: `Plitzi CLI on carlos-mbp`, `Claude`. */
|
|
1175
|
+
name: string;
|
|
1176
|
+
/** RFC 7591 `software_id`, when it sent one: a stable name for the SOFTWARE, the same on every machine. */
|
|
1177
|
+
softwareId?: string;
|
|
1178
|
+
};
|
|
1179
|
+
request?: {
|
|
1180
|
+
userAgent?: string;
|
|
1181
|
+
ip?: string;
|
|
1182
|
+
};
|
|
1183
|
+
/**
|
|
1184
|
+
* Where the code of THIS grant is sent: the `redirect_uri` of the authorization request, at consent. A deployment
|
|
1185
|
+
* whose credential is only good at certain addresses checks it here — registering a client is open to anybody, and
|
|
1186
|
+
* the address it names is the one thing that says who will receive what the person agreed to. Absent on a renewal.
|
|
1187
|
+
*/
|
|
1188
|
+
redirectUri?: string;
|
|
1189
|
+
/**
|
|
1190
|
+
* The credential this grant last issued, on a renewal. A deployment that keeps a row per credential updates that
|
|
1191
|
+
* row rather than adding one, so a device renewing every hour stays one device.
|
|
1192
|
+
*/
|
|
1193
|
+
replaces?: string;
|
|
1194
|
+
};
|
|
984
1195
|
/** A connection a visitor may take WITHOUT signing in, for a server whose public surface needs no identity — the
|
|
985
1196
|
* MCP App, the tool and resource listings, the guide. The consent screen offers it as a second button beside the
|
|
986
1197
|
* sign-in, and the grant is whatever `target` grants: point it at a target that carries no space, never at one
|
|
@@ -1043,6 +1254,21 @@ export type OAuthConsentView = {
|
|
|
1043
1254
|
canSwitchUser?: boolean;
|
|
1044
1255
|
/** A message to show the user. */
|
|
1045
1256
|
error?: string;
|
|
1257
|
+
/**
|
|
1258
|
+
* Who is asking, and where the grant goes if the person says yes.
|
|
1259
|
+
*
|
|
1260
|
+
* Anybody can register a client, call it anything and send somebody this screen on the deployment's own domain, so
|
|
1261
|
+
* the name alone proves nothing. The host the code is sent back to is the one fact the requester cannot choose
|
|
1262
|
+
* freely, and it is what tells "the app I just opened" apart from a stranger's server.
|
|
1263
|
+
*/
|
|
1264
|
+
client: {
|
|
1265
|
+
/** What the client registered itself as. Chosen by the client, so it is shown as a claim. */
|
|
1266
|
+
name: string;
|
|
1267
|
+
/** The host of the `redirect_uri` the grant is delivered to. */
|
|
1268
|
+
redirectHost: string;
|
|
1269
|
+
/** The grant goes back to an app listening on this computer (RFC 8252 loopback), not to a server. */
|
|
1270
|
+
loopback: boolean;
|
|
1271
|
+
};
|
|
1046
1272
|
branding: OAuthBranding;
|
|
1047
1273
|
};
|
|
1048
1274
|
/** OAuth 2.1 authorization for the MCP server (RFC 9728 discovery + RFC 7591 dynamic client registration +
|
|
@@ -1091,6 +1317,15 @@ export type OAuthConfig = {
|
|
|
1091
1317
|
* holds, and wrapping it costs a store read on every request and gives a second thing to revoke.
|
|
1092
1318
|
*/
|
|
1093
1319
|
directTokens?: boolean;
|
|
1320
|
+
/**
|
|
1321
|
+
* Accept only loopback `redirect_uri`s (`http://127.0.0.1:<port>/…`, RFC 8252 §7.3), at registration and again at
|
|
1322
|
+
* `/authorize`.
|
|
1323
|
+
*
|
|
1324
|
+
* Turn it on when every client is a native app on the person's own machine — a CLI, a desktop app — and above all
|
|
1325
|
+
* with {@link directTokens}, where the grant IS the person's session. Registration is open to anybody, so with https
|
|
1326
|
+
* redirects allowed a stranger's server can register, send somebody the link, and collect what they approve.
|
|
1327
|
+
*/
|
|
1328
|
+
loopbackRedirectsOnly?: boolean;
|
|
1094
1329
|
};
|
|
1095
1330
|
/** A short-TTL, one-shot store for unsaved draft offline-data behind a preview token. The SDK ships an
|
|
1096
1331
|
* in-memory default (fine for a single replica); a multi-replica deployment injects a shared (e.g. Redis)
|
|
@@ -1107,11 +1342,15 @@ export type OAuthConfig = {
|
|
|
1107
1342
|
export type DraftPutOptions = {
|
|
1108
1343
|
ttlMs: number;
|
|
1109
1344
|
reusable?: boolean;
|
|
1345
|
+
/** The space the draft was made from. It is only ever rendered for that space. */
|
|
1346
|
+
spaceId: number;
|
|
1110
1347
|
};
|
|
1111
1348
|
/** A stashed draft, and whether the read that resolved it left it there. */
|
|
1112
1349
|
export type DraftEntry = {
|
|
1113
1350
|
data: OfflineDataRaw;
|
|
1114
1351
|
reusable: boolean;
|
|
1352
|
+
/** The space the draft was made from — see {@link DraftPutOptions.spaceId}. */
|
|
1353
|
+
spaceId: number;
|
|
1115
1354
|
};
|
|
1116
1355
|
export type DraftStore = {
|
|
1117
1356
|
put: (token: string, data: OfflineDataRaw, options: DraftPutOptions) => void | Promise<void>;
|
|
@@ -1133,7 +1372,12 @@ export type SSRPreviewConfig = {
|
|
|
1133
1372
|
enabled?: boolean;
|
|
1134
1373
|
/** Internal endpoint path that mints a preview token. Default '/__preview'. */
|
|
1135
1374
|
path?: string;
|
|
1136
|
-
/**
|
|
1375
|
+
/**
|
|
1376
|
+
* Shared secret required in the `x-preview-secret` header; requests without it are rejected.
|
|
1377
|
+
*
|
|
1378
|
+
* Required for the endpoint to answer at all: the page server that hosts it is the one the public reaches, so an
|
|
1379
|
+
* enabled endpoint with no secret refuses every request rather than serving anyone.
|
|
1380
|
+
*/
|
|
1137
1381
|
secret?: string;
|
|
1138
1382
|
/** One-shot token time-to-live in milliseconds. Default 60000. */
|
|
1139
1383
|
ttlMs?: number;
|
|
@@ -44,6 +44,59 @@ export type SpaceCredential = {
|
|
|
44
44
|
createdAt: number;
|
|
45
45
|
updatedAt: number;
|
|
46
46
|
};
|
|
47
|
+
/**
|
|
48
|
+
* A person given one of the space's visitor roles (`settings.visitorRoles`), by email. `claimed` says whether an
|
|
49
|
+
* account has taken it yet: a role given to an address waits for somebody to sign in with it, verified.
|
|
50
|
+
*/
|
|
51
|
+
export type SpaceVisitor = {
|
|
52
|
+
id: number;
|
|
53
|
+
email: string;
|
|
54
|
+
role: string;
|
|
55
|
+
claimed: boolean;
|
|
56
|
+
createdAt: number;
|
|
57
|
+
updatedAt: number;
|
|
58
|
+
};
|
|
59
|
+
/** One environment's runtime — the space's own server code run beside the platform — and how it last was. */
|
|
60
|
+
export type SpaceRuntimeEnvironment = {
|
|
61
|
+
environment: string;
|
|
62
|
+
/** 0 for the draft. */
|
|
63
|
+
revision: number;
|
|
64
|
+
/** The packed code it runs, by what its bytes are. */
|
|
65
|
+
digest: string;
|
|
66
|
+
status: 'waiting' | 'starting' | 'ready' | 'failed' | 'stopping' | 'stopped';
|
|
67
|
+
/** Why it is not running, for whoever manages the space. */
|
|
68
|
+
error: string | null;
|
|
69
|
+
/** Why it is kept stopped: `idle` (unused for too long) or `manual`. */
|
|
70
|
+
stoppedReason: 'idle' | 'manual' | null;
|
|
71
|
+
/** When a running one stops for being unused, unless something uses it before — unix seconds. */
|
|
72
|
+
idleStopsAt: number | null;
|
|
73
|
+
/** The paths of the space it answers itself (`/mcp`). */
|
|
74
|
+
endpoints: string[];
|
|
75
|
+
/** Its tasks, as flows name them (`board.create`). */
|
|
76
|
+
tasks: string[];
|
|
77
|
+
startedAt: number | null;
|
|
78
|
+
/** The size it runs at — or will start at — by name (`SpaceRuntimeSizeOption['name']`). */
|
|
79
|
+
size: string;
|
|
80
|
+
};
|
|
81
|
+
/** A size a runtime may run at: what its pod may spend, and whether the space's plan includes it. */
|
|
82
|
+
export type SpaceRuntimeSizeOption = {
|
|
83
|
+
name: string;
|
|
84
|
+
label: string;
|
|
85
|
+
/** As Kubernetes reads it: `250m` is a quarter of a core. */
|
|
86
|
+
cpu: string;
|
|
87
|
+
/** As Kubernetes reads it: `256Mi`. */
|
|
88
|
+
memory: string;
|
|
89
|
+
included: boolean;
|
|
90
|
+
};
|
|
91
|
+
/** A space's runtime: every environment's, and the names of the variables it starts with — never their values. */
|
|
92
|
+
export type SpaceRuntime = {
|
|
93
|
+
environments: SpaceRuntimeEnvironment[];
|
|
94
|
+
variables: string[];
|
|
95
|
+
/** Every size there is, smallest first. */
|
|
96
|
+
sizes: SpaceRuntimeSizeOption[];
|
|
97
|
+
/** How long a runtime may go unused before it is stopped; 0 when the platform never stops one. */
|
|
98
|
+
idleMinutes: number;
|
|
99
|
+
};
|
|
47
100
|
export type SpaceDeployment = {
|
|
48
101
|
id: number;
|
|
49
102
|
environment: Environment;
|
|
@@ -4,4 +4,10 @@ export type RuntimeStateInstance = {
|
|
|
4
4
|
setState: (value: RuntimeState | ((prev: RuntimeState) => RuntimeState)) => void;
|
|
5
5
|
setStateByKey: (key: string, value: unknown) => void;
|
|
6
6
|
clearState: () => void;
|
|
7
|
+
/**
|
|
8
|
+
* Called with the whole state after every change to it, until the returned function is called. What a host or a
|
|
9
|
+
* plugin that keeps the state somewhere of its own — a store, a URL, an analytics call — listens to instead of
|
|
10
|
+
* polling `state`.
|
|
11
|
+
*/
|
|
12
|
+
subscribe: (listener: (state: RuntimeState) => void) => () => void;
|
|
7
13
|
};
|