@shpitdev/convex-cliproxy-observability 0.1.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 +11 -0
- package/LICENSE +201 -0
- package/README.md +40 -0
- package/dist/capture/index.d.ts +79 -0
- package/dist/capture/index.d.ts.map +1 -0
- package/dist/capture/index.js +182 -0
- package/dist/capture/index.js.map +1 -0
- package/dist/client.d.ts +129 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +232 -0
- package/dist/client.js.map +1 -0
- package/dist/component/_generated/api.d.ts +12 -0
- package/dist/component/_generated/api.d.ts.map +1 -0
- package/dist/component/_generated/api.js +7 -0
- package/dist/component/_generated/api.js.map +1 -0
- package/dist/component/_generated/component.d.ts +17 -0
- package/dist/component/_generated/component.d.ts.map +1 -0
- package/dist/component/_generated/component.js +3 -0
- package/dist/component/_generated/component.js.map +1 -0
- package/dist/component/_generated/dataModel.d.ts +8 -0
- package/dist/component/_generated/dataModel.d.ts.map +1 -0
- package/dist/component/_generated/dataModel.js +3 -0
- package/dist/component/_generated/dataModel.js.map +1 -0
- package/dist/component/_generated/server.d.ts +21 -0
- package/dist/component/_generated/server.d.ts.map +1 -0
- package/dist/component/_generated/server.js +11 -0
- package/dist/component/_generated/server.js.map +1 -0
- package/dist/component/convex.config.d.ts +4 -0
- package/dist/component/convex.config.d.ts.map +1 -0
- package/dist/component/convex.config.js +4 -0
- package/dist/component/convex.config.js.map +1 -0
- package/dist/component/ingest.d.ts +64 -0
- package/dist/component/ingest.d.ts.map +1 -0
- package/dist/component/ingest.js +309 -0
- package/dist/component/ingest.js.map +1 -0
- package/dist/component/queries.d.ts +136 -0
- package/dist/component/queries.d.ts.map +1 -0
- package/dist/component/queries.js +219 -0
- package/dist/component/queries.js.map +1 -0
- package/dist/component/schema.d.ts +159 -0
- package/dist/component/schema.d.ts.map +1 -0
- package/dist/component/schema.js +74 -0
- package/dist/component/schema.js.map +1 -0
- package/dist/content/index.d.ts +8 -0
- package/dist/content/index.d.ts.map +1 -0
- package/dist/content/index.js +41 -0
- package/dist/content/index.js.map +1 -0
- package/dist/model-call/index.d.ts +120 -0
- package/dist/model-call/index.d.ts.map +1 -0
- package/dist/model-call/index.js +96 -0
- package/dist/model-call/index.js.map +1 -0
- package/dist/projection.d.ts +19 -0
- package/dist/projection.d.ts.map +1 -0
- package/dist/projection.js +83 -0
- package/dist/projection.js.map +1 -0
- package/dist/protocols/anthropic-messages.d.ts +11 -0
- package/dist/protocols/anthropic-messages.d.ts.map +1 -0
- package/dist/protocols/anthropic-messages.js +114 -0
- package/dist/protocols/anthropic-messages.js.map +1 -0
- package/dist/protocols/chat-completions.d.ts +10 -0
- package/dist/protocols/chat-completions.d.ts.map +1 -0
- package/dist/protocols/chat-completions.js +89 -0
- package/dist/protocols/chat-completions.js.map +1 -0
- package/dist/protocols/checkpoint.d.ts +20 -0
- package/dist/protocols/checkpoint.d.ts.map +1 -0
- package/dist/protocols/checkpoint.js +318 -0
- package/dist/protocols/checkpoint.js.map +1 -0
- package/dist/protocols/content.d.ts +34 -0
- package/dist/protocols/content.d.ts.map +1 -0
- package/dist/protocols/content.js +40 -0
- package/dist/protocols/content.js.map +1 -0
- package/dist/protocols/framing.d.ts +20 -0
- package/dist/protocols/framing.d.ts.map +1 -0
- package/dist/protocols/framing.js +67 -0
- package/dist/protocols/framing.js.map +1 -0
- package/dist/protocols/index.d.ts +20 -0
- package/dist/protocols/index.d.ts.map +1 -0
- package/dist/protocols/index.js +139 -0
- package/dist/protocols/index.js.map +1 -0
- package/dist/protocols/output.d.ts +4 -0
- package/dist/protocols/output.d.ts.map +1 -0
- package/dist/protocols/output.js +81 -0
- package/dist/protocols/output.js.map +1 -0
- package/dist/protocols/responses.d.ts +12 -0
- package/dist/protocols/responses.d.ts.map +1 -0
- package/dist/protocols/responses.js +189 -0
- package/dist/protocols/responses.js.map +1 -0
- package/dist/protocols/types.d.ts +27 -0
- package/dist/protocols/types.d.ts.map +1 -0
- package/dist/protocols/types.js +2 -0
- package/dist/protocols/types.js.map +1 -0
- package/dist/protocols/usage.d.ts +3 -0
- package/dist/protocols/usage.d.ts.map +1 -0
- package/dist/protocols/usage.js +27 -0
- package/dist/protocols/usage.js.map +1 -0
- package/dist/protocols/values.d.ts +10 -0
- package/dist/protocols/values.d.ts.map +1 -0
- package/dist/protocols/values.js +32 -0
- package/dist/protocols/values.js.map +1 -0
- package/dist/test.d.ts +155 -0
- package/dist/test.d.ts.map +1 -0
- package/dist/test.js +8 -0
- package/dist/test.js.map +1 -0
- package/package.json +90 -0
- package/src/capture/index.ts +277 -0
- package/src/client.ts +286 -0
- package/src/component/_generated/api.ts +19 -0
- package/src/component/_generated/component.ts +32 -0
- package/src/component/_generated/dataModel.ts +15 -0
- package/src/component/_generated/server.ts +43 -0
- package/src/component/convex.config.ts +3 -0
- package/src/component/ingest.ts +328 -0
- package/src/component/queries.ts +248 -0
- package/src/component/schema.ts +73 -0
- package/src/content/index.ts +53 -0
- package/src/model-call/index.ts +224 -0
- package/src/projection.ts +99 -0
- package/src/protocols/anthropic-messages.ts +115 -0
- package/src/protocols/chat-completions.ts +94 -0
- package/src/protocols/checkpoint.ts +342 -0
- package/src/protocols/content.ts +41 -0
- package/src/protocols/framing.ts +62 -0
- package/src/protocols/index.ts +140 -0
- package/src/protocols/output.ts +78 -0
- package/src/protocols/responses.ts +188 -0
- package/src/protocols/types.ts +26 -0
- package/src/protocols/usage.ts +36 -0
- package/src/protocols/values.ts +35 -0
- package/src/test.ts +16 -0
package/src/client.ts
ADDED
|
@@ -0,0 +1,286 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
GenericActionCtx,
|
|
3
|
+
GenericDataModel,
|
|
4
|
+
GenericMutationCtx,
|
|
5
|
+
GenericQueryCtx,
|
|
6
|
+
FunctionArgs,
|
|
7
|
+
} from "convex/server";
|
|
8
|
+
import type { ComponentApi } from "./component/_generated/component.js";
|
|
9
|
+
import type { CaptureObservationV1 } from "./capture/index.js";
|
|
10
|
+
import { MAX_ENVELOPE_BYTES, validateSegment, sha256 } from "./capture/index.js";
|
|
11
|
+
import type { ModelCallV1, PrivateContentReference } from "./model-call/index.js";
|
|
12
|
+
import type { PrivateCaptureStorage } from "./content/index.js";
|
|
13
|
+
import { nanoTime, protocolForRoute, PARSER_VERSION } from "./protocols/index.js";
|
|
14
|
+
export * from "./model-call/index.js";
|
|
15
|
+
export { resolveCallBlob, type PrivateCaptureStorage } from "./content/index.js";
|
|
16
|
+
export type CliproxyObservabilityComponent = ComponentApi;
|
|
17
|
+
type ReadContext = Pick<
|
|
18
|
+
| GenericQueryCtx<GenericDataModel>
|
|
19
|
+
| GenericMutationCtx<GenericDataModel>
|
|
20
|
+
| GenericActionCtx<GenericDataModel>,
|
|
21
|
+
"runQuery"
|
|
22
|
+
>;
|
|
23
|
+
type ActionContext = Pick<GenericActionCtx<GenericDataModel>, "runMutation" | "runQuery">;
|
|
24
|
+
export class CliproxyObservability {
|
|
25
|
+
constructor(readonly component: ComponentApi) {}
|
|
26
|
+
pageRecentSummaries(
|
|
27
|
+
ctx: ReadContext,
|
|
28
|
+
args: FunctionArgs<ComponentApi["queries"]["pageRecentSummaries"]>,
|
|
29
|
+
) {
|
|
30
|
+
return ctx.runQuery(this.component.queries.pageRecentSummaries, args);
|
|
31
|
+
}
|
|
32
|
+
pageCorrelationSummaries(
|
|
33
|
+
ctx: ReadContext,
|
|
34
|
+
args: FunctionArgs<ComponentApi["queries"]["pageRecentSummaries"]> & {
|
|
35
|
+
correlation: NonNullable<
|
|
36
|
+
FunctionArgs<ComponentApi["queries"]["pageRecentSummaries"]>["correlation"]
|
|
37
|
+
>;
|
|
38
|
+
},
|
|
39
|
+
) {
|
|
40
|
+
return this.pageRecentSummaries(ctx, args);
|
|
41
|
+
}
|
|
42
|
+
getCall(ctx: ReadContext, args: { destinationId: string; callId: string }) {
|
|
43
|
+
return ctx.runQuery(this.component.queries.getCall, args);
|
|
44
|
+
}
|
|
45
|
+
pageEventSegments(
|
|
46
|
+
ctx: ReadContext,
|
|
47
|
+
args: FunctionArgs<ComponentApi["queries"]["pageEventSegments"]>,
|
|
48
|
+
) {
|
|
49
|
+
return ctx.runQuery(this.component.queries.pageEventSegments, args);
|
|
50
|
+
}
|
|
51
|
+
getBootHealth(
|
|
52
|
+
ctx: ReadContext,
|
|
53
|
+
args: { destinationId: string; instanceId: string; pluginBootId: string },
|
|
54
|
+
) {
|
|
55
|
+
return ctx.runQuery(this.component.queries.getBootHealth, args);
|
|
56
|
+
}
|
|
57
|
+
getCaptureCoverage(ctx: ReadContext, args: { destinationId: string }) {
|
|
58
|
+
return ctx.runQuery(this.component.queries.getCaptureCoverage, args);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
export function initialCall(
|
|
62
|
+
o: CaptureObservationV1,
|
|
63
|
+
callId: string,
|
|
64
|
+
receivedAt: number,
|
|
65
|
+
): ModelCallV1 {
|
|
66
|
+
return {
|
|
67
|
+
schemaVersion: 1,
|
|
68
|
+
source: "cliproxy",
|
|
69
|
+
callId,
|
|
70
|
+
sourceDocumentId: "",
|
|
71
|
+
gateway: "cliproxy",
|
|
72
|
+
authType: "unknown",
|
|
73
|
+
route: o.route,
|
|
74
|
+
configRevision: o.configRevision,
|
|
75
|
+
destinationId: o.destinationId,
|
|
76
|
+
instanceId: o.instanceId,
|
|
77
|
+
pluginBootId: o.pluginBootId,
|
|
78
|
+
executionId: o.requestId,
|
|
79
|
+
sourceTraceId: o.sourceTraceId,
|
|
80
|
+
traceId: o.correlation?.traceId,
|
|
81
|
+
requestModel: o.requestedModel?.slice(0, 256),
|
|
82
|
+
operation:
|
|
83
|
+
o.route === "GET /v1/models"
|
|
84
|
+
? "discovery"
|
|
85
|
+
: o.route === "POST /v1/messages/count_tokens"
|
|
86
|
+
? "token_count"
|
|
87
|
+
: "generation",
|
|
88
|
+
clientProtocol: protocolForRoute(o.route),
|
|
89
|
+
state: "in_progress",
|
|
90
|
+
timingSource: "plugin_observed",
|
|
91
|
+
startTimeUnixNano: nanoTime(o.observedAt),
|
|
92
|
+
correlation: o.correlation ?? {},
|
|
93
|
+
correlationConflicts: o.correlationConflicts ?? [],
|
|
94
|
+
usage: [],
|
|
95
|
+
cost: { kind: "unknown" },
|
|
96
|
+
attemptDetail: "unavailable",
|
|
97
|
+
capture: {
|
|
98
|
+
raw: "partial",
|
|
99
|
+
projection: "partial",
|
|
100
|
+
usage: "unavailable",
|
|
101
|
+
preHook: "unavailable",
|
|
102
|
+
projectedThroughSequence: 0,
|
|
103
|
+
persistedThroughSequence: 0,
|
|
104
|
+
gaps: [],
|
|
105
|
+
parserVersion: PARSER_VERSION,
|
|
106
|
+
pluginVersion: o.pluginVersion,
|
|
107
|
+
redactionVersion: o.redactionVersion,
|
|
108
|
+
lastObservedAt: o.observedAt,
|
|
109
|
+
},
|
|
110
|
+
receivedAt,
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
export type CaptureHandlerOptions = {
|
|
114
|
+
client: CliproxyObservability;
|
|
115
|
+
destinationId: string;
|
|
116
|
+
deploymentId: string;
|
|
117
|
+
environment: "dev" | "prod";
|
|
118
|
+
instanceIds: readonly string[];
|
|
119
|
+
tokens: readonly string[];
|
|
120
|
+
storage: PrivateCaptureStorage;
|
|
121
|
+
scheduleProjection: (ctx: ActionContext, callId: string) => Promise<void>;
|
|
122
|
+
};
|
|
123
|
+
function tokenMatches(presented: string, expected: string): boolean {
|
|
124
|
+
let diff = presented.length ^ expected.length;
|
|
125
|
+
for (let i = 0; i < Math.max(presented.length, expected.length); i++)
|
|
126
|
+
diff |= (presented.charCodeAt(i) || 0) ^ (expected.charCodeAt(i) || 0);
|
|
127
|
+
return diff === 0;
|
|
128
|
+
}
|
|
129
|
+
export async function readBoundedCaptureBody(request: Request): Promise<Uint8Array> {
|
|
130
|
+
if (Number(request.headers.get("Content-Length")) > MAX_ENVELOPE_BYTES)
|
|
131
|
+
throw new RangeError("envelope limit");
|
|
132
|
+
const reader = request.body?.getReader();
|
|
133
|
+
if (!reader) return new Uint8Array();
|
|
134
|
+
let size = 0;
|
|
135
|
+
const chunks: Uint8Array[] = [];
|
|
136
|
+
try {
|
|
137
|
+
while (true) {
|
|
138
|
+
const { done, value } = await reader.read();
|
|
139
|
+
if (done) break;
|
|
140
|
+
size += value.byteLength;
|
|
141
|
+
if (size > MAX_ENVELOPE_BYTES) {
|
|
142
|
+
await reader.cancel();
|
|
143
|
+
throw new RangeError("envelope limit");
|
|
144
|
+
}
|
|
145
|
+
chunks.push(value);
|
|
146
|
+
}
|
|
147
|
+
} finally {
|
|
148
|
+
reader.releaseLock();
|
|
149
|
+
}
|
|
150
|
+
const out = new Uint8Array(size);
|
|
151
|
+
let offset = 0;
|
|
152
|
+
for (const chunk of chunks) {
|
|
153
|
+
out.set(chunk, offset);
|
|
154
|
+
offset += chunk.length;
|
|
155
|
+
}
|
|
156
|
+
return out;
|
|
157
|
+
}
|
|
158
|
+
export async function handleCliproxyCaptureRequest(
|
|
159
|
+
ctx: ActionContext,
|
|
160
|
+
request: Request,
|
|
161
|
+
options: CaptureHandlerOptions,
|
|
162
|
+
): Promise<Response> {
|
|
163
|
+
if (request.method !== "POST") return new Response("method not allowed", { status: 405 });
|
|
164
|
+
if (options.tokens.length === 0 || options.tokens.some((x) => x.length < 24))
|
|
165
|
+
return new Response("capture unavailable", { status: 503 });
|
|
166
|
+
const bearer = request.headers.get("Authorization") ?? "";
|
|
167
|
+
if (
|
|
168
|
+
!/^Bearer [^,\r\n]+$/.test(bearer) ||
|
|
169
|
+
!options.tokens.some((token) => tokenMatches(bearer, `Bearer ${token}`))
|
|
170
|
+
)
|
|
171
|
+
return new Response("unauthorized", { status: 401 });
|
|
172
|
+
if (request.headers.get("Content-Type")?.split(";")[0]?.trim() !== "application/json")
|
|
173
|
+
return new Response("unsupported content type", { status: 415 });
|
|
174
|
+
let parsed: Awaited<ReturnType<typeof validateSegment>>;
|
|
175
|
+
try {
|
|
176
|
+
const raw = await readBoundedCaptureBody(request);
|
|
177
|
+
const candidate = JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(raw));
|
|
178
|
+
if (candidate?.operation === "health") {
|
|
179
|
+
if (
|
|
180
|
+
candidate.schemaVersion !== 1 ||
|
|
181
|
+
candidate.destinationId !== options.destinationId ||
|
|
182
|
+
!options.instanceIds.includes(candidate.instanceId)
|
|
183
|
+
)
|
|
184
|
+
return new Response("scope mismatch", { status: 403 });
|
|
185
|
+
return Response.json({
|
|
186
|
+
ready: true,
|
|
187
|
+
destinationId: options.destinationId,
|
|
188
|
+
deploymentId: options.deploymentId,
|
|
189
|
+
instanceId: candidate.instanceId,
|
|
190
|
+
schemaVersion: 1,
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
if (candidate?.operation === "health_record") {
|
|
194
|
+
if (
|
|
195
|
+
raw.length > 16384 ||
|
|
196
|
+
candidate.schemaVersion !== 1 ||
|
|
197
|
+
candidate.destinationId !== options.destinationId ||
|
|
198
|
+
!options.instanceIds.includes(candidate.instanceId) ||
|
|
199
|
+
!/^[a-zA-Z0-9][a-zA-Z0-9._:-]{0,199}$/.test(candidate.pluginBootId) ||
|
|
200
|
+
candidate.precommitCoverage !== "unknown_before_local_commit"
|
|
201
|
+
)
|
|
202
|
+
return new Response("invalid health scope", { status: 403 });
|
|
203
|
+
const result = await ctx.runMutation(options.client.component.ingest.recordHealth, {
|
|
204
|
+
destinationId: options.destinationId,
|
|
205
|
+
instanceId: candidate.instanceId,
|
|
206
|
+
pluginBootId: candidate.pluginBootId,
|
|
207
|
+
startedAt: candidate.startedAt,
|
|
208
|
+
observedAt: candidate.observedAt,
|
|
209
|
+
observationsTotal: candidate.observationsTotal,
|
|
210
|
+
droppedObservationsTotal: candidate.droppedObservationsTotal,
|
|
211
|
+
lostControlObservationsTotal: candidate.lostControlObservationsTotal,
|
|
212
|
+
scopeConflictsTotal: candidate.scopeConflictsTotal,
|
|
213
|
+
expiredScopesTotal: candidate.expiredScopesTotal,
|
|
214
|
+
activeCalls: candidate.activeCalls,
|
|
215
|
+
});
|
|
216
|
+
return Response.json({
|
|
217
|
+
...result,
|
|
218
|
+
digest: await sha256(raw),
|
|
219
|
+
destinationId: options.destinationId,
|
|
220
|
+
deploymentId: options.deploymentId,
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
parsed = await validateSegment(raw, options);
|
|
224
|
+
} catch (error) {
|
|
225
|
+
return new Response("invalid capture segment", {
|
|
226
|
+
status: error instanceof RangeError ? 413 : 400,
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
const { envelope, content, callId, identity, digest, observations } = parsed;
|
|
230
|
+
const first = observations[0]!;
|
|
231
|
+
const reference: PrivateContentReference = {
|
|
232
|
+
key: `observability/cliproxy/v2/${envelope.destinationId}/${envelope.instanceId}/${callId}/${envelope.firstSequence}-${digest}.ndjson`,
|
|
233
|
+
sha256: digest,
|
|
234
|
+
byteLength: content.byteLength,
|
|
235
|
+
contentType: "application/x-ndjson",
|
|
236
|
+
};
|
|
237
|
+
try {
|
|
238
|
+
await options.storage.put(reference, content);
|
|
239
|
+
const correlation = first.correlation ?? {};
|
|
240
|
+
const terminal = observations.find((o) => o.kind === "completion");
|
|
241
|
+
const receipt = await ctx.runMutation(options.client.component.ingest.admit, {
|
|
242
|
+
destinationId: envelope.destinationId,
|
|
243
|
+
instanceId: envelope.instanceId,
|
|
244
|
+
pluginBootId: envelope.pluginBootId,
|
|
245
|
+
executionId: envelope.requestId,
|
|
246
|
+
callId,
|
|
247
|
+
sequence: envelope.firstSequence,
|
|
248
|
+
throughSequence: envelope.throughSequence,
|
|
249
|
+
terminalSequence: terminal?.sequence,
|
|
250
|
+
identity,
|
|
251
|
+
digest,
|
|
252
|
+
reference,
|
|
253
|
+
summaryJson: JSON.stringify({
|
|
254
|
+
...initialCall(first, callId, Date.now()),
|
|
255
|
+
deploymentId: options.deploymentId,
|
|
256
|
+
environment: options.environment,
|
|
257
|
+
}),
|
|
258
|
+
observedAt: first.observedAt,
|
|
259
|
+
correlation: {
|
|
260
|
+
requestId: correlation.requestId,
|
|
261
|
+
runId: correlation.runId,
|
|
262
|
+
jobId: correlation.jobId,
|
|
263
|
+
rootExecutionId: correlation.rootExecutionId,
|
|
264
|
+
opencodeSessionId: correlation.opencodeSessionId,
|
|
265
|
+
},
|
|
266
|
+
});
|
|
267
|
+
// Scheduling failure returns retryable 503 after durable receipt; retry is idempotent.
|
|
268
|
+
await options.scheduleProjection(ctx, callId);
|
|
269
|
+
return Response.json({ ...receipt, rawCommitted: true, projectionCommitted: false });
|
|
270
|
+
} catch (error) {
|
|
271
|
+
const message = error instanceof Error ? error.message : "";
|
|
272
|
+
return new Response(
|
|
273
|
+
message.includes("capture_digest_conflict") || message.includes("capture_sequence_conflict")
|
|
274
|
+
? "capture identity conflict"
|
|
275
|
+
: "capture temporarily unavailable",
|
|
276
|
+
{
|
|
277
|
+
status:
|
|
278
|
+
message.includes("capture_digest_conflict") ||
|
|
279
|
+
message.includes("capture_sequence_conflict")
|
|
280
|
+
? 409
|
|
281
|
+
: 503,
|
|
282
|
+
},
|
|
283
|
+
);
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
export { projectPendingSegments } from "./projection.js";
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/* eslint-disable */
|
|
2
|
+
|
|
3
|
+
import type * as ingest from "../ingest.js";
|
|
4
|
+
import type * as queries from "../queries.js";
|
|
5
|
+
import type {
|
|
6
|
+
ApiFromModules,
|
|
7
|
+
FilterApi,
|
|
8
|
+
FunctionReference,
|
|
9
|
+
} from "convex/server";
|
|
10
|
+
import { anyApi, componentsGeneric } from "convex/server";
|
|
11
|
+
|
|
12
|
+
const fullApi: ApiFromModules<{
|
|
13
|
+
ingest: typeof ingest;
|
|
14
|
+
queries: typeof queries;
|
|
15
|
+
}> = anyApi as any;
|
|
16
|
+
|
|
17
|
+
export const api: FilterApi<typeof fullApi, FunctionReference<any, "public">> = anyApi as any;
|
|
18
|
+
export const internal: FilterApi<typeof fullApi, FunctionReference<any, "internal">> = anyApi as any;
|
|
19
|
+
export const components = componentsGeneric() as unknown as {};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/* eslint-disable */
|
|
2
|
+
|
|
3
|
+
import type { FunctionReference, RegisteredMutation, RegisteredQuery } from "convex/server";
|
|
4
|
+
import type * as ingest from "../ingest.js";
|
|
5
|
+
import type * as queries from "../queries.js";
|
|
6
|
+
|
|
7
|
+
type ComponentQuery<Registered, Name extends string | undefined> =
|
|
8
|
+
Registered extends RegisteredQuery<any, infer Args, infer Returns>
|
|
9
|
+
? FunctionReference<"query", "internal", Args, Awaited<Returns>, Name>
|
|
10
|
+
: never;
|
|
11
|
+
|
|
12
|
+
type PublicQueries<Module, Name extends string | undefined> = {
|
|
13
|
+
[Key in keyof Module as Module[Key] extends RegisteredQuery<"public", any, any>
|
|
14
|
+
? Key
|
|
15
|
+
: never]: ComponentQuery<Module[Key], Name>;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
type ComponentMutation<Registered, Name extends string | undefined> =
|
|
19
|
+
Registered extends RegisteredMutation<any, infer Args, infer Returns>
|
|
20
|
+
? FunctionReference<"mutation", "internal", Args, Awaited<Returns>, Name>
|
|
21
|
+
: never;
|
|
22
|
+
|
|
23
|
+
type PublicMutations<Module, Name extends string | undefined> = {
|
|
24
|
+
[Key in keyof Module as Module[Key] extends RegisteredMutation<"public", any, any>
|
|
25
|
+
? Key
|
|
26
|
+
: never]: ComponentMutation<Module[Key], Name>;
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export type ComponentApi<Name extends string | undefined = string | undefined> = {
|
|
30
|
+
ingest: PublicMutations<typeof ingest, Name>;
|
|
31
|
+
queries: PublicQueries<typeof queries, Name>;
|
|
32
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/* eslint-disable */
|
|
2
|
+
|
|
3
|
+
import type {
|
|
4
|
+
DataModelFromSchemaDefinition,
|
|
5
|
+
DocumentByName,
|
|
6
|
+
SystemTableNames,
|
|
7
|
+
TableNamesInDataModel,
|
|
8
|
+
} from "convex/server";
|
|
9
|
+
import type { GenericId } from "convex/values";
|
|
10
|
+
import schema from "../schema.js";
|
|
11
|
+
|
|
12
|
+
export type DataModel = DataModelFromSchemaDefinition<typeof schema>;
|
|
13
|
+
export type TableNames = TableNamesInDataModel<DataModel>;
|
|
14
|
+
export type Doc<TableName extends TableNames> = DocumentByName<DataModel, TableName>;
|
|
15
|
+
export type Id<TableName extends TableNames | SystemTableNames> = GenericId<TableName>;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/* eslint-disable */
|
|
2
|
+
|
|
3
|
+
import type {
|
|
4
|
+
ActionBuilder,
|
|
5
|
+
GenericActionCtx,
|
|
6
|
+
GenericDatabaseReader,
|
|
7
|
+
GenericDatabaseWriter,
|
|
8
|
+
GenericMutationCtx,
|
|
9
|
+
GenericQueryCtx,
|
|
10
|
+
HttpActionBuilder,
|
|
11
|
+
MutationBuilder,
|
|
12
|
+
QueryBuilder,
|
|
13
|
+
} from "convex/server";
|
|
14
|
+
import {
|
|
15
|
+
actionGeneric,
|
|
16
|
+
httpActionGeneric,
|
|
17
|
+
internalActionGeneric,
|
|
18
|
+
internalMutationGeneric,
|
|
19
|
+
internalQueryGeneric,
|
|
20
|
+
mutationGeneric,
|
|
21
|
+
queryGeneric,
|
|
22
|
+
} from "convex/server";
|
|
23
|
+
import type { DataModel } from "./dataModel.js";
|
|
24
|
+
|
|
25
|
+
type Env = {
|
|
26
|
+
readonly CONVEX_CLOUD_URL: string;
|
|
27
|
+
readonly CONVEX_SITE_URL: string;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
export const query: QueryBuilder<DataModel, "public"> = queryGeneric;
|
|
31
|
+
export const internalQuery: QueryBuilder<DataModel, "internal"> = internalQueryGeneric;
|
|
32
|
+
export const mutation: MutationBuilder<DataModel, "public"> = mutationGeneric;
|
|
33
|
+
export const internalMutation: MutationBuilder<DataModel, "internal"> = internalMutationGeneric;
|
|
34
|
+
export const action: ActionBuilder<DataModel, "public"> = actionGeneric;
|
|
35
|
+
export const internalAction: ActionBuilder<DataModel, "internal"> = internalActionGeneric;
|
|
36
|
+
export const httpAction: HttpActionBuilder = httpActionGeneric;
|
|
37
|
+
export const env: Env = (globalThis as unknown as { process: { env: Env } }).process.env;
|
|
38
|
+
|
|
39
|
+
export type QueryCtx = GenericQueryCtx<DataModel>;
|
|
40
|
+
export type MutationCtx = GenericMutationCtx<DataModel>;
|
|
41
|
+
export type ActionCtx = GenericActionCtx<DataModel>;
|
|
42
|
+
export type DatabaseReader = GenericDatabaseReader<DataModel>;
|
|
43
|
+
export type DatabaseWriter = GenericDatabaseWriter<DataModel>;
|