@cloudpdf/contract 3.0.0-next.1 → 3.0.0-next.3
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/README.md +1 -1
- package/dist/index.d.ts +5137 -2019
- package/dist/index.js +362 -14
- package/dist/index.js.map +1 -1
- package/dist/openapi.js +365 -13
- package/dist/openapi.js.map +1 -1
- package/openapi.json +2365 -700
- package/package.json +4 -4
package/dist/openapi.js
CHANGED
|
@@ -19,6 +19,14 @@ import {
|
|
|
19
19
|
var sha256Hex = /^[0-9a-f]{64}$/i;
|
|
20
20
|
var docIdPattern = /^[A-Za-z0-9_-]+$/;
|
|
21
21
|
var tenantIdPattern = /^[A-Za-z0-9_-]+$/;
|
|
22
|
+
var originPattern = /^https?:\/\/(\*\.)?[a-zA-Z0-9]([a-zA-Z0-9-]*[a-zA-Z0-9])?(\.[a-zA-Z0-9]([a-zA-Z0-9-]*[a-zA-Z0-9])?)*(:\d{1,5})?$/;
|
|
23
|
+
var originPatternArray = z.array(
|
|
24
|
+
z.string().max(262).regex(
|
|
25
|
+
originPattern,
|
|
26
|
+
"must be a web origin like https://example.com (optionally one leading *. wildcard label, optional port, no path)"
|
|
27
|
+
)
|
|
28
|
+
).min(1).max(32);
|
|
29
|
+
var shareTokenPattern = /^shr_[A-Za-z0-9_-]{24}$/;
|
|
22
30
|
var adminWirePaths = {
|
|
23
31
|
tenants: "/v1/tenants",
|
|
24
32
|
tenant: (tenantId) => `/v1/tenants/${encodeURIComponent(tenantId)}`,
|
|
@@ -26,16 +34,28 @@ var adminWirePaths = {
|
|
|
26
34
|
documentsInit: (tenantId) => `/v1/tenants/${encodeURIComponent(tenantId)}/documents/init`,
|
|
27
35
|
document: (tenantId, docId) => `/v1/tenants/${encodeURIComponent(tenantId)}/documents/${encodeURIComponent(docId)}`,
|
|
28
36
|
documentCommit: (tenantId, docId) => `/v1/tenants/${encodeURIComponent(tenantId)}/documents/${encodeURIComponent(docId)}/commit`,
|
|
29
|
-
|
|
37
|
+
documentUploadProxy: (tenantId, docId) => `/v1/tenants/${encodeURIComponent(tenantId)}/documents/${encodeURIComponent(docId)}/upload-proxy`,
|
|
30
38
|
documentDownload: (tenantId, docId) => `/v1/tenants/${encodeURIComponent(tenantId)}/documents/${encodeURIComponent(docId)}/download`,
|
|
31
39
|
/** The warmed dashboard-tile artifact. Returns 404 while `pending`/`locked`. */
|
|
32
40
|
documentThumbnail: (tenantId, docId) => `/v1/tenants/${encodeURIComponent(tenantId)}/documents/${encodeURIComponent(docId)}/thumbnail`,
|
|
33
41
|
tokenIssue: (tenantId) => `/v1/tenants/${encodeURIComponent(tenantId)}/tokens`,
|
|
34
42
|
tokenRevoke: (tenantId, jti) => `/v1/tenants/${encodeURIComponent(tenantId)}/tokens/${encodeURIComponent(jti)}/revoke`,
|
|
43
|
+
shares: (tenantId) => `/v1/tenants/${encodeURIComponent(tenantId)}/shares`,
|
|
44
|
+
share: (tenantId, shareId) => `/v1/tenants/${encodeURIComponent(tenantId)}/shares/${encodeURIComponent(shareId)}`,
|
|
45
|
+
tenantUsage: (tenantId) => `/v1/tenants/${encodeURIComponent(tenantId)}/usage`,
|
|
46
|
+
tenantSuspend: (tenantId) => `/v1/tenants/${encodeURIComponent(tenantId)}/suspend`,
|
|
47
|
+
tenantResume: (tenantId) => `/v1/tenants/${encodeURIComponent(tenantId)}/resume`,
|
|
48
|
+
/**
|
|
49
|
+
* The public share-session exchange. Deliberately outside any tenant
|
|
50
|
+
* subtree: the caller holds only a share token and does not know the
|
|
51
|
+
* tenant — the grant row resolves it server-side.
|
|
52
|
+
*/
|
|
53
|
+
shareSessions: "/v1/share-sessions",
|
|
35
54
|
/** Deployment-global singletons: API-token only, no tenant context. */
|
|
36
55
|
deploymentLicenseStatus: "/v1/deployment/license/status"
|
|
37
56
|
};
|
|
38
57
|
var DedupModeSchema = z.enum(["always-create", "reuse-existing"]);
|
|
58
|
+
var UploadPreferenceSchema = z.enum(["auto", "presigned", "proxy"]);
|
|
39
59
|
var DocumentStateSchema = z.enum(["pending", "ready", "failed", "deleting"]);
|
|
40
60
|
var AdminDocumentRecordSchema = z.object({
|
|
41
61
|
id: z.string(),
|
|
@@ -60,7 +80,8 @@ var AdminDocumentInitRequestSchema = z.object({
|
|
|
60
80
|
idempotencyKey: z.string().optional(),
|
|
61
81
|
dedupMode: DedupModeSchema.optional(),
|
|
62
82
|
docId: z.string().regex(docIdPattern).optional(),
|
|
63
|
-
uploadTtlSec: z.number().finite().min(60).max(3600).optional()
|
|
83
|
+
uploadTtlSec: z.number().finite().min(60).max(3600).optional(),
|
|
84
|
+
uploadPreference: UploadPreferenceSchema.optional()
|
|
64
85
|
});
|
|
65
86
|
var AdminPresignedUploadSchema = z.object({
|
|
66
87
|
url: z.string(),
|
|
@@ -75,7 +96,7 @@ var AdminInitUploadSchema = z.discriminatedUnion("kind", [
|
|
|
75
96
|
key: z.string()
|
|
76
97
|
}),
|
|
77
98
|
z.object({
|
|
78
|
-
kind: z.literal("
|
|
99
|
+
kind: z.literal("proxy"),
|
|
79
100
|
url: z.string(),
|
|
80
101
|
key: z.string()
|
|
81
102
|
})
|
|
@@ -121,7 +142,7 @@ var AdminDocumentListResponseSchema = z.object({
|
|
|
121
142
|
*/
|
|
122
143
|
nextCursor: z.string().nullable().optional()
|
|
123
144
|
});
|
|
124
|
-
var
|
|
145
|
+
var AdminUploadProxyResponseSchema = z.object({
|
|
125
146
|
sha256: z.string().regex(sha256Hex)
|
|
126
147
|
});
|
|
127
148
|
var AdminErrorPayloadSchema = z.object({
|
|
@@ -168,6 +189,13 @@ var AdminTenantRecordSchema = z.object({
|
|
|
168
189
|
name: z.string(),
|
|
169
190
|
/** True when the namespace materialized on first use rather than via explicit create. */
|
|
170
191
|
autoProvisioned: z.boolean(),
|
|
192
|
+
/**
|
|
193
|
+
* `suspended` tenants fail closed: every tenant JWT, doc JWT, and
|
|
194
|
+
* share exchange is refused until resume. The API token is exempt —
|
|
195
|
+
* the operator must be able to inspect, resume, or delete a
|
|
196
|
+
* suspended tenant. Optional because older servers omit it.
|
|
197
|
+
*/
|
|
198
|
+
status: z.enum(["active", "suspended"]).optional(),
|
|
171
199
|
createdAt: z.number()
|
|
172
200
|
});
|
|
173
201
|
var AdminTenantCreateRequestSchema = z.object({
|
|
@@ -197,7 +225,8 @@ var adminTenantScopes = [
|
|
|
197
225
|
"docs.read",
|
|
198
226
|
"docs.delete",
|
|
199
227
|
"tokens.issue-doc",
|
|
200
|
-
"tokens.revoke"
|
|
228
|
+
"tokens.revoke",
|
|
229
|
+
"shares.manage"
|
|
201
230
|
];
|
|
202
231
|
var AdminTokenIssueDocRequestSchema = z.object({
|
|
203
232
|
kind: z.literal("doc"),
|
|
@@ -215,6 +244,14 @@ var AdminTokenIssueDocRequestSchema = z.object({
|
|
|
215
244
|
displayName: z.string().max(256).optional(),
|
|
216
245
|
groupId: z.string().max(256).optional(),
|
|
217
246
|
groups: z.array(z.string().max(256)).max(64).optional(),
|
|
247
|
+
/**
|
|
248
|
+
* Origin lock: web origins (scheme + host, optional port; one leading
|
|
249
|
+
* `*.` wildcard label allowed) the minted token may be presented
|
|
250
|
+
* from. Enforced on every engine request that carries a browser
|
|
251
|
+
* `Origin` header — hotlink prevention, not DRM: non-browser callers
|
|
252
|
+
* are governed by the token itself.
|
|
253
|
+
*/
|
|
254
|
+
origins: originPatternArray.optional(),
|
|
218
255
|
/** Token lifetime in seconds. */
|
|
219
256
|
expiresIn: z.number().int().min(60).max(60 * 60 * 24 * 90)
|
|
220
257
|
});
|
|
@@ -235,9 +272,110 @@ var AdminTokenIssueResponseSchema = z.object({
|
|
|
235
272
|
/** Unix seconds. */
|
|
236
273
|
expiresAt: z.number()
|
|
237
274
|
});
|
|
275
|
+
var ShareGrantRecordSchema = z.object({
|
|
276
|
+
/** Grant id; doubles as the public share token (`shr_…`). */
|
|
277
|
+
id: z.string(),
|
|
278
|
+
tenantId: z.string(),
|
|
279
|
+
docId: z.string(),
|
|
280
|
+
layerName: z.string(),
|
|
281
|
+
/** Doc capabilities the exchanged session carries. */
|
|
282
|
+
scope: z.array(z.string()),
|
|
283
|
+
/** Origin allowlist; null means any origin. */
|
|
284
|
+
origins: z.array(z.string()).nullable(),
|
|
285
|
+
/** True when a passphrase is required at exchange. The passphrase itself is never returned. */
|
|
286
|
+
passwordProtected: z.boolean(),
|
|
287
|
+
/** Lifetime of each exchanged session token, in seconds. */
|
|
288
|
+
sessionTtlSeconds: z.number(),
|
|
289
|
+
/** Paused grants refuse exchange (404) but keep their configuration. */
|
|
290
|
+
disabled: z.boolean(),
|
|
291
|
+
/** Unix epoch ms after which exchange returns 410; null = no expiry. */
|
|
292
|
+
expiresAt: z.number().nullable(),
|
|
293
|
+
/** Total successful exchanges — a dashboard convenience, not the usage meter. */
|
|
294
|
+
exchangeCount: z.number(),
|
|
295
|
+
lastExchangedAt: z.number().nullable(),
|
|
296
|
+
createdBy: z.string(),
|
|
297
|
+
createdAt: z.number(),
|
|
298
|
+
updatedAt: z.number()
|
|
299
|
+
});
|
|
300
|
+
var ShareGrantCreateRequestSchema = z.object({
|
|
301
|
+
docId: z.string().regex(docIdPattern),
|
|
302
|
+
layerName: z.string().min(1).max(256).optional(),
|
|
303
|
+
/**
|
|
304
|
+
* Doc capability scopes the exchanged session will carry. Validated
|
|
305
|
+
* server-side against the engine's scope vocabulary, same as
|
|
306
|
+
* `tokens.issue`.
|
|
307
|
+
*/
|
|
308
|
+
scope: z.array(z.string().min(1).max(128)).min(1).max(64),
|
|
309
|
+
/** Origin allowlist; omit to allow any origin. */
|
|
310
|
+
origins: originPatternArray.optional(),
|
|
311
|
+
/** Optional passphrase gate, checked at exchange. Stored as a hash; never returned. */
|
|
312
|
+
password: z.string().min(1).max(1024).optional(),
|
|
313
|
+
/** Lifetime of exchanged session tokens. Default 600. */
|
|
314
|
+
sessionTtlSeconds: z.number().int().min(60).max(60 * 60).optional(),
|
|
315
|
+
/** Unix epoch ms after which the grant stops exchanging; omit for no expiry. */
|
|
316
|
+
expiresAt: z.number().int().positive().optional()
|
|
317
|
+
});
|
|
318
|
+
var ShareGrantUpdateRequestSchema = z.object({
|
|
319
|
+
scope: z.array(z.string().min(1).max(128)).min(1).max(64).optional(),
|
|
320
|
+
origins: originPatternArray.nullable().optional(),
|
|
321
|
+
password: z.string().min(1).max(1024).nullable().optional(),
|
|
322
|
+
sessionTtlSeconds: z.number().int().min(60).max(60 * 60).optional(),
|
|
323
|
+
disabled: z.boolean().optional(),
|
|
324
|
+
expiresAt: z.number().int().positive().nullable().optional()
|
|
325
|
+
});
|
|
326
|
+
var ShareGrantResponseSchema = z.object({
|
|
327
|
+
share: ShareGrantRecordSchema
|
|
328
|
+
});
|
|
329
|
+
var ShareGrantListQuerySchema = z.object({
|
|
330
|
+
limit: z.coerce.number().int().min(1).max(ADMIN_DOCUMENT_LIST_MAX_LIMIT).default(ADMIN_DOCUMENT_LIST_DEFAULT_LIMIT),
|
|
331
|
+
cursor: z.string().min(1).optional(),
|
|
332
|
+
/** Filter to one document's grants. */
|
|
333
|
+
docId: z.string().regex(docIdPattern).optional()
|
|
334
|
+
});
|
|
335
|
+
var ShareGrantListResponseSchema = z.object({
|
|
336
|
+
shares: z.array(ShareGrantRecordSchema),
|
|
337
|
+
/** Opaque cursor for the next page; `null` on the last page. */
|
|
338
|
+
nextCursor: z.string().nullable().optional()
|
|
339
|
+
});
|
|
340
|
+
var AdminTenantShareParamsSchema = z.object({
|
|
341
|
+
tenantId: z.string().regex(tenantIdPattern),
|
|
342
|
+
shareId: z.string().regex(shareTokenPattern)
|
|
343
|
+
});
|
|
344
|
+
var ShareExchangeRequestSchema = z.object({
|
|
345
|
+
shareToken: z.string().regex(shareTokenPattern),
|
|
346
|
+
/** Required when the grant is passphrase-protected (422 otherwise). */
|
|
347
|
+
password: z.string().min(1).max(1024).optional()
|
|
348
|
+
});
|
|
349
|
+
var ShareSessionResponseSchema = z.object({
|
|
350
|
+
/** A doc-scoped session JWT carrying the grant's capabilities and origin lock. */
|
|
351
|
+
token: z.string(),
|
|
352
|
+
docId: z.string(),
|
|
353
|
+
layerName: z.string(),
|
|
354
|
+
/** Unix seconds when the session token expires; exchange again for a fresh one. */
|
|
355
|
+
expiresAt: z.number()
|
|
356
|
+
});
|
|
357
|
+
var TenantUsageQuerySchema = z.object({
|
|
358
|
+
/** UTC month to report, `YYYY-MM`. Defaults to the current month. */
|
|
359
|
+
period: z.string().regex(/^\d{4}-(0[1-9]|1[0-2])$/).optional()
|
|
360
|
+
});
|
|
361
|
+
var TenantUsageResponseSchema = z.object({
|
|
362
|
+
tenantId: z.string(),
|
|
363
|
+
periodStart: z.string(),
|
|
364
|
+
periodEnd: z.string(),
|
|
365
|
+
metrics: z.object({
|
|
366
|
+
"pdf.views": z.number(),
|
|
367
|
+
"pdf.uploads": z.number(),
|
|
368
|
+
"storage.bytes": z.number()
|
|
369
|
+
})
|
|
370
|
+
});
|
|
371
|
+
var TenantSuspendRequestSchema = z.object({
|
|
372
|
+
/** Optional operator reason, written to the security-events trail. */
|
|
373
|
+
reason: z.string().max(1024).optional()
|
|
374
|
+
});
|
|
238
375
|
var adminOperations = {
|
|
239
376
|
"tenants.create": {
|
|
240
377
|
operationId: "tenants.create",
|
|
378
|
+
title: "Create tenant",
|
|
241
379
|
summary: "Create a tenant, or confirm it already exists \u2014 ensure-style, idempotent.",
|
|
242
380
|
method: "POST",
|
|
243
381
|
path: adminWirePaths.tenants,
|
|
@@ -251,6 +389,7 @@ var adminOperations = {
|
|
|
251
389
|
},
|
|
252
390
|
"tenants.list": {
|
|
253
391
|
operationId: "tenants.list",
|
|
392
|
+
title: "List tenants",
|
|
254
393
|
summary: "List tenants, newest first, cursor-paginated.",
|
|
255
394
|
method: "GET",
|
|
256
395
|
path: adminWirePaths.tenants,
|
|
@@ -264,6 +403,7 @@ var adminOperations = {
|
|
|
264
403
|
},
|
|
265
404
|
"tenants.get": {
|
|
266
405
|
operationId: "tenants.get",
|
|
406
|
+
title: "Get tenant",
|
|
267
407
|
summary: "Fetch one tenant record.",
|
|
268
408
|
method: "GET",
|
|
269
409
|
path: "/v1/tenants/:tenantId",
|
|
@@ -277,6 +417,7 @@ var adminOperations = {
|
|
|
277
417
|
},
|
|
278
418
|
"tenants.delete": {
|
|
279
419
|
operationId: "tenants.delete",
|
|
420
|
+
title: "Delete tenant",
|
|
280
421
|
summary: "Delete a tenant and everything under it.",
|
|
281
422
|
method: "DELETE",
|
|
282
423
|
path: "/v1/tenants/:tenantId",
|
|
@@ -291,6 +432,7 @@ var adminOperations = {
|
|
|
291
432
|
},
|
|
292
433
|
"documents.init": {
|
|
293
434
|
operationId: "documents.init",
|
|
435
|
+
title: "Initialize upload",
|
|
294
436
|
summary: "Begin an upload: create (or resume/dedupe) a pending document and issue upload access.",
|
|
295
437
|
method: "POST",
|
|
296
438
|
path: "/v1/tenants/:tenantId/documents/init",
|
|
@@ -305,6 +447,7 @@ var adminOperations = {
|
|
|
305
447
|
},
|
|
306
448
|
"documents.commit": {
|
|
307
449
|
operationId: "documents.commit",
|
|
450
|
+
title: "Commit upload",
|
|
308
451
|
summary: "Finish an upload: verify the SHA-256 and promote the document to ready.",
|
|
309
452
|
method: "POST",
|
|
310
453
|
path: "/v1/tenants/:tenantId/documents/:id/commit",
|
|
@@ -318,24 +461,28 @@ var adminOperations = {
|
|
|
318
461
|
404: { contentType: "application/json", schema: AdminErrorPayloadSchema }
|
|
319
462
|
}
|
|
320
463
|
},
|
|
321
|
-
"documents.
|
|
322
|
-
operationId: "documents.
|
|
323
|
-
|
|
464
|
+
"documents.uploadProxy": {
|
|
465
|
+
operationId: "documents.uploadProxy",
|
|
466
|
+
title: "Upload document through the origin",
|
|
467
|
+
summary: "Upload a bounded PDF through the API when the initialized transfer kind is proxy.",
|
|
324
468
|
method: "POST",
|
|
325
|
-
path: "/v1/tenants/:tenantId/documents/:id/upload-
|
|
469
|
+
path: "/v1/tenants/:tenantId/documents/:id/upload-proxy",
|
|
326
470
|
credentials: ["api-token", "tenant-jwt"],
|
|
327
471
|
scope: ["docs.create"],
|
|
328
472
|
params: AdminTenantDocParamsSchema,
|
|
329
473
|
body: {
|
|
330
|
-
contentType:
|
|
474
|
+
contentType: "multipart/form-data"
|
|
331
475
|
},
|
|
332
476
|
responses: {
|
|
333
|
-
200: { contentType: "application/json", schema:
|
|
334
|
-
400: { contentType: "application/json", schema: AdminErrorPayloadSchema }
|
|
335
|
-
|
|
477
|
+
200: { contentType: "application/json", schema: AdminUploadProxyResponseSchema },
|
|
478
|
+
400: { contentType: "application/json", schema: AdminErrorPayloadSchema },
|
|
479
|
+
409: { contentType: "application/json", schema: AdminErrorPayloadSchema }
|
|
480
|
+
},
|
|
481
|
+
notes: "This bounded origin-mediated fallback must only be used after documents.init returns upload.kind=proxy. Auto mode prefers a presigned object-store PUT whenever available."
|
|
336
482
|
},
|
|
337
483
|
"documents.list": {
|
|
338
484
|
operationId: "documents.list",
|
|
485
|
+
title: "List documents",
|
|
339
486
|
summary: "List documents in the tenant, newest first, cursor-paginated.",
|
|
340
487
|
method: "GET",
|
|
341
488
|
path: "/v1/tenants/:tenantId/documents",
|
|
@@ -350,6 +497,7 @@ var adminOperations = {
|
|
|
350
497
|
},
|
|
351
498
|
"documents.get": {
|
|
352
499
|
operationId: "documents.get",
|
|
500
|
+
title: "Get document",
|
|
353
501
|
summary: "Fetch one document record.",
|
|
354
502
|
method: "GET",
|
|
355
503
|
path: "/v1/tenants/:tenantId/documents/:id",
|
|
@@ -364,6 +512,7 @@ var adminOperations = {
|
|
|
364
512
|
},
|
|
365
513
|
"documents.download": {
|
|
366
514
|
operationId: "documents.download",
|
|
515
|
+
title: "Download document",
|
|
367
516
|
summary: "Download the stored base PDF bytes.",
|
|
368
517
|
method: "GET",
|
|
369
518
|
path: "/v1/tenants/:tenantId/documents/:id/download",
|
|
@@ -378,6 +527,7 @@ var adminOperations = {
|
|
|
378
527
|
},
|
|
379
528
|
"documents.delete": {
|
|
380
529
|
operationId: "documents.delete",
|
|
530
|
+
title: "Delete document",
|
|
381
531
|
summary: "Delete a document and its stored artifacts.",
|
|
382
532
|
method: "DELETE",
|
|
383
533
|
path: "/v1/tenants/:tenantId/documents/:id",
|
|
@@ -392,6 +542,7 @@ var adminOperations = {
|
|
|
392
542
|
},
|
|
393
543
|
"documents.thumbnail": {
|
|
394
544
|
operationId: "documents.thumbnail",
|
|
545
|
+
title: "Get thumbnail",
|
|
395
546
|
summary: "Fetch the warmed dashboard-tile render for a document.",
|
|
396
547
|
method: "GET",
|
|
397
548
|
path: "/v1/tenants/:tenantId/documents/:id/thumbnail",
|
|
@@ -405,6 +556,7 @@ var adminOperations = {
|
|
|
405
556
|
},
|
|
406
557
|
"deployment.licenseStatus": {
|
|
407
558
|
operationId: "deployment.licenseStatus",
|
|
559
|
+
title: "License status",
|
|
408
560
|
summary: "License decision plus usage-reporting and meter snapshots for this deployment.",
|
|
409
561
|
method: "GET",
|
|
410
562
|
path: adminWirePaths.deploymentLicenseStatus,
|
|
@@ -416,6 +568,7 @@ var adminOperations = {
|
|
|
416
568
|
},
|
|
417
569
|
"tokens.issue": {
|
|
418
570
|
operationId: "tokens.issue",
|
|
571
|
+
title: "Issue token",
|
|
419
572
|
summary: "Mint a delegated JWT: a doc token, or (API token only) a tenant token.",
|
|
420
573
|
method: "POST",
|
|
421
574
|
path: "/v1/tenants/:tenantId/tokens",
|
|
@@ -433,6 +586,7 @@ var adminOperations = {
|
|
|
433
586
|
},
|
|
434
587
|
"tokens.revoke": {
|
|
435
588
|
operationId: "tokens.revoke",
|
|
589
|
+
title: "Revoke token",
|
|
436
590
|
summary: "Revoke a token by jti; live sessions drop on their next heartbeat.",
|
|
437
591
|
method: "POST",
|
|
438
592
|
path: "/v1/tenants/:tenantId/tokens/:jti/revoke",
|
|
@@ -449,6 +603,153 @@ var adminOperations = {
|
|
|
449
603
|
400: { contentType: "application/json", schema: AdminErrorPayloadSchema }
|
|
450
604
|
},
|
|
451
605
|
notes: "Mounted only when the deployment enables token revocation."
|
|
606
|
+
},
|
|
607
|
+
"tenants.usage": {
|
|
608
|
+
operationId: "tenants.usage",
|
|
609
|
+
title: "Tenant usage",
|
|
610
|
+
summary: "Per-tenant usage facts (views, uploads, stored bytes) for one UTC month.",
|
|
611
|
+
method: "GET",
|
|
612
|
+
path: "/v1/tenants/:tenantId/usage",
|
|
613
|
+
credentials: ["api-token", "tenant-jwt"],
|
|
614
|
+
scope: ["docs.read"],
|
|
615
|
+
params: AdminTenantParamsSchema,
|
|
616
|
+
query: TenantUsageQuerySchema,
|
|
617
|
+
responses: {
|
|
618
|
+
200: { contentType: "application/json", schema: TenantUsageResponseSchema },
|
|
619
|
+
400: { contentType: "application/json", schema: AdminErrorPayloadSchema },
|
|
620
|
+
404: { contentType: "application/json", schema: AdminErrorPayloadSchema }
|
|
621
|
+
},
|
|
622
|
+
notes: "Facts only \u2014 no limits or billing state. Views count share exchanges plus authorized /v1/access grants, deduplicated across the two."
|
|
623
|
+
},
|
|
624
|
+
"tenants.suspend": {
|
|
625
|
+
operationId: "tenants.suspend",
|
|
626
|
+
title: "Suspend tenant",
|
|
627
|
+
summary: "Fail the tenant closed: refuse every tenant JWT, doc JWT, and share exchange.",
|
|
628
|
+
method: "POST",
|
|
629
|
+
path: "/v1/tenants/:tenantId/suspend",
|
|
630
|
+
credentials: ["api-token"],
|
|
631
|
+
scope: [],
|
|
632
|
+
params: AdminTenantParamsSchema,
|
|
633
|
+
body: {
|
|
634
|
+
contentType: "application/json",
|
|
635
|
+
schema: TenantSuspendRequestSchema,
|
|
636
|
+
required: false
|
|
637
|
+
},
|
|
638
|
+
responses: {
|
|
639
|
+
204: {},
|
|
640
|
+
404: { contentType: "application/json", schema: AdminErrorPayloadSchema }
|
|
641
|
+
},
|
|
642
|
+
notes: "Instantly reversible with resume. The API token is exempt, so a suspended tenant can still be inspected, exported, resumed, or deleted."
|
|
643
|
+
},
|
|
644
|
+
"tenants.resume": {
|
|
645
|
+
operationId: "tenants.resume",
|
|
646
|
+
title: "Resume tenant",
|
|
647
|
+
summary: "Lift a suspension; credentials for the tenant verify again.",
|
|
648
|
+
method: "POST",
|
|
649
|
+
path: "/v1/tenants/:tenantId/resume",
|
|
650
|
+
credentials: ["api-token"],
|
|
651
|
+
scope: [],
|
|
652
|
+
params: AdminTenantParamsSchema,
|
|
653
|
+
responses: {
|
|
654
|
+
204: {},
|
|
655
|
+
404: { contentType: "application/json", schema: AdminErrorPayloadSchema }
|
|
656
|
+
}
|
|
657
|
+
},
|
|
658
|
+
"shares.create": {
|
|
659
|
+
operationId: "shares.create",
|
|
660
|
+
title: "Create share",
|
|
661
|
+
summary: "Create a standing share grant for one document \u2014 the no-backend embed credential.",
|
|
662
|
+
method: "POST",
|
|
663
|
+
path: "/v1/tenants/:tenantId/shares",
|
|
664
|
+
credentials: ["api-token", "tenant-jwt"],
|
|
665
|
+
scope: ["shares.manage"],
|
|
666
|
+
params: AdminTenantParamsSchema,
|
|
667
|
+
body: { contentType: "application/json", schema: ShareGrantCreateRequestSchema },
|
|
668
|
+
responses: {
|
|
669
|
+
200: { contentType: "application/json", schema: ShareGrantResponseSchema },
|
|
670
|
+
400: { contentType: "application/json", schema: AdminErrorPayloadSchema },
|
|
671
|
+
403: { contentType: "application/json", schema: AdminErrorPayloadSchema },
|
|
672
|
+
404: { contentType: "application/json", schema: AdminErrorPayloadSchema }
|
|
673
|
+
},
|
|
674
|
+
notes: "The returned share id IS the public share token. Mounted only when the deployment can sign (HS256 mode) \u2014 exchange mints session JWTs, so grants exist only where minting does."
|
|
675
|
+
},
|
|
676
|
+
"shares.list": {
|
|
677
|
+
operationId: "shares.list",
|
|
678
|
+
title: "List shares",
|
|
679
|
+
summary: "List share grants in the tenant, newest first, cursor-paginated.",
|
|
680
|
+
method: "GET",
|
|
681
|
+
path: "/v1/tenants/:tenantId/shares",
|
|
682
|
+
credentials: ["api-token", "tenant-jwt"],
|
|
683
|
+
scope: ["shares.manage"],
|
|
684
|
+
params: AdminTenantParamsSchema,
|
|
685
|
+
query: ShareGrantListQuerySchema,
|
|
686
|
+
responses: {
|
|
687
|
+
200: { contentType: "application/json", schema: ShareGrantListResponseSchema },
|
|
688
|
+
400: { contentType: "application/json", schema: AdminErrorPayloadSchema }
|
|
689
|
+
}
|
|
690
|
+
},
|
|
691
|
+
"shares.get": {
|
|
692
|
+
operationId: "shares.get",
|
|
693
|
+
title: "Get share",
|
|
694
|
+
summary: "Fetch one share grant.",
|
|
695
|
+
method: "GET",
|
|
696
|
+
path: "/v1/tenants/:tenantId/shares/:shareId",
|
|
697
|
+
credentials: ["api-token", "tenant-jwt"],
|
|
698
|
+
scope: ["shares.manage"],
|
|
699
|
+
params: AdminTenantShareParamsSchema,
|
|
700
|
+
responses: {
|
|
701
|
+
200: { contentType: "application/json", schema: ShareGrantResponseSchema },
|
|
702
|
+
404: { contentType: "application/json", schema: AdminErrorPayloadSchema }
|
|
703
|
+
}
|
|
704
|
+
},
|
|
705
|
+
"shares.update": {
|
|
706
|
+
operationId: "shares.update",
|
|
707
|
+
title: "Update share",
|
|
708
|
+
summary: "Edit a grant in place \u2014 every embedded copy of the token follows the row.",
|
|
709
|
+
method: "PATCH",
|
|
710
|
+
path: "/v1/tenants/:tenantId/shares/:shareId",
|
|
711
|
+
credentials: ["api-token", "tenant-jwt"],
|
|
712
|
+
scope: ["shares.manage"],
|
|
713
|
+
params: AdminTenantShareParamsSchema,
|
|
714
|
+
body: { contentType: "application/json", schema: ShareGrantUpdateRequestSchema },
|
|
715
|
+
responses: {
|
|
716
|
+
200: { contentType: "application/json", schema: ShareGrantResponseSchema },
|
|
717
|
+
400: { contentType: "application/json", schema: AdminErrorPayloadSchema },
|
|
718
|
+
404: { contentType: "application/json", schema: AdminErrorPayloadSchema }
|
|
719
|
+
}
|
|
720
|
+
},
|
|
721
|
+
"shares.delete": {
|
|
722
|
+
operationId: "shares.delete",
|
|
723
|
+
title: "Revoke share",
|
|
724
|
+
summary: "Delete a grant; exchange stops immediately, live sessions lapse at their exp.",
|
|
725
|
+
method: "DELETE",
|
|
726
|
+
path: "/v1/tenants/:tenantId/shares/:shareId",
|
|
727
|
+
credentials: ["api-token", "tenant-jwt"],
|
|
728
|
+
scope: ["shares.manage"],
|
|
729
|
+
params: AdminTenantShareParamsSchema,
|
|
730
|
+
responses: {
|
|
731
|
+
204: {},
|
|
732
|
+
404: { contentType: "application/json", schema: AdminErrorPayloadSchema }
|
|
733
|
+
}
|
|
734
|
+
},
|
|
735
|
+
"shares.exchange": {
|
|
736
|
+
operationId: "shares.exchange",
|
|
737
|
+
title: "Exchange share token",
|
|
738
|
+
summary: "Trade a public share token for a short-lived document session JWT.",
|
|
739
|
+
method: "POST",
|
|
740
|
+
path: adminWirePaths.shareSessions,
|
|
741
|
+
credentials: [],
|
|
742
|
+
scope: [],
|
|
743
|
+
body: { contentType: "application/json", schema: ShareExchangeRequestSchema },
|
|
744
|
+
responses: {
|
|
745
|
+
200: { contentType: "application/json", schema: ShareSessionResponseSchema },
|
|
746
|
+
400: { contentType: "application/json", schema: AdminErrorPayloadSchema },
|
|
747
|
+
403: { contentType: "application/json", schema: AdminErrorPayloadSchema },
|
|
748
|
+
404: { contentType: "application/json", schema: AdminErrorPayloadSchema },
|
|
749
|
+
410: { contentType: "application/json", schema: AdminErrorPayloadSchema },
|
|
750
|
+
422: { contentType: "application/json", schema: AdminErrorPayloadSchema }
|
|
751
|
+
},
|
|
752
|
+
notes: "Unauthenticated, but requires a browser Origin header, checked against the grant allowlist. Unknown, revoked, and disabled tokens are indistinguishable (404). Passphrase-protected grants return 422 SharePasswordRequired until `password` is supplied. Mounted only when the deployment can sign (HS256 mode)."
|
|
452
753
|
}
|
|
453
754
|
};
|
|
454
755
|
var DocIdParamsSchema = z.object({
|
|
@@ -477,6 +778,7 @@ var MutationResponseSchema = z.object({ meta: MutationMetaSchema }).passthrough(
|
|
|
477
778
|
var docOperations = {
|
|
478
779
|
"doc.head": {
|
|
479
780
|
operationId: "doc.head",
|
|
781
|
+
title: "Open document",
|
|
480
782
|
summary: "Open a document and return its head (versions, page count, security).",
|
|
481
783
|
method: "GET",
|
|
482
784
|
path: wireTemplates.docHead,
|
|
@@ -492,6 +794,7 @@ var docOperations = {
|
|
|
492
794
|
},
|
|
493
795
|
"doc.manifest": {
|
|
494
796
|
operationId: "doc.manifest",
|
|
797
|
+
title: "Get manifest",
|
|
495
798
|
summary: "Full layer manifest at the layer's current version.",
|
|
496
799
|
method: "GET",
|
|
497
800
|
path: wireTemplates.layerManifest,
|
|
@@ -507,6 +810,7 @@ var docOperations = {
|
|
|
507
810
|
},
|
|
508
811
|
"doc.metadata.get": {
|
|
509
812
|
operationId: "doc.metadata.get",
|
|
813
|
+
title: "Get metadata",
|
|
510
814
|
summary: "Document metadata (PDF info dictionary view) for a layer.",
|
|
511
815
|
method: "GET",
|
|
512
816
|
path: wireTemplates.layerMetadata,
|
|
@@ -522,6 +826,7 @@ var docOperations = {
|
|
|
522
826
|
},
|
|
523
827
|
"doc.render": {
|
|
524
828
|
operationId: "doc.render",
|
|
829
|
+
title: "Render page",
|
|
525
830
|
summary: "Render one page as an image at the current layer version.",
|
|
526
831
|
method: "GET",
|
|
527
832
|
path: wireTemplates.layerRenderPage,
|
|
@@ -538,6 +843,7 @@ var docOperations = {
|
|
|
538
843
|
},
|
|
539
844
|
"doc.text": {
|
|
540
845
|
operationId: "doc.text",
|
|
846
|
+
title: "Extract page text",
|
|
541
847
|
summary: "Extracted text content for one page.",
|
|
542
848
|
method: "GET",
|
|
543
849
|
path: wireTemplates.layerTextPage,
|
|
@@ -553,6 +859,7 @@ var docOperations = {
|
|
|
553
859
|
},
|
|
554
860
|
"doc.annotations.list": {
|
|
555
861
|
operationId: "doc.annotations.list",
|
|
862
|
+
title: "List annotations",
|
|
556
863
|
summary: "One page's annotations at the current layer version.",
|
|
557
864
|
method: "GET",
|
|
558
865
|
path: wireTemplates.layerAnnotationItems,
|
|
@@ -568,6 +875,7 @@ var docOperations = {
|
|
|
568
875
|
},
|
|
569
876
|
"doc.annotations.create": {
|
|
570
877
|
operationId: "doc.annotations.create",
|
|
878
|
+
title: "Create annotation",
|
|
571
879
|
summary: "Create an annotation on a page.",
|
|
572
880
|
method: "POST",
|
|
573
881
|
path: wireTemplates.layerAnnotationItems,
|
|
@@ -586,6 +894,7 @@ var docOperations = {
|
|
|
586
894
|
},
|
|
587
895
|
"doc.annotations.update": {
|
|
588
896
|
operationId: "doc.annotations.update",
|
|
897
|
+
title: "Update annotation",
|
|
589
898
|
summary: "Update one annotation by key.",
|
|
590
899
|
method: "PATCH",
|
|
591
900
|
path: wireTemplates.layerAnnotationItem,
|
|
@@ -603,6 +912,7 @@ var docOperations = {
|
|
|
603
912
|
},
|
|
604
913
|
"doc.annotations.delete": {
|
|
605
914
|
operationId: "doc.annotations.delete",
|
|
915
|
+
title: "Delete annotation",
|
|
606
916
|
summary: "Delete one annotation by key.",
|
|
607
917
|
method: "DELETE",
|
|
608
918
|
path: wireTemplates.layerAnnotationItem,
|
|
@@ -618,6 +928,7 @@ var docOperations = {
|
|
|
618
928
|
},
|
|
619
929
|
"doc.forms.get": {
|
|
620
930
|
operationId: "doc.forms.get",
|
|
931
|
+
title: "Get form snapshot",
|
|
621
932
|
summary: "Reconciled form snapshot: fields, widgets, values.",
|
|
622
933
|
method: "GET",
|
|
623
934
|
path: wireTemplates.layerForm,
|
|
@@ -633,6 +944,7 @@ var docOperations = {
|
|
|
633
944
|
},
|
|
634
945
|
"doc.forms.setValue": {
|
|
635
946
|
operationId: "doc.forms.setValue",
|
|
947
|
+
title: "Set form value",
|
|
636
948
|
summary: "Set one form field's value.",
|
|
637
949
|
method: "POST",
|
|
638
950
|
path: wireTemplates.layerFormFieldValue,
|
|
@@ -650,6 +962,7 @@ var docOperations = {
|
|
|
650
962
|
},
|
|
651
963
|
"doc.forms.reset": {
|
|
652
964
|
operationId: "doc.forms.reset",
|
|
965
|
+
title: "Reset form field",
|
|
653
966
|
summary: "Reset one form field to its default value.",
|
|
654
967
|
method: "POST",
|
|
655
968
|
path: wireTemplates.layerFormFieldReset,
|
|
@@ -665,6 +978,7 @@ var docOperations = {
|
|
|
665
978
|
},
|
|
666
979
|
"doc.forms.exportData": {
|
|
667
980
|
operationId: "doc.forms.exportData",
|
|
981
|
+
title: "Export form data",
|
|
668
982
|
summary: "Export form data as FDF or XFDF.",
|
|
669
983
|
method: "GET",
|
|
670
984
|
path: wireTemplates.layerFormData,
|
|
@@ -681,6 +995,7 @@ var docOperations = {
|
|
|
681
995
|
},
|
|
682
996
|
"doc.forms.importData": {
|
|
683
997
|
operationId: "doc.forms.importData",
|
|
998
|
+
title: "Import form data",
|
|
684
999
|
summary: "Import form data (FDF/XFDF), filling matching fields.",
|
|
685
1000
|
method: "POST",
|
|
686
1001
|
path: wireTemplates.layerFormData,
|
|
@@ -698,6 +1013,7 @@ var docOperations = {
|
|
|
698
1013
|
},
|
|
699
1014
|
"doc.pages.move": {
|
|
700
1015
|
operationId: "doc.pages.move",
|
|
1016
|
+
title: "Move pages",
|
|
701
1017
|
summary: "Reorder pages.",
|
|
702
1018
|
method: "POST",
|
|
703
1019
|
path: wireTemplates.layerPagesMove,
|
|
@@ -715,6 +1031,7 @@ var docOperations = {
|
|
|
715
1031
|
},
|
|
716
1032
|
"doc.pages.rotate": {
|
|
717
1033
|
operationId: "doc.pages.rotate",
|
|
1034
|
+
title: "Rotate pages",
|
|
718
1035
|
summary: "Set absolute rotation on pages.",
|
|
719
1036
|
method: "POST",
|
|
720
1037
|
path: wireTemplates.layerPagesRotate,
|
|
@@ -732,6 +1049,7 @@ var docOperations = {
|
|
|
732
1049
|
},
|
|
733
1050
|
"doc.pages.delete": {
|
|
734
1051
|
operationId: "doc.pages.delete",
|
|
1052
|
+
title: "Delete pages",
|
|
735
1053
|
summary: "Delete pages.",
|
|
736
1054
|
method: "POST",
|
|
737
1055
|
path: wireTemplates.layerPagesDelete,
|
|
@@ -749,6 +1067,7 @@ var docOperations = {
|
|
|
749
1067
|
},
|
|
750
1068
|
"doc.pages.flatten": {
|
|
751
1069
|
operationId: "doc.pages.flatten",
|
|
1070
|
+
title: "Flatten pages",
|
|
752
1071
|
summary: "Flatten annotations and form fields into page content.",
|
|
753
1072
|
method: "POST",
|
|
754
1073
|
path: wireTemplates.layerPagesFlatten,
|
|
@@ -766,6 +1085,7 @@ var docOperations = {
|
|
|
766
1085
|
},
|
|
767
1086
|
"doc.redactions.apply": {
|
|
768
1087
|
operationId: "doc.redactions.apply",
|
|
1088
|
+
title: "Apply redactions",
|
|
769
1089
|
summary: "Apply pending redactions, permanently removing content.",
|
|
770
1090
|
method: "POST",
|
|
771
1091
|
path: wireTemplates.layerRedactionsApply,
|
|
@@ -783,6 +1103,7 @@ var docOperations = {
|
|
|
783
1103
|
},
|
|
784
1104
|
"doc.download": {
|
|
785
1105
|
operationId: "doc.download",
|
|
1106
|
+
title: "Download PDF",
|
|
786
1107
|
summary: "Download the layer's current PDF (base plus layer edits).",
|
|
787
1108
|
method: "GET",
|
|
788
1109
|
path: wireTemplates.layerDownload,
|
|
@@ -798,6 +1119,19 @@ var docOperations = {
|
|
|
798
1119
|
}
|
|
799
1120
|
};
|
|
800
1121
|
var allOperations = { ...adminOperations, ...docOperations };
|
|
1122
|
+
var docsGroups = {
|
|
1123
|
+
deployment: { title: "Deployment" },
|
|
1124
|
+
tenants: { title: "Tenants" },
|
|
1125
|
+
documents: { title: "Tenant documents" },
|
|
1126
|
+
tokens: { title: "Tokens" },
|
|
1127
|
+
shares: { title: "Shares" },
|
|
1128
|
+
doc: { title: "Document operations", slug: "document-operations" },
|
|
1129
|
+
"doc.annotations": { title: "Annotations" },
|
|
1130
|
+
"doc.forms": { title: "Forms" },
|
|
1131
|
+
"doc.metadata": { title: "Metadata" },
|
|
1132
|
+
"doc.pages": { title: "Pages" },
|
|
1133
|
+
"doc.redactions": { title: "Redactions" }
|
|
1134
|
+
};
|
|
801
1135
|
|
|
802
1136
|
// src/openapi.ts
|
|
803
1137
|
var STATUS_TEXT = {
|
|
@@ -808,6 +1142,7 @@ var STATUS_TEXT = {
|
|
|
808
1142
|
403: "Forbidden",
|
|
809
1143
|
404: "Not found",
|
|
810
1144
|
409: "Conflict",
|
|
1145
|
+
410: "Gone",
|
|
811
1146
|
422: "Unprocessable"
|
|
812
1147
|
};
|
|
813
1148
|
var SECURITY_SCHEME = {
|
|
@@ -823,6 +1158,7 @@ function buildAdminOpenApiDocument(opts) {
|
|
|
823
1158
|
registerSchema(schemas, "AdminErrorPayload", AdminErrorPayloadSchema);
|
|
824
1159
|
registerSchema(schemas, "EngineErrorPayload", EngineErrorPayloadSchema2);
|
|
825
1160
|
for (const op of Object.values(allOperations)) {
|
|
1161
|
+
assertDocsGroupsCover(op);
|
|
826
1162
|
const openApiPath = toOpenApiPath(op.path);
|
|
827
1163
|
const method = op.method.toLowerCase();
|
|
828
1164
|
const entry = paths[openApiPath] ??= {};
|
|
@@ -837,23 +1173,29 @@ function buildAdminOpenApiDocument(opts) {
|
|
|
837
1173
|
license: { name: "Apache-2.0", identifier: "Apache-2.0" }
|
|
838
1174
|
},
|
|
839
1175
|
paths: sortKeys(paths),
|
|
1176
|
+
// Docs navigation manifest: section titles and URL slugs for the API
|
|
1177
|
+
// reference, in sidebar order (see `docsGroups` in the registry).
|
|
1178
|
+
"x-docs-groups": docsGroups,
|
|
840
1179
|
components: {
|
|
841
1180
|
securitySchemes: {
|
|
842
1181
|
apiToken: {
|
|
843
1182
|
type: "http",
|
|
844
1183
|
scheme: "bearer",
|
|
1184
|
+
"x-docs-title": "API token",
|
|
845
1185
|
description: "The deployment's static root credential (CLOUDPDF_API_AUTH_TOKENS), valid on every surface."
|
|
846
1186
|
},
|
|
847
1187
|
tenantToken: {
|
|
848
1188
|
type: "http",
|
|
849
1189
|
scheme: "bearer",
|
|
850
1190
|
bearerFormat: "JWT",
|
|
1191
|
+
"x-docs-title": "Tenant token",
|
|
851
1192
|
description: "Delegated tenant JWT, valid only under its own /v1/tenants/{tenantId}/ subtree \u2014 the path tenant must equal the token's tenant_id. Doc-scoped viewer tokens are rejected on every admin route."
|
|
852
1193
|
},
|
|
853
1194
|
docToken: {
|
|
854
1195
|
type: "http",
|
|
855
1196
|
scheme: "bearer",
|
|
856
1197
|
bearerFormat: "JWT",
|
|
1198
|
+
"x-docs-title": "Document token",
|
|
857
1199
|
description: "Doc-scoped JWT, valid only on the /v1/docs/{docId} subtree it names, gated by the capability scopes it carries (each operation's x-required-capability)."
|
|
858
1200
|
}
|
|
859
1201
|
},
|
|
@@ -861,6 +1203,15 @@ function buildAdminOpenApiDocument(opts) {
|
|
|
861
1203
|
}
|
|
862
1204
|
};
|
|
863
1205
|
}
|
|
1206
|
+
function assertDocsGroupsCover(op) {
|
|
1207
|
+
const { groups } = sdkOperationName(op.operationId);
|
|
1208
|
+
for (let depth = 1; depth <= groups.length; depth += 1) {
|
|
1209
|
+
const key = groups.slice(0, depth).join(".");
|
|
1210
|
+
if (!(key in docsGroups)) {
|
|
1211
|
+
throw new Error(`Operation ${op.operationId} has no docsGroups entry for "${key}"`);
|
|
1212
|
+
}
|
|
1213
|
+
}
|
|
1214
|
+
}
|
|
864
1215
|
function operationObject(op, schemas) {
|
|
865
1216
|
const parameters = [...pathParameters(op), ...queryParameters(op), ...headerParameters(op)];
|
|
866
1217
|
const sdkName = sdkOperationName(op.operationId);
|
|
@@ -868,6 +1219,7 @@ function operationObject(op, schemas) {
|
|
|
868
1219
|
operationId: op.operationId,
|
|
869
1220
|
"x-fern-sdk-group-name": sdkName.groups,
|
|
870
1221
|
"x-fern-sdk-method-name": sdkName.method,
|
|
1222
|
+
"x-docs-title": op.title,
|
|
871
1223
|
summary: op.summary,
|
|
872
1224
|
...op.notes ? { description: op.notes } : {},
|
|
873
1225
|
security: op.credentials.map((credential) => ({ [SECURITY_SCHEME[credential]]: [] })),
|