@verdict-ai/api 0.1.0 → 0.2.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.
Files changed (53) hide show
  1. package/dist/app.d.ts +50 -4
  2. package/dist/app.js +63 -11
  3. package/dist/app.js.map +1 -1
  4. package/dist/github.d.ts +15 -0
  5. package/dist/github.js +40 -0
  6. package/dist/github.js.map +1 -0
  7. package/dist/hub-pages.d.ts +24 -0
  8. package/dist/hub-pages.js +119 -0
  9. package/dist/hub-pages.js.map +1 -0
  10. package/dist/index.d.ts +2 -1
  11. package/dist/index.js +2 -1
  12. package/dist/index.js.map +1 -1
  13. package/dist/openapi.d.ts +355 -0
  14. package/dist/openapi.js +35 -4
  15. package/dist/openapi.js.map +1 -1
  16. package/dist/present.d.ts +3 -0
  17. package/dist/rate-limit.d.ts +44 -0
  18. package/dist/rate-limit.js +40 -0
  19. package/dist/rate-limit.js.map +1 -0
  20. package/dist/routes/admin.d.ts +1 -1
  21. package/dist/routes/admin.js +54 -8
  22. package/dist/routes/admin.js.map +1 -1
  23. package/dist/routes/hub.d.ts +12 -0
  24. package/dist/routes/hub.js +66 -0
  25. package/dist/routes/hub.js.map +1 -0
  26. package/dist/routes/project-versions.d.ts +4 -0
  27. package/dist/routes/project-versions.js +56 -0
  28. package/dist/routes/project-versions.js.map +1 -0
  29. package/dist/routes/projects.d.ts +4 -0
  30. package/dist/routes/projects.js +91 -0
  31. package/dist/routes/projects.js.map +1 -0
  32. package/dist/routes/promotions.d.ts +4 -0
  33. package/dist/routes/promotions.js +72 -0
  34. package/dist/routes/promotions.js.map +1 -0
  35. package/dist/routes/public-hub.d.ts +41 -0
  36. package/dist/routes/public-hub.js +119 -0
  37. package/dist/routes/public-hub.js.map +1 -0
  38. package/dist/routes/publications.d.ts +4 -0
  39. package/dist/routes/publications.js +79 -0
  40. package/dist/routes/publications.js.map +1 -0
  41. package/dist/routes/reports.d.ts +4 -0
  42. package/dist/routes/reports.js +84 -0
  43. package/dist/routes/reports.js.map +1 -0
  44. package/dist/routes/shared.d.ts +34 -0
  45. package/dist/routes/shared.js +73 -1
  46. package/dist/routes/shared.js.map +1 -1
  47. package/dist/server.js +12 -4
  48. package/dist/server.js.map +1 -1
  49. package/dist/worker.d.ts +20 -2
  50. package/dist/worker.js +23 -5
  51. package/dist/worker.js.map +1 -1
  52. package/package.json +3 -3
  53. package/wrangler.example.toml +18 -1
package/dist/openapi.d.ts CHANGED
@@ -2,6 +2,219 @@
2
2
  * Describes the public REST operations for API discovery.
3
3
  * The published paths mirror route registration; runtime validation remains owned by request schemas.
4
4
  */
5
+ import type { RouteGroup } from "./app.js";
6
+ /** The document for an app that serves only some route groups: paths of the others are left out. */
7
+ export declare function openapiFor(groups: readonly RouteGroup[]): {
8
+ paths: {
9
+ [k: string]: {
10
+ post: {
11
+ summary: string;
12
+ };
13
+ get: {
14
+ summary: string;
15
+ };
16
+ } | {
17
+ post: {
18
+ summary: string;
19
+ };
20
+ } | {
21
+ get: {
22
+ summary: string;
23
+ };
24
+ put: {
25
+ summary: string;
26
+ };
27
+ delete: {
28
+ summary: string;
29
+ };
30
+ } | {
31
+ get: {
32
+ summary: string;
33
+ };
34
+ } | {
35
+ post: {
36
+ summary: string;
37
+ };
38
+ get: {
39
+ summary: string;
40
+ };
41
+ } | {
42
+ get: {
43
+ summary: string;
44
+ };
45
+ } | {
46
+ post: {
47
+ summary: string;
48
+ };
49
+ } | {
50
+ post: {
51
+ summary: string;
52
+ };
53
+ } | {
54
+ post: {
55
+ summary: string;
56
+ };
57
+ } | {
58
+ get: {
59
+ summary: string;
60
+ };
61
+ } | {
62
+ post: {
63
+ summary: string;
64
+ };
65
+ } | {
66
+ get: {
67
+ summary: string;
68
+ };
69
+ } | {
70
+ post: {
71
+ summary: string;
72
+ };
73
+ } | {
74
+ get: {
75
+ summary: string;
76
+ };
77
+ } | {
78
+ delete: {
79
+ summary: string;
80
+ };
81
+ } | {
82
+ get: {
83
+ summary: string;
84
+ security: never[];
85
+ };
86
+ } | {
87
+ get: {
88
+ summary: string;
89
+ security: never[];
90
+ };
91
+ } | {
92
+ get: {
93
+ summary: string;
94
+ security: never[];
95
+ };
96
+ } | {
97
+ post: {
98
+ summary: string;
99
+ };
100
+ get: {
101
+ summary: string;
102
+ };
103
+ } | {
104
+ post: {
105
+ summary: string;
106
+ };
107
+ } | {
108
+ delete: {
109
+ summary: string;
110
+ };
111
+ } | {
112
+ post: {
113
+ summary: string;
114
+ };
115
+ get: {
116
+ summary: string;
117
+ };
118
+ } | {
119
+ delete: {
120
+ summary: string;
121
+ };
122
+ } | {
123
+ post: {
124
+ summary: string;
125
+ };
126
+ get: {
127
+ summary: string;
128
+ };
129
+ } | {
130
+ get: {
131
+ summary: string;
132
+ };
133
+ delete: {
134
+ summary: string;
135
+ };
136
+ } | {
137
+ post: {
138
+ summary: string;
139
+ };
140
+ } | {
141
+ post: {
142
+ summary: string;
143
+ };
144
+ } | {
145
+ get: {
146
+ summary: string;
147
+ };
148
+ } | {
149
+ get: {
150
+ summary: string;
151
+ };
152
+ } | {
153
+ post: {
154
+ summary: string;
155
+ };
156
+ get: {
157
+ summary: string;
158
+ };
159
+ } | {
160
+ get: {
161
+ summary: string;
162
+ };
163
+ delete: {
164
+ summary: string;
165
+ };
166
+ } | {
167
+ post: {
168
+ summary: string;
169
+ };
170
+ get: {
171
+ summary: string;
172
+ };
173
+ } | {
174
+ get: {
175
+ summary: string;
176
+ };
177
+ } | {
178
+ post: {
179
+ summary: string;
180
+ };
181
+ get: {
182
+ summary: string;
183
+ };
184
+ } | {
185
+ post: {
186
+ summary: string;
187
+ };
188
+ get: {
189
+ summary: string;
190
+ };
191
+ } | {
192
+ delete: {
193
+ summary: string;
194
+ };
195
+ };
196
+ };
197
+ openapi: string;
198
+ info: {
199
+ title: string;
200
+ version: string;
201
+ description: string;
202
+ };
203
+ servers: {
204
+ url: string;
205
+ }[];
206
+ security: {
207
+ bearer: never[];
208
+ }[];
209
+ components: {
210
+ securitySchemes: {
211
+ bearer: {
212
+ type: string;
213
+ scheme: string;
214
+ };
215
+ };
216
+ };
217
+ };
5
218
  export declare const openapi: {
6
219
  openapi: string;
7
220
  info: {
@@ -91,6 +304,148 @@ export declare const openapi: {
91
304
  summary: string;
92
305
  };
93
306
  };
307
+ "/v1/hub/config": {
308
+ get: {
309
+ summary: string;
310
+ };
311
+ };
312
+ "/v1/hub/login": {
313
+ post: {
314
+ summary: string;
315
+ };
316
+ };
317
+ "/v1/hub/me": {
318
+ get: {
319
+ summary: string;
320
+ };
321
+ };
322
+ "/v1/hub/keys/{id}": {
323
+ delete: {
324
+ summary: string;
325
+ };
326
+ };
327
+ "/v1/public/rubrics": {
328
+ get: {
329
+ summary: string;
330
+ security: never[];
331
+ };
332
+ };
333
+ "/v1/public/rubrics/{owner}/{slug}": {
334
+ get: {
335
+ summary: string;
336
+ security: never[];
337
+ };
338
+ };
339
+ "/v1/public/publications/{id}": {
340
+ get: {
341
+ summary: string;
342
+ security: never[];
343
+ };
344
+ };
345
+ "/v1/publications": {
346
+ post: {
347
+ summary: string;
348
+ };
349
+ get: {
350
+ summary: string;
351
+ };
352
+ };
353
+ "/v1/publications/preview": {
354
+ post: {
355
+ summary: string;
356
+ };
357
+ };
358
+ "/v1/publications/{id}": {
359
+ delete: {
360
+ summary: string;
361
+ };
362
+ };
363
+ "/v1/projects": {
364
+ post: {
365
+ summary: string;
366
+ };
367
+ get: {
368
+ summary: string;
369
+ };
370
+ };
371
+ "/v1/projects/{project}": {
372
+ delete: {
373
+ summary: string;
374
+ };
375
+ };
376
+ "/v1/projects/{project}/environments": {
377
+ post: {
378
+ summary: string;
379
+ };
380
+ get: {
381
+ summary: string;
382
+ };
383
+ };
384
+ "/v1/projects/{project}/environments/{environment}": {
385
+ get: {
386
+ summary: string;
387
+ };
388
+ delete: {
389
+ summary: string;
390
+ };
391
+ };
392
+ "/v1/projects/{project}/environments/{environment}/promotions": {
393
+ post: {
394
+ summary: string;
395
+ };
396
+ };
397
+ "/v1/projects/{project}/environments/{environment}/rollbacks": {
398
+ post: {
399
+ summary: string;
400
+ };
401
+ };
402
+ "/v1/projects/{project}/history": {
403
+ get: {
404
+ summary: string;
405
+ };
406
+ };
407
+ "/v1/projects/{project}/rubrics": {
408
+ get: {
409
+ summary: string;
410
+ };
411
+ };
412
+ "/v1/projects/{project}/rubrics/{name}/versions": {
413
+ post: {
414
+ summary: string;
415
+ };
416
+ get: {
417
+ summary: string;
418
+ };
419
+ };
420
+ "/v1/projects/{project}/rubrics/{name}/versions/{id}": {
421
+ get: {
422
+ summary: string;
423
+ };
424
+ delete: {
425
+ summary: string;
426
+ };
427
+ };
428
+ "/v1/projects/{project}/reports/runs": {
429
+ post: {
430
+ summary: string;
431
+ };
432
+ get: {
433
+ summary: string;
434
+ };
435
+ };
436
+ "/v1/projects/{project}/reports/runs/{runId}": {
437
+ get: {
438
+ summary: string;
439
+ };
440
+ };
441
+ "/v1/projects/{project}/reports/comparisons": {
442
+ post: {
443
+ summary: string;
444
+ };
445
+ get: {
446
+ summary: string;
447
+ };
448
+ };
94
449
  "/v1/admin/keys": {
95
450
  post: {
96
451
  summary: string;
package/dist/openapi.js CHANGED
@@ -1,7 +1,15 @@
1
- /**
2
- * Describes the public REST operations for API discovery.
3
- * The published paths mirror route registration; runtime validation remains owned by request schemas.
4
- */
1
+ const GROUP_PATHS = {
2
+ evaluations: ["/v1/evaluations", "/v1/tasks", "/v1/batches"],
3
+ rubrics: ["/v1/rubrics"],
4
+ hub: ["/v1/hub", "/v1/public", "/v1/publications"],
5
+ control: ["/v1/projects"],
6
+ };
7
+ /** The document for an app that serves only some route groups: paths of the others are left out. */
8
+ export function openapiFor(groups) {
9
+ const off = Object.keys(GROUP_PATHS).filter((g) => !groups.includes(g)).flatMap((g) => GROUP_PATHS[g]);
10
+ const served = (path) => !off.some((prefix) => path === prefix || path.startsWith(`${prefix}/`));
11
+ return { ...openapi, paths: Object.fromEntries(Object.entries(openapi.paths).filter(([path]) => served(path))) };
12
+ }
5
13
  export const openapi = {
6
14
  openapi: "3.1.0",
7
15
  info: { title: "Verdict Evaluation API", version: "0.1.0", description: "Customizable rubrics, pluggable judges (LLM / human / benchmark), customizable aggregation." },
@@ -20,6 +28,29 @@ export const openapi = {
20
28
  "/v1/evaluations/{id}/aggregate": { post: { summary: "Re-aggregate with a different aggregation config (no re-judging)" } },
21
29
  "/v1/tasks": { get: { summary: "Pending human-rating tasks (`?rater=`)" } },
22
30
  "/v1/batches": { post: { summary: "Evaluate many subjects against one rubric and rank them. Optional Idempotency-Key header (1–255 chars); replay 200, conflict 409, TTL 24h" } },
31
+ "/v1/hub/config": { get: { summary: "Public: the GitHub OAuth client id for sign-in (null when the server publishes under tenant ids), and `signIn` when the server runs CLI sign-in itself (browser approval)" } },
32
+ "/v1/hub/login": { post: { summary: "Public: trade a GitHub token from the device flow for a hub API key bound to that account (201 { apiKey, keyId, handle, tenantId })" } },
33
+ "/v1/hub/me": { get: { summary: "Who this key publishes as" } },
34
+ "/v1/hub/keys/{id}": { delete: { summary: "Revoke one of this account's hub keys (sign out)" } },
35
+ "/v1/public/rubrics": { get: { summary: "Public, no key: search published cards (q, domain, locale, type, owner, limit ≤ 50); one result per owner/slug at its newest live version", security: [] } },
36
+ "/v1/public/rubrics/{owner}/{slug}": { get: { summary: "Public, no key: a card at ?version= (default: newest live) with its version history; 410 when that version was withdrawn", security: [] } },
37
+ "/v1/public/publications/{id}": { get: { summary: "Public, no key: one publication by id; 410 when withdrawn", security: [] } },
38
+ "/v1/publications": { post: { summary: "Publish a rubric version, chosen public cases and run summaries to the hub (one criterion, licence, binary threshold; 400 with issues)" }, get: { summary: "List this tenant's publications, withdrawn included" } },
39
+ "/v1/publications/preview": { post: { summary: "Build the publication without storing it: { ok, issues, warnings, publication } — the exact document publish would store" } },
40
+ "/v1/publications/{id}": { delete: { summary: "Withdraw a publication (it stays readable by id, marked withdrawn, and leaves search)" } },
41
+ "/v1/projects": { post: { summary: "Create a project: { name } (201; 409 already_exists)" }, get: { summary: "List this tenant's projects" } },
42
+ "/v1/projects/{project}": { delete: { summary: "Delete a project and everything in it. Body { confirm: \"<name>\" }" } },
43
+ "/v1/projects/{project}/environments": { post: { summary: "Create an environment: { name } (201; 409 already_exists)" }, get: { summary: "List a project's environments" } },
44
+ "/v1/projects/{project}/environments/{environment}": { get: { summary: "An environment and its pointers: which version of each rubric it runs. `?include=rubrics` adds each rubric document (what services poll); answers carry an ETag, and If-None-Match gets 304 while nothing changed" }, delete: { summary: "Delete an environment and its pointers; its history stays. Body { confirm: \"<name>\" }" } },
45
+ "/v1/projects/{project}/environments/{environment}/promotions": { post: { summary: "Move pointers, all or none: { changes: [{ name, versionId | null, expected | null }], note? } (≤ 20 changes; null versionId removes the pointer; 409 pointer_conflict with the current versions when `expected` is stale)" } },
46
+ "/v1/projects/{project}/environments/{environment}/rollbacks": { post: { summary: "Undo a pointer's latest change: { name, expected, note? } (409 pointer_conflict / nothing_to_roll_back)" } },
47
+ "/v1/projects/{project}/history": { get: { summary: "Pointer changes, newest first (`?environment=&name=&limit=`)" } },
48
+ "/v1/projects/{project}/rubrics": { get: { summary: "Rubric names of a project, with version counts" } },
49
+ "/v1/projects/{project}/rubrics/{name}/versions": { post: { summary: "Upload an immutable rubric version: { id, rubric, parentVersionId?, fork? }. The server freezes the rubric again and refuses another id (201 new, 200 already there, 413 over 1 MB)" }, get: { summary: "List a rubric's versions, newest first, without the rubric documents" } },
50
+ "/v1/projects/{project}/rubrics/{name}/versions/{id}": { get: { summary: "One version with its rubric document" }, delete: { summary: "Delete a version no environment points at (409 in_use otherwise)" } },
51
+ "/v1/projects/{project}/reports/runs": { post: { summary: "Report a run's numbers: { name, run, report, datasetName?, source?, version? }. No case ids, inputs or outputs are read. `version` uploads the run's rubric version when the server lacks it (201 new, 200 already reported, 400 unknown_version)" }, get: { summary: "Run reports, newest run first (`?name=&versionId=&dataset=&limit=`)" } },
52
+ "/v1/projects/{project}/reports/runs/{runId}": { get: { summary: "One run report" } },
53
+ "/v1/projects/{project}/reports/comparisons": { post: { summary: "Report a comparison of two reported runs: { name, comparison, source? } — counts per criterion, no per-case rows (400 unknown_run)" }, get: { summary: "Comparison reports, newest first (`?name=&head=&limit=`)" } },
23
54
  "/v1/admin/keys": { post: { summary: "Create an API key for a tenant (admin)" }, get: { summary: "List a tenant's keys (admin, `?tenant=`)" } },
24
55
  "/v1/admin/keys/{id}": { delete: { summary: "Revoke a key (admin)" } },
25
56
  },
@@ -1 +1 @@
1
- {"version":3,"file":"openapi.js","sourceRoot":"","sources":["../src/openapi.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,CAAC,MAAM,OAAO,GAAG;IACrB,OAAO,EAAE,OAAO;IAChB,IAAI,EAAE,EAAE,KAAK,EAAE,wBAAwB,EAAE,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,6FAA6F,EAAE;IACvK,OAAO,EAAE,CAAC,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC;IACvB,QAAQ,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;IAC1B,UAAU,EAAE,EAAE,eAAe,EAAE,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE,EAAE;IAC/E,KAAK,EAAE;QACL,aAAa,EAAE,EAAE,IAAI,EAAE,EAAE,OAAO,EAAE,mCAAmC,EAAE,EAAE,GAAG,EAAE,EAAE,OAAO,EAAE,cAAc,EAAE,EAAE;QAC3G,sBAAsB,EAAE,EAAE,IAAI,EAAE,EAAE,OAAO,EAAE,sCAAsC,EAAE,EAAE;QACrF,kBAAkB,EAAE,EAAE,GAAG,EAAE,EAAE,OAAO,EAAE,YAAY,EAAE,EAAE,GAAG,EAAE,EAAE,OAAO,EAAE,gBAAgB,EAAE,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,eAAe,EAAE,EAAE;QAChI,8BAA8B,EAAE,EAAE,GAAG,EAAE,EAAE,OAAO,EAAE,yDAAyD,EAAE,EAAE;QAC/G,iBAAiB,EAAE,EAAE,IAAI,EAAE,EAAE,OAAO,EAAE,mIAAmI,EAAE,EAAE,GAAG,EAAE,EAAE,OAAO,EAAE,kBAAkB,EAAE,EAAE;QACnN,sBAAsB,EAAE,EAAE,GAAG,EAAE,EAAE,OAAO,EAAE,iDAAiD,EAAE,EAAE;QAC/F,4BAA4B,EAAE,EAAE,IAAI,EAAE,EAAE,OAAO,EAAE,mEAAmE,EAAE,EAAE;QACxH,6BAA6B,EAAE,EAAE,IAAI,EAAE,EAAE,OAAO,EAAE,8CAA8C,EAAE,EAAE;QACpG,gCAAgC,EAAE,EAAE,IAAI,EAAE,EAAE,OAAO,EAAE,kEAAkE,EAAE,EAAE;QAC3H,WAAW,EAAE,EAAE,GAAG,EAAE,EAAE,OAAO,EAAE,wCAAwC,EAAE,EAAE;QAC3E,aAAa,EAAE,EAAE,IAAI,EAAE,EAAE,OAAO,EAAE,2IAA2I,EAAE,EAAE;QACjL,gBAAgB,EAAE,EAAE,IAAI,EAAE,EAAE,OAAO,EAAE,wCAAwC,EAAE,EAAE,GAAG,EAAE,EAAE,OAAO,EAAE,0CAA0C,EAAE,EAAE;QAC/I,qBAAqB,EAAE,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,sBAAsB,EAAE,EAAE;KACvE;CACF,CAAC"}
1
+ {"version":3,"file":"openapi.js","sourceRoot":"","sources":["../src/openapi.ts"],"names":[],"mappings":"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"}
package/dist/present.d.ts CHANGED
@@ -41,6 +41,7 @@ export declare function present(ev: Evaluation, { evidence, ratings }?: {
41
41
  json?: unknown;
42
42
  source?: string;
43
43
  truncated?: boolean;
44
+ images?: import("@verdict-ai/core").ImageMeta[];
44
45
  stats: {
45
46
  chars: number;
46
47
  words: number;
@@ -93,6 +94,7 @@ export declare function present(ev: Evaluation, { evidence, ratings }?: {
93
94
  error?: string;
94
95
  }>;
95
96
  error?: string;
97
+ inputErrors?: import("@verdict-ai/core").InputError[];
96
98
  usage: {
97
99
  decisionCalls: number;
98
100
  llmCalls: number;
@@ -102,6 +104,7 @@ export declare function present(ev: Evaluation, { evidence, ratings }?: {
102
104
  };
103
105
  metadata?: Record<string, unknown>;
104
106
  webhook?: string;
107
+ batchId?: string;
105
108
  createdAt: string;
106
109
  updatedAt: string;
107
110
  };
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Request limits for the hub's open doors (docs/design/hub.md H6): sign-in, publishing, and public reads. A limiter
3
+ * answers whether one more request under a key is allowed. The in-memory limiter counts per process (per isolate on
4
+ * Workers) and is a floor; on Cloudflare, bind the Workers Rate Limiting API to share counts across isolates.
5
+ */
6
+ import type { Context } from "hono";
7
+ import { HTTPException } from "hono/http-exception";
8
+ export interface RateLimiter {
9
+ limit(key: string): Promise<boolean> | boolean;
10
+ }
11
+ /** `login`: per client address. `publish` (preview included): per account. `read`: public JSON and pages, per client address. */
12
+ export interface HubLimits {
13
+ login?: RateLimiter;
14
+ publish?: RateLimiter;
15
+ read?: RateLimiter;
16
+ }
17
+ export interface Rule {
18
+ limit: number;
19
+ windowMs: number;
20
+ }
21
+ export declare const DEFAULT_HUB_RULES: Record<keyof HubLimits, Rule>;
22
+ /** Fixed-window counter. Old windows are dropped as the map grows, so memory stays bounded by active keys. */
23
+ export declare function memoryLimiter({ limit, windowMs }: Rule, now?: () => number): RateLimiter;
24
+ export declare function defaultHubLimits(now?: () => number): Required<HubLimits>;
25
+ /** Cloudflare's Workers Rate Limiting binding (`[[ratelimits]]` in wrangler.toml). */
26
+ export interface CloudflareRateLimit {
27
+ limit(options: {
28
+ key: string;
29
+ }): Promise<{
30
+ success: boolean;
31
+ }>;
32
+ }
33
+ export declare const cloudflareLimiter: (binding: CloudflareRateLimit) => RateLimiter;
34
+ /**
35
+ * The client a request comes from. Only a header the platform sets is trusted (Cloudflare's `cf-connecting-ip`), or the
36
+ * socket address the Node server passes in; X-Forwarded-For is anyone's to write.
37
+ */
38
+ export type ClientKey = (c: Context) => string;
39
+ export declare const defaultClientKey: ClientKey;
40
+ /** Answered as 429 with Retry-After by the app's error handler. */
41
+ export declare class RateLimitedError extends HTTPException {
42
+ constructor(what: string);
43
+ }
44
+ export declare function enforce(limiter: RateLimiter | undefined, key: string, what: string): Promise<void>;
@@ -0,0 +1,40 @@
1
+ import { HTTPException } from "hono/http-exception";
2
+ export const DEFAULT_HUB_RULES = {
3
+ login: { limit: 10, windowMs: 60_000 },
4
+ publish: { limit: 30, windowMs: 60_000 },
5
+ read: { limit: 300, windowMs: 60_000 },
6
+ };
7
+ /** Fixed-window counter. Old windows are dropped as the map grows, so memory stays bounded by active keys. */
8
+ export function memoryLimiter({ limit, windowMs }, now = Date.now) {
9
+ const windows = new Map();
10
+ return {
11
+ limit(key) {
12
+ const t = now();
13
+ if (windows.size > 10_000)
14
+ for (const [k, w] of windows)
15
+ if (t - w.start >= windowMs)
16
+ windows.delete(k);
17
+ const w = windows.get(key);
18
+ if (!w || t - w.start >= windowMs) {
19
+ windows.set(key, { start: t, count: 1 });
20
+ return true;
21
+ }
22
+ w.count++;
23
+ return w.count <= limit;
24
+ },
25
+ };
26
+ }
27
+ export function defaultHubLimits(now) {
28
+ return { login: memoryLimiter(DEFAULT_HUB_RULES.login, now), publish: memoryLimiter(DEFAULT_HUB_RULES.publish, now), read: memoryLimiter(DEFAULT_HUB_RULES.read, now) };
29
+ }
30
+ export const cloudflareLimiter = (binding) => ({ limit: async (key) => (await binding.limit({ key })).success });
31
+ export const defaultClientKey = (c) => c.req.header("cf-connecting-ip") ?? "anonymous";
32
+ /** Answered as 429 with Retry-After by the app's error handler. */
33
+ export class RateLimitedError extends HTTPException {
34
+ constructor(what) { super(429, { message: `too many ${what} requests; try again in a minute` }); }
35
+ }
36
+ export async function enforce(limiter, key, what) {
37
+ if (limiter && !(await limiter.limit(key)))
38
+ throw new RateLimitedError(what);
39
+ }
40
+ //# sourceMappingURL=rate-limit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rate-limit.js","sourceRoot":"","sources":["../src/rate-limit.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAQpD,MAAM,CAAC,MAAM,iBAAiB,GAAkC;IAC9D,KAAK,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE;IACtC,OAAO,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE;IACxC,IAAI,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE;CACvC,CAAC;AAEF,8GAA8G;AAC9G,MAAM,UAAU,aAAa,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAQ,EAAE,MAAoB,IAAI,CAAC,GAAG;IACnF,MAAM,OAAO,GAAG,IAAI,GAAG,EAA4C,CAAC;IACpE,OAAO;QACL,KAAK,CAAC,GAAG;YACP,MAAM,CAAC,GAAG,GAAG,EAAE,CAAC;YAChB,IAAI,OAAO,CAAC,IAAI,GAAG,MAAM;gBAAE,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,OAAO;oBAAE,IAAI,CAAC,GAAG,CAAC,CAAC,KAAK,IAAI,QAAQ;wBAAE,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;YACxG,MAAM,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YAC3B,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,KAAK,IAAI,QAAQ,EAAE,CAAC;gBAAC,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC;gBAAC,OAAO,IAAI,CAAC;YAAC,CAAC;YAC7F,CAAC,CAAC,KAAK,EAAE,CAAC;YACV,OAAO,CAAC,CAAC,KAAK,IAAI,KAAK,CAAC;QAC1B,CAAC;KACF,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,GAAkB;IACjD,OAAO,EAAE,KAAK,EAAE,aAAa,CAAC,iBAAiB,CAAC,KAAK,EAAE,GAAG,CAAC,EAAE,OAAO,EAAE,aAAa,CAAC,iBAAiB,CAAC,OAAO,EAAE,GAAG,CAAC,EAAE,IAAI,EAAE,aAAa,CAAC,iBAAiB,CAAC,IAAI,EAAE,GAAG,CAAC,EAAE,CAAC;AAC1K,CAAC;AAKD,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,OAA4B,EAAe,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC,MAAM,OAAO,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;AAOnJ,MAAM,CAAC,MAAM,gBAAgB,GAAc,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,kBAAkB,CAAC,IAAI,WAAW,CAAC;AAElG,mEAAmE;AACnE,MAAM,OAAO,gBAAiB,SAAQ,aAAa;IACjD,YAAY,IAAY,IAAI,KAAK,CAAC,GAAG,EAAE,EAAE,OAAO,EAAE,YAAY,IAAI,kCAAkC,EAAE,CAAC,CAAC,CAAC,CAAC;CAC3G;AAED,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,OAAgC,EAAE,GAAW,EAAE,IAAY;IACvF,IAAI,OAAO,IAAI,CAAC,CAAC,MAAM,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAAE,MAAM,IAAI,gBAAgB,CAAC,IAAI,CAAC,CAAC;AAC/E,CAAC"}
@@ -1,4 +1,4 @@
1
1
  import { Hono } from "hono";
2
2
  import type { AppOptions, Env } from "../app.js";
3
3
  /** Registers admin operations; handler failures propagate to the transport error boundary. */
4
- export declare function registerAdmin(app: Hono<Env>, { keys, adminKey }: AppOptions): void;
4
+ export declare function registerAdmin(app: Hono<Env>, { engine, keys, adminKey, now }: AppOptions): void;
@@ -2,34 +2,80 @@
2
2
  * Defines admin request handling at the REST boundary.
3
3
  * Tenant context flows to every engine/store operation; validation failures use the shared HTTP error mapper.
4
4
  */
5
- import { NotFoundError, ValidationError } from "@verdict-ai/core";
5
+ import { hasPublications, NotFoundError, ValidationError } from "@verdict-ai/core";
6
6
  import { HTTPException } from "hono/http-exception";
7
7
  import { z } from "zod";
8
8
  /** Registers admin operations; handler failures propagate to the transport error boundary. */
9
- export function registerAdmin(app, { keys, adminKey }) {
10
- /* ---------- admin: API keys ---------- */
9
+ export function registerAdmin(app, { engine, keys, adminKey, now = () => Date.now() }) {
11
10
  app.use("/v1/admin/*", async (c, next) => {
12
- if (!adminKey || !keys)
13
- throw new HTTPException(404, { message: "admin API disabled (set VERDICT_ADMIN_KEY and a database-backed key store)" });
11
+ if (!adminKey)
12
+ throw new HTTPException(404, { message: "admin API disabled (set VERDICT_ADMIN_KEY)" });
14
13
  const header = c.req.header("authorization")?.replace(/^Bearer\s+/i, "");
15
14
  if (header !== adminKey)
16
15
  throw new HTTPException(401, { message: "invalid admin key" });
17
16
  await next();
18
17
  });
18
+ registerAdminKeys(app, keys);
19
+ registerTakedowns(app, engine, now);
20
+ }
21
+ /* ---------- admin: API keys ---------- */
22
+ function registerAdminKeys(app, keys) {
23
+ const manager = () => {
24
+ if (!keys)
25
+ throw new HTTPException(404, { message: "key management needs a database-backed key store" });
26
+ return keys;
27
+ };
19
28
  app.post("/v1/admin/keys", async (c) => {
20
29
  const body = z.object({ tenantId: z.string().min(1), name: z.string().min(1) }).parse(await c.req.json());
21
- return c.json(await keys.createKey(body.tenantId, body.name), 201);
30
+ return c.json(await manager().createKey(body.tenantId, body.name), 201);
22
31
  });
23
32
  app.get("/v1/admin/keys", async (c) => {
24
33
  const tenantId = c.req.query("tenant");
25
34
  if (!tenantId)
26
35
  throw new ValidationError("query param `tenant` is required");
27
- return c.json({ data: await keys.listKeys(tenantId) });
36
+ return c.json({ data: await manager().listKeys(tenantId) });
28
37
  });
29
38
  app.delete("/v1/admin/keys/:id", async (c) => {
30
- if (!(await keys.revokeKey(c.req.param("id"))))
39
+ if (!(await manager().revokeKey(c.req.param("id"))))
31
40
  throw new NotFoundError(`key ${c.req.param("id")} not found`);
32
41
  return c.body(null, 204);
33
42
  });
34
43
  }
44
+ /*
45
+ * ---------- admin: hub takedowns (docs/design/hub.md H6) ----------
46
+ * Operators can take any publication down, with a reason that is shown publicly, and put back only what they took down:
47
+ * an author's own withdrawal is the author's to keep.
48
+ */
49
+ function registerTakedowns(app, engine, now) {
50
+ const store = () => {
51
+ if (!hasPublications(engine.store))
52
+ throw new HTTPException(404, { message: "this server's store cannot keep publications" });
53
+ return engine.store;
54
+ };
55
+ const find = async (id) => {
56
+ const p = await store().getPublication(id);
57
+ if (!p)
58
+ throw new NotFoundError(`publication ${id} not found`);
59
+ return p;
60
+ };
61
+ app.get("/v1/admin/publications", async (c) => {
62
+ const q = z.object({ q: z.string().optional(), owner: z.string().optional(), slug: z.string().optional(), limit: z.coerce.number().int().min(1).max(500).default(100) }).parse(c.req.query());
63
+ return c.json({ data: await store().listPublications({ ...q, includeWithdrawn: true }) });
64
+ });
65
+ app.post("/v1/admin/publications/:id/takedown", async (c) => {
66
+ const { reason } = z.object({ reason: z.string().trim().min(1).max(500) }).parse(await c.req.json());
67
+ const p = await find(c.req.param("id")), at = new Date(now()).toISOString();
68
+ const next = { ...p, withdrawnAt: p.withdrawnAt ?? at, takedown: { reason, at } };
69
+ await store().putPublication(next);
70
+ return c.json({ publication: next });
71
+ });
72
+ app.post("/v1/admin/publications/:id/restore", async (c) => {
73
+ const p = await find(c.req.param("id"));
74
+ if (!p.takedown)
75
+ throw new HTTPException(409, { message: `${p.ref} at ${p.version.id} was not taken down${p.withdrawnAt ? "; its author withdrew it" : ""}` });
76
+ const { takedown: _takedown, withdrawnAt: _withdrawnAt, ...restored } = p;
77
+ await store().putPublication(restored);
78
+ return c.json({ publication: restored });
79
+ });
80
+ }
35
81
  //# sourceMappingURL=admin.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"admin.js","sourceRoot":"","sources":["../../src/routes/admin.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAElE,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,8FAA8F;AAC9F,MAAM,UAAU,aAAa,CAAC,GAAc,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAc;IAC1E,2CAA2C;IAC3C,GAAG,CAAC,GAAG,CAAC,aAAa,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE;QACvC,IAAI,CAAC,QAAQ,IAAI,CAAC,IAAI;YAAE,MAAM,IAAI,aAAa,CAAC,GAAG,EAAE,EAAE,OAAO,EAAE,4EAA4E,EAAE,CAAC,CAAC;QAChJ,MAAM,MAAM,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,eAAe,CAAC,EAAE,OAAO,CAAC,aAAa,EAAE,EAAE,CAAC,CAAC;QACzE,IAAI,MAAM,KAAK,QAAQ;YAAE,MAAM,IAAI,aAAa,CAAC,GAAG,EAAE,EAAE,OAAO,EAAE,mBAAmB,EAAE,CAAC,CAAC;QACxF,MAAM,IAAI,EAAE,CAAC;IACf,CAAC,CAAC,CAAC;IACH,GAAG,CAAC,IAAI,CAAC,gBAAgB,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;QACrC,MAAM,IAAI,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC;QAC1G,OAAO,CAAC,CAAC,IAAI,CAAC,MAAM,IAAK,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC;IACtE,CAAC,CAAC,CAAC;IACH,GAAG,CAAC,GAAG,CAAC,gBAAgB,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;QACpC,MAAM,QAAQ,GAAG,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QACvC,IAAI,CAAC,QAAQ;YAAE,MAAM,IAAI,eAAe,CAAC,kCAAkC,CAAC,CAAC;QAC7E,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,IAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;IAC1D,CAAC,CAAC,CAAC;IACH,GAAG,CAAC,MAAM,CAAC,oBAAoB,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;QAC3C,IAAI,CAAC,CAAC,MAAM,IAAK,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;YAAE,MAAM,IAAI,aAAa,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QAC/G,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;IAC3B,CAAC,CAAC,CAAC;AAEL,CAAC"}
1
+ {"version":3,"file":"admin.js","sourceRoot":"","sources":["../../src/routes/admin.ts"],"names":[],"mappings":"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"}