@cloudpdf/contract 3.0.0-next.1 → 3.0.0-next.11
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 +6998 -2549
- package/dist/index.js +542 -17
- package/dist/index.js.map +1 -1
- package/dist/openapi.d.ts +5 -1
- package/dist/openapi.js +637 -20
- package/dist/openapi.js.map +1 -1
- package/openapi.json +9377 -2843
- package/package.json +4 -4
package/dist/openapi.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
// src/openapi.ts
|
|
2
|
-
import {
|
|
2
|
+
import { EngineErrorPayloadSchema as EngineErrorPayloadSchema2, PdfActionWireComponents } from "@embedpdf/engine-core/wire";
|
|
3
3
|
import { z as z2 } from "zod";
|
|
4
|
-
import {
|
|
4
|
+
import { ignoreOverride, zodToJsonSchema } from "zod-to-json-schema";
|
|
5
5
|
|
|
6
6
|
// src/index.ts
|
|
7
|
-
import { z } from "zod";
|
|
8
7
|
import {
|
|
9
8
|
AnnotationListPageSnapshotSchema,
|
|
9
|
+
AnnotationListSnapshotAllPagesSchema,
|
|
10
10
|
DocumentHeadSchema,
|
|
11
11
|
DocumentManifestSchema,
|
|
12
12
|
DocumentMetadataSchema,
|
|
@@ -16,26 +16,50 @@ import {
|
|
|
16
16
|
PageTextSnapshotSchema,
|
|
17
17
|
wireTemplates
|
|
18
18
|
} from "@embedpdf/engine-core/wire";
|
|
19
|
+
import { z } from "zod";
|
|
19
20
|
var sha256Hex = /^[0-9a-f]{64}$/i;
|
|
20
21
|
var docIdPattern = /^[A-Za-z0-9_-]+$/;
|
|
21
22
|
var tenantIdPattern = /^[A-Za-z0-9_-]+$/;
|
|
23
|
+
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})?$/;
|
|
24
|
+
var originPatternArray = z.array(
|
|
25
|
+
z.string().max(262).regex(
|
|
26
|
+
originPattern,
|
|
27
|
+
"must be a web origin like https://example.com (optionally one leading *. wildcard label, optional port, no path)"
|
|
28
|
+
)
|
|
29
|
+
).min(1).max(32);
|
|
30
|
+
var shareTokenPattern = /^shr_[A-Za-z0-9_-]{24}$/;
|
|
22
31
|
var adminWirePaths = {
|
|
23
32
|
tenants: "/v1/tenants",
|
|
24
33
|
tenant: (tenantId) => `/v1/tenants/${encodeURIComponent(tenantId)}`,
|
|
25
34
|
documents: (tenantId) => `/v1/tenants/${encodeURIComponent(tenantId)}/documents`,
|
|
26
35
|
documentsInit: (tenantId) => `/v1/tenants/${encodeURIComponent(tenantId)}/documents/init`,
|
|
36
|
+
documentsImport: (tenantId) => `/v1/tenants/${encodeURIComponent(tenantId)}/documents/import`,
|
|
27
37
|
document: (tenantId, docId) => `/v1/tenants/${encodeURIComponent(tenantId)}/documents/${encodeURIComponent(docId)}`,
|
|
28
38
|
documentCommit: (tenantId, docId) => `/v1/tenants/${encodeURIComponent(tenantId)}/documents/${encodeURIComponent(docId)}/commit`,
|
|
29
|
-
|
|
39
|
+
documentUploadProxy: (tenantId, docId) => `/v1/tenants/${encodeURIComponent(tenantId)}/documents/${encodeURIComponent(docId)}/upload-proxy`,
|
|
30
40
|
documentDownload: (tenantId, docId) => `/v1/tenants/${encodeURIComponent(tenantId)}/documents/${encodeURIComponent(docId)}/download`,
|
|
31
41
|
/** The warmed dashboard-tile artifact. Returns 404 while `pending`/`locked`. */
|
|
32
42
|
documentThumbnail: (tenantId, docId) => `/v1/tenants/${encodeURIComponent(tenantId)}/documents/${encodeURIComponent(docId)}/thumbnail`,
|
|
33
43
|
tokenIssue: (tenantId) => `/v1/tenants/${encodeURIComponent(tenantId)}/tokens`,
|
|
34
44
|
tokenRevoke: (tenantId, jti) => `/v1/tenants/${encodeURIComponent(tenantId)}/tokens/${encodeURIComponent(jti)}/revoke`,
|
|
45
|
+
shares: (tenantId) => `/v1/tenants/${encodeURIComponent(tenantId)}/shares`,
|
|
46
|
+
share: (tenantId, shareId) => `/v1/tenants/${encodeURIComponent(tenantId)}/shares/${encodeURIComponent(shareId)}`,
|
|
47
|
+
tenantUsage: (tenantId) => `/v1/tenants/${encodeURIComponent(tenantId)}/usage`,
|
|
48
|
+
tenantSuspend: (tenantId) => `/v1/tenants/${encodeURIComponent(tenantId)}/suspend`,
|
|
49
|
+
tenantResume: (tenantId) => `/v1/tenants/${encodeURIComponent(tenantId)}/resume`,
|
|
50
|
+
/**
|
|
51
|
+
* The public share-session exchange. Deliberately outside any tenant
|
|
52
|
+
* subtree: the caller holds only a share token and does not know the
|
|
53
|
+
* tenant — the grant row resolves it server-side.
|
|
54
|
+
*/
|
|
55
|
+
shareSessions: "/v1/share-sessions",
|
|
35
56
|
/** Deployment-global singletons: API-token only, no tenant context. */
|
|
36
57
|
deploymentLicenseStatus: "/v1/deployment/license/status"
|
|
37
58
|
};
|
|
38
|
-
var DedupModeSchema = z.enum(["always-create", "reuse-existing"])
|
|
59
|
+
var DedupModeSchema = z.enum(["always-create", "reuse-existing"]).describe(
|
|
60
|
+
"always-create (default) creates a new document every time. reuse-existing returns a document that already holds the same content instead of storing it twice."
|
|
61
|
+
);
|
|
62
|
+
var UploadPreferenceSchema = z.enum(["auto", "presigned", "proxy"]);
|
|
39
63
|
var DocumentStateSchema = z.enum(["pending", "ready", "failed", "deleting"]);
|
|
40
64
|
var AdminDocumentRecordSchema = z.object({
|
|
41
65
|
id: z.string(),
|
|
@@ -60,7 +84,8 @@ var AdminDocumentInitRequestSchema = z.object({
|
|
|
60
84
|
idempotencyKey: z.string().optional(),
|
|
61
85
|
dedupMode: DedupModeSchema.optional(),
|
|
62
86
|
docId: z.string().regex(docIdPattern).optional(),
|
|
63
|
-
uploadTtlSec: z.number().finite().min(60).max(3600).optional()
|
|
87
|
+
uploadTtlSec: z.number().finite().min(60).max(3600).optional(),
|
|
88
|
+
uploadPreference: UploadPreferenceSchema.optional()
|
|
64
89
|
});
|
|
65
90
|
var AdminPresignedUploadSchema = z.object({
|
|
66
91
|
url: z.string(),
|
|
@@ -75,7 +100,7 @@ var AdminInitUploadSchema = z.discriminatedUnion("kind", [
|
|
|
75
100
|
key: z.string()
|
|
76
101
|
}),
|
|
77
102
|
z.object({
|
|
78
|
-
kind: z.literal("
|
|
103
|
+
kind: z.literal("proxy"),
|
|
79
104
|
url: z.string(),
|
|
80
105
|
key: z.string()
|
|
81
106
|
})
|
|
@@ -102,6 +127,79 @@ var AdminDocumentCommitRequestSchema = z.object({
|
|
|
102
127
|
var AdminDocumentCommitResponseSchema = z.object({
|
|
103
128
|
document: AdminDocumentRecordSchema
|
|
104
129
|
});
|
|
130
|
+
var utf8ByteLength = (s) => new TextEncoder().encode(s).length;
|
|
131
|
+
var AdminImportSourceSchema = z.discriminatedUnion("kind", [
|
|
132
|
+
z.object({
|
|
133
|
+
kind: z.literal("url"),
|
|
134
|
+
url: z.string().url().max(8192).describe(
|
|
135
|
+
"The URL to fetch. Must be allowed by the deployment import policy (scheme, network range, size) and must declare a length."
|
|
136
|
+
)
|
|
137
|
+
}).describe(
|
|
138
|
+
"The caller supplies the authority: a presigned S3/GCS/Azure/R2/MinIO GET, or any HTTPS endpoint the deployment import policy allows. The URL is a capability \u2014 treat it as a secret. CloudPDF never echoes its query string back in errors, logs, or stored failure reasons."
|
|
139
|
+
),
|
|
140
|
+
z.object({
|
|
141
|
+
kind: z.literal("connection"),
|
|
142
|
+
connectionId: z.string().min(1).max(128).describe("The operator-registered storage connection to read from."),
|
|
143
|
+
key: z.string().min(1).refine((k) => !k.includes("\0"), "key must not contain NUL").refine((k) => utf8ByteLength(k) <= 1024, "key must be at most 1024 UTF-8 bytes").describe(
|
|
144
|
+
"The object key to read, inside the connection's configured scope. At most 1024 UTF-8 bytes."
|
|
145
|
+
),
|
|
146
|
+
revision: z.string().min(1).max(1024).optional().describe(
|
|
147
|
+
"Pins a specific version of the object. Provider-interpreted (S3 VersionId, GCS generation, Azure version id); providers without versioning reject it."
|
|
148
|
+
)
|
|
149
|
+
}).describe(
|
|
150
|
+
"The operator pre-registered the authority: the request names a connection and a key inside it. Which provider backs the connection (S3, GCS, Azure Blob, filesystem, ...) is deployment configuration, never wire surface."
|
|
151
|
+
)
|
|
152
|
+
]).describe(
|
|
153
|
+
"Where CloudPDF pulls the bytes from. The two shapes differ in WHO supplies the authority to read, not in which storage vendor holds the file."
|
|
154
|
+
);
|
|
155
|
+
var AdminDocumentImportRequestSchema = z.object({
|
|
156
|
+
source: AdminImportSourceSchema,
|
|
157
|
+
/**
|
|
158
|
+
* Optional integrity pins, enforced when present: `sizeBytes`
|
|
159
|
+
* against the source's declared Content-Length before the transfer,
|
|
160
|
+
* `sha256` against the server-observed digest after it. When absent
|
|
161
|
+
* the server-observed values become authoritative.
|
|
162
|
+
* `dedupMode=reuse-existing` REQUIRES `sha256` — without a declared
|
|
163
|
+
* hash the server cannot know what content to reuse.
|
|
164
|
+
*/
|
|
165
|
+
expected: z.object({
|
|
166
|
+
sizeBytes: z.number().int().min(1).optional().describe("Checked against the source's declared Content-Length before the transfer."),
|
|
167
|
+
sha256: z.string().regex(sha256Hex).optional().describe(
|
|
168
|
+
"Checked against the server-observed digest after the transfer. Required when dedupMode is reuse-existing."
|
|
169
|
+
)
|
|
170
|
+
}).optional().describe(
|
|
171
|
+
"Integrity pins, enforced when present. When absent, the server-observed values become authoritative."
|
|
172
|
+
),
|
|
173
|
+
metadata: z.record(z.string(), z.unknown()).optional(),
|
|
174
|
+
idempotencyKey: z.string().optional().describe(
|
|
175
|
+
"Retrying with the same key resumes the same document rather than importing a second copy \u2014 including after a 502."
|
|
176
|
+
),
|
|
177
|
+
dedupMode: DedupModeSchema.optional(),
|
|
178
|
+
docId: z.string().regex(docIdPattern).optional(),
|
|
179
|
+
/**
|
|
180
|
+
* `sync` (default) holds the response open for the whole transfer.
|
|
181
|
+
* `async` accepts the request (202, document `pending`), transfers
|
|
182
|
+
* in the background, and the caller polls the document. Async
|
|
183
|
+
* requires a `connection` source (URLs are secrets and expire, so
|
|
184
|
+
* they cannot sit in a durable job); filesystem connections
|
|
185
|
+
* additionally require `expected.sha256`, since they have no
|
|
186
|
+
* revisions to pin retries to.
|
|
187
|
+
*/
|
|
188
|
+
mode: z.enum(["sync", "async"]).optional().describe(
|
|
189
|
+
"sync (default) holds the response open for the whole transfer. async answers 202 with the document pending and transfers in the background; it requires a connection source, and filesystem connections additionally require expected.sha256."
|
|
190
|
+
)
|
|
191
|
+
});
|
|
192
|
+
var AdminDocumentImportResponseSchema = z.object({
|
|
193
|
+
/**
|
|
194
|
+
* `imported` — bytes were pulled, verified, and committed (sync).
|
|
195
|
+
* `deduped` — an existing document satisfied the request without a
|
|
196
|
+
* transfer (content dedup or idempotent replay).
|
|
197
|
+
* `accepted` — async: the job is queued (HTTP 202); poll the
|
|
198
|
+
* document until `ready` or `failed`.
|
|
199
|
+
*/
|
|
200
|
+
tag: z.enum(["imported", "deduped", "accepted"]),
|
|
201
|
+
document: AdminDocumentRecordSchema
|
|
202
|
+
});
|
|
105
203
|
var AdminDocumentResponseSchema = z.object({
|
|
106
204
|
document: AdminDocumentRecordSchema
|
|
107
205
|
});
|
|
@@ -121,7 +219,7 @@ var AdminDocumentListResponseSchema = z.object({
|
|
|
121
219
|
*/
|
|
122
220
|
nextCursor: z.string().nullable().optional()
|
|
123
221
|
});
|
|
124
|
-
var
|
|
222
|
+
var AdminUploadProxyResponseSchema = z.object({
|
|
125
223
|
sha256: z.string().regex(sha256Hex)
|
|
126
224
|
});
|
|
127
225
|
var AdminErrorPayloadSchema = z.object({
|
|
@@ -168,6 +266,13 @@ var AdminTenantRecordSchema = z.object({
|
|
|
168
266
|
name: z.string(),
|
|
169
267
|
/** True when the namespace materialized on first use rather than via explicit create. */
|
|
170
268
|
autoProvisioned: z.boolean(),
|
|
269
|
+
/**
|
|
270
|
+
* `suspended` tenants fail closed: every tenant JWT, doc JWT, and
|
|
271
|
+
* share exchange is refused until resume. The API token is exempt —
|
|
272
|
+
* the operator must be able to inspect, resume, or delete a
|
|
273
|
+
* suspended tenant. Optional because older servers omit it.
|
|
274
|
+
*/
|
|
275
|
+
status: z.enum(["active", "suspended"]).optional(),
|
|
171
276
|
createdAt: z.number()
|
|
172
277
|
});
|
|
173
278
|
var AdminTenantCreateRequestSchema = z.object({
|
|
@@ -197,7 +302,8 @@ var adminTenantScopes = [
|
|
|
197
302
|
"docs.read",
|
|
198
303
|
"docs.delete",
|
|
199
304
|
"tokens.issue-doc",
|
|
200
|
-
"tokens.revoke"
|
|
305
|
+
"tokens.revoke",
|
|
306
|
+
"shares.manage"
|
|
201
307
|
];
|
|
202
308
|
var AdminTokenIssueDocRequestSchema = z.object({
|
|
203
309
|
kind: z.literal("doc"),
|
|
@@ -215,6 +321,14 @@ var AdminTokenIssueDocRequestSchema = z.object({
|
|
|
215
321
|
displayName: z.string().max(256).optional(),
|
|
216
322
|
groupId: z.string().max(256).optional(),
|
|
217
323
|
groups: z.array(z.string().max(256)).max(64).optional(),
|
|
324
|
+
/**
|
|
325
|
+
* Origin lock: web origins (scheme + host, optional port; one leading
|
|
326
|
+
* `*.` wildcard label allowed) the minted token may be presented
|
|
327
|
+
* from. Enforced on every engine request that carries a browser
|
|
328
|
+
* `Origin` header — hotlink prevention, not DRM: non-browser callers
|
|
329
|
+
* are governed by the token itself.
|
|
330
|
+
*/
|
|
331
|
+
origins: originPatternArray.optional(),
|
|
218
332
|
/** Token lifetime in seconds. */
|
|
219
333
|
expiresIn: z.number().int().min(60).max(60 * 60 * 24 * 90)
|
|
220
334
|
});
|
|
@@ -235,9 +349,110 @@ var AdminTokenIssueResponseSchema = z.object({
|
|
|
235
349
|
/** Unix seconds. */
|
|
236
350
|
expiresAt: z.number()
|
|
237
351
|
});
|
|
352
|
+
var ShareGrantRecordSchema = z.object({
|
|
353
|
+
/** Grant id; doubles as the public share token (`shr_…`). */
|
|
354
|
+
id: z.string(),
|
|
355
|
+
tenantId: z.string(),
|
|
356
|
+
docId: z.string(),
|
|
357
|
+
layerName: z.string(),
|
|
358
|
+
/** Doc capabilities the exchanged session carries. */
|
|
359
|
+
scope: z.array(z.string()),
|
|
360
|
+
/** Origin allowlist; null means any origin. */
|
|
361
|
+
origins: z.array(z.string()).nullable(),
|
|
362
|
+
/** True when a passphrase is required at exchange. The passphrase itself is never returned. */
|
|
363
|
+
passwordProtected: z.boolean(),
|
|
364
|
+
/** Lifetime of each exchanged session token, in seconds. */
|
|
365
|
+
sessionTtlSeconds: z.number(),
|
|
366
|
+
/** Paused grants refuse exchange (404) but keep their configuration. */
|
|
367
|
+
disabled: z.boolean(),
|
|
368
|
+
/** Unix epoch ms after which exchange returns 410; null = no expiry. */
|
|
369
|
+
expiresAt: z.number().nullable(),
|
|
370
|
+
/** Total successful exchanges — a dashboard convenience, not the usage meter. */
|
|
371
|
+
exchangeCount: z.number(),
|
|
372
|
+
lastExchangedAt: z.number().nullable(),
|
|
373
|
+
createdBy: z.string(),
|
|
374
|
+
createdAt: z.number(),
|
|
375
|
+
updatedAt: z.number()
|
|
376
|
+
});
|
|
377
|
+
var ShareGrantCreateRequestSchema = z.object({
|
|
378
|
+
docId: z.string().regex(docIdPattern),
|
|
379
|
+
layerName: z.string().min(1).max(256).optional(),
|
|
380
|
+
/**
|
|
381
|
+
* Doc capability scopes the exchanged session will carry. Validated
|
|
382
|
+
* server-side against the engine's scope vocabulary, same as
|
|
383
|
+
* `tokens.issue`.
|
|
384
|
+
*/
|
|
385
|
+
scope: z.array(z.string().min(1).max(128)).min(1).max(64),
|
|
386
|
+
/** Origin allowlist; omit to allow any origin. */
|
|
387
|
+
origins: originPatternArray.optional(),
|
|
388
|
+
/** Optional passphrase gate, checked at exchange. Stored as a hash; never returned. */
|
|
389
|
+
password: z.string().min(1).max(1024).optional(),
|
|
390
|
+
/** Lifetime of exchanged session tokens. Default 600. */
|
|
391
|
+
sessionTtlSeconds: z.number().int().min(60).max(60 * 60).optional(),
|
|
392
|
+
/** Unix epoch ms after which the grant stops exchanging; omit for no expiry. */
|
|
393
|
+
expiresAt: z.number().int().positive().optional()
|
|
394
|
+
});
|
|
395
|
+
var ShareGrantUpdateRequestSchema = z.object({
|
|
396
|
+
scope: z.array(z.string().min(1).max(128)).min(1).max(64).optional(),
|
|
397
|
+
origins: originPatternArray.nullable().optional(),
|
|
398
|
+
password: z.string().min(1).max(1024).nullable().optional(),
|
|
399
|
+
sessionTtlSeconds: z.number().int().min(60).max(60 * 60).optional(),
|
|
400
|
+
disabled: z.boolean().optional(),
|
|
401
|
+
expiresAt: z.number().int().positive().nullable().optional()
|
|
402
|
+
});
|
|
403
|
+
var ShareGrantResponseSchema = z.object({
|
|
404
|
+
share: ShareGrantRecordSchema
|
|
405
|
+
});
|
|
406
|
+
var ShareGrantListQuerySchema = z.object({
|
|
407
|
+
limit: z.coerce.number().int().min(1).max(ADMIN_DOCUMENT_LIST_MAX_LIMIT).default(ADMIN_DOCUMENT_LIST_DEFAULT_LIMIT),
|
|
408
|
+
cursor: z.string().min(1).optional(),
|
|
409
|
+
/** Filter to one document's grants. */
|
|
410
|
+
docId: z.string().regex(docIdPattern).optional()
|
|
411
|
+
});
|
|
412
|
+
var ShareGrantListResponseSchema = z.object({
|
|
413
|
+
shares: z.array(ShareGrantRecordSchema),
|
|
414
|
+
/** Opaque cursor for the next page; `null` on the last page. */
|
|
415
|
+
nextCursor: z.string().nullable().optional()
|
|
416
|
+
});
|
|
417
|
+
var AdminTenantShareParamsSchema = z.object({
|
|
418
|
+
tenantId: z.string().regex(tenantIdPattern),
|
|
419
|
+
shareId: z.string().regex(shareTokenPattern)
|
|
420
|
+
});
|
|
421
|
+
var ShareExchangeRequestSchema = z.object({
|
|
422
|
+
shareToken: z.string().regex(shareTokenPattern),
|
|
423
|
+
/** Required when the grant is passphrase-protected (422 otherwise). */
|
|
424
|
+
password: z.string().min(1).max(1024).optional()
|
|
425
|
+
});
|
|
426
|
+
var ShareSessionResponseSchema = z.object({
|
|
427
|
+
/** A doc-scoped session JWT carrying the grant's capabilities and origin lock. */
|
|
428
|
+
token: z.string(),
|
|
429
|
+
docId: z.string(),
|
|
430
|
+
layerName: z.string(),
|
|
431
|
+
/** Unix seconds when the session token expires; exchange again for a fresh one. */
|
|
432
|
+
expiresAt: z.number()
|
|
433
|
+
});
|
|
434
|
+
var TenantUsageQuerySchema = z.object({
|
|
435
|
+
/** UTC month to report, `YYYY-MM`. Defaults to the current month. */
|
|
436
|
+
period: z.string().regex(/^\d{4}-(0[1-9]|1[0-2])$/).optional()
|
|
437
|
+
});
|
|
438
|
+
var TenantUsageResponseSchema = z.object({
|
|
439
|
+
tenantId: z.string(),
|
|
440
|
+
periodStart: z.string(),
|
|
441
|
+
periodEnd: z.string(),
|
|
442
|
+
metrics: z.object({
|
|
443
|
+
"pdf.views": z.number(),
|
|
444
|
+
"pdf.uploads": z.number(),
|
|
445
|
+
"storage.bytes": z.number()
|
|
446
|
+
})
|
|
447
|
+
});
|
|
448
|
+
var TenantSuspendRequestSchema = z.object({
|
|
449
|
+
/** Optional operator reason, written to the security-events trail. */
|
|
450
|
+
reason: z.string().max(1024).optional()
|
|
451
|
+
});
|
|
238
452
|
var adminOperations = {
|
|
239
453
|
"tenants.create": {
|
|
240
454
|
operationId: "tenants.create",
|
|
455
|
+
title: "Create tenant",
|
|
241
456
|
summary: "Create a tenant, or confirm it already exists \u2014 ensure-style, idempotent.",
|
|
242
457
|
method: "POST",
|
|
243
458
|
path: adminWirePaths.tenants,
|
|
@@ -251,6 +466,7 @@ var adminOperations = {
|
|
|
251
466
|
},
|
|
252
467
|
"tenants.list": {
|
|
253
468
|
operationId: "tenants.list",
|
|
469
|
+
title: "List tenants",
|
|
254
470
|
summary: "List tenants, newest first, cursor-paginated.",
|
|
255
471
|
method: "GET",
|
|
256
472
|
path: adminWirePaths.tenants,
|
|
@@ -264,6 +480,7 @@ var adminOperations = {
|
|
|
264
480
|
},
|
|
265
481
|
"tenants.get": {
|
|
266
482
|
operationId: "tenants.get",
|
|
483
|
+
title: "Get tenant",
|
|
267
484
|
summary: "Fetch one tenant record.",
|
|
268
485
|
method: "GET",
|
|
269
486
|
path: "/v1/tenants/:tenantId",
|
|
@@ -277,6 +494,7 @@ var adminOperations = {
|
|
|
277
494
|
},
|
|
278
495
|
"tenants.delete": {
|
|
279
496
|
operationId: "tenants.delete",
|
|
497
|
+
title: "Delete tenant",
|
|
280
498
|
summary: "Delete a tenant and everything under it.",
|
|
281
499
|
method: "DELETE",
|
|
282
500
|
path: "/v1/tenants/:tenantId",
|
|
@@ -291,6 +509,7 @@ var adminOperations = {
|
|
|
291
509
|
},
|
|
292
510
|
"documents.init": {
|
|
293
511
|
operationId: "documents.init",
|
|
512
|
+
title: "Initialize upload",
|
|
294
513
|
summary: "Begin an upload: create (or resume/dedupe) a pending document and issue upload access.",
|
|
295
514
|
method: "POST",
|
|
296
515
|
path: "/v1/tenants/:tenantId/documents/init",
|
|
@@ -305,6 +524,7 @@ var adminOperations = {
|
|
|
305
524
|
},
|
|
306
525
|
"documents.commit": {
|
|
307
526
|
operationId: "documents.commit",
|
|
527
|
+
title: "Commit upload",
|
|
308
528
|
summary: "Finish an upload: verify the SHA-256 and promote the document to ready.",
|
|
309
529
|
method: "POST",
|
|
310
530
|
path: "/v1/tenants/:tenantId/documents/:id/commit",
|
|
@@ -318,24 +538,47 @@ var adminOperations = {
|
|
|
318
538
|
404: { contentType: "application/json", schema: AdminErrorPayloadSchema }
|
|
319
539
|
}
|
|
320
540
|
},
|
|
321
|
-
"documents.
|
|
322
|
-
operationId: "documents.
|
|
323
|
-
|
|
541
|
+
"documents.uploadProxy": {
|
|
542
|
+
operationId: "documents.uploadProxy",
|
|
543
|
+
title: "Upload document through the origin",
|
|
544
|
+
summary: "Upload a bounded PDF through the API when the initialized transfer kind is proxy.",
|
|
324
545
|
method: "POST",
|
|
325
|
-
path: "/v1/tenants/:tenantId/documents/:id/upload-
|
|
546
|
+
path: "/v1/tenants/:tenantId/documents/:id/upload-proxy",
|
|
326
547
|
credentials: ["api-token", "tenant-jwt"],
|
|
327
548
|
scope: ["docs.create"],
|
|
328
549
|
params: AdminTenantDocParamsSchema,
|
|
329
550
|
body: {
|
|
330
|
-
contentType:
|
|
551
|
+
contentType: "multipart/form-data"
|
|
331
552
|
},
|
|
332
553
|
responses: {
|
|
333
|
-
200: { contentType: "application/json", schema:
|
|
334
|
-
400: { contentType: "application/json", schema: AdminErrorPayloadSchema }
|
|
335
|
-
|
|
554
|
+
200: { contentType: "application/json", schema: AdminUploadProxyResponseSchema },
|
|
555
|
+
400: { contentType: "application/json", schema: AdminErrorPayloadSchema },
|
|
556
|
+
409: { contentType: "application/json", schema: AdminErrorPayloadSchema }
|
|
557
|
+
},
|
|
558
|
+
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."
|
|
559
|
+
},
|
|
560
|
+
"documents.importFrom": {
|
|
561
|
+
operationId: "documents.importFrom",
|
|
562
|
+
title: "Import document",
|
|
563
|
+
summary: "Server-side pull: fetch a PDF from a caller-supplied URL (e.g. a presigned object-store GET) or an operator-registered storage connection into CloudPDF-owned storage, verify it, and commit it.",
|
|
564
|
+
method: "POST",
|
|
565
|
+
path: "/v1/tenants/:tenantId/documents/import",
|
|
566
|
+
credentials: ["api-token", "tenant-jwt"],
|
|
567
|
+
scope: ["docs.create"],
|
|
568
|
+
params: AdminTenantParamsSchema,
|
|
569
|
+
body: { contentType: "application/json", schema: AdminDocumentImportRequestSchema },
|
|
570
|
+
responses: {
|
|
571
|
+
200: { contentType: "application/json", schema: AdminDocumentImportResponseSchema },
|
|
572
|
+
202: { contentType: "application/json", schema: AdminDocumentImportResponseSchema },
|
|
573
|
+
400: { contentType: "application/json", schema: AdminErrorPayloadSchema },
|
|
574
|
+
403: { contentType: "application/json", schema: AdminErrorPayloadSchema },
|
|
575
|
+
502: { contentType: "application/json", schema: AdminErrorPayloadSchema }
|
|
576
|
+
},
|
|
577
|
+
notes: "Default mode is synchronous and bounded: the response returns only after the transfer verified and committed (or failed). mode=async (connection sources only) answers 202 immediately and an in-process worker performs the transfer with leased, fenced retries; poll the document until ready/failed. The deployment import policy gates scheme, network range, and size; sources must declare a length. CloudPDF copies and owns the bytes \u2014 the source is never referenced in place. A 502 marks a retryable upstream failure: retry with the same idempotencyKey to resume the same document. URL sources are capabilities and never echoed back. Connection sources name operator-registered storage (bucket/prefix scope, allowed credential classes, and tenant bindings are deployment configuration); `revision` is provider-interpreted (S3 VersionId, GCS generation, Azure version id)."
|
|
336
578
|
},
|
|
337
579
|
"documents.list": {
|
|
338
580
|
operationId: "documents.list",
|
|
581
|
+
title: "List documents",
|
|
339
582
|
summary: "List documents in the tenant, newest first, cursor-paginated.",
|
|
340
583
|
method: "GET",
|
|
341
584
|
path: "/v1/tenants/:tenantId/documents",
|
|
@@ -350,6 +593,7 @@ var adminOperations = {
|
|
|
350
593
|
},
|
|
351
594
|
"documents.get": {
|
|
352
595
|
operationId: "documents.get",
|
|
596
|
+
title: "Get document",
|
|
353
597
|
summary: "Fetch one document record.",
|
|
354
598
|
method: "GET",
|
|
355
599
|
path: "/v1/tenants/:tenantId/documents/:id",
|
|
@@ -364,6 +608,7 @@ var adminOperations = {
|
|
|
364
608
|
},
|
|
365
609
|
"documents.download": {
|
|
366
610
|
operationId: "documents.download",
|
|
611
|
+
title: "Download document",
|
|
367
612
|
summary: "Download the stored base PDF bytes.",
|
|
368
613
|
method: "GET",
|
|
369
614
|
path: "/v1/tenants/:tenantId/documents/:id/download",
|
|
@@ -378,6 +623,7 @@ var adminOperations = {
|
|
|
378
623
|
},
|
|
379
624
|
"documents.delete": {
|
|
380
625
|
operationId: "documents.delete",
|
|
626
|
+
title: "Delete document",
|
|
381
627
|
summary: "Delete a document and its stored artifacts.",
|
|
382
628
|
method: "DELETE",
|
|
383
629
|
path: "/v1/tenants/:tenantId/documents/:id",
|
|
@@ -392,6 +638,7 @@ var adminOperations = {
|
|
|
392
638
|
},
|
|
393
639
|
"documents.thumbnail": {
|
|
394
640
|
operationId: "documents.thumbnail",
|
|
641
|
+
title: "Get thumbnail",
|
|
395
642
|
summary: "Fetch the warmed dashboard-tile render for a document.",
|
|
396
643
|
method: "GET",
|
|
397
644
|
path: "/v1/tenants/:tenantId/documents/:id/thumbnail",
|
|
@@ -405,6 +652,7 @@ var adminOperations = {
|
|
|
405
652
|
},
|
|
406
653
|
"deployment.licenseStatus": {
|
|
407
654
|
operationId: "deployment.licenseStatus",
|
|
655
|
+
title: "License status",
|
|
408
656
|
summary: "License decision plus usage-reporting and meter snapshots for this deployment.",
|
|
409
657
|
method: "GET",
|
|
410
658
|
path: adminWirePaths.deploymentLicenseStatus,
|
|
@@ -416,6 +664,7 @@ var adminOperations = {
|
|
|
416
664
|
},
|
|
417
665
|
"tokens.issue": {
|
|
418
666
|
operationId: "tokens.issue",
|
|
667
|
+
title: "Issue token",
|
|
419
668
|
summary: "Mint a delegated JWT: a doc token, or (API token only) a tenant token.",
|
|
420
669
|
method: "POST",
|
|
421
670
|
path: "/v1/tenants/:tenantId/tokens",
|
|
@@ -433,6 +682,7 @@ var adminOperations = {
|
|
|
433
682
|
},
|
|
434
683
|
"tokens.revoke": {
|
|
435
684
|
operationId: "tokens.revoke",
|
|
685
|
+
title: "Revoke token",
|
|
436
686
|
summary: "Revoke a token by jti; live sessions drop on their next heartbeat.",
|
|
437
687
|
method: "POST",
|
|
438
688
|
path: "/v1/tenants/:tenantId/tokens/:jti/revoke",
|
|
@@ -449,6 +699,153 @@ var adminOperations = {
|
|
|
449
699
|
400: { contentType: "application/json", schema: AdminErrorPayloadSchema }
|
|
450
700
|
},
|
|
451
701
|
notes: "Mounted only when the deployment enables token revocation."
|
|
702
|
+
},
|
|
703
|
+
"tenants.usage": {
|
|
704
|
+
operationId: "tenants.usage",
|
|
705
|
+
title: "Tenant usage",
|
|
706
|
+
summary: "Per-tenant usage facts (views, uploads, stored bytes) for one UTC month.",
|
|
707
|
+
method: "GET",
|
|
708
|
+
path: "/v1/tenants/:tenantId/usage",
|
|
709
|
+
credentials: ["api-token", "tenant-jwt"],
|
|
710
|
+
scope: ["docs.read"],
|
|
711
|
+
params: AdminTenantParamsSchema,
|
|
712
|
+
query: TenantUsageQuerySchema,
|
|
713
|
+
responses: {
|
|
714
|
+
200: { contentType: "application/json", schema: TenantUsageResponseSchema },
|
|
715
|
+
400: { contentType: "application/json", schema: AdminErrorPayloadSchema },
|
|
716
|
+
404: { contentType: "application/json", schema: AdminErrorPayloadSchema }
|
|
717
|
+
},
|
|
718
|
+
notes: "Facts only \u2014 no limits or billing state. Views count share exchanges plus authorized /v1/access grants, deduplicated across the two."
|
|
719
|
+
},
|
|
720
|
+
"tenants.suspend": {
|
|
721
|
+
operationId: "tenants.suspend",
|
|
722
|
+
title: "Suspend tenant",
|
|
723
|
+
summary: "Fail the tenant closed: refuse every tenant JWT, doc JWT, and share exchange.",
|
|
724
|
+
method: "POST",
|
|
725
|
+
path: "/v1/tenants/:tenantId/suspend",
|
|
726
|
+
credentials: ["api-token"],
|
|
727
|
+
scope: [],
|
|
728
|
+
params: AdminTenantParamsSchema,
|
|
729
|
+
body: {
|
|
730
|
+
contentType: "application/json",
|
|
731
|
+
schema: TenantSuspendRequestSchema,
|
|
732
|
+
required: false
|
|
733
|
+
},
|
|
734
|
+
responses: {
|
|
735
|
+
204: {},
|
|
736
|
+
404: { contentType: "application/json", schema: AdminErrorPayloadSchema }
|
|
737
|
+
},
|
|
738
|
+
notes: "Instantly reversible with resume. The API token is exempt, so a suspended tenant can still be inspected, exported, resumed, or deleted."
|
|
739
|
+
},
|
|
740
|
+
"tenants.resume": {
|
|
741
|
+
operationId: "tenants.resume",
|
|
742
|
+
title: "Resume tenant",
|
|
743
|
+
summary: "Lift a suspension; credentials for the tenant verify again.",
|
|
744
|
+
method: "POST",
|
|
745
|
+
path: "/v1/tenants/:tenantId/resume",
|
|
746
|
+
credentials: ["api-token"],
|
|
747
|
+
scope: [],
|
|
748
|
+
params: AdminTenantParamsSchema,
|
|
749
|
+
responses: {
|
|
750
|
+
204: {},
|
|
751
|
+
404: { contentType: "application/json", schema: AdminErrorPayloadSchema }
|
|
752
|
+
}
|
|
753
|
+
},
|
|
754
|
+
"shares.create": {
|
|
755
|
+
operationId: "shares.create",
|
|
756
|
+
title: "Create share",
|
|
757
|
+
summary: "Create a standing share grant for one document \u2014 the no-backend embed credential.",
|
|
758
|
+
method: "POST",
|
|
759
|
+
path: "/v1/tenants/:tenantId/shares",
|
|
760
|
+
credentials: ["api-token", "tenant-jwt"],
|
|
761
|
+
scope: ["shares.manage"],
|
|
762
|
+
params: AdminTenantParamsSchema,
|
|
763
|
+
body: { contentType: "application/json", schema: ShareGrantCreateRequestSchema },
|
|
764
|
+
responses: {
|
|
765
|
+
200: { contentType: "application/json", schema: ShareGrantResponseSchema },
|
|
766
|
+
400: { contentType: "application/json", schema: AdminErrorPayloadSchema },
|
|
767
|
+
403: { contentType: "application/json", schema: AdminErrorPayloadSchema },
|
|
768
|
+
404: { contentType: "application/json", schema: AdminErrorPayloadSchema }
|
|
769
|
+
},
|
|
770
|
+
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."
|
|
771
|
+
},
|
|
772
|
+
"shares.list": {
|
|
773
|
+
operationId: "shares.list",
|
|
774
|
+
title: "List shares",
|
|
775
|
+
summary: "List share grants in the tenant, newest first, cursor-paginated.",
|
|
776
|
+
method: "GET",
|
|
777
|
+
path: "/v1/tenants/:tenantId/shares",
|
|
778
|
+
credentials: ["api-token", "tenant-jwt"],
|
|
779
|
+
scope: ["shares.manage"],
|
|
780
|
+
params: AdminTenantParamsSchema,
|
|
781
|
+
query: ShareGrantListQuerySchema,
|
|
782
|
+
responses: {
|
|
783
|
+
200: { contentType: "application/json", schema: ShareGrantListResponseSchema },
|
|
784
|
+
400: { contentType: "application/json", schema: AdminErrorPayloadSchema }
|
|
785
|
+
}
|
|
786
|
+
},
|
|
787
|
+
"shares.get": {
|
|
788
|
+
operationId: "shares.get",
|
|
789
|
+
title: "Get share",
|
|
790
|
+
summary: "Fetch one share grant.",
|
|
791
|
+
method: "GET",
|
|
792
|
+
path: "/v1/tenants/:tenantId/shares/:shareId",
|
|
793
|
+
credentials: ["api-token", "tenant-jwt"],
|
|
794
|
+
scope: ["shares.manage"],
|
|
795
|
+
params: AdminTenantShareParamsSchema,
|
|
796
|
+
responses: {
|
|
797
|
+
200: { contentType: "application/json", schema: ShareGrantResponseSchema },
|
|
798
|
+
404: { contentType: "application/json", schema: AdminErrorPayloadSchema }
|
|
799
|
+
}
|
|
800
|
+
},
|
|
801
|
+
"shares.update": {
|
|
802
|
+
operationId: "shares.update",
|
|
803
|
+
title: "Update share",
|
|
804
|
+
summary: "Edit a grant in place \u2014 every embedded copy of the token follows the row.",
|
|
805
|
+
method: "PATCH",
|
|
806
|
+
path: "/v1/tenants/:tenantId/shares/:shareId",
|
|
807
|
+
credentials: ["api-token", "tenant-jwt"],
|
|
808
|
+
scope: ["shares.manage"],
|
|
809
|
+
params: AdminTenantShareParamsSchema,
|
|
810
|
+
body: { contentType: "application/json", schema: ShareGrantUpdateRequestSchema },
|
|
811
|
+
responses: {
|
|
812
|
+
200: { contentType: "application/json", schema: ShareGrantResponseSchema },
|
|
813
|
+
400: { contentType: "application/json", schema: AdminErrorPayloadSchema },
|
|
814
|
+
404: { contentType: "application/json", schema: AdminErrorPayloadSchema }
|
|
815
|
+
}
|
|
816
|
+
},
|
|
817
|
+
"shares.delete": {
|
|
818
|
+
operationId: "shares.delete",
|
|
819
|
+
title: "Revoke share",
|
|
820
|
+
summary: "Delete a grant; exchange stops immediately, live sessions lapse at their exp.",
|
|
821
|
+
method: "DELETE",
|
|
822
|
+
path: "/v1/tenants/:tenantId/shares/:shareId",
|
|
823
|
+
credentials: ["api-token", "tenant-jwt"],
|
|
824
|
+
scope: ["shares.manage"],
|
|
825
|
+
params: AdminTenantShareParamsSchema,
|
|
826
|
+
responses: {
|
|
827
|
+
204: {},
|
|
828
|
+
404: { contentType: "application/json", schema: AdminErrorPayloadSchema }
|
|
829
|
+
}
|
|
830
|
+
},
|
|
831
|
+
"shares.exchange": {
|
|
832
|
+
operationId: "shares.exchange",
|
|
833
|
+
title: "Exchange share token",
|
|
834
|
+
summary: "Trade a public share token for a short-lived document session JWT.",
|
|
835
|
+
method: "POST",
|
|
836
|
+
path: adminWirePaths.shareSessions,
|
|
837
|
+
credentials: [],
|
|
838
|
+
scope: [],
|
|
839
|
+
body: { contentType: "application/json", schema: ShareExchangeRequestSchema },
|
|
840
|
+
responses: {
|
|
841
|
+
200: { contentType: "application/json", schema: ShareSessionResponseSchema },
|
|
842
|
+
400: { contentType: "application/json", schema: AdminErrorPayloadSchema },
|
|
843
|
+
403: { contentType: "application/json", schema: AdminErrorPayloadSchema },
|
|
844
|
+
404: { contentType: "application/json", schema: AdminErrorPayloadSchema },
|
|
845
|
+
410: { contentType: "application/json", schema: AdminErrorPayloadSchema },
|
|
846
|
+
422: { contentType: "application/json", schema: AdminErrorPayloadSchema }
|
|
847
|
+
},
|
|
848
|
+
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
849
|
}
|
|
453
850
|
};
|
|
454
851
|
var DocIdParamsSchema = z.object({
|
|
@@ -477,6 +874,7 @@ var MutationResponseSchema = z.object({ meta: MutationMetaSchema }).passthrough(
|
|
|
477
874
|
var docOperations = {
|
|
478
875
|
"doc.head": {
|
|
479
876
|
operationId: "doc.head",
|
|
877
|
+
title: "Open document",
|
|
480
878
|
summary: "Open a document and return its head (versions, page count, security).",
|
|
481
879
|
method: "GET",
|
|
482
880
|
path: wireTemplates.docHead,
|
|
@@ -492,6 +890,7 @@ var docOperations = {
|
|
|
492
890
|
},
|
|
493
891
|
"doc.manifest": {
|
|
494
892
|
operationId: "doc.manifest",
|
|
893
|
+
title: "Get manifest",
|
|
495
894
|
summary: "Full layer manifest at the layer's current version.",
|
|
496
895
|
method: "GET",
|
|
497
896
|
path: wireTemplates.layerManifest,
|
|
@@ -507,6 +906,7 @@ var docOperations = {
|
|
|
507
906
|
},
|
|
508
907
|
"doc.metadata.get": {
|
|
509
908
|
operationId: "doc.metadata.get",
|
|
909
|
+
title: "Get metadata",
|
|
510
910
|
summary: "Document metadata (PDF info dictionary view) for a layer.",
|
|
511
911
|
method: "GET",
|
|
512
912
|
path: wireTemplates.layerMetadata,
|
|
@@ -522,6 +922,7 @@ var docOperations = {
|
|
|
522
922
|
},
|
|
523
923
|
"doc.render": {
|
|
524
924
|
operationId: "doc.render",
|
|
925
|
+
title: "Render page",
|
|
525
926
|
summary: "Render one page as an image at the current layer version.",
|
|
526
927
|
method: "GET",
|
|
527
928
|
path: wireTemplates.layerRenderPage,
|
|
@@ -538,6 +939,7 @@ var docOperations = {
|
|
|
538
939
|
},
|
|
539
940
|
"doc.text": {
|
|
540
941
|
operationId: "doc.text",
|
|
942
|
+
title: "Extract page text",
|
|
541
943
|
summary: "Extracted text content for one page.",
|
|
542
944
|
method: "GET",
|
|
543
945
|
path: wireTemplates.layerTextPage,
|
|
@@ -553,6 +955,7 @@ var docOperations = {
|
|
|
553
955
|
},
|
|
554
956
|
"doc.annotations.list": {
|
|
555
957
|
operationId: "doc.annotations.list",
|
|
958
|
+
title: "List annotations",
|
|
556
959
|
summary: "One page's annotations at the current layer version.",
|
|
557
960
|
method: "GET",
|
|
558
961
|
path: wireTemplates.layerAnnotationItems,
|
|
@@ -566,8 +969,27 @@ var docOperations = {
|
|
|
566
969
|
404: { contentType: "application/json", schema: EngineErrorPayloadSchema }
|
|
567
970
|
}
|
|
568
971
|
},
|
|
972
|
+
"doc.annotations.listAll": {
|
|
973
|
+
operationId: "doc.annotations.listAll",
|
|
974
|
+
title: "List all annotations",
|
|
975
|
+
summary: "All pages' annotations as one coherent snapshot at the current layer version.",
|
|
976
|
+
method: "GET",
|
|
977
|
+
path: wireTemplates.layerAnnotationItemsAll,
|
|
978
|
+
credentials: docCredentials,
|
|
979
|
+
scope: [],
|
|
980
|
+
docCapabilities: ["doc.annotate.read"],
|
|
981
|
+
requestHeaders: [documentPasswordHeader],
|
|
982
|
+
params: DocLayerParamsSchema,
|
|
983
|
+
notes: "Returns one entry per page plus the audit-log cursor for reconciling subsequent document events. Page order is unspecified; join by `pageState.pageObjectNumber` when display order matters.",
|
|
984
|
+
responses: {
|
|
985
|
+
200: { contentType: "application/json", schema: AnnotationListSnapshotAllPagesSchema },
|
|
986
|
+
404: { contentType: "application/json", schema: EngineErrorPayloadSchema },
|
|
987
|
+
409: { contentType: "application/json", schema: EngineErrorPayloadSchema }
|
|
988
|
+
}
|
|
989
|
+
},
|
|
569
990
|
"doc.annotations.create": {
|
|
570
991
|
operationId: "doc.annotations.create",
|
|
992
|
+
title: "Create annotation",
|
|
571
993
|
summary: "Create an annotation on a page.",
|
|
572
994
|
method: "POST",
|
|
573
995
|
path: wireTemplates.layerAnnotationItems,
|
|
@@ -586,6 +1008,7 @@ var docOperations = {
|
|
|
586
1008
|
},
|
|
587
1009
|
"doc.annotations.update": {
|
|
588
1010
|
operationId: "doc.annotations.update",
|
|
1011
|
+
title: "Update annotation",
|
|
589
1012
|
summary: "Update one annotation by key.",
|
|
590
1013
|
method: "PATCH",
|
|
591
1014
|
path: wireTemplates.layerAnnotationItem,
|
|
@@ -603,6 +1026,7 @@ var docOperations = {
|
|
|
603
1026
|
},
|
|
604
1027
|
"doc.annotations.delete": {
|
|
605
1028
|
operationId: "doc.annotations.delete",
|
|
1029
|
+
title: "Delete annotation",
|
|
606
1030
|
summary: "Delete one annotation by key.",
|
|
607
1031
|
method: "DELETE",
|
|
608
1032
|
path: wireTemplates.layerAnnotationItem,
|
|
@@ -618,6 +1042,7 @@ var docOperations = {
|
|
|
618
1042
|
},
|
|
619
1043
|
"doc.forms.get": {
|
|
620
1044
|
operationId: "doc.forms.get",
|
|
1045
|
+
title: "Get form snapshot",
|
|
621
1046
|
summary: "Reconciled form snapshot: fields, widgets, values.",
|
|
622
1047
|
method: "GET",
|
|
623
1048
|
path: wireTemplates.layerForm,
|
|
@@ -633,6 +1058,7 @@ var docOperations = {
|
|
|
633
1058
|
},
|
|
634
1059
|
"doc.forms.setValue": {
|
|
635
1060
|
operationId: "doc.forms.setValue",
|
|
1061
|
+
title: "Set form value",
|
|
636
1062
|
summary: "Set one form field's value.",
|
|
637
1063
|
method: "POST",
|
|
638
1064
|
path: wireTemplates.layerFormFieldValue,
|
|
@@ -650,6 +1076,7 @@ var docOperations = {
|
|
|
650
1076
|
},
|
|
651
1077
|
"doc.forms.reset": {
|
|
652
1078
|
operationId: "doc.forms.reset",
|
|
1079
|
+
title: "Reset form field",
|
|
653
1080
|
summary: "Reset one form field to its default value.",
|
|
654
1081
|
method: "POST",
|
|
655
1082
|
path: wireTemplates.layerFormFieldReset,
|
|
@@ -665,6 +1092,7 @@ var docOperations = {
|
|
|
665
1092
|
},
|
|
666
1093
|
"doc.forms.exportData": {
|
|
667
1094
|
operationId: "doc.forms.exportData",
|
|
1095
|
+
title: "Export form data",
|
|
668
1096
|
summary: "Export form data as FDF or XFDF.",
|
|
669
1097
|
method: "GET",
|
|
670
1098
|
path: wireTemplates.layerFormData,
|
|
@@ -681,6 +1109,7 @@ var docOperations = {
|
|
|
681
1109
|
},
|
|
682
1110
|
"doc.forms.importData": {
|
|
683
1111
|
operationId: "doc.forms.importData",
|
|
1112
|
+
title: "Import form data",
|
|
684
1113
|
summary: "Import form data (FDF/XFDF), filling matching fields.",
|
|
685
1114
|
method: "POST",
|
|
686
1115
|
path: wireTemplates.layerFormData,
|
|
@@ -698,6 +1127,7 @@ var docOperations = {
|
|
|
698
1127
|
},
|
|
699
1128
|
"doc.pages.move": {
|
|
700
1129
|
operationId: "doc.pages.move",
|
|
1130
|
+
title: "Move pages",
|
|
701
1131
|
summary: "Reorder pages.",
|
|
702
1132
|
method: "POST",
|
|
703
1133
|
path: wireTemplates.layerPagesMove,
|
|
@@ -715,6 +1145,7 @@ var docOperations = {
|
|
|
715
1145
|
},
|
|
716
1146
|
"doc.pages.rotate": {
|
|
717
1147
|
operationId: "doc.pages.rotate",
|
|
1148
|
+
title: "Rotate pages",
|
|
718
1149
|
summary: "Set absolute rotation on pages.",
|
|
719
1150
|
method: "POST",
|
|
720
1151
|
path: wireTemplates.layerPagesRotate,
|
|
@@ -732,6 +1163,7 @@ var docOperations = {
|
|
|
732
1163
|
},
|
|
733
1164
|
"doc.pages.delete": {
|
|
734
1165
|
operationId: "doc.pages.delete",
|
|
1166
|
+
title: "Delete pages",
|
|
735
1167
|
summary: "Delete pages.",
|
|
736
1168
|
method: "POST",
|
|
737
1169
|
path: wireTemplates.layerPagesDelete,
|
|
@@ -749,6 +1181,7 @@ var docOperations = {
|
|
|
749
1181
|
},
|
|
750
1182
|
"doc.pages.flatten": {
|
|
751
1183
|
operationId: "doc.pages.flatten",
|
|
1184
|
+
title: "Flatten pages",
|
|
752
1185
|
summary: "Flatten annotations and form fields into page content.",
|
|
753
1186
|
method: "POST",
|
|
754
1187
|
path: wireTemplates.layerPagesFlatten,
|
|
@@ -764,8 +1197,68 @@ var docOperations = {
|
|
|
764
1197
|
404: { contentType: "application/json", schema: EngineErrorPayloadSchema }
|
|
765
1198
|
}
|
|
766
1199
|
},
|
|
1200
|
+
"doc.pages.insert": {
|
|
1201
|
+
operationId: "doc.pages.insert",
|
|
1202
|
+
title: "Insert pages from a PDF",
|
|
1203
|
+
summary: "Copy every page of an uploaded PDF into the document at an index.",
|
|
1204
|
+
method: "POST",
|
|
1205
|
+
path: wireTemplates.layerPagesInsert,
|
|
1206
|
+
credentials: docCredentials,
|
|
1207
|
+
scope: [],
|
|
1208
|
+
docCapabilities: ["doc.pages.assemble"],
|
|
1209
|
+
requestHeaders: [documentPasswordHeader],
|
|
1210
|
+
params: DocLayerParamsSchema,
|
|
1211
|
+
body: {
|
|
1212
|
+
contentType: "multipart/form-data"
|
|
1213
|
+
},
|
|
1214
|
+
responses: {
|
|
1215
|
+
200: { contentType: "application/json", schema: MutationResponseSchema },
|
|
1216
|
+
400: { contentType: "application/json", schema: EngineErrorPayloadSchema },
|
|
1217
|
+
404: { contentType: "application/json", schema: EngineErrorPayloadSchema }
|
|
1218
|
+
},
|
|
1219
|
+
notes: 'Multipart mutation envelope: a `body` field holding `{"destIndex"?: number}` (omitted \u2192 append) plus a `resource:source` file part carrying the standalone PDF whose pages are copied in. The inserted copies get fresh page object numbers, returned in insertion order.'
|
|
1220
|
+
},
|
|
1221
|
+
"doc.pages.insertBlank": {
|
|
1222
|
+
operationId: "doc.pages.insertBlank",
|
|
1223
|
+
title: "Insert blank pages",
|
|
1224
|
+
summary: "Create blank pages of an explicit size at an index.",
|
|
1225
|
+
method: "POST",
|
|
1226
|
+
path: wireTemplates.layerPagesInsertBlank,
|
|
1227
|
+
credentials: docCredentials,
|
|
1228
|
+
scope: [],
|
|
1229
|
+
docCapabilities: ["doc.pages.assemble"],
|
|
1230
|
+
requestHeaders: [documentPasswordHeader],
|
|
1231
|
+
params: DocLayerParamsSchema,
|
|
1232
|
+
body: { contentType: "application/json", schema: looseJson },
|
|
1233
|
+
responses: {
|
|
1234
|
+
200: { contentType: "application/json", schema: MutationResponseSchema },
|
|
1235
|
+
400: { contentType: "application/json", schema: EngineErrorPayloadSchema },
|
|
1236
|
+
404: { contentType: "application/json", schema: EngineErrorPayloadSchema }
|
|
1237
|
+
},
|
|
1238
|
+
notes: 'Body is `{"size": {"width", "height"}, "count"?, "destIndex"?}` \u2014 size in PDF points, count in [1, 100], destIndex omitted \u2192 append.'
|
|
1239
|
+
},
|
|
1240
|
+
"doc.pages.extract": {
|
|
1241
|
+
operationId: "doc.pages.extract",
|
|
1242
|
+
title: "Extract pages",
|
|
1243
|
+
summary: "Export the listed pages, in order, as a standalone PDF.",
|
|
1244
|
+
method: "POST",
|
|
1245
|
+
path: wireTemplates.layerPagesExtract,
|
|
1246
|
+
credentials: docCredentials,
|
|
1247
|
+
scope: [],
|
|
1248
|
+
docCapabilities: ["doc.download"],
|
|
1249
|
+
requestHeaders: [documentPasswordHeader],
|
|
1250
|
+
params: DocLayerParamsSchema,
|
|
1251
|
+
body: { contentType: "application/json", schema: looseJson },
|
|
1252
|
+
responses: {
|
|
1253
|
+
200: { contentType: "application/pdf" },
|
|
1254
|
+
400: { contentType: "application/json", schema: EngineErrorPayloadSchema },
|
|
1255
|
+
404: { contentType: "application/json", schema: EngineErrorPayloadSchema }
|
|
1256
|
+
},
|
|
1257
|
+
notes: 'A read, not a mutation: the source document is untouched and no event is published. Body is `{"pageObjectNumbers": number[]}`; the response body is the new PDF.'
|
|
1258
|
+
},
|
|
767
1259
|
"doc.redactions.apply": {
|
|
768
1260
|
operationId: "doc.redactions.apply",
|
|
1261
|
+
title: "Apply redactions",
|
|
769
1262
|
summary: "Apply pending redactions, permanently removing content.",
|
|
770
1263
|
method: "POST",
|
|
771
1264
|
path: wireTemplates.layerRedactionsApply,
|
|
@@ -783,6 +1276,7 @@ var docOperations = {
|
|
|
783
1276
|
},
|
|
784
1277
|
"doc.download": {
|
|
785
1278
|
operationId: "doc.download",
|
|
1279
|
+
title: "Download PDF",
|
|
786
1280
|
summary: "Download the layer's current PDF (base plus layer edits).",
|
|
787
1281
|
method: "GET",
|
|
788
1282
|
path: wireTemplates.layerDownload,
|
|
@@ -798,6 +1292,19 @@ var docOperations = {
|
|
|
798
1292
|
}
|
|
799
1293
|
};
|
|
800
1294
|
var allOperations = { ...adminOperations, ...docOperations };
|
|
1295
|
+
var docsGroups = {
|
|
1296
|
+
deployment: { title: "Deployment" },
|
|
1297
|
+
tenants: { title: "Tenants" },
|
|
1298
|
+
documents: { title: "Tenant documents" },
|
|
1299
|
+
tokens: { title: "Tokens" },
|
|
1300
|
+
shares: { title: "Shares" },
|
|
1301
|
+
doc: { title: "Document operations", slug: "document-operations" },
|
|
1302
|
+
"doc.annotations": { title: "Annotations" },
|
|
1303
|
+
"doc.forms": { title: "Forms" },
|
|
1304
|
+
"doc.metadata": { title: "Metadata" },
|
|
1305
|
+
"doc.pages": { title: "Pages" },
|
|
1306
|
+
"doc.redactions": { title: "Redactions" }
|
|
1307
|
+
};
|
|
801
1308
|
|
|
802
1309
|
// src/openapi.ts
|
|
803
1310
|
var STATUS_TEXT = {
|
|
@@ -808,6 +1315,7 @@ var STATUS_TEXT = {
|
|
|
808
1315
|
403: "Forbidden",
|
|
809
1316
|
404: "Not found",
|
|
810
1317
|
409: "Conflict",
|
|
1318
|
+
410: "Gone",
|
|
811
1319
|
422: "Unprocessable"
|
|
812
1320
|
};
|
|
813
1321
|
var SECURITY_SCHEME = {
|
|
@@ -817,12 +1325,23 @@ var SECURITY_SCHEME = {
|
|
|
817
1325
|
};
|
|
818
1326
|
var ADMIN_ERROR_REF = "#/components/schemas/AdminErrorPayload";
|
|
819
1327
|
var ENGINE_ERROR_REF = "#/components/schemas/EngineErrorPayload";
|
|
1328
|
+
var SHARED_COMPONENT_SCHEMAS = PdfActionWireComponents;
|
|
1329
|
+
var SHARED_COMPONENT_BY_DEFINITION = new Map(
|
|
1330
|
+
Object.entries(SHARED_COMPONENT_SCHEMAS).map(([name, schema]) => [schema._def, name])
|
|
1331
|
+
);
|
|
1332
|
+
var SHARED_COMPONENT_REFS = new Set(
|
|
1333
|
+
Object.keys(SHARED_COMPONENT_SCHEMAS).map((name) => `#/components/schemas/${name}`)
|
|
1334
|
+
);
|
|
820
1335
|
function buildAdminOpenApiDocument(opts) {
|
|
821
1336
|
const paths = {};
|
|
822
1337
|
const schemas = {};
|
|
823
1338
|
registerSchema(schemas, "AdminErrorPayload", AdminErrorPayloadSchema);
|
|
824
1339
|
registerSchema(schemas, "EngineErrorPayload", EngineErrorPayloadSchema2);
|
|
1340
|
+
for (const [name, schema] of Object.entries(SHARED_COMPONENT_SCHEMAS)) {
|
|
1341
|
+
registerSchema(schemas, name, schema);
|
|
1342
|
+
}
|
|
825
1343
|
for (const op of Object.values(allOperations)) {
|
|
1344
|
+
assertDocsGroupsCover(op);
|
|
826
1345
|
const openApiPath = toOpenApiPath(op.path);
|
|
827
1346
|
const method = op.method.toLowerCase();
|
|
828
1347
|
const entry = paths[openApiPath] ??= {};
|
|
@@ -837,23 +1356,29 @@ function buildAdminOpenApiDocument(opts) {
|
|
|
837
1356
|
license: { name: "Apache-2.0", identifier: "Apache-2.0" }
|
|
838
1357
|
},
|
|
839
1358
|
paths: sortKeys(paths),
|
|
1359
|
+
// Docs navigation manifest: section titles and URL slugs for the API
|
|
1360
|
+
// reference, in sidebar order (see `docsGroups` in the registry).
|
|
1361
|
+
"x-docs-groups": docsGroups,
|
|
840
1362
|
components: {
|
|
841
1363
|
securitySchemes: {
|
|
842
1364
|
apiToken: {
|
|
843
1365
|
type: "http",
|
|
844
1366
|
scheme: "bearer",
|
|
1367
|
+
"x-docs-title": "API token",
|
|
845
1368
|
description: "The deployment's static root credential (CLOUDPDF_API_AUTH_TOKENS), valid on every surface."
|
|
846
1369
|
},
|
|
847
1370
|
tenantToken: {
|
|
848
1371
|
type: "http",
|
|
849
1372
|
scheme: "bearer",
|
|
850
1373
|
bearerFormat: "JWT",
|
|
1374
|
+
"x-docs-title": "Tenant token",
|
|
851
1375
|
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
1376
|
},
|
|
853
1377
|
docToken: {
|
|
854
1378
|
type: "http",
|
|
855
1379
|
scheme: "bearer",
|
|
856
1380
|
bearerFormat: "JWT",
|
|
1381
|
+
"x-docs-title": "Document token",
|
|
857
1382
|
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
1383
|
}
|
|
859
1384
|
},
|
|
@@ -861,6 +1386,15 @@ function buildAdminOpenApiDocument(opts) {
|
|
|
861
1386
|
}
|
|
862
1387
|
};
|
|
863
1388
|
}
|
|
1389
|
+
function assertDocsGroupsCover(op) {
|
|
1390
|
+
const { groups } = sdkOperationName(op.operationId);
|
|
1391
|
+
for (let depth = 1; depth <= groups.length; depth += 1) {
|
|
1392
|
+
const key = groups.slice(0, depth).join(".");
|
|
1393
|
+
if (!(key in docsGroups)) {
|
|
1394
|
+
throw new Error(`Operation ${op.operationId} has no docsGroups entry for "${key}"`);
|
|
1395
|
+
}
|
|
1396
|
+
}
|
|
1397
|
+
}
|
|
864
1398
|
function operationObject(op, schemas) {
|
|
865
1399
|
const parameters = [...pathParameters(op), ...queryParameters(op), ...headerParameters(op)];
|
|
866
1400
|
const sdkName = sdkOperationName(op.operationId);
|
|
@@ -868,6 +1402,7 @@ function operationObject(op, schemas) {
|
|
|
868
1402
|
operationId: op.operationId,
|
|
869
1403
|
"x-fern-sdk-group-name": sdkName.groups,
|
|
870
1404
|
"x-fern-sdk-method-name": sdkName.method,
|
|
1405
|
+
"x-docs-title": op.title,
|
|
871
1406
|
summary: op.summary,
|
|
872
1407
|
...op.notes ? { description: op.notes } : {},
|
|
873
1408
|
security: op.credentials.map((credential) => ({ [SECURITY_SCHEME[credential]]: [] })),
|
|
@@ -879,12 +1414,54 @@ function operationObject(op, schemas) {
|
|
|
879
1414
|
};
|
|
880
1415
|
return out;
|
|
881
1416
|
}
|
|
1417
|
+
var RESERVED_SDK_SEGMENTS = [
|
|
1418
|
+
[
|
|
1419
|
+
"Java",
|
|
1420
|
+
/* @__PURE__ */ new Set([
|
|
1421
|
+
...["abstract", "assert", "boolean", "break", "byte", "case", "catch", "char", "class"],
|
|
1422
|
+
...["const", "continue", "default", "do", "double", "else", "enum", "extends", "final"],
|
|
1423
|
+
...["finally", "float", "for", "goto", "if", "implements", "import", "instanceof", "int"],
|
|
1424
|
+
...["interface", "long", "native", "new", "package", "private", "protected", "public"],
|
|
1425
|
+
...["return", "short", "static", "strictfp", "super", "switch", "synchronized", "this"],
|
|
1426
|
+
...["throw", "throws", "transient", "try", "void", "volatile", "while"],
|
|
1427
|
+
...["true", "false", "null"]
|
|
1428
|
+
])
|
|
1429
|
+
],
|
|
1430
|
+
[
|
|
1431
|
+
"Python",
|
|
1432
|
+
/* @__PURE__ */ new Set([
|
|
1433
|
+
...["False", "None", "True", "and", "as", "assert", "async", "await", "break", "class"],
|
|
1434
|
+
...["continue", "def", "del", "elif", "else", "except", "finally", "for", "from"],
|
|
1435
|
+
...["global", "if", "import", "in", "is", "lambda", "nonlocal", "not", "or", "pass"],
|
|
1436
|
+
...["raise", "return", "try", "while", "with", "yield"]
|
|
1437
|
+
])
|
|
1438
|
+
],
|
|
1439
|
+
[
|
|
1440
|
+
"Ruby",
|
|
1441
|
+
/* @__PURE__ */ new Set([
|
|
1442
|
+
...["alias", "and", "begin", "break", "case", "class", "def", "do", "else", "elsif"],
|
|
1443
|
+
...["end", "ensure", "false", "for", "if", "in", "module", "next", "nil", "not", "or"],
|
|
1444
|
+
...["redo", "rescue", "retry", "return", "self", "super", "then", "true", "undef"],
|
|
1445
|
+
...["unless", "until", "when", "while", "yield"]
|
|
1446
|
+
])
|
|
1447
|
+
]
|
|
1448
|
+
];
|
|
882
1449
|
function sdkOperationName(operationId) {
|
|
883
1450
|
const parts = operationId.split(".");
|
|
884
1451
|
const method = parts.pop();
|
|
885
1452
|
if (!method || parts.length === 0) {
|
|
886
1453
|
throw new Error(`Operation ID must use resource.method form: ${operationId}`);
|
|
887
1454
|
}
|
|
1455
|
+
for (const segment of [...parts, method]) {
|
|
1456
|
+
const collisions = RESERVED_SDK_SEGMENTS.filter(([, words]) => words.has(segment)).map(
|
|
1457
|
+
([language]) => language
|
|
1458
|
+
);
|
|
1459
|
+
if (collisions.length > 0) {
|
|
1460
|
+
throw new Error(
|
|
1461
|
+
`Operation "${operationId}" cannot use "${segment}" as an SDK name segment: it is a reserved word in ${collisions.join(" and ")}, so SDK generators would rename or reject it. Pick a compound name instead (e.g. importFrom rather than import).`
|
|
1462
|
+
);
|
|
1463
|
+
}
|
|
1464
|
+
}
|
|
888
1465
|
return { groups: parts, method };
|
|
889
1466
|
}
|
|
890
1467
|
function headerParameters(op) {
|
|
@@ -978,11 +1555,50 @@ function registerSchema(schemas, name, schema) {
|
|
|
978
1555
|
const referenced = zodToJsonSchema(schema, {
|
|
979
1556
|
target: "openApi3",
|
|
980
1557
|
$refStrategy: "root",
|
|
981
|
-
basePath: ["#", ...componentPath]
|
|
1558
|
+
basePath: ["#", ...componentPath],
|
|
1559
|
+
override: (definition) => {
|
|
1560
|
+
const sharedName = SHARED_COMPONENT_BY_DEFINITION.get(definition);
|
|
1561
|
+
if (!sharedName || sharedName === name) return ignoreOverride;
|
|
1562
|
+
return { $ref: `#/components/schemas/${sharedName}` };
|
|
1563
|
+
}
|
|
982
1564
|
});
|
|
983
|
-
|
|
1565
|
+
const canonical = collapseSharedReferenceAliases(referenced, referenced, componentPath);
|
|
1566
|
+
schemas[name] = breakAncestorReferences(canonical, componentPath);
|
|
984
1567
|
return { $ref: `#/components/schemas/${name}` };
|
|
985
1568
|
}
|
|
1569
|
+
function collapseSharedReferenceAliases(value, component, componentPath) {
|
|
1570
|
+
if (Array.isArray(value)) {
|
|
1571
|
+
return value.map((child) => collapseSharedReferenceAliases(child, component, componentPath));
|
|
1572
|
+
}
|
|
1573
|
+
if (!value || typeof value !== "object") return value;
|
|
1574
|
+
const record = value;
|
|
1575
|
+
if (Object.keys(record).length === 1 && typeof record.$ref === "string") {
|
|
1576
|
+
const target = resolveComponentReference(component, record.$ref, componentPath);
|
|
1577
|
+
if (target && typeof target === "object" && !Array.isArray(target)) {
|
|
1578
|
+
const targetRecord = target;
|
|
1579
|
+
if (Object.keys(targetRecord).length === 1 && typeof targetRecord.$ref === "string" && SHARED_COMPONENT_REFS.has(targetRecord.$ref)) {
|
|
1580
|
+
return { $ref: targetRecord.$ref };
|
|
1581
|
+
}
|
|
1582
|
+
}
|
|
1583
|
+
}
|
|
1584
|
+
return Object.fromEntries(
|
|
1585
|
+
Object.entries(record).map(([key, child]) => [
|
|
1586
|
+
key,
|
|
1587
|
+
collapseSharedReferenceAliases(child, component, componentPath)
|
|
1588
|
+
])
|
|
1589
|
+
);
|
|
1590
|
+
}
|
|
1591
|
+
function resolveComponentReference(component, reference, componentPath) {
|
|
1592
|
+
if (!reference.startsWith("#/")) return void 0;
|
|
1593
|
+
const target = reference.slice(2).split("/").map((segment) => segment.replaceAll("~1", "/").replaceAll("~0", "~"));
|
|
1594
|
+
if (target.length < componentPath.length || !componentPath.every((segment, index) => target[index] === segment)) {
|
|
1595
|
+
return void 0;
|
|
1596
|
+
}
|
|
1597
|
+
return target.slice(componentPath.length).reduce((current, segment) => {
|
|
1598
|
+
if (!current || typeof current !== "object") return void 0;
|
|
1599
|
+
return current[segment];
|
|
1600
|
+
}, component);
|
|
1601
|
+
}
|
|
986
1602
|
function breakAncestorReferences(value, path) {
|
|
987
1603
|
if (Array.isArray(value)) {
|
|
988
1604
|
return value.map((child, index) => breakAncestorReferences(child, [...path, String(index)]));
|
|
@@ -1024,6 +1640,7 @@ function sortKeys(obj) {
|
|
|
1024
1640
|
return Object.fromEntries(Object.entries(obj).sort(([a], [b]) => a.localeCompare(b)));
|
|
1025
1641
|
}
|
|
1026
1642
|
export {
|
|
1027
|
-
buildAdminOpenApiDocument
|
|
1643
|
+
buildAdminOpenApiDocument,
|
|
1644
|
+
sdkOperationName
|
|
1028
1645
|
};
|
|
1029
1646
|
//# sourceMappingURL=openapi.js.map
|