@zocomputer/system-api 0.0.0-stage → 0.1.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.
Files changed (57) hide show
  1. package/README.md +51 -2
  2. package/dist/catalog/index.d.ts +106 -0
  3. package/dist/catalog/index.js +237 -0
  4. package/dist/core/catalog.d.ts +155 -0
  5. package/dist/core/catalog.js +24 -0
  6. package/dist/core/client.d.ts +156 -0
  7. package/dist/core/client.js +87 -0
  8. package/dist/core/database.d.ts +124 -0
  9. package/dist/core/database.js +314 -0
  10. package/dist/core/envelope.d.ts +45 -0
  11. package/dist/core/envelope.js +112 -0
  12. package/dist/core/errors.d.ts +52 -0
  13. package/dist/core/errors.js +33 -0
  14. package/dist/core/index.d.ts +14 -0
  15. package/dist/core/index.js +13 -0
  16. package/dist/core/json-call.d.ts +4 -0
  17. package/dist/core/json-call.js +109 -0
  18. package/dist/core/json.d.ts +17 -0
  19. package/dist/core/json.js +4 -0
  20. package/dist/core/transport.d.ts +47 -0
  21. package/dist/core/transport.js +367 -0
  22. package/dist/core/validator.d.ts +52 -0
  23. package/dist/core/validator.js +1 -0
  24. package/dist/generate/cli.d.ts +44 -0
  25. package/dist/generate/cli.js +358 -0
  26. package/dist/generate/generate.d.ts +46 -0
  27. package/dist/generate/generate.js +215 -0
  28. package/dist/generate/identifiers.d.ts +27 -0
  29. package/dist/generate/identifiers.js +67 -0
  30. package/dist/generate/index.d.ts +15 -0
  31. package/dist/generate/index.js +15 -0
  32. package/dist/generate/manifest.d.ts +1 -0
  33. package/dist/generate/manifest.js +1 -0
  34. package/dist/generate/types.d.ts +57 -0
  35. package/dist/generate/types.js +357 -0
  36. package/dist/generated/catalog.d.ts +2 -0
  37. package/dist/generated/catalog.js +854 -0
  38. package/dist/generated/index.d.ts +2 -0
  39. package/dist/generated/index.js +4 -0
  40. package/dist/generated/manifest.json +799 -0
  41. package/dist/generated/operations.d.ts +8450 -0
  42. package/dist/generated/operations.js +3 -0
  43. package/dist/generated/schema.json +39451 -0
  44. package/dist/index.d.ts +11 -0
  45. package/dist/index.js +11 -0
  46. package/dist/json/index.d.ts +81 -0
  47. package/dist/json/index.js +404 -0
  48. package/dist/validation/index.d.ts +19 -0
  49. package/dist/validation/index.js +149 -0
  50. package/dist/validation/json.d.ts +1 -0
  51. package/dist/validation/json.js +1 -0
  52. package/dist/validation/pattern.d.ts +56 -0
  53. package/dist/validation/pattern.js +382 -0
  54. package/dist/validation/schema.d.ts +103 -0
  55. package/dist/validation/schema.js +1300 -0
  56. package/openapi.json +40754 -0
  57. package/package.json +93 -4
@@ -0,0 +1,45 @@
1
+ import { type JsonObject } from "./json.ts";
2
+ export interface InvocationOptions {
3
+ readonly version: number;
4
+ /**
5
+ * A list query: paging, order and filters. On a success, the query the
6
+ * server applied, echoed only when the request carried one.
7
+ */
8
+ readonly query?: JsonObject;
9
+ }
10
+ export interface InvocationRequestOptions extends InvocationOptions {
11
+ readonly idempotency_key?: string;
12
+ }
13
+ export interface InvocationEnvelope {
14
+ readonly action: string;
15
+ readonly input: JsonObject;
16
+ readonly options: InvocationRequestOptions;
17
+ }
18
+ export interface InvocationSuccess {
19
+ readonly request_id: string;
20
+ readonly action: string;
21
+ readonly options: InvocationOptions;
22
+ readonly result: unknown;
23
+ }
24
+ export interface InvocationErrorBody {
25
+ readonly request_id: string;
26
+ readonly error: {
27
+ readonly code: string;
28
+ readonly message: string;
29
+ readonly details?: unknown;
30
+ };
31
+ }
32
+ /** Read the correlation id from any object-shaped body, for error reporting. */
33
+ export declare function readRequestId(body: unknown): string | undefined;
34
+ /** True when a decoded body is a well-formed, closed error envelope. */
35
+ export declare function isErrorBody(body: unknown): body is InvocationErrorBody;
36
+ /**
37
+ * Validate a decoded success body against the sent envelope and return it.
38
+ * Throws `invalid_response` when the body is not a closed success envelope or
39
+ * its echoed action/version does not match what was requested — a mismatched
40
+ * echo means the correlation cannot be trusted, so the result is not returned.
41
+ * `httpStatus` is the status of the (2xx) response the body came from; it is
42
+ * carried onto the error so a malformed success body is not mistaken for a
43
+ * transport failure that never reached the server.
44
+ */
45
+ export declare function parseSuccess(body: unknown, sent: Pick<InvocationEnvelope, "action" | "options">, httpStatus: number): InvocationSuccess;
@@ -0,0 +1,112 @@
1
+ /**
2
+ * Invocation wire types and bounded trust-boundary validation.
3
+ *
4
+ * These mirror the merged Python contract (`InvocationEnvelope`,
5
+ * `InvocationSuccess`, error body), which are closed models (`extra=forbid`):
6
+ * the validators here reject unknown properties, non-positive/out-of-range
7
+ * versions, and malformed error codes rather than trusting the body because the
8
+ * server is expected to sanitize it. `options` is REQUIRED on the wire and
9
+ * always carries the resolved integer `version`. This path checks the envelope
10
+ * shape and the echoed action/version correlation only — never per-action
11
+ * input/output schemas — so it pulls in no validator.
12
+ */
13
+ import { SystemAPIError } from "./errors.js";
14
+ import { isJsonObject } from "./json.js";
15
+ /** Matches the merged contract's `PositiveVersion` (gt 0, le int32 max). */
16
+ const MAX_WIRE_VERSION = 2_147_483_647;
17
+ /** Wire error-code grammar, mirroring contracts.py error-code pattern. */
18
+ const ERROR_CODE_PATTERN = /^[a-z][a-z0-9_]*$/;
19
+ /** True when `obj` carries no properties outside `allowed` (closed model). */
20
+ function hasOnlyKeys(obj, allowed) {
21
+ for (const key of Object.keys(obj)) {
22
+ if (!allowed.includes(key))
23
+ return false;
24
+ }
25
+ return true;
26
+ }
27
+ /** A positive, in-range integer version, matching the contract's `PositiveVersion`. */
28
+ function isWireVersion(value) {
29
+ return (typeof value === "number" &&
30
+ Number.isInteger(value) &&
31
+ value > 0 &&
32
+ value <= MAX_WIRE_VERSION);
33
+ }
34
+ function isOptions(value) {
35
+ return (isJsonObject(value) &&
36
+ isWireVersion(value["version"]) &&
37
+ hasOnlyKeys(value, ["version", "query"]) &&
38
+ (!("query" in value) || isJsonObject(value["query"])));
39
+ }
40
+ function isWireErrorCode(value) {
41
+ // Parity with contracts.py: only the error-code grammar (which already
42
+ // requires a non-empty leading-letter code). No SDK-only length cap — the
43
+ // total response byte limit bounds the code, and the merged Python contract
44
+ // imposes no separate per-code length bound.
45
+ return typeof value === "string" && ERROR_CODE_PATTERN.test(value);
46
+ }
47
+ /** Read the correlation id from any object-shaped body, for error reporting. */
48
+ export function readRequestId(body) {
49
+ if (isJsonObject(body) && typeof body["request_id"] === "string")
50
+ return body["request_id"];
51
+ return undefined;
52
+ }
53
+ /** True when a decoded body is a well-formed, closed error envelope. */
54
+ export function isErrorBody(body) {
55
+ if (!isJsonObject(body))
56
+ return false;
57
+ if (typeof body["request_id"] !== "string")
58
+ return false;
59
+ if (!hasOnlyKeys(body, ["request_id", "error"]))
60
+ return false;
61
+ const error = body["error"];
62
+ return (isJsonObject(error) &&
63
+ isWireErrorCode(error["code"]) &&
64
+ typeof error["message"] === "string" &&
65
+ hasOnlyKeys(error, ["code", "message", "details"]));
66
+ }
67
+ /**
68
+ * Validate a decoded success body against the sent envelope and return it.
69
+ * Throws `invalid_response` when the body is not a closed success envelope or
70
+ * its echoed action/version does not match what was requested — a mismatched
71
+ * echo means the correlation cannot be trusted, so the result is not returned.
72
+ * `httpStatus` is the status of the (2xx) response the body came from; it is
73
+ * carried onto the error so a malformed success body is not mistaken for a
74
+ * transport failure that never reached the server.
75
+ */
76
+ export function parseSuccess(body, sent, httpStatus) {
77
+ const fail = (message) => {
78
+ throw new SystemAPIError({
79
+ code: "invalid_response",
80
+ message,
81
+ requestId: readRequestId(body),
82
+ httpStatus,
83
+ outcome: "unknown",
84
+ });
85
+ };
86
+ if (!isJsonObject(body))
87
+ return fail("response body is not a JSON object");
88
+ if (!hasOnlyKeys(body, ["request_id", "action", "options", "result"])) {
89
+ return fail("response envelope carries unknown properties");
90
+ }
91
+ if (typeof body["request_id"] !== "string")
92
+ return fail("response is missing a string request_id");
93
+ if (!("result" in body))
94
+ return fail("response is missing a result");
95
+ if (typeof body["action"] !== "string" || !isOptions(body["options"])) {
96
+ return fail("response is missing action/version correlation");
97
+ }
98
+ if (body["action"] !== sent.action ||
99
+ body["options"].version !== sent.options.version) {
100
+ return fail("response action/version does not match the request");
101
+ }
102
+ // The server echoes the applied query exactly when the request sent one.
103
+ if ("query" in body["options"] !== (sent.options.query !== undefined)) {
104
+ return fail("response query echo does not match the request");
105
+ }
106
+ return {
107
+ request_id: body["request_id"],
108
+ action: body["action"],
109
+ options: body["options"],
110
+ result: body["result"],
111
+ };
112
+ }
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Structured, safe client errors.
3
+ *
4
+ * Every failure the SDK surfaces is a `SystemAPIError`. The public ergonomics
5
+ * are Promise/throw (no `Result` type crosses the boundary), so a caller either
6
+ * gets the unwrapped result or a thrown `SystemAPIError`.
7
+ *
8
+ * We distinguish three failure origins (decision 5 of the seam):
9
+ * - transport failures (`network`): the request never produced an HTTP
10
+ * response — `httpStatus` is absent.
11
+ * - malformed protocol responses (`invalid_response`): an HTTP response
12
+ * arrived but its body is not a well-formed invocation envelope.
13
+ * - server errors: a well-formed error envelope; its `code` is preserved
14
+ * verbatim, including custom action-declared failure codes we do not know.
15
+ */
16
+ /**
17
+ * Stable client/server error codes. Known codes are enumerated for
18
+ * autocomplete; `(string & {})` preserves any other well-formed server code
19
+ * (e.g. a custom action failure) rather than collapsing it to a known value.
20
+ */
21
+ export type SystemAPIErrorCode = "invalid_envelope" | "unauthenticated" | "insufficient_scope" | "permission_denied" | "missing_grants" | "approval_required" | "resource_not_found" | "action_not_found" | "conflict" | "revision_not_ready" | "workflow_has_open_runs" | "catalog_changed" | "authorization_changed" | "payload_too_large" | "invalid_input" | "invalid_query" | "invalid_definition" | "unsupported_version" | "rate_limited" | "invalid_implementation_output" | "output_limit_exceeded" | "implementation_unavailable" | "execution_deadline_exceeded" | "network" | "invalid_response" | "version_required" | "unknown" | (string & {});
22
+ /**
23
+ * Whether a side effect may have occurred. Set only when genuinely uncertain
24
+ * (e.g. a disconnect or deadline after the request was sent); never inferred
25
+ * from an arbitrary HTTP status.
26
+ */
27
+ export type Outcome = "not_started" | "unknown";
28
+ export interface SystemAPIErrorInit {
29
+ code: SystemAPIErrorCode;
30
+ message: string;
31
+ /** Server correlation id, when the response carried one. */
32
+ requestId?: string;
33
+ /** HTTP status; absent when no HTTP response was produced (transport failure). */
34
+ httpStatus?: number;
35
+ /** Code-specific, already server-sanitized detail payload. */
36
+ details?: unknown;
37
+ /** Bounded, non-negative seconds parsed from a `Retry-After` header. */
38
+ retryAfterSeconds?: number;
39
+ /** Explicit effect uncertainty after a send/network/output failure. */
40
+ outcome?: Outcome;
41
+ /** Underlying cause (e.g. the fetch rejection), for debugging. */
42
+ cause?: unknown;
43
+ }
44
+ export declare class SystemAPIError extends Error {
45
+ readonly code: SystemAPIErrorCode;
46
+ readonly requestId?: string;
47
+ readonly httpStatus?: number;
48
+ readonly details?: unknown;
49
+ readonly retryAfterSeconds?: number;
50
+ readonly outcome?: Outcome;
51
+ constructor(init: SystemAPIErrorInit);
52
+ }
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Structured, safe client errors.
3
+ *
4
+ * Every failure the SDK surfaces is a `SystemAPIError`. The public ergonomics
5
+ * are Promise/throw (no `Result` type crosses the boundary), so a caller either
6
+ * gets the unwrapped result or a thrown `SystemAPIError`.
7
+ *
8
+ * We distinguish three failure origins (decision 5 of the seam):
9
+ * - transport failures (`network`): the request never produced an HTTP
10
+ * response — `httpStatus` is absent.
11
+ * - malformed protocol responses (`invalid_response`): an HTTP response
12
+ * arrived but its body is not a well-formed invocation envelope.
13
+ * - server errors: a well-formed error envelope; its `code` is preserved
14
+ * verbatim, including custom action-declared failure codes we do not know.
15
+ */
16
+ export class SystemAPIError extends Error {
17
+ code;
18
+ requestId;
19
+ httpStatus;
20
+ details;
21
+ retryAfterSeconds;
22
+ outcome;
23
+ constructor(init) {
24
+ super(init.message, init.cause === undefined ? undefined : { cause: init.cause });
25
+ this.name = "SystemAPIError";
26
+ this.code = init.code;
27
+ this.requestId = init.requestId;
28
+ this.httpStatus = init.httpStatus;
29
+ this.details = init.details;
30
+ this.retryAfterSeconds = init.retryAfterSeconds;
31
+ this.outcome = init.outcome;
32
+ }
33
+ }
@@ -0,0 +1,14 @@
1
+ /**
2
+ * `@zocomputer/system-api/core` — the generic System API client runtime.
3
+ *
4
+ * This entry has no dependency on any released built-in catalog and pulls in no
5
+ * schema validator: a typed-only consumer imports just this.
6
+ */
7
+ export { createClient, type ClientConfig, type JsonCallOptions, type JsonCallResult, type RuntimeClient, type TypedClient, } from "./client.ts";
8
+ export { defineCatalog, defineRuntimeCatalog, type ActionEntry, type DefaultVersionsShape, type DefaultsOf, type OperationsOf, type OperationsShape, type RuntimeCatalog, type TypedActions, type TypedCatalog, type VersionEntry, } from "./catalog.ts";
9
+ export { SystemAPIError, type Outcome, type SystemAPIErrorCode, type SystemAPIErrorInit, } from "./errors.ts";
10
+ export { type InvocationEnvelope, type InvocationErrorBody, type InvocationOptions, type InvocationRequestOptions, type InvocationSuccess, } from "./envelope.ts";
11
+ export { DEFAULT_BASE_URL, type AccessTokenProvider, type FetchLike, } from "./transport.ts";
12
+ export { isJsonObject, type JsonObject, type JsonScalar, type JsonValue, } from "./json.ts";
13
+ export type { InvocationTarget, InvocationValidator } from "./validator.ts";
14
+ export { DatabaseDate, DatabaseTimestamp, decodeDatabaseRows, decodeDatabaseValue, type DatabaseColumn, type DatabaseDateFields, type DatabaseDecodeOptions, type DatabaseResult, type DatabaseTimestampFields, type DatabaseValue, } from "./database.ts";
@@ -0,0 +1,13 @@
1
+ /**
2
+ * `@zocomputer/system-api/core` — the generic System API client runtime.
3
+ *
4
+ * This entry has no dependency on any released built-in catalog and pulls in no
5
+ * schema validator: a typed-only consumer imports just this.
6
+ */
7
+ export { createClient, } from "./client.js";
8
+ export { defineCatalog, defineRuntimeCatalog, } from "./catalog.js";
9
+ export { SystemAPIError, } from "./errors.js";
10
+ export {} from "./envelope.js";
11
+ export { DEFAULT_BASE_URL, } from "./transport.js";
12
+ export { isJsonObject, } from "./json.js";
13
+ export { DatabaseDate, DatabaseTimestamp, decodeDatabaseRows, decodeDatabaseValue, } from "./database.js";
@@ -0,0 +1,4 @@
1
+ import type { JsonCallOptions, JsonCallResult } from "./client.ts";
2
+ import { type Transport } from "./transport.ts";
3
+ import type { InvocationTarget } from "./validator.ts";
4
+ export declare function invokeJson(transport: Transport, target: InvocationTarget, inputJson: string, options?: JsonCallOptions): Promise<JsonCallResult>;
@@ -0,0 +1,109 @@
1
+ import { JsonError, JsonNumber, MAX_JSON_DEPTH, checkJsonValue, dumpsJson, loadsJson, } from "../json/index.js";
2
+ import { SystemAPIError } from "./errors.js";
3
+ import { MAX_REQUEST_BYTES, MAX_RESPONSE_BYTES, } from "./transport.js";
4
+ function isObject(value) {
5
+ return (value !== null &&
6
+ typeof value === "object" &&
7
+ !Array.isArray(value) &&
8
+ !(value instanceof JsonNumber));
9
+ }
10
+ function parseObject(text, name) {
11
+ const value = loadsJson(text, { maxBytes: MAX_REQUEST_BYTES });
12
+ if (!isObject(value))
13
+ throw new Error(`${name} must be a JSON object`);
14
+ return value;
15
+ }
16
+ export async function invokeJson(transport, target, inputJson, options) {
17
+ let requestBody;
18
+ try {
19
+ parseObject(inputJson, "input");
20
+ if (options?.queryJson !== undefined)
21
+ parseObject(options.queryJson, "query");
22
+ const wireOptions = JSON.stringify({
23
+ version: target.version,
24
+ ...(options?.idempotencyKey !== undefined
25
+ ? { idempotency_key: options.idempotencyKey }
26
+ : {}),
27
+ });
28
+ const query = options?.queryJson === undefined ? "" : `,"query":${options.queryJson}`;
29
+ requestBody = `{"action":${JSON.stringify(target.action)},"input":${inputJson},"options":${wireOptions.slice(0, -1)}${query}}}`;
30
+ }
31
+ catch (cause) {
32
+ throw new SystemAPIError({
33
+ code: cause instanceof JsonError && cause.code === "too_large"
34
+ ? "payload_too_large"
35
+ : "invalid_input",
36
+ message: "input and query must be bounded JSON objects",
37
+ outcome: "not_started",
38
+ cause,
39
+ });
40
+ }
41
+ let responseValue;
42
+ const { success, text, httpStatus } = await transport.invokeText(requestBody, {
43
+ action: target.action,
44
+ options: {
45
+ version: target.version,
46
+ ...(options?.queryJson !== undefined ? { query: {} } : {}),
47
+ },
48
+ }, target, (responseText) => {
49
+ responseValue = loadsJson(responseText, {
50
+ maxBytes: MAX_RESPONSE_BYTES,
51
+ maxDepth: MAX_JSON_DEPTH + 2,
52
+ maxNodes: null,
53
+ });
54
+ if (!isObject(responseValue))
55
+ return responseValue;
56
+ const wireOptions = responseValue["options"];
57
+ if (!isObject(wireOptions))
58
+ return responseValue;
59
+ const version = wireOptions["version"];
60
+ // Existing validator hooks expect ordinary JS query values. Their exact
61
+ // comparison source is responseText; responseValue keeps the output exact.
62
+ return {
63
+ ...responseValue,
64
+ options: {
65
+ ...wireOptions,
66
+ ...("query" in wireOptions
67
+ ? {
68
+ query: isObject(wireOptions["query"])
69
+ ? JSON.parse(dumpsJson(wireOptions["query"]))
70
+ : null,
71
+ }
72
+ : {}),
73
+ version: version instanceof JsonNumber && version.isInteger
74
+ ? Number(version.text)
75
+ : undefined,
76
+ },
77
+ };
78
+ });
79
+ // parseSuccess has checked these fields; the original tree retains numbers.
80
+ if (!isObject(responseValue) || responseValue["result"] === undefined)
81
+ throw new Error("validated response lost its result");
82
+ const result = responseValue["result"];
83
+ const appliedOptions = responseValue["options"];
84
+ const query = isObject(appliedOptions) ? appliedOptions["query"] : undefined;
85
+ try {
86
+ checkJsonValue(result);
87
+ if (query !== undefined)
88
+ checkJsonValue(query);
89
+ }
90
+ catch (cause) {
91
+ throw new SystemAPIError({
92
+ code: "invalid_response",
93
+ message: "response result or query exceeds JSON bounds",
94
+ requestId: success.request_id,
95
+ httpStatus,
96
+ outcome: "unknown",
97
+ cause,
98
+ });
99
+ }
100
+ return {
101
+ envelopeJson: text,
102
+ resultJson: dumpsJson(result),
103
+ requestId: success.request_id,
104
+ action: success.action,
105
+ version: success.options.version,
106
+ ...(query !== undefined ? { queryJson: dumpsJson(query) } : {}),
107
+ httpStatus,
108
+ };
109
+ }
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Bounded JSON value types mirroring the Python contract's `JsonValue`.
3
+ *
4
+ * The wire is JSON, so every value the SDK sends or receives is one of these.
5
+ * `JsonObject` is the shape of an action input and of the invocation envelope's
6
+ * object fields; `JsonValue` is any bounded finite JSON value (the shape of an
7
+ * `x-zo-json-value` field and of a successful `result`).
8
+ */
9
+ export type JsonScalar = string | number | boolean | null;
10
+ export type JsonValue = JsonScalar | JsonValue[] | {
11
+ [key: string]: JsonValue;
12
+ };
13
+ export type JsonObject = {
14
+ [key: string]: JsonValue;
15
+ };
16
+ /** Narrow an `unknown` decoded body to a JSON object without an `as`-cast. */
17
+ export declare function isJsonObject(value: unknown): value is JsonObject;
@@ -0,0 +1,4 @@
1
+ /** Narrow an `unknown` decoded body to a JSON object without an `as`-cast. */
2
+ export function isJsonObject(value) {
3
+ return typeof value === "object" && value !== null && !Array.isArray(value);
4
+ }
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Fetch transport for the single `/invoke` route.
3
+ *
4
+ * Browser-safe: uses `fetch` only, no Node built-ins. Invoke is never retried
5
+ * automatically — a disconnect, deadline, or malformed result after a mutation
6
+ * may mean the effect happened, so uncertainty is surfaced rather than replayed.
7
+ * The request is serialized, size-checked, and the token obtained and validated
8
+ * BEFORE any network call, so a pre-flight failure reports `outcome:
9
+ * "not_started"`; `network` is used solely for a `fetch` rejection. Response
10
+ * bodies are read under a byte cap before parsing, and redirects are refused so
11
+ * a bearer credential is never replayed to a redirected origin.
12
+ */
13
+ import { type InvocationEnvelope, type InvocationSuccess } from "./envelope.ts";
14
+ import type { InvocationTarget, InvocationValidator } from "./validator.ts";
15
+ export type FetchLike = typeof fetch;
16
+ export type AccessTokenProvider = () => string | Promise<string>;
17
+ export interface TransportConfig {
18
+ readonly accessToken: AccessTokenProvider;
19
+ readonly baseUrl?: string;
20
+ readonly workspaceId?: string;
21
+ readonly fetch?: FetchLike;
22
+ /**
23
+ * Optional validation. When present, its hooks run on the exact request and
24
+ * response bytes; when absent, the two call sites are no-ops and nothing from
25
+ * a validator is imported or bundled.
26
+ */
27
+ readonly validator?: InvocationValidator;
28
+ }
29
+ export declare const DEFAULT_BASE_URL = "https://api.zo.computer/zo-system-api/v1";
30
+ /**
31
+ * Total serialized request-body cap: 5 MiB. Inline file content may be up to
32
+ * 4 MiB of UTF-8, but the whole body as sent must fit here: JSON escaping
33
+ * (quotes, backslashes, control characters) counts, so heavily escaped
34
+ * content may need a prepared upload.
35
+ */
36
+ export declare const MAX_REQUEST_BYTES: number;
37
+ export declare const MAX_RESPONSE_BYTES: number;
38
+ export interface TransportResponse {
39
+ readonly success: InvocationSuccess;
40
+ readonly text: string;
41
+ readonly httpStatus: number;
42
+ }
43
+ export interface Transport {
44
+ invokeText(requestBody: string, sent: Pick<InvocationEnvelope, "action" | "options">, target: InvocationTarget, decodeBody?: (text: string) => unknown): Promise<TransportResponse>;
45
+ invoke(envelope: InvocationEnvelope, target: InvocationTarget): Promise<InvocationSuccess>;
46
+ }
47
+ export declare function createTransport(config: TransportConfig): Transport;