@embedpdf/engine-core 3.0.0-next.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/LICENSE +192 -0
  2. package/README.md +24 -0
  3. package/dist/AbortError-ByBflvEl.cjs +38 -0
  4. package/dist/AbortError-ByBflvEl.cjs.map +1 -0
  5. package/dist/AbortError-CjSasIlL.js +27 -0
  6. package/dist/AbortError-CjSasIlL.js.map +1 -0
  7. package/dist/AnnotationListSnapshot-W0RCsyDE.d.cts +5043 -0
  8. package/dist/AnnotationListSnapshot-W0RCsyDE.d.ts +5043 -0
  9. package/dist/DocumentSecurityService-B-tULKNY.d.ts +332 -0
  10. package/dist/DocumentSecurityService-Df79fgpe.d.cts +332 -0
  11. package/dist/Engine-B7Oe7f5i.d.ts +1013 -0
  12. package/dist/Engine-D9loFZc1.d.cts +1013 -0
  13. package/dist/builders-BvikWRuO.cjs +1684 -0
  14. package/dist/builders-BvikWRuO.cjs.map +1 -0
  15. package/dist/builders-C548U47M.js +1367 -0
  16. package/dist/builders-C548U47M.js.map +1 -0
  17. package/dist/conformance.cjs +5414 -0
  18. package/dist/conformance.cjs.map +1 -0
  19. package/dist/conformance.d.cts +530 -0
  20. package/dist/conformance.d.ts +530 -0
  21. package/dist/conformance.js +5394 -0
  22. package/dist/conformance.js.map +1 -0
  23. package/dist/fold-CB4fAOOy.js +175 -0
  24. package/dist/fold-CB4fAOOy.js.map +1 -0
  25. package/dist/fold-IaMph3CO.cjs +216 -0
  26. package/dist/fold-IaMph3CO.cjs.map +1 -0
  27. package/dist/index.cjs +82 -0
  28. package/dist/index.d.cts +2 -0
  29. package/dist/index.d.ts +2 -0
  30. package/dist/index.js +5 -0
  31. package/dist/resolver-DAZWVoJL.cjs +434 -0
  32. package/dist/resolver-DAZWVoJL.cjs.map +1 -0
  33. package/dist/resolver-DiPMTfcy.js +363 -0
  34. package/dist/resolver-DiPMTfcy.js.map +1 -0
  35. package/dist/runtime.cjs +453 -0
  36. package/dist/runtime.cjs.map +1 -0
  37. package/dist/runtime.d.cts +1002 -0
  38. package/dist/runtime.d.ts +1002 -0
  39. package/dist/runtime.js +361 -0
  40. package/dist/runtime.js.map +1 -0
  41. package/dist/schemas-9OpSSeM6.js +2493 -0
  42. package/dist/schemas-9OpSSeM6.js.map +1 -0
  43. package/dist/schemas-B_1VyFsm.cjs +3608 -0
  44. package/dist/schemas-B_1VyFsm.cjs.map +1 -0
  45. package/dist/subtype-BvAzLCGC.js +196 -0
  46. package/dist/subtype-BvAzLCGC.js.map +1 -0
  47. package/dist/subtype-qejjVr6h.cjs +231 -0
  48. package/dist/subtype-qejjVr6h.cjs.map +1 -0
  49. package/dist/wire.cjs +1516 -0
  50. package/dist/wire.cjs.map +1 -0
  51. package/dist/wire.d.cts +1546 -0
  52. package/dist/wire.d.ts +1546 -0
  53. package/dist/wire.js +1280 -0
  54. package/dist/wire.js.map +1 -0
  55. package/package.json +74 -0
@@ -0,0 +1,332 @@
1
+ import { Hs as DocCapability, Us as IdentityClaims, Ys as PdfBits } from "./AnnotationListSnapshot-W0RCsyDE.js";
2
+ //#region src/promise/AbortablePromise.d.ts
3
+ type AbortableExecutor<T, P> = (resolve: (value: T | PromiseLike<T>) => void, reject: (reason: unknown) => void, progress: (p: P) => void, signal: AbortSignal) => void;
4
+ /**
5
+ * Awaitable Promise subclass with abort and progress.
6
+ *
7
+ * Symbol.species returns plain Promise so chained .then/.catch/.finally
8
+ * return regular promises and never try to synthesize a new
9
+ * AbortablePromise (which would have no executor).
10
+ *
11
+ * Settlement contract:
12
+ * - The first settlement wins. resolve/reject handed to the executor
13
+ * are wrapped so that any subsequent call (whether by the executor,
14
+ * by abort(), or by both racing) becomes a silent no-op.
15
+ * - abort() rejects the public promise with AbortError immediately,
16
+ * even if the executor never observes the AbortSignal. The executor
17
+ * still receives the AbortSignal so it can stop real work
18
+ * cooperatively (release a queue slot, abort fetch, post a worker
19
+ * abort, etc.). Anything the executor does after that — including
20
+ * a late resolve(value), a late reject(error), or a rejected inner
21
+ * Promise inside AbortablePromise.run — is dropped silently.
22
+ * - abort() after settlement is a no-op.
23
+ */
24
+ declare class AbortablePromise<T, P = never> extends Promise<T> {
25
+ static get [Symbol.species](): PromiseConstructor;
26
+ readonly signal: AbortSignal;
27
+ private readonly _ctrl;
28
+ private readonly _progressCbs;
29
+ private readonly _state;
30
+ private readonly _internalReject;
31
+ constructor(executor: AbortableExecutor<T, P>);
32
+ /**
33
+ * Abort the underlying operation.
34
+ *
35
+ * - If the promise has already settled, this is a no-op.
36
+ * - Otherwise the public promise rejects synchronously with an
37
+ * AbortError (wrapping the supplied reason if it is not already an
38
+ * AbortError) and the AbortSignal fires for any cooperative
39
+ * cancellation the executor wired up.
40
+ */
41
+ abort(reason?: unknown): void;
42
+ /**
43
+ * Subscribe to progress events. Returns an unsubscribe function.
44
+ */
45
+ onProgress(cb: (p: P) => void): () => void;
46
+ /**
47
+ * Wrap a value in an already-resolved AbortablePromise. Mirrors Promise.resolve.
48
+ */
49
+ static resolveValue<T>(value: T | PromiseLike<T>): AbortablePromise<T>;
50
+ /**
51
+ * Wrap a thrown reason in an already-rejected AbortablePromise.
52
+ */
53
+ static rejectReason<T = never>(reason: unknown): AbortablePromise<T>;
54
+ /**
55
+ * Run an async function as an AbortablePromise so callers get .abort() and .signal.
56
+ * The async function receives the AbortSignal (and a progress emitter) so it can
57
+ * cooperate with the abort.
58
+ *
59
+ * If abort() fires while the inner async function is still running, the
60
+ * public promise rejects with AbortError immediately. The inner async
61
+ * function's eventual settlement (resolve or reject) is funneled through
62
+ * the wrapped settlers and silently dropped — including a late rejection
63
+ * from the underlying work, which prevents an UnhandledRejection because
64
+ * the .then(resolve, reject) below "handles" it via the no-op.
65
+ */
66
+ static run<T, P = never>(fn: (signal: AbortSignal, progress: (p: P) => void) => Promise<T>): AbortablePromise<T, P>;
67
+ }
68
+ //#endregion
69
+ //#region src/engine/passwordPrompt.d.ts
70
+ type PasswordPrompt = {
71
+ readonly state: 'none';
72
+ } | {
73
+ readonly state: 'required';
74
+ readonly hint: 'user' | 'owner' | null;
75
+ } | {
76
+ readonly state: 'optional';
77
+ readonly hint: 'owner';
78
+ };
79
+ /**
80
+ * Derive the high-level password prompt from the raw security state.
81
+ *
82
+ * The function is pure and total — every `DocumentSecurityState`
83
+ * maps to exactly one `PasswordPrompt`. Use this as the SINGLE source
84
+ * of truth wherever the SDK exposes a "do you need a password?" flag:
85
+ * both `LocalDocumentSecurityService` and `CloudDocumentSecurityService`
86
+ * call it, so the contract can never drift.
87
+ *
88
+ * Mapping rules (top to bottom; first match wins):
89
+ *
90
+ * 1. encryption.state === 'none'
91
+ * → { state: 'none' } the document isn't encrypted
92
+ *
93
+ * 2. !permissions.known
94
+ * → { state: 'required', hint: null } we haven't probed yet; can't
95
+ * tell user-vs-owner; show
96
+ * generic prompt
97
+ *
98
+ * 3. requiresPassword && openedAs === 'none'
99
+ * → { state: 'required', hint: 'user' } encrypted, anonymous open
100
+ * failed → user pwd needed
101
+ *
102
+ * 4. openedAs === 'owner'
103
+ * → { state: 'none' } already at the top — nothing more
104
+ * to unlock
105
+ *
106
+ * 5. permissions.canUpgradeToOwner === true
107
+ * → { state: 'optional', hint: 'owner' } open as user (or as none
108
+ * for owner-pwd-only docs)
109
+ * but more is available
110
+ *
111
+ * 6. fallthrough → { state: 'none' } open and nothing more available
112
+ */
113
+ declare function passwordPromptFromState(state: DocumentSecurityState): PasswordPrompt;
114
+ //#endregion
115
+ //#region src/engine/DocumentSecurityService.d.ts
116
+ type DocumentOpenMode = 'none' | 'user' | 'owner';
117
+ type DocumentEncryptionState = 'unknown' | 'none' | 'encrypted' | 'unsupported';
118
+ type DocumentAccessReason = 'password' | 'cdn' | 'permissions-unknown';
119
+ /**
120
+ * Boolean view of "what the PDF's permission bits allow," surfaced for
121
+ * client UI badges ("this PDF disallows printing", "copy is blocked",
122
+ * etc.). Names mirror the user-facing capability they correspond to,
123
+ * not the raw bit names — so docs can render "Print: disabled" without
124
+ * the reader needing to know PDF bit positions.
125
+ *
126
+ * Computed from {@link PdfBits} via the strict ISO 32000 rules:
127
+ * bit 12 only meaningful when bit 3 is also set
128
+ * form modification requires both bit 6 AND bit 4
129
+ * form fill is satisfied by bit 6 OR bit 9
130
+ */
131
+ interface PdfPermissionAdvisory {
132
+ readonly canPrint: boolean;
133
+ readonly canPrintHigh: boolean;
134
+ readonly canCopy: boolean;
135
+ readonly canAnnotate: boolean;
136
+ readonly canFillForms: boolean;
137
+ readonly canModifyForms: boolean;
138
+ readonly canModifyPages: boolean;
139
+ readonly canAssemble: boolean;
140
+ }
141
+ interface PdfPermissionInfo {
142
+ readonly known: boolean;
143
+ readonly allAllowed: boolean | null;
144
+ readonly bits: number | null;
145
+ readonly openedAs: DocumentOpenMode | null;
146
+ readonly securityHandlerRevision: number | null;
147
+ /**
148
+ * Typed boolean view of `bits`. Present whenever the caller had
149
+ * access to the document's PDF bits at construction time (always
150
+ * true in the /access response; not always populated by the cheaper
151
+ * /head shape).
152
+ */
153
+ readonly flags?: PdfBits;
154
+ /**
155
+ * Capability-shaped "what does this PDF natively allow" view for UI
156
+ * badges. Same population rule as `flags`.
157
+ */
158
+ readonly advisory?: PdfPermissionAdvisory;
159
+ }
160
+ interface DocumentSecurityState {
161
+ readonly encryption: {
162
+ readonly state: DocumentEncryptionState;
163
+ readonly requiresPassword: boolean | null;
164
+ };
165
+ readonly permissions: {
166
+ readonly known: boolean;
167
+ readonly bits: number | null;
168
+ readonly allAllowed: boolean | null;
169
+ readonly openedAs: DocumentOpenMode | null;
170
+ readonly securityHandlerRevision: number | null;
171
+ readonly canUpgradeToOwner: boolean;
172
+ };
173
+ readonly access: {
174
+ readonly required: boolean;
175
+ readonly reasons: DocumentAccessReason[];
176
+ readonly endpoint?: string;
177
+ };
178
+ }
179
+ /**
180
+ * The CDN adapter identifier surfaced on the wire. Cloudflare users
181
+ * deploy a custom Worker that verifies HMAC-SHA256 signatures and
182
+ * configure the `custom-hmac` adapter — no first-class `'cloudflare'`
183
+ * value is needed.
184
+ */
185
+ type CdnAdapter = 'none' | 'cloudfront' | 'cloud-cdn' | 'bunny' | 'azure-fd' | 'custom-hmac';
186
+ /**
187
+ * Per-caller CDN access bits returned in the /access response. The
188
+ * SDK fetch wrapper applies whatever channels are populated:
189
+ * - baseUrlOverrides : swap the origin host/path-prefix for the CDN URL
190
+ * - authHeader : attach a single header to every CDN request
191
+ * - signedQueryParams : append params to every CDN URL (single-token signers)
192
+ * - signedCookies : set cookies on the CDN origin before requests
193
+ * - signedPathPolicies : per-prefix params (one signature covers a path subtree)
194
+ *
195
+ * Each adapter populates only the channels it uses; the others stay
196
+ * null. Frontend stays provider-agnostic — it doesn't branch on
197
+ * `adapter`, it just applies whatever's present.
198
+ */
199
+ interface CdnAccessInfo {
200
+ readonly adapter: CdnAdapter;
201
+ readonly expiresAt: number;
202
+ readonly cache: {
203
+ readonly scope: 'browser-private' | 'edge-shared';
204
+ readonly immutableVersionedReads: boolean;
205
+ };
206
+ readonly baseUrlOverrides: Partial<Record<string, string>> | null;
207
+ readonly authHeader: {
208
+ name: string;
209
+ value: string;
210
+ } | null;
211
+ readonly signedQueryParams: Record<string, string> | null;
212
+ readonly signedCookies: ReadonlyArray<{
213
+ readonly name: string;
214
+ readonly value: string;
215
+ readonly domain?: string;
216
+ readonly path?: string;
217
+ readonly expires?: number;
218
+ }> | null;
219
+ readonly signedPathPolicies: ReadonlyArray<{
220
+ readonly pathPrefix: string;
221
+ readonly queryParams: Record<string, string>;
222
+ }> | null;
223
+ }
224
+ interface DocumentAccessInfo {
225
+ readonly cdn: CdnAccessInfo;
226
+ readonly passwordGrant: string | null;
227
+ readonly pdfPermissions: PdfPermissionInfo | null;
228
+ /**
229
+ * Raw scope array exactly as the JWT carried it. Useful for debugging
230
+ * and for clients that want to display the literal grants.
231
+ */
232
+ readonly scope: string[];
233
+ /**
234
+ * Concrete capability set granted to this caller, after expanding
235
+ * `pdf.permissions` against the document's PDF bits and applying
236
+ * the implication rules in the resolver (e.g. annotation collab
237
+ * scopes imply `doc.annotate.read`). Client UI should drive feature
238
+ * visibility off this, not off the raw `scope`.
239
+ *
240
+ * Sorted alphabetically for stable display.
241
+ */
242
+ readonly effectiveScope: string[];
243
+ readonly identity: {
244
+ readonly user_id?: string;
245
+ readonly group_id?: string;
246
+ readonly groups?: string[];
247
+ readonly display_name?: string;
248
+ };
249
+ readonly originPasswordPolicy: {
250
+ readonly mode: 'not-needed' | 'client-retry' | 'server-session';
251
+ };
252
+ readonly expiresAt: number;
253
+ /**
254
+ * The deployment's render lattice: canonical full-page
255
+ * `viewport.width` points whose renders are durable, CDN-shared
256
+ * artifacts, plus the reserved tile-pyramid block. Local engines report
257
+ * nothing here (continuous rendering); cloud engines surface it so
258
+ * `snapFullPageViewport` can conform requests EXPLICITLY — the SDK
259
+ * never snaps implicitly (engine parity).
260
+ */
261
+ readonly renderPolicy?: {
262
+ readonly fullPage: {
263
+ readonly widths: readonly number[];
264
+ };
265
+ readonly tiles?: {
266
+ readonly tileSizes: readonly number[];
267
+ readonly scales: readonly number[];
268
+ };
269
+ readonly appearances?: {
270
+ readonly scales: readonly number[];
271
+ };
272
+ readonly maxRenderPixels?: number;
273
+ readonly formats: readonly ('webp' | 'png')[];
274
+ readonly background: 'white';
275
+ readonly enforced: boolean;
276
+ };
277
+ }
278
+ interface DocumentUnlockInput {
279
+ readonly password: string;
280
+ readonly mode?: 'any' | 'owner';
281
+ }
282
+ interface DocumentUnlockResult {
283
+ readonly security: DocumentSecurityState;
284
+ readonly access?: DocumentAccessInfo;
285
+ }
286
+ interface DocumentSecurityService {
287
+ /**
288
+ * Raw structured security probe. Stable across engines, refreshed
289
+ * after unlock/refresh. Power users and diagnostic tools read this;
290
+ * most dev code uses the higher-level accessors below.
291
+ */
292
+ readonly current: DocumentSecurityState;
293
+ /**
294
+ * The caller's expanded capability set — raw scope + pdf bits +
295
+ * implication rules, enumerated for DISPLAY ("here's what you can
296
+ * do"). Identical shape on local and cloud; cloud uses the
297
+ * server-canonical value when available, else computes locally from
298
+ * JWT scope + /head bits.
299
+ *
300
+ * NOTE: this is an *enumeration*, not an authorization check. The `*`
301
+ * admin wildcard and unbounded parametric collab grants are NOT
302
+ * listed here (they can't be). To gate UI, use {@link allows} — the
303
+ * same wildcard-aware predicate the engine enforces with.
304
+ */
305
+ readonly effectiveScope: ReadonlyArray<string>;
306
+ /**
307
+ * Wildcard-aware authorization check — the SAME predicate the engine
308
+ * enforces with (`checkCapability`). A shown control gated on this
309
+ * mirrors exactly what the engine will allow: the `*` admin grant and
310
+ * `pdf.permissions`-derived bits are both honored. Use this for edit
311
+ * gating (e.g. `allows('doc.pages.assemble')`); use `effectiveScope`
312
+ * only to *display* the concrete grants.
313
+ */
314
+ allows(capability: DocCapability): boolean;
315
+ /**
316
+ * Identity of the current caller, or null when anonymous.
317
+ */
318
+ readonly identity: IdentityClaims | null;
319
+ /**
320
+ * "Should I prompt the user for a password?" — the single source
321
+ * of truth. Three states, each carrying exactly the data needed:
322
+ * - `none` — do nothing
323
+ * - `required` — hard block; show modal; `hint` labels the prompt
324
+ * - `optional` — soft offer; show banner; only ever asks for owner
325
+ * See {@link PasswordPrompt} for the full contract.
326
+ */
327
+ readonly passwordPrompt: PasswordPrompt;
328
+ unlock(input: DocumentUnlockInput): AbortablePromise<DocumentUnlockResult>;
329
+ }
330
+ //#endregion
331
+ export { DocumentEncryptionState as a, DocumentSecurityState as c, PdfPermissionAdvisory as d, PdfPermissionInfo as f, AbortablePromise as g, AbortableExecutor as h, DocumentAccessReason as i, DocumentUnlockInput as l, passwordPromptFromState as m, CdnAdapter as n, DocumentOpenMode as o, PasswordPrompt as p, DocumentAccessInfo as r, DocumentSecurityService as s, CdnAccessInfo as t, DocumentUnlockResult as u };
332
+ //# sourceMappingURL=DocumentSecurityService-B-tULKNY.d.ts.map
@@ -0,0 +1,332 @@
1
+ import { Hs as DocCapability, Us as IdentityClaims, Ys as PdfBits } from "./AnnotationListSnapshot-W0RCsyDE.cjs";
2
+ //#region src/promise/AbortablePromise.d.ts
3
+ type AbortableExecutor<T, P> = (resolve: (value: T | PromiseLike<T>) => void, reject: (reason: unknown) => void, progress: (p: P) => void, signal: AbortSignal) => void;
4
+ /**
5
+ * Awaitable Promise subclass with abort and progress.
6
+ *
7
+ * Symbol.species returns plain Promise so chained .then/.catch/.finally
8
+ * return regular promises and never try to synthesize a new
9
+ * AbortablePromise (which would have no executor).
10
+ *
11
+ * Settlement contract:
12
+ * - The first settlement wins. resolve/reject handed to the executor
13
+ * are wrapped so that any subsequent call (whether by the executor,
14
+ * by abort(), or by both racing) becomes a silent no-op.
15
+ * - abort() rejects the public promise with AbortError immediately,
16
+ * even if the executor never observes the AbortSignal. The executor
17
+ * still receives the AbortSignal so it can stop real work
18
+ * cooperatively (release a queue slot, abort fetch, post a worker
19
+ * abort, etc.). Anything the executor does after that — including
20
+ * a late resolve(value), a late reject(error), or a rejected inner
21
+ * Promise inside AbortablePromise.run — is dropped silently.
22
+ * - abort() after settlement is a no-op.
23
+ */
24
+ declare class AbortablePromise<T, P = never> extends Promise<T> {
25
+ static get [Symbol.species](): PromiseConstructor;
26
+ readonly signal: AbortSignal;
27
+ private readonly _ctrl;
28
+ private readonly _progressCbs;
29
+ private readonly _state;
30
+ private readonly _internalReject;
31
+ constructor(executor: AbortableExecutor<T, P>);
32
+ /**
33
+ * Abort the underlying operation.
34
+ *
35
+ * - If the promise has already settled, this is a no-op.
36
+ * - Otherwise the public promise rejects synchronously with an
37
+ * AbortError (wrapping the supplied reason if it is not already an
38
+ * AbortError) and the AbortSignal fires for any cooperative
39
+ * cancellation the executor wired up.
40
+ */
41
+ abort(reason?: unknown): void;
42
+ /**
43
+ * Subscribe to progress events. Returns an unsubscribe function.
44
+ */
45
+ onProgress(cb: (p: P) => void): () => void;
46
+ /**
47
+ * Wrap a value in an already-resolved AbortablePromise. Mirrors Promise.resolve.
48
+ */
49
+ static resolveValue<T>(value: T | PromiseLike<T>): AbortablePromise<T>;
50
+ /**
51
+ * Wrap a thrown reason in an already-rejected AbortablePromise.
52
+ */
53
+ static rejectReason<T = never>(reason: unknown): AbortablePromise<T>;
54
+ /**
55
+ * Run an async function as an AbortablePromise so callers get .abort() and .signal.
56
+ * The async function receives the AbortSignal (and a progress emitter) so it can
57
+ * cooperate with the abort.
58
+ *
59
+ * If abort() fires while the inner async function is still running, the
60
+ * public promise rejects with AbortError immediately. The inner async
61
+ * function's eventual settlement (resolve or reject) is funneled through
62
+ * the wrapped settlers and silently dropped — including a late rejection
63
+ * from the underlying work, which prevents an UnhandledRejection because
64
+ * the .then(resolve, reject) below "handles" it via the no-op.
65
+ */
66
+ static run<T, P = never>(fn: (signal: AbortSignal, progress: (p: P) => void) => Promise<T>): AbortablePromise<T, P>;
67
+ }
68
+ //#endregion
69
+ //#region src/engine/passwordPrompt.d.ts
70
+ type PasswordPrompt = {
71
+ readonly state: 'none';
72
+ } | {
73
+ readonly state: 'required';
74
+ readonly hint: 'user' | 'owner' | null;
75
+ } | {
76
+ readonly state: 'optional';
77
+ readonly hint: 'owner';
78
+ };
79
+ /**
80
+ * Derive the high-level password prompt from the raw security state.
81
+ *
82
+ * The function is pure and total — every `DocumentSecurityState`
83
+ * maps to exactly one `PasswordPrompt`. Use this as the SINGLE source
84
+ * of truth wherever the SDK exposes a "do you need a password?" flag:
85
+ * both `LocalDocumentSecurityService` and `CloudDocumentSecurityService`
86
+ * call it, so the contract can never drift.
87
+ *
88
+ * Mapping rules (top to bottom; first match wins):
89
+ *
90
+ * 1. encryption.state === 'none'
91
+ * → { state: 'none' } the document isn't encrypted
92
+ *
93
+ * 2. !permissions.known
94
+ * → { state: 'required', hint: null } we haven't probed yet; can't
95
+ * tell user-vs-owner; show
96
+ * generic prompt
97
+ *
98
+ * 3. requiresPassword && openedAs === 'none'
99
+ * → { state: 'required', hint: 'user' } encrypted, anonymous open
100
+ * failed → user pwd needed
101
+ *
102
+ * 4. openedAs === 'owner'
103
+ * → { state: 'none' } already at the top — nothing more
104
+ * to unlock
105
+ *
106
+ * 5. permissions.canUpgradeToOwner === true
107
+ * → { state: 'optional', hint: 'owner' } open as user (or as none
108
+ * for owner-pwd-only docs)
109
+ * but more is available
110
+ *
111
+ * 6. fallthrough → { state: 'none' } open and nothing more available
112
+ */
113
+ declare function passwordPromptFromState(state: DocumentSecurityState): PasswordPrompt;
114
+ //#endregion
115
+ //#region src/engine/DocumentSecurityService.d.ts
116
+ type DocumentOpenMode = 'none' | 'user' | 'owner';
117
+ type DocumentEncryptionState = 'unknown' | 'none' | 'encrypted' | 'unsupported';
118
+ type DocumentAccessReason = 'password' | 'cdn' | 'permissions-unknown';
119
+ /**
120
+ * Boolean view of "what the PDF's permission bits allow," surfaced for
121
+ * client UI badges ("this PDF disallows printing", "copy is blocked",
122
+ * etc.). Names mirror the user-facing capability they correspond to,
123
+ * not the raw bit names — so docs can render "Print: disabled" without
124
+ * the reader needing to know PDF bit positions.
125
+ *
126
+ * Computed from {@link PdfBits} via the strict ISO 32000 rules:
127
+ * bit 12 only meaningful when bit 3 is also set
128
+ * form modification requires both bit 6 AND bit 4
129
+ * form fill is satisfied by bit 6 OR bit 9
130
+ */
131
+ interface PdfPermissionAdvisory {
132
+ readonly canPrint: boolean;
133
+ readonly canPrintHigh: boolean;
134
+ readonly canCopy: boolean;
135
+ readonly canAnnotate: boolean;
136
+ readonly canFillForms: boolean;
137
+ readonly canModifyForms: boolean;
138
+ readonly canModifyPages: boolean;
139
+ readonly canAssemble: boolean;
140
+ }
141
+ interface PdfPermissionInfo {
142
+ readonly known: boolean;
143
+ readonly allAllowed: boolean | null;
144
+ readonly bits: number | null;
145
+ readonly openedAs: DocumentOpenMode | null;
146
+ readonly securityHandlerRevision: number | null;
147
+ /**
148
+ * Typed boolean view of `bits`. Present whenever the caller had
149
+ * access to the document's PDF bits at construction time (always
150
+ * true in the /access response; not always populated by the cheaper
151
+ * /head shape).
152
+ */
153
+ readonly flags?: PdfBits;
154
+ /**
155
+ * Capability-shaped "what does this PDF natively allow" view for UI
156
+ * badges. Same population rule as `flags`.
157
+ */
158
+ readonly advisory?: PdfPermissionAdvisory;
159
+ }
160
+ interface DocumentSecurityState {
161
+ readonly encryption: {
162
+ readonly state: DocumentEncryptionState;
163
+ readonly requiresPassword: boolean | null;
164
+ };
165
+ readonly permissions: {
166
+ readonly known: boolean;
167
+ readonly bits: number | null;
168
+ readonly allAllowed: boolean | null;
169
+ readonly openedAs: DocumentOpenMode | null;
170
+ readonly securityHandlerRevision: number | null;
171
+ readonly canUpgradeToOwner: boolean;
172
+ };
173
+ readonly access: {
174
+ readonly required: boolean;
175
+ readonly reasons: DocumentAccessReason[];
176
+ readonly endpoint?: string;
177
+ };
178
+ }
179
+ /**
180
+ * The CDN adapter identifier surfaced on the wire. Cloudflare users
181
+ * deploy a custom Worker that verifies HMAC-SHA256 signatures and
182
+ * configure the `custom-hmac` adapter — no first-class `'cloudflare'`
183
+ * value is needed.
184
+ */
185
+ type CdnAdapter = 'none' | 'cloudfront' | 'cloud-cdn' | 'bunny' | 'azure-fd' | 'custom-hmac';
186
+ /**
187
+ * Per-caller CDN access bits returned in the /access response. The
188
+ * SDK fetch wrapper applies whatever channels are populated:
189
+ * - baseUrlOverrides : swap the origin host/path-prefix for the CDN URL
190
+ * - authHeader : attach a single header to every CDN request
191
+ * - signedQueryParams : append params to every CDN URL (single-token signers)
192
+ * - signedCookies : set cookies on the CDN origin before requests
193
+ * - signedPathPolicies : per-prefix params (one signature covers a path subtree)
194
+ *
195
+ * Each adapter populates only the channels it uses; the others stay
196
+ * null. Frontend stays provider-agnostic — it doesn't branch on
197
+ * `adapter`, it just applies whatever's present.
198
+ */
199
+ interface CdnAccessInfo {
200
+ readonly adapter: CdnAdapter;
201
+ readonly expiresAt: number;
202
+ readonly cache: {
203
+ readonly scope: 'browser-private' | 'edge-shared';
204
+ readonly immutableVersionedReads: boolean;
205
+ };
206
+ readonly baseUrlOverrides: Partial<Record<string, string>> | null;
207
+ readonly authHeader: {
208
+ name: string;
209
+ value: string;
210
+ } | null;
211
+ readonly signedQueryParams: Record<string, string> | null;
212
+ readonly signedCookies: ReadonlyArray<{
213
+ readonly name: string;
214
+ readonly value: string;
215
+ readonly domain?: string;
216
+ readonly path?: string;
217
+ readonly expires?: number;
218
+ }> | null;
219
+ readonly signedPathPolicies: ReadonlyArray<{
220
+ readonly pathPrefix: string;
221
+ readonly queryParams: Record<string, string>;
222
+ }> | null;
223
+ }
224
+ interface DocumentAccessInfo {
225
+ readonly cdn: CdnAccessInfo;
226
+ readonly passwordGrant: string | null;
227
+ readonly pdfPermissions: PdfPermissionInfo | null;
228
+ /**
229
+ * Raw scope array exactly as the JWT carried it. Useful for debugging
230
+ * and for clients that want to display the literal grants.
231
+ */
232
+ readonly scope: string[];
233
+ /**
234
+ * Concrete capability set granted to this caller, after expanding
235
+ * `pdf.permissions` against the document's PDF bits and applying
236
+ * the implication rules in the resolver (e.g. annotation collab
237
+ * scopes imply `doc.annotate.read`). Client UI should drive feature
238
+ * visibility off this, not off the raw `scope`.
239
+ *
240
+ * Sorted alphabetically for stable display.
241
+ */
242
+ readonly effectiveScope: string[];
243
+ readonly identity: {
244
+ readonly user_id?: string;
245
+ readonly group_id?: string;
246
+ readonly groups?: string[];
247
+ readonly display_name?: string;
248
+ };
249
+ readonly originPasswordPolicy: {
250
+ readonly mode: 'not-needed' | 'client-retry' | 'server-session';
251
+ };
252
+ readonly expiresAt: number;
253
+ /**
254
+ * The deployment's render lattice: canonical full-page
255
+ * `viewport.width` points whose renders are durable, CDN-shared
256
+ * artifacts, plus the reserved tile-pyramid block. Local engines report
257
+ * nothing here (continuous rendering); cloud engines surface it so
258
+ * `snapFullPageViewport` can conform requests EXPLICITLY — the SDK
259
+ * never snaps implicitly (engine parity).
260
+ */
261
+ readonly renderPolicy?: {
262
+ readonly fullPage: {
263
+ readonly widths: readonly number[];
264
+ };
265
+ readonly tiles?: {
266
+ readonly tileSizes: readonly number[];
267
+ readonly scales: readonly number[];
268
+ };
269
+ readonly appearances?: {
270
+ readonly scales: readonly number[];
271
+ };
272
+ readonly maxRenderPixels?: number;
273
+ readonly formats: readonly ('webp' | 'png')[];
274
+ readonly background: 'white';
275
+ readonly enforced: boolean;
276
+ };
277
+ }
278
+ interface DocumentUnlockInput {
279
+ readonly password: string;
280
+ readonly mode?: 'any' | 'owner';
281
+ }
282
+ interface DocumentUnlockResult {
283
+ readonly security: DocumentSecurityState;
284
+ readonly access?: DocumentAccessInfo;
285
+ }
286
+ interface DocumentSecurityService {
287
+ /**
288
+ * Raw structured security probe. Stable across engines, refreshed
289
+ * after unlock/refresh. Power users and diagnostic tools read this;
290
+ * most dev code uses the higher-level accessors below.
291
+ */
292
+ readonly current: DocumentSecurityState;
293
+ /**
294
+ * The caller's expanded capability set — raw scope + pdf bits +
295
+ * implication rules, enumerated for DISPLAY ("here's what you can
296
+ * do"). Identical shape on local and cloud; cloud uses the
297
+ * server-canonical value when available, else computes locally from
298
+ * JWT scope + /head bits.
299
+ *
300
+ * NOTE: this is an *enumeration*, not an authorization check. The `*`
301
+ * admin wildcard and unbounded parametric collab grants are NOT
302
+ * listed here (they can't be). To gate UI, use {@link allows} — the
303
+ * same wildcard-aware predicate the engine enforces with.
304
+ */
305
+ readonly effectiveScope: ReadonlyArray<string>;
306
+ /**
307
+ * Wildcard-aware authorization check — the SAME predicate the engine
308
+ * enforces with (`checkCapability`). A shown control gated on this
309
+ * mirrors exactly what the engine will allow: the `*` admin grant and
310
+ * `pdf.permissions`-derived bits are both honored. Use this for edit
311
+ * gating (e.g. `allows('doc.pages.assemble')`); use `effectiveScope`
312
+ * only to *display* the concrete grants.
313
+ */
314
+ allows(capability: DocCapability): boolean;
315
+ /**
316
+ * Identity of the current caller, or null when anonymous.
317
+ */
318
+ readonly identity: IdentityClaims | null;
319
+ /**
320
+ * "Should I prompt the user for a password?" — the single source
321
+ * of truth. Three states, each carrying exactly the data needed:
322
+ * - `none` — do nothing
323
+ * - `required` — hard block; show modal; `hint` labels the prompt
324
+ * - `optional` — soft offer; show banner; only ever asks for owner
325
+ * See {@link PasswordPrompt} for the full contract.
326
+ */
327
+ readonly passwordPrompt: PasswordPrompt;
328
+ unlock(input: DocumentUnlockInput): AbortablePromise<DocumentUnlockResult>;
329
+ }
330
+ //#endregion
331
+ export { DocumentEncryptionState as a, DocumentSecurityState as c, PdfPermissionAdvisory as d, PdfPermissionInfo as f, AbortablePromise as g, AbortableExecutor as h, DocumentAccessReason as i, DocumentUnlockInput as l, passwordPromptFromState as m, CdnAdapter as n, DocumentOpenMode as o, PasswordPrompt as p, DocumentAccessInfo as r, DocumentSecurityService as s, CdnAccessInfo as t, DocumentUnlockResult as u };
332
+ //# sourceMappingURL=DocumentSecurityService-Df79fgpe.d.cts.map