@honua/react 0.1.4-beta.0 → 0.1.9-beta.0
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/contract/types.d.ts +1 -1
- package/contract/types.d.ts.map +1 -1
- package/contract/types.js +4 -0
- package/control-plane/admin-client.d.ts +87 -0
- package/control-plane/admin-client.d.ts.map +1 -0
- package/control-plane/admin-client.js +169 -0
- package/control-plane/client.d.ts.map +1 -1
- package/control-plane/client.js +21 -3
- package/control-plane/commands/catalog.d.ts +133 -0
- package/control-plane/commands/catalog.d.ts.map +1 -0
- package/control-plane/commands/catalog.js +353 -0
- package/control-plane/commands/errors.d.ts +96 -0
- package/control-plane/commands/errors.d.ts.map +1 -0
- package/control-plane/commands/errors.js +130 -0
- package/control-plane/commands/identity.d.ts +71 -0
- package/control-plane/commands/identity.d.ts.map +1 -0
- package/control-plane/commands/identity.js +0 -0
- package/control-plane/commands/index.d.ts +39 -0
- package/control-plane/commands/index.d.ts.map +1 -0
- package/control-plane/commands/index.js +34 -0
- package/control-plane/commands/runtime.d.ts +146 -0
- package/control-plane/commands/runtime.d.ts.map +1 -0
- package/control-plane/commands/runtime.js +318 -0
- package/control-plane/commands/types.d.ts +226 -0
- package/control-plane/commands/types.d.ts.map +1 -0
- package/control-plane/commands/types.js +30 -0
- package/control-plane/commands/validate.d.ts +27 -0
- package/control-plane/commands/validate.d.ts.map +1 -0
- package/control-plane/commands/validate.js +132 -0
- package/control-plane/generated/admin-api.d.ts +30263 -0
- package/control-plane/generated/admin-api.d.ts.map +1 -0
- package/control-plane/generated/admin-api.js +5 -0
- package/control-plane/generated/admin-operations.d.ts +4053 -0
- package/control-plane/generated/admin-operations.d.ts.map +1 -0
- package/control-plane/generated/admin-operations.js +820 -0
- package/control-plane/index.d.ts +11 -0
- package/control-plane/index.d.ts.map +1 -1
- package/control-plane/index.js +8 -0
- package/control-plane/types.d.ts +14 -0
- package/control-plane/types.d.ts.map +1 -1
- package/core/client.d.ts +6 -0
- package/core/client.d.ts.map +1 -1
- package/core/client.js +12 -10
- package/core/credential-redaction.d.ts +163 -0
- package/core/credential-redaction.d.ts.map +1 -0
- package/core/credential-redaction.js +389 -0
- package/core/error-classifications.d.ts +32 -0
- package/core/error-classifications.d.ts.map +1 -1
- package/core/error-classifications.js +32 -0
- package/core/error-code-registry.d.ts +33 -1
- package/core/error-code-registry.d.ts.map +1 -1
- package/core/error-code-registry.js +32 -0
- package/core/errors.d.ts +1 -1
- package/core/errors.d.ts.map +1 -1
- package/core/geoparquet-sql.d.ts +1 -1
- package/core/geoparquet-sql.js +2 -2
- package/core/grpc-adapter.d.ts +2 -2
- package/core/grpc-adapter.d.ts.map +1 -1
- package/core/grpc-adapter.js +30 -6
- package/core/job-run-errors.d.ts +10 -0
- package/core/job-run-errors.d.ts.map +1 -0
- package/core/job-run-errors.js +14 -0
- package/core/job-run-lifecycle.d.ts +34 -0
- package/core/job-run-lifecycle.d.ts.map +1 -0
- package/core/job-run-lifecycle.js +193 -0
- package/core/ogc-processes.d.ts +38 -31
- package/core/ogc-processes.d.ts.map +1 -1
- package/core/ogc-processes.js +123 -173
- package/core/process-runner.js +15 -100
- package/core/stac.d.ts +2 -1
- package/core/stac.d.ts.map +1 -1
- package/core/stac.js +29 -11
- package/core/surfaces.d.ts +2 -8
- package/core/surfaces.d.ts.map +1 -1
- package/core/surfaces.js +21 -112
- package/core/types.d.ts +22 -8
- package/core/types.d.ts.map +1 -1
- package/gen/geospatial/v1/common_pb.d.ts +514 -0
- package/gen/geospatial/v1/common_pb.d.ts.map +1 -0
- package/gen/geospatial/v1/common_pb.js +335 -0
- package/gen/geospatial/v1/execution_types_pb.d.ts +1186 -0
- package/gen/geospatial/v1/execution_types_pb.d.ts.map +1 -0
- package/gen/geospatial/v1/execution_types_pb.js +396 -0
- package/gen/geospatial/v1/feature_service_pb.d.ts +403 -0
- package/gen/geospatial/v1/feature_service_pb.d.ts.map +1 -0
- package/gen/geospatial/v1/feature_service_pb.js +47 -0
- package/gen/geospatial/v1/index.d.ts +5 -0
- package/gen/geospatial/v1/index.d.ts.map +1 -0
- package/gen/geospatial/v1/index.js +9 -0
- package/gen/geospatial/v1/spatial_types_pb.d.ts +285 -0
- package/gen/geospatial/v1/spatial_types_pb.d.ts.map +1 -0
- package/gen/geospatial/v1/spatial_types_pb.js +58 -0
- package/gen/geospatial/v1/workspace_artifact_types_pb.d.ts +379 -0
- package/gen/geospatial/v1/workspace_artifact_types_pb.d.ts.map +1 -0
- package/gen/geospatial/v1/workspace_artifact_types_pb.js +151 -0
- package/generated-app/projection.d.ts.map +1 -1
- package/generated-app/projection.js +10 -1
- package/interactions/declarative-contract.d.ts +149 -0
- package/interactions/declarative-contract.d.ts.map +1 -0
- package/interactions/declarative-contract.js +293 -0
- package/interactions/declarative.d.ts +198 -0
- package/interactions/declarative.d.ts.map +1 -0
- package/interactions/declarative.js +470 -0
- package/interactions/feature-state.d.ts +7 -0
- package/interactions/feature-state.d.ts.map +1 -1
- package/interactions/feature-state.js +10 -2
- package/map/maplibre-target.js +1 -1
- package/package.json +2 -2
- package/query-planner/grpc.d.ts +4 -4
- package/query-planner/grpc.d.ts.map +1 -1
- package/query-planner/grpc.js +11 -11
- package/query-planner/types.d.ts +4 -4
- package/query-planner/types.d.ts.map +1 -1
- package/realtime/sse.d.ts.map +1 -1
- package/realtime/sse.js +7 -1
- package/runtime/errors.d.ts +1 -1
- package/runtime/errors.d.ts.map +1 -1
- package/runtime/errors.js +2 -0
- package/runtime/generated/map-package-schema-meta.d.ts +11 -0
- package/runtime/generated/map-package-schema-meta.d.ts.map +1 -0
- package/runtime/generated/map-package-schema-meta.js +12 -0
- package/runtime/generated/map-package-schema-validator.d.ts +16 -0
- package/runtime/generated/map-package-schema-validator.d.ts.map +1 -0
- package/runtime/generated/map-package-schema-validator.js +1422 -0
- package/runtime/index.d.ts +5 -1
- package/runtime/index.d.ts.map +1 -1
- package/runtime/index.js +6 -0
- package/runtime/map-package-export.d.ts +151 -0
- package/runtime/map-package-export.d.ts.map +1 -0
- package/runtime/map-package-export.js +636 -0
- package/runtime/map-package-validation.d.ts +21 -1
- package/runtime/map-package-validation.d.ts.map +1 -1
- package/runtime/map-package-validation.js +132 -95
- package/runtime/map-package.d.ts +80 -0
- package/runtime/map-package.d.ts.map +1 -1
- package/runtime/style-compose.d.ts.map +1 -1
- package/runtime/style-compose.js +78 -9
- package/studio/chart-spec.d.ts +6 -6
- package/studio/chart-spec.d.ts.map +1 -1
- package/studio/chart-spec.js +6 -6
- package/studio/index.d.ts +17 -7
- package/studio/index.d.ts.map +1 -1
- package/studio/index.js +15 -5
- package/studio/lifecycle-client.d.ts +262 -22
- package/studio/lifecycle-client.d.ts.map +1 -1
- package/studio/lifecycle-client.js +524 -24
- package/studio/lifecycle-errors.d.ts +8 -2
- package/studio/lifecycle-errors.d.ts.map +1 -1
- package/studio/lifecycle-errors.js +6 -1
- package/studio/lifecycle-types.d.ts +228 -8
- package/studio/lifecycle-types.d.ts.map +1 -1
- package/studio/publication-status.d.ts +55 -0
- package/studio/publication-status.d.ts.map +1 -0
- package/studio/publication-status.js +103 -0
- package/gen/honua/v1/feature_service_pb.d.ts +0 -918
- package/gen/honua/v1/feature_service_pb.d.ts.map +0 -1
- package/gen/honua/v1/feature_service_pb.js +0 -375
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared application-command contract for the Honua control plane.
|
|
3
|
+
*
|
|
4
|
+
* Every surface — the `honua` CLI, the MCP server, Studio, and direct JS —
|
|
5
|
+
* invokes the *same* {@link HonuaCommand} objects. A transport adapts input
|
|
6
|
+
* and output only: it parses its own argument shape into the command's
|
|
7
|
+
* declared JSON-schema input, hands the result to
|
|
8
|
+
* `HonuaCommandRuntime.execute`, and renders the returned
|
|
9
|
+
* {@link HonuaCommandReceipt}. Domain sequencing (read-modify-write,
|
|
10
|
+
* optimistic-concurrency checks, job hand-off) and the dry-run projection live
|
|
11
|
+
* on the command, never on the transport.
|
|
12
|
+
*
|
|
13
|
+
* Authorization is deliberately **not** modelled here beyond an echo. The
|
|
14
|
+
* command layer carries no administrator credential of its own, refuses
|
|
15
|
+
* caller-supplied authority headers and the request-identity headers it derives
|
|
16
|
+
* itself (see `assertNoAuthorityOverride` and `assertNoCommandKeyOverride` in
|
|
17
|
+
* `./runtime.js`), and stamps every receipt `authorization:
|
|
18
|
+
* "server-enforced"`. A client cannot approve its own publication by choosing
|
|
19
|
+
* a different transport because no transport can express approval at all —
|
|
20
|
+
* the shared command inputs have no approval field and every command input
|
|
21
|
+
* schema is closed (`additionalProperties: false`).
|
|
22
|
+
*
|
|
23
|
+
* @experimental Part of the `@honua/sdk-js/control-plane` experimental
|
|
24
|
+
* entrypoint; not yet covered by the SDK's semver contract.
|
|
25
|
+
* @module
|
|
26
|
+
*/
|
|
27
|
+
import type { QueryMethod } from "../../core/types.js";
|
|
28
|
+
import type { HonuaStudioLifecycleClient } from "../../studio/lifecycle-client.js";
|
|
29
|
+
import type { HonuaControlPlaneClient } from "../client.js";
|
|
30
|
+
import type { HonuaControlPlaneRequestOptions, HonuaEntityValidators, HonuaProblemDetails } from "../types.js";
|
|
31
|
+
import type { HonuaCommandValidationIssue } from "./errors.js";
|
|
32
|
+
/**
|
|
33
|
+
* JSON-Schema subset used to describe a command's input.
|
|
34
|
+
*
|
|
35
|
+
* Structurally the same dialect `HonuaAgentToolDefinition.inputSchema` uses
|
|
36
|
+
* (`src/agent-tools/index.ts`) so MCP tool schemas, CLI help, and Studio forms
|
|
37
|
+
* can all project from one description. It is redeclared here rather than
|
|
38
|
+
* imported so the control-plane split package does not pull in the agent-tool
|
|
39
|
+
* runtime. `src/` is deliberately zod-free.
|
|
40
|
+
*/
|
|
41
|
+
export interface HonuaCommandJsonSchema {
|
|
42
|
+
readonly type?: string | readonly string[];
|
|
43
|
+
readonly description?: string;
|
|
44
|
+
readonly enum?: readonly unknown[];
|
|
45
|
+
readonly format?: string;
|
|
46
|
+
readonly properties?: Readonly<Record<string, HonuaCommandJsonSchema>>;
|
|
47
|
+
readonly items?: HonuaCommandJsonSchema;
|
|
48
|
+
readonly required?: readonly string[];
|
|
49
|
+
readonly additionalProperties?: boolean | HonuaCommandJsonSchema;
|
|
50
|
+
readonly minLength?: number;
|
|
51
|
+
readonly maxLength?: number;
|
|
52
|
+
readonly minimum?: number;
|
|
53
|
+
readonly maximum?: number;
|
|
54
|
+
readonly default?: unknown;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* `read` commands never mutate and never carry an idempotency key on the
|
|
58
|
+
* wire; `action` commands do both. Mirrors `HonuaAgentToolMode`.
|
|
59
|
+
*/
|
|
60
|
+
export type HonuaCommandMode = "read" | "action";
|
|
61
|
+
/**
|
|
62
|
+
* Terminal state recorded on a {@link HonuaCommandReceipt}. Mirrors
|
|
63
|
+
* `HonuaAgentToolStatus` and adds `cancelled` for `AbortSignal` aborts.
|
|
64
|
+
*/
|
|
65
|
+
export type HonuaCommandStatus = "ok" | "dry-run" | "denied" | "cancelled" | "error";
|
|
66
|
+
/** Surfaces that may invoke a command. Recorded, never trusted. */
|
|
67
|
+
export declare const HONUA_COMMAND_TRANSPORTS: readonly ["cli", "mcp", "studio", "sdk"];
|
|
68
|
+
/** One of {@link HONUA_COMMAND_TRANSPORTS}. */
|
|
69
|
+
export type HonuaCommandTransport = (typeof HONUA_COMMAND_TRANSPORTS)[number];
|
|
70
|
+
/**
|
|
71
|
+
* Acting identity and tenant, as the *caller claims them*.
|
|
72
|
+
*
|
|
73
|
+
* These values are echoed onto the receipt so a downstream audit join can line
|
|
74
|
+
* a receipt up with the server-side record. They are never sent as request
|
|
75
|
+
* headers and never used to make a local authorization decision — the server
|
|
76
|
+
* derives the real acting identity from the credential on the
|
|
77
|
+
* {@link HonuaControlPlaneClient}'s underlying `HonuaClient`.
|
|
78
|
+
*/
|
|
79
|
+
export interface HonuaCommandIdentity {
|
|
80
|
+
/** Acting principal id as claimed by the caller. */
|
|
81
|
+
readonly actor?: string;
|
|
82
|
+
/** Tenant / workspace-owner echo. */
|
|
83
|
+
readonly tenantId?: string;
|
|
84
|
+
/** OAuth scope ceiling the caller believes it holds, sorted for determinism. */
|
|
85
|
+
readonly scopes?: readonly string[];
|
|
86
|
+
}
|
|
87
|
+
/** Stable pointer to the resource a command read or affected. */
|
|
88
|
+
export interface HonuaCommandResourceRef {
|
|
89
|
+
/** Resource kind, e.g. `map-package`, `import-job`, `connection`. */
|
|
90
|
+
readonly type: string;
|
|
91
|
+
/** Server-assigned identifier, when the server returned one. */
|
|
92
|
+
readonly id?: string;
|
|
93
|
+
/** Owning workspace, when scoped. */
|
|
94
|
+
readonly workspaceId?: string;
|
|
95
|
+
/** Absolute or root-relative link the server returned for the resource. */
|
|
96
|
+
readonly href?: string;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* The request a command *would* issue. Produced by {@link HonuaCommand.plan},
|
|
100
|
+
* recorded on every receipt, and the only thing a dry run evaluates — a dry
|
|
101
|
+
* run never reaches {@link HonuaCommand.execute}, so no transport can
|
|
102
|
+
* accidentally execute while previewing.
|
|
103
|
+
*
|
|
104
|
+
* Deliberately carries no request body: command inputs can contain connection
|
|
105
|
+
* credentials, and a plan is rendered to terminals and logs.
|
|
106
|
+
*
|
|
107
|
+
* It also carries no **resource link**. `resourceRef.href` is dropped by the
|
|
108
|
+
* runtime before the plan reaches a receipt, so a dry run — which is nothing
|
|
109
|
+
* but this plan — cannot print a URL for a resource that was never created or
|
|
110
|
+
* published (honua-sdk-js#1426). A link appears on a receipt only when the
|
|
111
|
+
* *server* returned one to {@link HonuaCommand.execute}.
|
|
112
|
+
*/
|
|
113
|
+
export interface HonuaCommandPlan {
|
|
114
|
+
readonly method: QueryMethod;
|
|
115
|
+
/** Path relative to the client's base path, exactly as the command will call it. */
|
|
116
|
+
readonly path: string;
|
|
117
|
+
/**
|
|
118
|
+
* One-line human summary for CLI/Studio previews.
|
|
119
|
+
*
|
|
120
|
+
* A command builds this from its own input, so it can name a source URL. The
|
|
121
|
+
* runtime passes it through the SDK's credential recognizer before it reaches
|
|
122
|
+
* a receipt, so a presigned URL or an embedded secret is withheld rather than
|
|
123
|
+
* persisted into an audit record. Commands should still prefer identifiers to
|
|
124
|
+
* URLs here.
|
|
125
|
+
*/
|
|
126
|
+
readonly summary: string;
|
|
127
|
+
/** Resource this request addresses. Any `href` is stripped by the runtime. */
|
|
128
|
+
readonly resourceRef?: HonuaCommandResourceRef;
|
|
129
|
+
}
|
|
130
|
+
/** What {@link HonuaCommand.execute} returns to the runtime. */
|
|
131
|
+
export interface HonuaCommandOutcome<TOutput> {
|
|
132
|
+
readonly output: TOutput;
|
|
133
|
+
/** Overrides `ok`; use `denied` when the server durably recorded a refusal. */
|
|
134
|
+
readonly status?: Extract<HonuaCommandStatus, "ok" | "denied">;
|
|
135
|
+
readonly resourceRef?: HonuaCommandResourceRef;
|
|
136
|
+
readonly validators?: HonuaEntityValidators;
|
|
137
|
+
readonly problem?: HonuaProblemDetails;
|
|
138
|
+
}
|
|
139
|
+
/** Discriminating tag on {@link HonuaCommandReceipt}. */
|
|
140
|
+
export declare const HONUA_COMMAND_RECEIPT_KIND: "honua.command.receipt.v1";
|
|
141
|
+
/**
|
|
142
|
+
* Deterministic, serializable record of one command invocation.
|
|
143
|
+
*
|
|
144
|
+
* Two equivalent calls made from different transports produce identical
|
|
145
|
+
* receipts apart from {@link HonuaCommandReceipt.transport}; `auditKey` hashes
|
|
146
|
+
* the transport-independent projection so a server-side audit join can match
|
|
147
|
+
* them. Nothing here is time-, host-, or random-dependent: `idempotencyKey`
|
|
148
|
+
* and `correlationId` are derived from the command id, the canonicalized
|
|
149
|
+
* input, and the tenant unless the caller supplies them.
|
|
150
|
+
*/
|
|
151
|
+
export interface HonuaCommandReceipt<TOutput = unknown> {
|
|
152
|
+
readonly kind: typeof HONUA_COMMAND_RECEIPT_KIND;
|
|
153
|
+
readonly commandId: string;
|
|
154
|
+
readonly mode: HonuaCommandMode;
|
|
155
|
+
readonly status: HonuaCommandStatus;
|
|
156
|
+
readonly idempotencyKey: string;
|
|
157
|
+
readonly correlationId: string;
|
|
158
|
+
readonly identity: HonuaCommandIdentity;
|
|
159
|
+
/** Surface that issued the call. Recorded for audit; excluded from `auditKey`. */
|
|
160
|
+
readonly transport: HonuaCommandTransport;
|
|
161
|
+
/** Always `server-enforced`: the command layer makes no authorization decision. */
|
|
162
|
+
readonly authorization: "server-enforced";
|
|
163
|
+
readonly plan: HonuaCommandPlan;
|
|
164
|
+
readonly resourceRef?: HonuaCommandResourceRef;
|
|
165
|
+
readonly validators?: HonuaEntityValidators;
|
|
166
|
+
readonly problem?: HonuaProblemDetails;
|
|
167
|
+
readonly output?: TOutput;
|
|
168
|
+
/** Hash of the transport-independent projection. Equal across transports. */
|
|
169
|
+
readonly auditKey: string;
|
|
170
|
+
}
|
|
171
|
+
/** Per-invocation context handed to {@link HonuaCommand.plan} and `execute`. */
|
|
172
|
+
export interface HonuaCommandContext<TInput> {
|
|
173
|
+
/** Input after schema validation. */
|
|
174
|
+
readonly input: TInput;
|
|
175
|
+
readonly controlPlane: HonuaControlPlaneClient;
|
|
176
|
+
/**
|
|
177
|
+
* Studio lifecycle client, present only when the host supplied one. Commands
|
|
178
|
+
* in the `studio.*` namespace throw a `transport` `HonuaCommandError` when it
|
|
179
|
+
* is absent rather than reaching for a second credential.
|
|
180
|
+
*/
|
|
181
|
+
readonly studio?: HonuaStudioLifecycleClient;
|
|
182
|
+
readonly identity: HonuaCommandIdentity;
|
|
183
|
+
readonly transport: HonuaCommandTransport;
|
|
184
|
+
readonly idempotencyKey: string;
|
|
185
|
+
readonly correlationId: string;
|
|
186
|
+
readonly dryRun: boolean;
|
|
187
|
+
readonly signal?: AbortSignal;
|
|
188
|
+
/**
|
|
189
|
+
* Request options for the underlying resource client, with `Idempotency-Key`
|
|
190
|
+
* (action commands only), `If-Match`, the caller's `AbortSignal`, and the
|
|
191
|
+
* caller's remaining headers already threaded. The headers that reach here
|
|
192
|
+
* can carry neither an authority claim nor a command-owned key: both
|
|
193
|
+
* families are refused before `plan` runs.
|
|
194
|
+
*/
|
|
195
|
+
requestOptions(overrides?: HonuaControlPlaneRequestOptions): HonuaControlPlaneRequestOptions;
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* One idempotent application command, shared verbatim by every transport.
|
|
199
|
+
*
|
|
200
|
+
* @typeParam TInput - Validated input shape, described by `inputSchema`.
|
|
201
|
+
* @typeParam TOutput - Value carried on the receipt's `output`.
|
|
202
|
+
*/
|
|
203
|
+
export interface HonuaCommand<TInput, TOutput> {
|
|
204
|
+
/** Stable dotted id, e.g. `map-package.publish`. */
|
|
205
|
+
readonly id: string;
|
|
206
|
+
readonly title: string;
|
|
207
|
+
readonly description: string;
|
|
208
|
+
readonly mode: HonuaCommandMode;
|
|
209
|
+
/** Resource kind this command addresses; used for the receipt's `resourceRef`. */
|
|
210
|
+
readonly resourceKind: string;
|
|
211
|
+
readonly inputSchema: HonuaCommandJsonSchema;
|
|
212
|
+
/**
|
|
213
|
+
* Cross-field checks the JSON schema cannot express ("one of these two is
|
|
214
|
+
* required"). Called by the runtime after schema validation and **before**
|
|
215
|
+
* `plan`, so a dry run can never approve an input the real invocation would
|
|
216
|
+
* reject. Must be pure. Return an empty array when the input is valid.
|
|
217
|
+
*/
|
|
218
|
+
validate?(input: TInput): readonly HonuaCommandValidationIssue[];
|
|
219
|
+
/** Describe the request without issuing it. Must be pure and side-effect free. */
|
|
220
|
+
plan(context: HonuaCommandContext<TInput>): HonuaCommandPlan;
|
|
221
|
+
/** Issue the request. Never called during a dry run. */
|
|
222
|
+
execute(context: HonuaCommandContext<TInput>): Promise<HonuaCommandOutcome<TOutput>>;
|
|
223
|
+
}
|
|
224
|
+
/** Any command, for registries and transport dispatch tables. */
|
|
225
|
+
export type HonuaAnyCommand = HonuaCommand<any, any>;
|
|
226
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/control-plane/commands/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared application-command contract for the Honua control plane.
|
|
3
|
+
*
|
|
4
|
+
* Every surface — the `honua` CLI, the MCP server, Studio, and direct JS —
|
|
5
|
+
* invokes the *same* {@link HonuaCommand} objects. A transport adapts input
|
|
6
|
+
* and output only: it parses its own argument shape into the command's
|
|
7
|
+
* declared JSON-schema input, hands the result to
|
|
8
|
+
* `HonuaCommandRuntime.execute`, and renders the returned
|
|
9
|
+
* {@link HonuaCommandReceipt}. Domain sequencing (read-modify-write,
|
|
10
|
+
* optimistic-concurrency checks, job hand-off) and the dry-run projection live
|
|
11
|
+
* on the command, never on the transport.
|
|
12
|
+
*
|
|
13
|
+
* Authorization is deliberately **not** modelled here beyond an echo. The
|
|
14
|
+
* command layer carries no administrator credential of its own, refuses
|
|
15
|
+
* caller-supplied authority headers and the request-identity headers it derives
|
|
16
|
+
* itself (see `assertNoAuthorityOverride` and `assertNoCommandKeyOverride` in
|
|
17
|
+
* `./runtime.js`), and stamps every receipt `authorization:
|
|
18
|
+
* "server-enforced"`. A client cannot approve its own publication by choosing
|
|
19
|
+
* a different transport because no transport can express approval at all —
|
|
20
|
+
* the shared command inputs have no approval field and every command input
|
|
21
|
+
* schema is closed (`additionalProperties: false`).
|
|
22
|
+
*
|
|
23
|
+
* @experimental Part of the `@honua/sdk-js/control-plane` experimental
|
|
24
|
+
* entrypoint; not yet covered by the SDK's semver contract.
|
|
25
|
+
* @module
|
|
26
|
+
*/
|
|
27
|
+
/** Surfaces that may invoke a command. Recorded, never trusted. */
|
|
28
|
+
export const HONUA_COMMAND_TRANSPORTS = ["cli", "mcp", "studio", "sdk"];
|
|
29
|
+
/** Discriminating tag on {@link HonuaCommandReceipt}. */
|
|
30
|
+
export const HONUA_COMMAND_RECEIPT_KIND = "honua.command.receipt.v1";
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Structural validation for command inputs.
|
|
3
|
+
*
|
|
4
|
+
* Commands describe their input with the JSON-Schema subset in `./types.js`,
|
|
5
|
+
* the same dialect `src/agent-tools/index.ts` uses for agent tool definitions.
|
|
6
|
+
* That one description drives CLI argument checking, MCP tool schemas, Studio
|
|
7
|
+
* forms, and this validator — so an input rejected by one transport is
|
|
8
|
+
* rejected identically by all of them.
|
|
9
|
+
*
|
|
10
|
+
* The validator covers exactly the keywords the dialect declares. It is not a
|
|
11
|
+
* general JSON-Schema implementation and deliberately adds no dependency;
|
|
12
|
+
* `src/` is zod-free.
|
|
13
|
+
*
|
|
14
|
+
* @experimental
|
|
15
|
+
* @module
|
|
16
|
+
*/
|
|
17
|
+
import type { HonuaCommandValidationIssue } from "./errors.js";
|
|
18
|
+
import type { HonuaCommandJsonSchema } from "./types.js";
|
|
19
|
+
/**
|
|
20
|
+
* Validate `value` against `schema`, returning every finding.
|
|
21
|
+
*
|
|
22
|
+
* `additionalProperties: false` is the load-bearing rule for the security
|
|
23
|
+
* contract: a closed input schema is why no transport can smuggle an approval
|
|
24
|
+
* or authority field into a shared command.
|
|
25
|
+
*/
|
|
26
|
+
export declare function validateCommandInput(schema: HonuaCommandJsonSchema, value: unknown): HonuaCommandValidationIssue[];
|
|
27
|
+
//# sourceMappingURL=validate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../../../src/control-plane/commands/validate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,aAAa,CAAC;AAC/D,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AAEzD;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,sBAAsB,EAAE,KAAK,EAAE,OAAO,GAAG,2BAA2B,EAAE,CAIlH"}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Structural validation for command inputs.
|
|
3
|
+
*
|
|
4
|
+
* Commands describe their input with the JSON-Schema subset in `./types.js`,
|
|
5
|
+
* the same dialect `src/agent-tools/index.ts` uses for agent tool definitions.
|
|
6
|
+
* That one description drives CLI argument checking, MCP tool schemas, Studio
|
|
7
|
+
* forms, and this validator — so an input rejected by one transport is
|
|
8
|
+
* rejected identically by all of them.
|
|
9
|
+
*
|
|
10
|
+
* The validator covers exactly the keywords the dialect declares. It is not a
|
|
11
|
+
* general JSON-Schema implementation and deliberately adds no dependency;
|
|
12
|
+
* `src/` is zod-free.
|
|
13
|
+
*
|
|
14
|
+
* @experimental
|
|
15
|
+
* @module
|
|
16
|
+
*/
|
|
17
|
+
/**
|
|
18
|
+
* Validate `value` against `schema`, returning every finding.
|
|
19
|
+
*
|
|
20
|
+
* `additionalProperties: false` is the load-bearing rule for the security
|
|
21
|
+
* contract: a closed input schema is why no transport can smuggle an approval
|
|
22
|
+
* or authority field into a shared command.
|
|
23
|
+
*/
|
|
24
|
+
export function validateCommandInput(schema, value) {
|
|
25
|
+
const issues = [];
|
|
26
|
+
validateNode(schema, value, "", issues);
|
|
27
|
+
return issues;
|
|
28
|
+
}
|
|
29
|
+
function validateNode(schema, value, path, issues) {
|
|
30
|
+
if (schema.type !== undefined && !matchesType(schema.type, value)) {
|
|
31
|
+
issues.push({ path, message: `expected type ${formatType(schema.type)}, received ${describe(value)}` });
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
if (schema.enum !== undefined && !schema.enum.some((allowed) => Object.is(allowed, value))) {
|
|
35
|
+
issues.push({ path, message: `expected one of ${schema.enum.map((entry) => JSON.stringify(entry)).join(", ")}` });
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
if (typeof value === "string")
|
|
39
|
+
validateString(schema, value, path, issues);
|
|
40
|
+
if (typeof value === "number")
|
|
41
|
+
validateNumber(schema, value, path, issues);
|
|
42
|
+
if (Array.isArray(value)) {
|
|
43
|
+
if (schema.items) {
|
|
44
|
+
value.forEach((entry, index) => validateNode(schema.items, entry, `${path}[${index}]`, issues));
|
|
45
|
+
}
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
if (isPlainRecord(value))
|
|
49
|
+
validateObject(schema, value, path, issues);
|
|
50
|
+
}
|
|
51
|
+
function validateString(schema, value, path, issues) {
|
|
52
|
+
if (schema.minLength !== undefined && value.length < schema.minLength) {
|
|
53
|
+
issues.push({ path, message: `expected at least ${schema.minLength} character(s)` });
|
|
54
|
+
}
|
|
55
|
+
if (schema.maxLength !== undefined && value.length > schema.maxLength) {
|
|
56
|
+
issues.push({ path, message: `expected at most ${schema.maxLength} character(s)` });
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
function validateNumber(schema, value, path, issues) {
|
|
60
|
+
if (schema.minimum !== undefined && value < schema.minimum) {
|
|
61
|
+
issues.push({ path, message: `expected >= ${schema.minimum}` });
|
|
62
|
+
}
|
|
63
|
+
if (schema.maximum !== undefined && value > schema.maximum) {
|
|
64
|
+
issues.push({ path, message: `expected <= ${schema.maximum}` });
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
function validateObject(schema, value, path, issues) {
|
|
68
|
+
const properties = schema.properties ?? {};
|
|
69
|
+
for (const required of schema.required ?? []) {
|
|
70
|
+
if (value[required] === undefined) {
|
|
71
|
+
issues.push({ path: join(path, required), message: "is required" });
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
for (const [key, child] of Object.entries(value)) {
|
|
75
|
+
if (child === undefined)
|
|
76
|
+
continue;
|
|
77
|
+
const propertySchema = properties[key];
|
|
78
|
+
if (propertySchema) {
|
|
79
|
+
validateNode(propertySchema, child, join(path, key), issues);
|
|
80
|
+
continue;
|
|
81
|
+
}
|
|
82
|
+
if (schema.additionalProperties === false) {
|
|
83
|
+
issues.push({ path: join(path, key), message: "is not an accepted property of this command" });
|
|
84
|
+
continue;
|
|
85
|
+
}
|
|
86
|
+
if (typeof schema.additionalProperties === "object") {
|
|
87
|
+
validateNode(schema.additionalProperties, child, join(path, key), issues);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
function matchesType(type, value) {
|
|
92
|
+
const types = typeof type === "string" ? [type] : type;
|
|
93
|
+
return types.some((entry) => matchesSingleType(entry, value));
|
|
94
|
+
}
|
|
95
|
+
function matchesSingleType(type, value) {
|
|
96
|
+
switch (type) {
|
|
97
|
+
case "string":
|
|
98
|
+
return typeof value === "string";
|
|
99
|
+
case "number":
|
|
100
|
+
return typeof value === "number" && Number.isFinite(value);
|
|
101
|
+
case "integer":
|
|
102
|
+
return typeof value === "number" && Number.isInteger(value);
|
|
103
|
+
case "boolean":
|
|
104
|
+
return typeof value === "boolean";
|
|
105
|
+
case "array":
|
|
106
|
+
return Array.isArray(value);
|
|
107
|
+
case "object":
|
|
108
|
+
return isPlainRecord(value);
|
|
109
|
+
case "null":
|
|
110
|
+
return value === null;
|
|
111
|
+
default:
|
|
112
|
+
return true;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
function formatType(type) {
|
|
116
|
+
return typeof type === "string" ? type : type.join(" | ");
|
|
117
|
+
}
|
|
118
|
+
function describe(value) {
|
|
119
|
+
if (value === null)
|
|
120
|
+
return "null";
|
|
121
|
+
if (value === undefined)
|
|
122
|
+
return "undefined";
|
|
123
|
+
if (Array.isArray(value))
|
|
124
|
+
return "array";
|
|
125
|
+
return typeof value;
|
|
126
|
+
}
|
|
127
|
+
function isPlainRecord(value) {
|
|
128
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
129
|
+
}
|
|
130
|
+
function join(path, key) {
|
|
131
|
+
return path ? `${path}.${key}` : key;
|
|
132
|
+
}
|