@voltro/protocol 0.70.0 → 0.71.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/CHANGELOG.md +1289 -111
- package/dist/apikey.d.ts +5 -0
- package/dist/index.d.ts +450 -12
- package/dist/index.js +598 -558
- package/dist/inspect.d.ts +100 -0
- package/dist/inspect.js +160 -0
- package/dist/jwt.d.ts +5 -0
- package/dist/rest.d.ts +111 -6
- package/dist/rest.js +310 -221
- package/dist/{restFormat-Bnngx-zI.js → restFormat-ChSVyufA.js} +93 -38
- package/dist/{scopes-DVtiKKsm.js → scopes-CW9_LbDO.js} +69 -40
- package/dist/session.d.ts +11 -0
- package/dist/session.js +6 -6
- package/package.json +9 -4
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { ParseOptions } from 'effect/SchemaAST';
|
|
2
|
+
import { Schema } from 'effect';
|
|
3
|
+
|
|
4
|
+
export declare const decodeInspectBackfillInput: (u: unknown, overrideOptions?: ParseOptions) => {
|
|
5
|
+
readonly from: string;
|
|
6
|
+
readonly name: string;
|
|
7
|
+
readonly limit: number;
|
|
8
|
+
readonly to: string;
|
|
9
|
+
readonly requestId: string;
|
|
10
|
+
readonly confirm: boolean;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export declare type InspectBackfillInput = typeof InspectBackfillInputSchema.Type;
|
|
14
|
+
|
|
15
|
+
export declare const InspectBackfillInputSchema: Schema.Struct<{
|
|
16
|
+
requestId: Schema.filter<Schema.filter<typeof Schema.String>>;
|
|
17
|
+
name: Schema.filter<Schema.filter<typeof Schema.String>>;
|
|
18
|
+
from: Schema.filter<typeof Schema.String>;
|
|
19
|
+
to: Schema.filter<typeof Schema.String>;
|
|
20
|
+
confirm: typeof Schema.Boolean;
|
|
21
|
+
limit: Schema.filter<Schema.filter<typeof Schema.Number>>;
|
|
22
|
+
}>;
|
|
23
|
+
|
|
24
|
+
export declare type InspectBackfillReceipt = typeof InspectBackfillReceiptSchema.Type;
|
|
25
|
+
|
|
26
|
+
export declare const InspectBackfillReceiptSchema: Schema.Struct<{
|
|
27
|
+
id: Schema.filter<Schema.filter<typeof Schema.String>>;
|
|
28
|
+
name: Schema.filter<Schema.filter<typeof Schema.String>>;
|
|
29
|
+
from: Schema.filter<typeof Schema.String>;
|
|
30
|
+
to: Schema.filter<typeof Schema.String>;
|
|
31
|
+
occurrences: Schema.Array$<typeof Schema.Number>;
|
|
32
|
+
status: Schema.Literal<["queued", "running", "completed", "interrupted"]>;
|
|
33
|
+
owner: Schema.NullOr<typeof Schema.String>;
|
|
34
|
+
createdAt: Schema.filter<typeof Schema.String>;
|
|
35
|
+
updatedAt: Schema.filter<typeof Schema.String>;
|
|
36
|
+
cursor: typeof Schema.Number;
|
|
37
|
+
activeIndex: Schema.NullOr<typeof Schema.Number>;
|
|
38
|
+
results: Schema.Array$<Schema.Struct<{
|
|
39
|
+
runId: Schema.filter<Schema.filter<typeof Schema.String>>;
|
|
40
|
+
status: Schema.Literal<["succeeded", "failed", "skipped", "missed"]>;
|
|
41
|
+
}>>;
|
|
42
|
+
error: Schema.NullOr<typeof Schema.String>;
|
|
43
|
+
}>;
|
|
44
|
+
|
|
45
|
+
export declare type InspectBackfillResult = typeof InspectBackfillResultSchema.Type;
|
|
46
|
+
|
|
47
|
+
export declare const InspectBackfillResultSchema: Schema.Union<[Schema.Struct<{
|
|
48
|
+
kind: Schema.Literal<["accepted"]>;
|
|
49
|
+
request: Schema.Struct<{
|
|
50
|
+
id: Schema.filter<Schema.filter<typeof Schema.String>>;
|
|
51
|
+
name: Schema.filter<Schema.filter<typeof Schema.String>>;
|
|
52
|
+
from: Schema.filter<typeof Schema.String>;
|
|
53
|
+
to: Schema.filter<typeof Schema.String>;
|
|
54
|
+
occurrences: Schema.Array$<typeof Schema.Number>;
|
|
55
|
+
status: Schema.Literal<["queued", "running", "completed", "interrupted"]>;
|
|
56
|
+
owner: Schema.NullOr<typeof Schema.String>;
|
|
57
|
+
createdAt: Schema.filter<typeof Schema.String>;
|
|
58
|
+
updatedAt: Schema.filter<typeof Schema.String>;
|
|
59
|
+
cursor: typeof Schema.Number;
|
|
60
|
+
activeIndex: Schema.NullOr<typeof Schema.Number>;
|
|
61
|
+
results: Schema.Array$<Schema.Struct<{
|
|
62
|
+
runId: Schema.filter<Schema.filter<typeof Schema.String>>;
|
|
63
|
+
status: Schema.Literal<["succeeded", "failed", "skipped", "missed"]>;
|
|
64
|
+
}>>;
|
|
65
|
+
error: Schema.NullOr<typeof Schema.String>;
|
|
66
|
+
}>;
|
|
67
|
+
}>, Schema.Struct<{
|
|
68
|
+
kind: Schema.Literal<["refused"]>;
|
|
69
|
+
name: Schema.filter<Schema.filter<typeof Schema.String>>;
|
|
70
|
+
occurrences: typeof Schema.Number;
|
|
71
|
+
reason: typeof Schema.String;
|
|
72
|
+
}>]>;
|
|
73
|
+
|
|
74
|
+
export declare type InspectReplicaSelection = {
|
|
75
|
+
readonly mode: 'all';
|
|
76
|
+
} | {
|
|
77
|
+
readonly mode: 'selected';
|
|
78
|
+
readonly replicaIds: ReadonlyArray<string>;
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
export declare class InvalidReplicaSelection extends Error {
|
|
82
|
+
readonly name = "InvalidReplicaSelection";
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/** Repeated parameters preserve IDs containing commas, spaces or punctuation. */
|
|
86
|
+
export declare const parseReplicaSelection: (params: URLSearchParams) => InspectReplicaSelection | undefined;
|
|
87
|
+
|
|
88
|
+
/** Preserve evidence about failed peers while projecting the composable inspect
|
|
89
|
+
* domains into their ordinary payload shape. Other domains require an explicit
|
|
90
|
+
* per-replica comparison; returning one responder as the aggregate is forbidden. */
|
|
91
|
+
export declare const projectReplicaObservation: (value: unknown) => unknown;
|
|
92
|
+
|
|
93
|
+
export declare class ScheduleBackfillRequestConflict extends Error {
|
|
94
|
+
readonly name = "ScheduleBackfillRequestConflict";
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/** Canonical selection parameters; unrelated filters and pagination survive. */
|
|
98
|
+
export declare const withReplicaSelection: (href: string, selection: InspectReplicaSelection) => string;
|
|
99
|
+
|
|
100
|
+
export { }
|
package/dist/inspect.js
ADDED
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import { Schema as e } from "effect";
|
|
2
|
+
//#region src/inspectBackfill.ts
|
|
3
|
+
var t = e.String.pipe(e.filter((e) => Number.isFinite(Date.parse(e)))), n = e.String.pipe(e.minLength(1), e.maxLength(256)), r = e.Struct({
|
|
4
|
+
id: n,
|
|
5
|
+
name: n,
|
|
6
|
+
from: t,
|
|
7
|
+
to: t,
|
|
8
|
+
occurrences: e.Array(e.Number),
|
|
9
|
+
status: e.Literal("queued", "running", "completed", "interrupted"),
|
|
10
|
+
owner: e.NullOr(e.String),
|
|
11
|
+
createdAt: t,
|
|
12
|
+
updatedAt: t,
|
|
13
|
+
cursor: e.Number,
|
|
14
|
+
activeIndex: e.NullOr(e.Number),
|
|
15
|
+
results: e.Array(e.Struct({
|
|
16
|
+
runId: n,
|
|
17
|
+
status: e.Literal("succeeded", "failed", "skipped", "missed")
|
|
18
|
+
})),
|
|
19
|
+
error: e.NullOr(e.String)
|
|
20
|
+
}), i = e.Struct({
|
|
21
|
+
requestId: n,
|
|
22
|
+
name: n,
|
|
23
|
+
from: t,
|
|
24
|
+
to: t,
|
|
25
|
+
confirm: e.Boolean,
|
|
26
|
+
limit: e.Number.pipe(e.int(), e.between(1, 1e4))
|
|
27
|
+
}), a = e.decodeUnknownSync(i), o = e.Union(e.Struct({
|
|
28
|
+
kind: e.Literal("accepted"),
|
|
29
|
+
request: r
|
|
30
|
+
}), e.Struct({
|
|
31
|
+
kind: e.Literal("refused"),
|
|
32
|
+
name: n,
|
|
33
|
+
occurrences: e.Number,
|
|
34
|
+
reason: e.String
|
|
35
|
+
})), s = class extends Error {
|
|
36
|
+
name = "ScheduleBackfillRequestConflict";
|
|
37
|
+
}, c = (e) => typeof e == "object" && e && !Array.isArray(e) ? e : void 0, l = (e) => Array.isArray(e) && e.every((e) => c(e) !== void 0) ? e : void 0, u = (e) => typeof e == "number" && Number.isFinite(e) ? e : 0, d = /* @__PURE__ */ new Set([
|
|
38
|
+
"counter",
|
|
39
|
+
"gauge",
|
|
40
|
+
"histogram",
|
|
41
|
+
"summary",
|
|
42
|
+
"frequency"
|
|
43
|
+
]), f = (e) => {
|
|
44
|
+
let t = l(e);
|
|
45
|
+
return t?.every((e) => typeof e.name == "string" && d.has(String(e.type))) ? t : void 0;
|
|
46
|
+
}, p = (e) => {
|
|
47
|
+
let t = c(e), n = c(t?.data), r = l(n?.results);
|
|
48
|
+
if (!t || !n?.selection || !r) return e;
|
|
49
|
+
let i = r.filter((e) => e.status === "answered").map((e) => ({
|
|
50
|
+
replicaId: String(e.replicaId),
|
|
51
|
+
observation: c(e.observation),
|
|
52
|
+
data: c(e.observation)?.data
|
|
53
|
+
}));
|
|
54
|
+
if (i.length === 0) throw Error("None of the selected replicas answered. Check replica availability and retry.");
|
|
55
|
+
let a = i.map((e) => ({
|
|
56
|
+
...e,
|
|
57
|
+
object: c(e.data)
|
|
58
|
+
})), o = (e) => a.reduce((t, n) => t + u(n.object?.[e]), 0), s = Math.max(...i.map((e) => u(e.observation?.capturedAt))), d = {
|
|
59
|
+
capturedAt: s,
|
|
60
|
+
bufferSize: o("bufferSize"),
|
|
61
|
+
bufferCapacity: o("bufferCapacity")
|
|
62
|
+
}, p;
|
|
63
|
+
if (a.every((e) => l(e.object?.records))) {
|
|
64
|
+
let e = a.flatMap((e) => l(e.object?.records).map((t) => ({
|
|
65
|
+
...t,
|
|
66
|
+
fields: {
|
|
67
|
+
...c(t.fields),
|
|
68
|
+
"voltro.replica": e.replicaId
|
|
69
|
+
}
|
|
70
|
+
}))).sort((e, t) => u(e.ts) - u(t.ts));
|
|
71
|
+
p = {
|
|
72
|
+
...d,
|
|
73
|
+
returned: e.length,
|
|
74
|
+
records: e
|
|
75
|
+
};
|
|
76
|
+
} else if (a.every((e) => l(e.object?.traces))) {
|
|
77
|
+
let e = /* @__PURE__ */ new Map();
|
|
78
|
+
for (let t of a) for (let n of l(t.object?.traces)) {
|
|
79
|
+
let r = String(n.traceId), i = (l(n.spans) ?? []).map((e) => ({
|
|
80
|
+
...e,
|
|
81
|
+
attributes: {
|
|
82
|
+
...c(e.attributes),
|
|
83
|
+
"voltro.replica": t.replicaId
|
|
84
|
+
}
|
|
85
|
+
})), a = e.get(r) ?? [];
|
|
86
|
+
a.push({
|
|
87
|
+
...n,
|
|
88
|
+
spans: i
|
|
89
|
+
}), e.set(r, a);
|
|
90
|
+
}
|
|
91
|
+
let t = [...e.values()].map((e) => {
|
|
92
|
+
let t = e.flatMap((e) => l(e.spans) ?? []).sort((e, t) => u(e.startMs) - u(t.startMs)), n = [...e].sort((e, t) => u(e.startMs) - u(t.startMs))[0], r = Math.min(...e.map((e) => u(e.startMs))), i = Math.max(...e.map((e) => u(e.startMs) + u(e.durationMs)));
|
|
93
|
+
return {
|
|
94
|
+
...n,
|
|
95
|
+
startMs: r,
|
|
96
|
+
durationMs: Math.max(0, i - r),
|
|
97
|
+
spanCount: t.length,
|
|
98
|
+
hasError: e.some((e) => e.hasError === !0),
|
|
99
|
+
spans: t,
|
|
100
|
+
...e.some((e) => e.deliveryCount !== void 0) ? { deliveryCount: e.reduce((e, t) => e + u(t.deliveryCount), 0) } : {},
|
|
101
|
+
...e.some((e) => e.lastDeliveryMs !== void 0) ? { lastDeliveryMs: Math.max(...e.map((e) => u(e.lastDeliveryMs))) } : {}
|
|
102
|
+
};
|
|
103
|
+
}).sort((e, t) => t.startMs - e.startMs);
|
|
104
|
+
p = {
|
|
105
|
+
...d,
|
|
106
|
+
returned: t.length,
|
|
107
|
+
traces: t
|
|
108
|
+
};
|
|
109
|
+
} else if (a.every((e) => l(e.object?.buckets) && typeof e.object?.windowMs == "number")) p = {
|
|
110
|
+
capturedAt: s,
|
|
111
|
+
windowMs: Math.max(...a.map((e) => u(e.object?.windowMs))),
|
|
112
|
+
totalSamples: o("totalSamples"),
|
|
113
|
+
buckets: a.flatMap((e) => l(e.object?.buckets).map((t) => ({
|
|
114
|
+
...t,
|
|
115
|
+
tag: `${String(t.tag)} [${e.replicaId}]`
|
|
116
|
+
})))
|
|
117
|
+
};
|
|
118
|
+
else if (i.every((e) => f(e.data))) p = i.flatMap((e) => f(e.data).map((t) => ({
|
|
119
|
+
...t,
|
|
120
|
+
labels: {
|
|
121
|
+
...c(t.labels),
|
|
122
|
+
voltro_replica: e.replicaId
|
|
123
|
+
}
|
|
124
|
+
})));
|
|
125
|
+
else if (a.every((e) => f(e.object?.samples))) p = { samples: a.flatMap((e) => f(e.object?.samples).map((t) => ({
|
|
126
|
+
...t,
|
|
127
|
+
labels: {
|
|
128
|
+
...c(t.labels),
|
|
129
|
+
voltro_replica: e.replicaId
|
|
130
|
+
}
|
|
131
|
+
}))) };
|
|
132
|
+
else throw Error("This view must compare observations per replica; its values cannot be safely combined.");
|
|
133
|
+
return {
|
|
134
|
+
...t,
|
|
135
|
+
data: p
|
|
136
|
+
};
|
|
137
|
+
}, m = class extends Error {
|
|
138
|
+
name = "InvalidReplicaSelection";
|
|
139
|
+
}, h = (e) => {
|
|
140
|
+
let t = e.getAll("replicas"), n = e.getAll("replica");
|
|
141
|
+
if (t.length !== 0 || n.length !== 0) {
|
|
142
|
+
if (t.length > 1 || t.length === 1 && t[0] !== "all" || t.length > 0 && n.length > 0) throw new m("Choose all replicas or explicit replica IDs, not both.");
|
|
143
|
+
if (t[0] === "all") return { mode: "all" };
|
|
144
|
+
if (n.some((e) => e.trim().length === 0 || e.length > 512 || /[\u0000-\u001f\u007f]/.test(e))) throw new m("Replica IDs must be nonempty and contain no control characters.");
|
|
145
|
+
return {
|
|
146
|
+
mode: "selected",
|
|
147
|
+
replicaIds: [...new Set(n)].sort()
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
}, g = (e, t) => {
|
|
151
|
+
let n = e.indexOf("#"), r = n < 0 ? "" : e.slice(n), i = n < 0 ? e : e.slice(0, n), a = i.indexOf("?"), o = a < 0 ? i : i.slice(0, a), s = new URLSearchParams(a < 0 ? "" : i.slice(a + 1));
|
|
152
|
+
if (s.delete("replica"), s.delete("replicas"), t.mode === "all") s.set("replicas", "all");
|
|
153
|
+
else {
|
|
154
|
+
if (t.replicaIds.length === 0) throw new m("Select at least one replica.");
|
|
155
|
+
for (let e of [...new Set(t.replicaIds)].sort()) s.append("replica", e);
|
|
156
|
+
}
|
|
157
|
+
return h(s), `${o}?${s}${r}`;
|
|
158
|
+
};
|
|
159
|
+
//#endregion
|
|
160
|
+
export { i as InspectBackfillInputSchema, r as InspectBackfillReceiptSchema, o as InspectBackfillResultSchema, m as InvalidReplicaSelection, s as ScheduleBackfillRequestConflict, a as decodeInspectBackfillInput, h as parseReplicaSelection, p as projectReplicaObservation, g as withReplicaSelection };
|
package/dist/jwt.d.ts
CHANGED
|
@@ -305,6 +305,11 @@ declare const Subject: Schema.Union<[Schema.Struct<{
|
|
|
305
305
|
type: Schema.Literal<["serviceAccount"]>;
|
|
306
306
|
id: typeof Schema.String;
|
|
307
307
|
tenantId: typeof Schema.String;
|
|
308
|
+
/** Application actor used for audit columns; null means machine work with
|
|
309
|
+
* no application actor. Identity only, never a permission grant. */
|
|
310
|
+
auditActorId: Schema.optionalWith<Schema.NullOr<typeof Schema.String>, {
|
|
311
|
+
exact: true;
|
|
312
|
+
}>;
|
|
308
313
|
scopes: Schema.optional<Schema.Array$<typeof Schema.String>>;
|
|
309
314
|
metadata: Schema.optional<Schema.Record$<typeof Schema.String, typeof Schema.Unknown>>;
|
|
310
315
|
}>, Schema.Struct<{
|
package/dist/rest.d.ts
CHANGED
|
@@ -159,11 +159,22 @@ declare interface DeleteTarget<Input = unknown> extends NestedTargetFields<Input
|
|
|
159
159
|
}
|
|
160
160
|
|
|
161
161
|
/** query→GET, mutation/action→POST, unless the spec overrides. */
|
|
162
|
-
export declare const derivePublicMethod: (kind: PublicApiDescriptor["kind"], spec: PublicApiSpec) => RestMethod;
|
|
162
|
+
export declare const derivePublicMethod: (kind: PublicApiDescriptor["kind"], spec: PublicApiSpec, descriptor?: ResourceDescriptorFacts) => RestMethod;
|
|
163
163
|
|
|
164
164
|
/** `/<version>/<tag-with-dots-as-slashes>` unless the spec gives an explicit
|
|
165
|
-
* path. `orders.create` @ v1 → `/v1/orders/create`. */
|
|
166
|
-
export declare const derivePublicPath: (tag: string, spec: PublicApiSpec) => string;
|
|
165
|
+
* path, or `resource` derives one. `orders.create` @ v1 → `/v1/orders/create`. */
|
|
166
|
+
export declare const derivePublicPath: (tag: string, spec: PublicApiSpec, descriptor?: ResourceDescriptorFacts) => string;
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* `publicApi.resource`: method and path from the resource, the descriptor's
|
|
170
|
+
* kind and target, and whether the input identifies one row — the convention
|
|
171
|
+
* `crud.*` already follows, so a surface of hundreds of projections is not
|
|
172
|
+
* hundreds of hand-written paths.
|
|
173
|
+
*/
|
|
174
|
+
export declare const deriveResource: (tag: string, spec: PublicApiSpec, descriptor: ResourceDescriptorFacts) => {
|
|
175
|
+
readonly method: RestMethod;
|
|
176
|
+
readonly path: string;
|
|
177
|
+
};
|
|
167
178
|
|
|
168
179
|
/**
|
|
169
180
|
* Dispatch a request across REST routes that SHARE a path. Every REST route
|
|
@@ -741,7 +752,7 @@ declare interface PluginHttpRouteStream {
|
|
|
741
752
|
*/
|
|
742
753
|
declare interface PolicyGuardSpec<Input = unknown> {
|
|
743
754
|
/** The action to authorize, as named in the resource policy's `actions`. */
|
|
744
|
-
readonly action: string;
|
|
755
|
+
readonly action: string | ((input: Input) => string);
|
|
745
756
|
/** Which registered resource policy governs the check. */
|
|
746
757
|
readonly resourceType: string;
|
|
747
758
|
/** PURE `input → resource id`. Returning undefined DENIES — an unidentifiable
|
|
@@ -771,6 +782,26 @@ export declare const problemTypeOf: (tag: string) => string;
|
|
|
771
782
|
*/
|
|
772
783
|
export declare const projectedFailure: (err: unknown, descriptor: PublicApiDescriptor, spec: PublicApiSpec, pluginErrors?: ReadonlyArray<PluginErrorSchema>) => unknown;
|
|
773
784
|
|
|
785
|
+
/** The generated TypeScript client, as the app declares it. */
|
|
786
|
+
export declare interface PublicApiClientConfig {
|
|
787
|
+
/** The npm package name. Default `@app/api-client`. */
|
|
788
|
+
readonly package?: string;
|
|
789
|
+
/** Where the package is written, relative to the app root. Default `sdk/typescript`. */
|
|
790
|
+
readonly out?: string;
|
|
791
|
+
/** `'plain'` — the Promise client, no Effect anywhere; `'effect'` — the
|
|
792
|
+
* Effect service; `'both'` — `.` plain and `./effect` Effect, with `effect`
|
|
793
|
+
* an optional peer. Default `'both'`. */
|
|
794
|
+
readonly flavor?: 'plain' | 'effect' | 'both';
|
|
795
|
+
/** The package's `license` field (an SPDX id). */
|
|
796
|
+
readonly license?: string;
|
|
797
|
+
/** The package's version. Default `0.1.0`. */
|
|
798
|
+
readonly packageVersion?: string;
|
|
799
|
+
/** Generate for ONE API version (`'v2'`). */
|
|
800
|
+
readonly apiVersion?: string;
|
|
801
|
+
/** The client's default base URL. */
|
|
802
|
+
readonly baseUrl?: string;
|
|
803
|
+
}
|
|
804
|
+
|
|
774
805
|
/** A descriptor kind that can be projected to REST (streams are not, in v1). */
|
|
775
806
|
export declare type PublicApiDescriptor = QueryProcedureDescriptor<string, Schema.Schema.Any, Schema.Schema.Any, Schema.Schema.All> | MutationProcedureDescriptor<string, Schema.Schema.Any, Schema.Schema.Any, Schema.Schema.All> | ActionProcedureDescriptor<string, Schema.Schema.Any, Schema.Schema.Any, Schema.Schema.All>;
|
|
776
807
|
|
|
@@ -802,6 +833,28 @@ export declare interface PublicApiProfileConfig {
|
|
|
802
833
|
readonly cursorParam?: string;
|
|
803
834
|
readonly naming?: RestNaming;
|
|
804
835
|
readonly etag?: boolean;
|
|
836
|
+
/** `'required'`: `voltro doctor` reports a projection without a
|
|
837
|
+
* `description` and an input/output field without a `description`
|
|
838
|
+
* annotation — so a new projection does not reach the surface without text.
|
|
839
|
+
* Default `'optional'`. */
|
|
840
|
+
readonly docs?: 'required' | 'optional';
|
|
841
|
+
/**
|
|
842
|
+
* Files `voltro dev` writes beside `rpcGroup.generated.ts` on every boot, from
|
|
843
|
+
* the mounted surface: `'openapi'` (`openapi.generated.json`) and the
|
|
844
|
+
* collections — `'postman'`, `'bruno'`, `'insomnia'`, `'hoppscotch'` — as
|
|
845
|
+
* committed, generated files, so a review diff shows the surface change and
|
|
846
|
+
* a client imported once cannot drift; `'typescript'` keeps the generated
|
|
847
|
+
* client package (`client`) written the same way. Off by default.
|
|
848
|
+
*/
|
|
849
|
+
readonly artifacts?: ReadonlyArray<'openapi' | 'postman' | 'bruno' | 'insomnia' | 'hoppscotch' | 'typescript'>;
|
|
850
|
+
/**
|
|
851
|
+
* The app's decision about its generated TypeScript client — what
|
|
852
|
+
* `voltro build api --target typescript` (and `voltro api-client build`)
|
|
853
|
+
* produces without flags, and what `voltro dev` keeps written when
|
|
854
|
+
* `artifacts` names `'typescript'`. `voltro api-client set …` writes this
|
|
855
|
+
* block; a flag on the command line overrides a field for one run.
|
|
856
|
+
*/
|
|
857
|
+
readonly client?: PublicApiClientConfig;
|
|
805
858
|
}
|
|
806
859
|
|
|
807
860
|
export declare type PublicApiProfileName = 'rpc' | 'standard' | 'jsonapi';
|
|
@@ -836,6 +889,18 @@ declare interface PublicApiSpec {
|
|
|
836
889
|
readonly method?: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
|
|
837
890
|
/** Derived from the tag + version when omitted: `/<version>/<tag-as-path>`. */
|
|
838
891
|
readonly path?: string;
|
|
892
|
+
/**
|
|
893
|
+
* Derive method and path from the resource instead of writing them — the
|
|
894
|
+
* convention `crud.*` already follows, opt-in per descriptor. `'teams'` on a
|
|
895
|
+
* query whose input carries `teamId` or `id` → `GET /v1/teams/{teamId}`,
|
|
896
|
+
* without one → `GET /v1/teams`; on a mutation whose `target.op` is
|
|
897
|
+
* `insert` → `POST /v1/teams`, `update` → `PATCH /v1/teams/{teamId}`,
|
|
898
|
+
* `delete` → `DELETE /v1/teams/{teamId}`; an action, or a mutation without
|
|
899
|
+
* a target, → `POST /v1/teams/{teamId}/<verb>` (the tag's last segment) when
|
|
900
|
+
* the input carries the id, else `POST /v1/teams/<verb>`. An explicit
|
|
901
|
+
* `method` or `path` wins over the derivation.
|
|
902
|
+
*/
|
|
903
|
+
readonly resource?: string;
|
|
839
904
|
/** Path version segment; multiple versions coexist as separate descriptors. */
|
|
840
905
|
readonly version?: string;
|
|
841
906
|
/** Additional API-key scopes required ON TOP of the handler's RBAC. */
|
|
@@ -912,6 +977,16 @@ export declare type PublicApiSubscribe = (input: unknown, ctx: RestRouteContext,
|
|
|
912
977
|
readonly [k: string]: unknown;
|
|
913
978
|
}) => void) => () => void;
|
|
914
979
|
|
|
980
|
+
/**
|
|
981
|
+
* The digest of a public surface: every projection's facts (tag, method, path,
|
|
982
|
+
* parameters, version, security, the typed errors and their statuses) and the
|
|
983
|
+
* SHAPE of its wire schemas, in tag order. The OpenAPI document publishes it as
|
|
984
|
+
* `x-voltro-surface-digest`, a generated client carries the one it was built
|
|
985
|
+
* from, and `voltro check --public-api --against` compares the two — so one
|
|
986
|
+
* number says whether a consumer's client still describes the API it calls.
|
|
987
|
+
*/
|
|
988
|
+
export declare const publicSurfaceDigest: (routes: ReadonlyArray<RestRouteDescriptor<any, any>>) => string;
|
|
989
|
+
|
|
915
990
|
/**
|
|
916
991
|
* Server-side snapshot caching for a query (see `defineQuery`). When set,
|
|
917
992
|
* the dispatcher caches the initial snapshot result and auto-invalidates it
|
|
@@ -1042,6 +1117,19 @@ export declare const requireScope: (scope: string) => RestGuard;
|
|
|
1042
1117
|
*/
|
|
1043
1118
|
export declare const resolveRestFormat: (config: PublicApiProfileConfig | undefined, override?: Partial<PublicApiProfileConfig> | undefined) => RestFormat;
|
|
1044
1119
|
|
|
1120
|
+
/** What `resource` derivation reads off a descriptor. */
|
|
1121
|
+
export declare interface ResourceDescriptorFacts {
|
|
1122
|
+
readonly kind: 'query' | 'mutation' | 'action' | 'stream';
|
|
1123
|
+
readonly input?: unknown;
|
|
1124
|
+
readonly target?: {
|
|
1125
|
+
readonly op?: string;
|
|
1126
|
+
} | undefined;
|
|
1127
|
+
}
|
|
1128
|
+
|
|
1129
|
+
/** The input field that identifies one row of `resource`: `<singular>Id`,
|
|
1130
|
+
* then `id`; `undefined` when the input names neither (a list, a create). */
|
|
1131
|
+
export declare const resourceIdField: (resource: string, input: unknown) => string | undefined;
|
|
1132
|
+
|
|
1045
1133
|
export declare const response: <O>(body: O, options?: {
|
|
1046
1134
|
readonly status?: number;
|
|
1047
1135
|
readonly headers?: Readonly<Record<string, string | ReadonlyArray<string>>>;
|
|
@@ -1305,6 +1393,9 @@ export declare interface RestRouteProjection {
|
|
|
1305
1393
|
readonly kind: 'query' | 'mutation' | 'action';
|
|
1306
1394
|
readonly version: string;
|
|
1307
1395
|
readonly security: 'required' | 'optional' | 'none';
|
|
1396
|
+
/** `publicApi.idempotent` — the route honours `Idempotency-Key` (under the
|
|
1397
|
+
* app's idempotency binding); a client sends one per attempt. */
|
|
1398
|
+
readonly idempotent: boolean;
|
|
1308
1399
|
readonly input: Schema.Schema.All;
|
|
1309
1400
|
/** The wire names of the input fields bound from the path. */
|
|
1310
1401
|
readonly pathParams: ReadonlyArray<string>;
|
|
@@ -1382,8 +1473,9 @@ export declare interface RestStreamResponse {
|
|
|
1382
1473
|
export declare const restViewSchema: (schema: Schema.Schema.All, format: RestFormat) => Schema.Schema.All;
|
|
1383
1474
|
|
|
1384
1475
|
/**
|
|
1385
|
-
* Whether `path` is one the route declared. The router
|
|
1386
|
-
*
|
|
1476
|
+
* Whether `path` is one the route declared. The underlying router folds case
|
|
1477
|
+
* and trailing slashes when selecting candidates; this dispatcher deliberately
|
|
1478
|
+
* rejects those undeclared aliases. It checks byte for byte: a literal
|
|
1387
1479
|
* segment must be equal, a `:name` segment takes one non-empty segment, and
|
|
1388
1480
|
* beyond the declared segments a `'prefix'` route (the default) owns any
|
|
1389
1481
|
* sub-path while an `'exact'` route owns nothing. A trailing slash alone is
|
|
@@ -1429,6 +1521,11 @@ declare const Subject: Schema.Union<[Schema.Struct<{
|
|
|
1429
1521
|
type: Schema.Literal<["serviceAccount"]>;
|
|
1430
1522
|
id: typeof Schema.String;
|
|
1431
1523
|
tenantId: typeof Schema.String;
|
|
1524
|
+
/** Application actor used for audit columns; null means machine work with
|
|
1525
|
+
* no application actor. Identity only, never a permission grant. */
|
|
1526
|
+
auditActorId: Schema.optionalWith<Schema.NullOr<typeof Schema.String>, {
|
|
1527
|
+
exact: true;
|
|
1528
|
+
}>;
|
|
1432
1529
|
scopes: Schema.optional<Schema.Array$<typeof Schema.String>>;
|
|
1433
1530
|
metadata: Schema.optional<Schema.Record$<typeof Schema.String, typeof Schema.Unknown>>;
|
|
1434
1531
|
}>, Schema.Struct<{
|
|
@@ -1532,4 +1629,12 @@ declare interface UpdateTarget<Input = unknown, Row = unknown, Item = Record<str
|
|
|
1532
1629
|
readonly shapeItem?: ((input: Input, current: Item) => Item) | undefined;
|
|
1533
1630
|
}
|
|
1534
1631
|
|
|
1632
|
+
export declare const wireExample: (example: {
|
|
1633
|
+
readonly request?: unknown;
|
|
1634
|
+
readonly response?: unknown;
|
|
1635
|
+
}, wireInput: Schema.Schema.All, wireOutput: Schema.Schema.All) => {
|
|
1636
|
+
readonly request?: unknown;
|
|
1637
|
+
readonly response?: unknown;
|
|
1638
|
+
};
|
|
1639
|
+
|
|
1535
1640
|
export { }
|