okrapdf 0.8.0 → 0.9.1
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/dist/browser.d.ts +1 -1
- package/dist/browser.js +1 -1
- package/dist/{chunk-HITG34US.js → chunk-4RJBVZJL.js} +52 -93
- package/dist/chunk-4RJBVZJL.js.map +1 -0
- package/dist/{chunk-C6ZT7DKX.js → chunk-5NINKIAC.js} +35 -9
- package/dist/chunk-5NINKIAC.js.map +1 -0
- package/dist/{chunk-AG3A2T3B.js → chunk-FS55NWKZ.js} +2 -2
- package/dist/{chunk-SBT5T6ZK.js → chunk-M52S3LPT.js} +174 -3
- package/dist/chunk-M52S3LPT.js.map +1 -0
- package/dist/chunk-NIZM2ETT.js +27 -0
- package/dist/chunk-NIZM2ETT.js.map +1 -0
- package/dist/cli/bin.js +152 -54
- package/dist/cli/bin.js.map +1 -1
- package/dist/cli/index.d.ts +2 -2
- package/dist/cli/index.js +2 -1
- package/dist/{client-aHzx0a5x.d.ts → client-BWcRvduT.d.ts} +1 -11
- package/dist/index.d.ts +82 -4
- package/dist/index.js +134 -4
- package/dist/index.js.map +1 -1
- package/dist/react/index.d.ts +3 -3
- package/dist/react/index.js +3 -2
- package/dist/react/index.js.map +1 -1
- package/dist/{types-DEYgGUnH.d.ts → types-C7IWrjwl.d.ts} +103 -63
- package/dist/url.d.ts +16 -2
- package/dist/url.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-C6ZT7DKX.js.map +0 -1
- package/dist/chunk-HITG34US.js.map +0 -1
- package/dist/chunk-SBT5T6ZK.js.map +0 -1
- /package/dist/{chunk-AG3A2T3B.js.map → chunk-FS55NWKZ.js.map} +0 -0
package/dist/browser.d.ts
CHANGED
package/dist/browser.js
CHANGED
|
@@ -1,24 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
details;
|
|
6
|
-
constructor(code, message, status = 500, details) {
|
|
7
|
-
super(message);
|
|
8
|
-
this.name = "OkraRuntimeError";
|
|
9
|
-
this.code = code;
|
|
10
|
-
this.status = status;
|
|
11
|
-
this.details = details;
|
|
12
|
-
}
|
|
13
|
-
};
|
|
14
|
-
var StructuredOutputError = class extends OkraRuntimeError {
|
|
15
|
-
code;
|
|
16
|
-
constructor(code, message, status, details) {
|
|
17
|
-
super(code, message, status, details);
|
|
18
|
-
this.name = "StructuredOutputError";
|
|
19
|
-
this.code = code;
|
|
20
|
-
}
|
|
21
|
-
};
|
|
1
|
+
import {
|
|
2
|
+
OkraRuntimeError,
|
|
3
|
+
StructuredOutputError
|
|
4
|
+
} from "./chunk-NIZM2ETT.js";
|
|
22
5
|
|
|
23
6
|
// src/client.ts
|
|
24
7
|
import { z } from "zod";
|
|
@@ -186,7 +169,6 @@ var OkraClient = class {
|
|
|
186
169
|
sharedSecret;
|
|
187
170
|
fetchImpl;
|
|
188
171
|
sessions;
|
|
189
|
-
deployments;
|
|
190
172
|
constructor(options) {
|
|
191
173
|
this.baseUrl = normalizeBaseUrl(options.baseUrl || DEFAULT_BASE_URL);
|
|
192
174
|
this.apiKey = options.apiKey;
|
|
@@ -235,46 +217,6 @@ var OkraClient = class {
|
|
|
235
217
|
);
|
|
236
218
|
}
|
|
237
219
|
};
|
|
238
|
-
this.deployments = {
|
|
239
|
-
create: async (opts) => {
|
|
240
|
-
return this.requestJson("/v1/deployments", {
|
|
241
|
-
method: "POST",
|
|
242
|
-
headers: { "Content-Type": "application/json" },
|
|
243
|
-
body: JSON.stringify(opts)
|
|
244
|
-
});
|
|
245
|
-
},
|
|
246
|
-
status: async (deploymentId) => {
|
|
247
|
-
return this.requestJson(`/d/${deploymentId}/status`, {
|
|
248
|
-
method: "GET"
|
|
249
|
-
});
|
|
250
|
-
},
|
|
251
|
-
completion: async (deploymentId, opts) => {
|
|
252
|
-
return this.requestJson(`/d/${deploymentId}/completion`, {
|
|
253
|
-
method: "POST",
|
|
254
|
-
headers: { "Content-Type": "application/json" },
|
|
255
|
-
body: JSON.stringify(opts)
|
|
256
|
-
});
|
|
257
|
-
},
|
|
258
|
-
tokens: {
|
|
259
|
-
create: async (deploymentId, opts) => {
|
|
260
|
-
return this.requestJson(`/d/${deploymentId}/tokens`, {
|
|
261
|
-
method: "POST",
|
|
262
|
-
headers: { "Content-Type": "application/json" },
|
|
263
|
-
body: JSON.stringify(opts)
|
|
264
|
-
});
|
|
265
|
-
},
|
|
266
|
-
list: async (deploymentId) => {
|
|
267
|
-
return this.requestJson(`/d/${deploymentId}/tokens`, {
|
|
268
|
-
method: "GET"
|
|
269
|
-
});
|
|
270
|
-
},
|
|
271
|
-
revoke: async (deploymentId, tokenHint) => {
|
|
272
|
-
return this.requestJson(`/d/${deploymentId}/tokens/${tokenHint}`, {
|
|
273
|
-
method: "DELETE"
|
|
274
|
-
});
|
|
275
|
-
}
|
|
276
|
-
}
|
|
277
|
-
};
|
|
278
220
|
}
|
|
279
221
|
// ─── Upload ──────────────────────────────────────────────────────────────
|
|
280
222
|
async upload(input, options = {}) {
|
|
@@ -411,15 +353,15 @@ var OkraClient = class {
|
|
|
411
353
|
{ method: "GET", signal }
|
|
412
354
|
);
|
|
413
355
|
}
|
|
414
|
-
// ─── Stream (streaming completion)
|
|
356
|
+
// ─── Stream (streaming completion via OpenAI SSE) ────────────────────────
|
|
415
357
|
async *stream(documentId, query, options) {
|
|
416
358
|
const response = await this.rawRequest(
|
|
417
|
-
`/document/${encodeURIComponent(documentId)}/
|
|
359
|
+
`/document/${encodeURIComponent(documentId)}/chat/completions`,
|
|
418
360
|
{
|
|
419
361
|
method: "POST",
|
|
420
362
|
headers: { "Content-Type": "application/json" },
|
|
421
363
|
body: JSON.stringify({
|
|
422
|
-
|
|
364
|
+
messages: [{ role: "user", content: query }],
|
|
423
365
|
stream: options?.stream !== false,
|
|
424
366
|
...options?.model ? { model: options.model } : {}
|
|
425
367
|
}),
|
|
@@ -436,6 +378,7 @@ var OkraClient = class {
|
|
|
436
378
|
const reader = response.body.getReader();
|
|
437
379
|
const decoder = new TextDecoder();
|
|
438
380
|
let buffer = "";
|
|
381
|
+
let fullText = "";
|
|
439
382
|
try {
|
|
440
383
|
while (true) {
|
|
441
384
|
const { done, value } = await reader.read();
|
|
@@ -445,19 +388,27 @@ var OkraClient = class {
|
|
|
445
388
|
buffer = lines.pop() || "";
|
|
446
389
|
for (const line of lines) {
|
|
447
390
|
const trimmed = line.trim();
|
|
448
|
-
if (!trimmed) continue;
|
|
391
|
+
if (!trimmed || trimmed === "data: [DONE]") continue;
|
|
392
|
+
if (!trimmed.startsWith("data: ")) continue;
|
|
393
|
+
const json = trimmed.slice(6);
|
|
449
394
|
try {
|
|
450
|
-
|
|
395
|
+
const chunk = JSON.parse(json);
|
|
396
|
+
if (chunk.error) {
|
|
397
|
+
yield { type: "error", message: chunk.error.message || "Stream error" };
|
|
398
|
+
continue;
|
|
399
|
+
}
|
|
400
|
+
const delta = chunk.choices?.[0]?.delta?.content;
|
|
401
|
+
if (delta) {
|
|
402
|
+
fullText += delta;
|
|
403
|
+
yield { type: "text_delta", text: delta };
|
|
404
|
+
}
|
|
405
|
+
if (chunk.choices?.[0]?.finish_reason === "stop") {
|
|
406
|
+
yield { type: "done", answer: fullText };
|
|
407
|
+
}
|
|
451
408
|
} catch {
|
|
452
409
|
}
|
|
453
410
|
}
|
|
454
411
|
}
|
|
455
|
-
if (buffer.trim()) {
|
|
456
|
-
try {
|
|
457
|
-
yield JSON.parse(buffer.trim());
|
|
458
|
-
} catch {
|
|
459
|
-
}
|
|
460
|
-
}
|
|
461
412
|
} finally {
|
|
462
413
|
reader.releaseLock();
|
|
463
414
|
}
|
|
@@ -467,20 +418,19 @@ var OkraClient = class {
|
|
|
467
418
|
return this.generateStructured(documentId, query, options);
|
|
468
419
|
}
|
|
469
420
|
const result = await this.requestJson(
|
|
470
|
-
`/document/${encodeURIComponent(documentId)}/
|
|
421
|
+
`/document/${encodeURIComponent(documentId)}/chat/completions`,
|
|
471
422
|
{
|
|
472
423
|
method: "POST",
|
|
473
424
|
headers: { "Content-Type": "application/json" },
|
|
474
425
|
body: JSON.stringify({
|
|
475
|
-
|
|
426
|
+
messages: [{ role: "user", content: query }],
|
|
476
427
|
...options?.model ? { model: options.model } : {}
|
|
477
428
|
}),
|
|
478
429
|
signal: options?.signal
|
|
479
430
|
}
|
|
480
431
|
);
|
|
481
432
|
return {
|
|
482
|
-
answer: result.
|
|
483
|
-
costUsd: result.usage?.costUsd
|
|
433
|
+
answer: result.choices?.[0]?.message?.content || ""
|
|
484
434
|
};
|
|
485
435
|
}
|
|
486
436
|
async generateStructured(documentId, query, options) {
|
|
@@ -488,39 +438,50 @@ var OkraClient = class {
|
|
|
488
438
|
throw new OkraRuntimeError("INVALID_REQUEST", "generate with schema requires a non-empty query", 400);
|
|
489
439
|
}
|
|
490
440
|
const normalized = normalizeSchema(options.schema);
|
|
491
|
-
const
|
|
492
|
-
`/document/${encodeURIComponent(documentId)}/
|
|
441
|
+
const result = await this.requestJson(
|
|
442
|
+
`/document/${encodeURIComponent(documentId)}/chat/completions`,
|
|
493
443
|
{
|
|
494
444
|
method: "POST",
|
|
495
445
|
headers: { "Content-Type": "application/json" },
|
|
496
446
|
body: JSON.stringify({
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
447
|
+
messages: [{ role: "user", content: query }],
|
|
448
|
+
response_format: {
|
|
449
|
+
type: "json_schema",
|
|
450
|
+
json_schema: { name: "result", schema: normalized.jsonSchema }
|
|
451
|
+
},
|
|
452
|
+
...options.model ? { model: options.model } : {}
|
|
501
453
|
}),
|
|
502
454
|
signal: options.signal
|
|
503
455
|
}
|
|
504
456
|
);
|
|
457
|
+
const raw = result.choices?.[0]?.message?.content;
|
|
458
|
+
if (!raw) {
|
|
459
|
+
throw new OkraRuntimeError("INVALID_RESPONSE", "No content in structured output response", 500);
|
|
460
|
+
}
|
|
461
|
+
let parsed;
|
|
462
|
+
try {
|
|
463
|
+
parsed = JSON.parse(raw);
|
|
464
|
+
} catch {
|
|
465
|
+
throw new OkraRuntimeError("INVALID_RESPONSE", "Structured output response is not valid JSON", 500);
|
|
466
|
+
}
|
|
505
467
|
let data;
|
|
506
468
|
if (normalized.parser) {
|
|
507
|
-
const
|
|
508
|
-
if (!
|
|
469
|
+
const zodResult = normalized.parser.safeParse(parsed);
|
|
470
|
+
if (!zodResult.success) {
|
|
509
471
|
throw new StructuredOutputError(
|
|
510
472
|
"SCHEMA_VALIDATION_FAILED",
|
|
511
473
|
"Client-side schema validation failed for structured output response",
|
|
512
474
|
422,
|
|
513
|
-
|
|
475
|
+
zodResult.error.issues
|
|
514
476
|
);
|
|
515
477
|
}
|
|
516
|
-
data =
|
|
478
|
+
data = zodResult.data;
|
|
517
479
|
} else {
|
|
518
|
-
data =
|
|
480
|
+
data = parsed;
|
|
519
481
|
}
|
|
520
482
|
return {
|
|
521
483
|
answer: "",
|
|
522
|
-
data
|
|
523
|
-
meta: body.meta
|
|
484
|
+
data
|
|
524
485
|
};
|
|
525
486
|
}
|
|
526
487
|
// ─── Model Endpoint ──────────────────────────────────────────────────────
|
|
@@ -619,8 +580,6 @@ var OkraClient = class {
|
|
|
619
580
|
};
|
|
620
581
|
|
|
621
582
|
export {
|
|
622
|
-
OkraRuntimeError,
|
|
623
|
-
StructuredOutputError,
|
|
624
583
|
OkraClient
|
|
625
584
|
};
|
|
626
|
-
//# sourceMappingURL=chunk-
|
|
585
|
+
//# sourceMappingURL=chunk-4RJBVZJL.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/client.ts"],"sourcesContent":["import { z, type ZodType } from 'zod';\nimport { OkraRuntimeError, StructuredOutputError } from './errors';\nimport type {\n OkraClientOptions,\n CompletionEvent,\n CompletionOptions,\n DocumentStatus,\n EntitiesResponse,\n GenerateOptions,\n GenerateResult,\n JsonSchema,\n Page,\n PublishResult,\n QueryResult,\n RuntimeErrorCode,\n ShareLinkOptions,\n ShareLinkResult,\n SessionAttachOptions,\n SessionCreateOptions,\n SessionState,\n OkraSession,\n StructuredOutputErrorCode,\n StructuredSchema,\n UploadInput,\n UploadOptions,\n WaitOptions,\n} from './types';\n\nconst DEFAULT_BASE_URL = 'https://api.okrapdf.com';\nconst DEFAULT_WAIT_TIMEOUT_MS = 5 * 60_000;\nconst DEFAULT_WAIT_POLL_MS = 1_500;\nconst COMPLETE_PHASES = new Set(['complete', 'awaiting_review']);\nconst TERMINAL_ERROR_PHASES = new Set(['error']);\nconst STRUCTURED_CODES = new Set<StructuredOutputErrorCode>([\n 'SCHEMA_VALIDATION_FAILED',\n 'EXTRACTION_FAILED',\n 'TIMEOUT',\n 'DOCUMENT_NOT_FOUND',\n]);\nconst NODE_FS_PROMISES_SPECIFIER = `node:${'fs/promises'}`;\nconst NODE_PATH_SPECIFIER = `node:${'path'}`;\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nfunction isHttpUrl(value: string): boolean {\n return /^https?:\\/\\//i.test(value);\n}\n\nfunction isDocumentId(value: string): boolean {\n return /^(?:ocr|doc)-[A-Za-z0-9_-]+$/.test(value);\n}\n\nfunction normalizeBaseUrl(baseUrl: string): string {\n return baseUrl.replace(/\\/+$/, '');\n}\n\nfunction makeDocId(): string {\n if (typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function') {\n return `doc-${crypto.randomUUID().replace(/-/g, '').slice(0, 20)}`;\n }\n const rand = Math.random().toString(36).slice(2, 22);\n return `doc-${rand}`;\n}\n\nfunction toUint8Array(input: ArrayBuffer | Uint8Array): Uint8Array {\n if (input instanceof Uint8Array) return input;\n return new Uint8Array(input);\n}\n\ninterface NodeFsModule {\n readFile(path: string): Promise<ArrayBuffer | Uint8Array>;\n}\n\ninterface NodePathModule {\n basename(path: string): string;\n}\n\ninterface NamedBlob extends Blob {\n name?: string;\n}\n\nfunction isBlobLike(input: unknown): input is Blob {\n if (typeof Blob !== 'undefined' && input instanceof Blob) return true;\n return !!input\n && typeof input === 'object'\n && typeof (input as { arrayBuffer?: unknown }).arrayBuffer === 'function';\n}\n\nfunction inferBlobName(input: Blob, fallback: string): string {\n const named = input as NamedBlob;\n if (typeof named.name === 'string' && named.name.trim() !== '') {\n return named.name;\n }\n return fallback;\n}\n\nasync function readLocalFileFromNode(inputPath: string): Promise<{ bytes: Uint8Array; fileName: string }> {\n try {\n const [fsModule, pathModule] = await Promise.all([\n import(NODE_FS_PROMISES_SPECIFIER) as Promise<NodeFsModule>,\n import(NODE_PATH_SPECIFIER) as Promise<NodePathModule>,\n ]);\n const raw = await fsModule.readFile(inputPath);\n return {\n bytes: toUint8Array(raw),\n fileName: pathModule.basename(inputPath),\n };\n } catch (error) {\n throw new OkraRuntimeError(\n 'INVALID_REQUEST',\n 'Local file path uploads are only supported in Node.js. In browser runtimes, pass File/Blob, ArrayBuffer, Uint8Array, or URL.',\n 400,\n error,\n );\n }\n}\n\ninterface StructuredErrorEnvelope {\n code?: string;\n message?: string;\n details?: unknown;\n error?: string;\n}\n\ninterface NormalizedSchema<T> {\n jsonSchema: JsonSchema;\n parser?: ZodType<T>;\n}\n\nfunction normalizeSchema<T>(schema: StructuredSchema<T>): NormalizedSchema<T> {\n const maybeZod = schema as ZodType<T>;\n const hasSafeParse = typeof (maybeZod as { safeParse?: unknown }).safeParse === 'function';\n if (hasSafeParse) {\n return {\n jsonSchema: z.toJSONSchema(maybeZod, { target: 'draft-2020-12' }) as JsonSchema,\n parser: maybeZod,\n };\n }\n return { jsonSchema: schema as JsonSchema };\n}\n\nfunction isStructuredCode(code: string | undefined): code is StructuredOutputErrorCode {\n return !!code && STRUCTURED_CODES.has(code as StructuredOutputErrorCode);\n}\n\n// ─── Session Handle ──────────────────────────────────────────────────────────\n\nclass OkraSessionHandle implements OkraSession {\n readonly id: string;\n readonly modelEndpoint: string;\n #model?: string;\n #client: OkraClient;\n\n constructor(client: OkraClient, documentId: string, model?: string) {\n this.#client = client;\n this.id = documentId;\n this.modelEndpoint = client.modelEndpoint(documentId);\n this.#model = model;\n }\n\n get model(): string | undefined {\n return this.#model;\n }\n\n state(): SessionState {\n return {\n id: this.id,\n model: this.#model,\n modelEndpoint: this.modelEndpoint,\n };\n }\n\n async setModel(model: string): Promise<void> {\n const normalized = model.trim();\n if (!normalized) {\n throw new OkraRuntimeError('INVALID_REQUEST', 'session.setModel requires a non-empty model', 400);\n }\n this.#model = normalized;\n }\n\n status(signal?: AbortSignal): Promise<DocumentStatus> {\n return this.#client.status(this.id, signal);\n }\n\n wait(options?: WaitOptions): Promise<DocumentStatus> {\n return this.#client.wait(this.id, options);\n }\n\n pages(options?: { range?: string; signal?: AbortSignal }): Promise<Page[]> {\n return this.#client.pages(this.id, options);\n }\n\n page(pageNumber: number, signal?: AbortSignal): Promise<Page> {\n return this.#client.page(this.id, pageNumber, signal);\n }\n\n entities(options?: { type?: string; limit?: number; offset?: number; signal?: AbortSignal }): Promise<EntitiesResponse> {\n return this.#client.entities(this.id, options);\n }\n\n downloadUrl(): string {\n return this.#client.downloadUrl(this.id);\n }\n\n query(sql: string, signal?: AbortSignal): Promise<QueryResult> {\n return this.#client.query(this.id, sql, signal);\n }\n\n publish(signal?: AbortSignal): Promise<PublishResult> {\n return this.#client.publish(this.id, signal);\n }\n\n shareLink(options?: ShareLinkOptions): Promise<ShareLinkResult> {\n return this.#client.shareLink(this.id, options);\n }\n\n prompt(\n query: string,\n options?: GenerateOptions & { schema?: undefined },\n ): Promise<GenerateResult>;\n prompt<T>(\n query: string,\n options: GenerateOptions & { schema: StructuredSchema<T> },\n ): Promise<GenerateResult<T>>;\n prompt<T = undefined>(\n query: string,\n options?: GenerateOptions,\n ): Promise<GenerateResult<T>> {\n const model = options?.model ?? this.#model;\n const merged = model ? { ...options, model } : options;\n if (merged?.schema !== undefined) {\n return this.#client.generate(\n this.id,\n query,\n merged as GenerateOptions & { schema: StructuredSchema<unknown> },\n ) as Promise<GenerateResult<T>>;\n }\n return this.#client.generate(\n this.id,\n query,\n merged as GenerateOptions & { schema?: undefined },\n ) as Promise<GenerateResult<T>>;\n }\n\n stream(\n query: string,\n options?: CompletionOptions,\n ): AsyncGenerator<CompletionEvent> {\n const model = options?.model ?? this.#model;\n const merged = model ? { ...options, model } : options;\n return this.#client.stream(this.id, query, merged);\n }\n}\n\n// ─── Client ──────────────────────────────────────────────────────────────────\n\nexport class OkraClient {\n private readonly baseUrl: string;\n private readonly apiKey?: string;\n private readonly sharedSecret?: string;\n private readonly fetchImpl: typeof globalThis.fetch;\n readonly sessions: {\n create: (sourceOrDocId: UploadInput, options?: SessionCreateOptions) => Promise<OkraSession>;\n from: (documentId: string, options?: SessionAttachOptions) => OkraSession;\n };\n constructor(options: OkraClientOptions) {\n this.baseUrl = normalizeBaseUrl(options.baseUrl || DEFAULT_BASE_URL);\n this.apiKey = options.apiKey;\n this.sharedSecret = options.sharedSecret;\n this.fetchImpl = options.fetch || globalThis.fetch.bind(globalThis);\n\n if (!this.apiKey && !this.sharedSecret) {\n throw new OkraRuntimeError(\n 'UNAUTHORIZED',\n 'OkraClient requires either apiKey or sharedSecret',\n 401,\n );\n }\n\n if (\n typeof globalThis !== 'undefined' && 'window' in globalThis\n && this.apiKey\n && !this.apiKey.startsWith('okra_pk_')\n ) {\n console.warn(\n '[OkraPDF] Secret API key detected in browser. Use a publishable key (okra_pk_...) for client-side usage. ' +\n 'See https://docs.okrapdf.dev/api-keys#publishable-keys',\n );\n }\n\n this.sessions = {\n create: async (sourceOrDocId, sessionOptions = {}) => {\n let documentId: string;\n if (typeof sourceOrDocId === 'string' && isDocumentId(sourceOrDocId.trim())) {\n documentId = sourceOrDocId.trim();\n } else {\n const session = await this.upload(sourceOrDocId, sessionOptions.upload);\n documentId = session.id;\n }\n\n const session = this.sessions.from(documentId, { model: sessionOptions.model });\n if (sessionOptions.wait ?? true) {\n await session.wait(sessionOptions.waitOptions);\n }\n return session;\n },\n from: (documentId, sessionOptions = {}) => {\n const normalized = documentId.trim();\n if (!normalized) {\n throw new OkraRuntimeError(\n 'INVALID_REQUEST',\n 'sessions.from requires a non-empty documentId',\n 400,\n );\n }\n\n return new OkraSessionHandle(\n this,\n normalized,\n sessionOptions.model?.trim() || undefined,\n );\n },\n };\n }\n\n // ─── Upload ──────────────────────────────────────────────────────────────\n\n async upload(input: UploadInput, options: UploadOptions = {}): Promise<OkraSession> {\n const documentId = options.documentId || makeDocId();\n const path = `/document/${encodeURIComponent(documentId)}`;\n const visibility = options.visibility || 'private';\n\n if (typeof input === 'string' && isHttpUrl(input)) {\n const urlHeaders: Record<string, string> = { 'Content-Type': 'application/json' };\n if (options.vendorKeys) {\n urlHeaders['X-Vendor-Keys'] = JSON.stringify(options.vendorKeys);\n }\n await this.requestJson<{ phase?: string }>(`${path}/upload-url`, {\n method: 'POST',\n headers: urlHeaders,\n body: JSON.stringify({\n url: input,\n capabilities: options.capabilities,\n visibility,\n redact: options.redact,\n }),\n });\n return this.sessions.from(documentId);\n }\n\n let bytes: Uint8Array;\n let fileName = options.fileName || 'document.pdf';\n if (typeof input === 'string') {\n const local = await readLocalFileFromNode(input);\n bytes = local.bytes;\n if (!options.fileName) fileName = local.fileName;\n } else if (isBlobLike(input)) {\n bytes = toUint8Array(await input.arrayBuffer());\n if (!options.fileName) {\n fileName = inferBlobName(input, fileName);\n }\n } else {\n bytes = toUint8Array(input);\n }\n\n const headers: Record<string, string> = {\n 'Content-Type': 'application/pdf',\n 'X-File-Name': fileName,\n };\n if (options.capabilities) {\n headers['X-Capabilities'] = JSON.stringify(options.capabilities);\n }\n if (options.vendorKeys) {\n headers['X-Vendor-Keys'] = JSON.stringify(options.vendorKeys);\n }\n if (options.redact) {\n headers['X-Redact'] = JSON.stringify(options.redact);\n }\n if (visibility === 'public') {\n headers['X-Visibility'] = 'public';\n }\n\n await this.requestJson<{ phase?: string }>(`${path}/upload`, {\n method: 'POST',\n headers,\n body: bytes as unknown as BodyInit,\n });\n\n return this.sessions.from(documentId);\n }\n\n // ─── Status / Wait ───────────────────────────────────────────────────────\n\n async status(documentId: string, signal?: AbortSignal): Promise<DocumentStatus> {\n return this.requestJson<DocumentStatus>(\n `/document/${encodeURIComponent(documentId)}/status`,\n { method: 'GET', signal },\n );\n }\n\n async wait(documentId: string, options: WaitOptions = {}): Promise<DocumentStatus> {\n const startedAt = Date.now();\n const timeoutMs = options.timeoutMs ?? DEFAULT_WAIT_TIMEOUT_MS;\n const pollIntervalMs = options.pollIntervalMs ?? DEFAULT_WAIT_POLL_MS;\n\n while (true) {\n if (options.signal?.aborted) {\n throw new OkraRuntimeError('TIMEOUT', 'Wait aborted', 499);\n }\n\n const current = await this.status(documentId, options.signal);\n if (COMPLETE_PHASES.has(current.phase)) {\n return current;\n }\n if (TERMINAL_ERROR_PHASES.has(current.phase)) {\n throw new OkraRuntimeError(\n 'EXTRACTION_FAILED',\n `Document entered terminal error phase (${current.phase})`,\n 500,\n current,\n );\n }\n\n const elapsed = Date.now() - startedAt;\n if (elapsed >= timeoutMs) {\n throw new OkraRuntimeError(\n 'TIMEOUT',\n `Timed out waiting for document ${documentId} after ${timeoutMs}ms`,\n 504,\n current,\n );\n }\n\n await sleep(pollIntervalMs);\n }\n }\n\n // ─── Pages ───────────────────────────────────────────────────────────────\n\n async pages(documentId: string, options?: { range?: string; signal?: AbortSignal }): Promise<Page[]> {\n const params = options?.range ? `?range=${encodeURIComponent(options.range)}` : '';\n return this.requestJson<Page[]>(\n `/document/${encodeURIComponent(documentId)}/pages${params}`,\n { method: 'GET', signal: options?.signal },\n );\n }\n\n async page(documentId: string, pageNumber: number, signal?: AbortSignal): Promise<Page> {\n return this.requestJson<Page>(\n `/document/${encodeURIComponent(documentId)}/page/${pageNumber}`,\n { method: 'GET', signal },\n );\n }\n\n // ─── Download ──────────────────────────────────────────────────────────\n\n downloadUrl(documentId: string): string {\n return `${this.baseUrl}/document/${encodeURIComponent(documentId)}/download`;\n }\n\n // ─── Entities ────────────────────────────────────────────────────────────\n\n async entities(\n documentId: string,\n options?: { type?: string; limit?: number; offset?: number; signal?: AbortSignal },\n ): Promise<EntitiesResponse> {\n const params = new URLSearchParams();\n if (options?.type) params.set('type', options.type);\n if (options?.limit) params.set('limit', String(options.limit));\n if (options?.offset) params.set('offset', String(options.offset));\n const qs = params.toString();\n return this.requestJson<EntitiesResponse>(\n `/document/${encodeURIComponent(documentId)}/nodes${qs ? `?${qs}` : ''}`,\n { method: 'GET', signal: options?.signal },\n );\n }\n\n // ─── Query (SQL) ─────────────────────────────────────────────────────────\n\n async query(documentId: string, sql: string, signal?: AbortSignal): Promise<QueryResult> {\n return this.requestJson<QueryResult>(\n `/document/${encodeURIComponent(documentId)}/query?select=${encodeURIComponent(sql)}`,\n { method: 'GET', signal },\n );\n }\n\n // ─── Stream (streaming completion via OpenAI SSE) ────────────────────────\n\n async *stream(\n documentId: string,\n query: string,\n options?: CompletionOptions,\n ): AsyncGenerator<CompletionEvent> {\n const response = await this.rawRequest(\n `/document/${encodeURIComponent(documentId)}/chat/completions`,\n {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n messages: [{ role: 'user', content: query }],\n stream: options?.stream !== false,\n ...(options?.model ? { model: options.model } : {}),\n }),\n signal: options?.signal,\n },\n );\n\n if (!response.ok) {\n const text = await response.text();\n throw new OkraRuntimeError('HTTP_ERROR', `Completion failed: ${text}`, response.status);\n }\n\n if (!response.body) {\n throw new OkraRuntimeError('INVALID_RESPONSE', 'No response body for completion stream', 500);\n }\n\n const reader = response.body.getReader();\n const decoder = new TextDecoder();\n let buffer = '';\n let fullText = '';\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n buffer += decoder.decode(value, { stream: true });\n const lines = buffer.split('\\n');\n buffer = lines.pop() || '';\n\n for (const line of lines) {\n const trimmed = line.trim();\n if (!trimmed || trimmed === 'data: [DONE]') continue;\n if (!trimmed.startsWith('data: ')) continue;\n const json = trimmed.slice(6);\n try {\n const chunk = JSON.parse(json) as {\n choices?: Array<{ delta?: { content?: string }; finish_reason?: string | null }>;\n usage?: { prompt_tokens?: number; completion_tokens?: number; total_tokens?: number };\n error?: { message?: string };\n };\n\n if (chunk.error) {\n yield { type: 'error', message: chunk.error.message || 'Stream error' };\n continue;\n }\n\n const delta = chunk.choices?.[0]?.delta?.content;\n if (delta) {\n fullText += delta;\n yield { type: 'text_delta', text: delta };\n }\n\n if (chunk.choices?.[0]?.finish_reason === 'stop') {\n yield { type: 'done', answer: fullText };\n }\n } catch {\n // skip malformed lines\n }\n }\n }\n } finally {\n reader.releaseLock();\n }\n }\n\n // ─── Generate (non-streaming AI) ─────────────────────────────────────────\n\n async generate(\n documentId: string,\n query: string,\n options?: GenerateOptions & { schema?: undefined },\n ): Promise<GenerateResult>;\n async generate<T>(\n documentId: string,\n query: string,\n options: GenerateOptions & { schema: StructuredSchema<T> },\n ): Promise<GenerateResult<T>>;\n async generate<T = undefined>(\n documentId: string,\n query: string,\n options?: GenerateOptions,\n ): Promise<GenerateResult<T>> {\n if (options?.schema) {\n return this.generateStructured<T>(documentId, query, options);\n }\n\n const result = await this.requestJson<{\n id: string;\n choices: Array<{ message: { content: string } }>;\n usage?: { prompt_tokens?: number; completion_tokens?: number; total_tokens?: number };\n }>(\n `/document/${encodeURIComponent(documentId)}/chat/completions`,\n {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n messages: [{ role: 'user', content: query }],\n ...(options?.model ? { model: options.model } : {}),\n }),\n signal: options?.signal,\n },\n );\n\n return {\n answer: result.choices?.[0]?.message?.content || '',\n };\n }\n\n private async generateStructured<T>(\n documentId: string,\n query: string,\n options: GenerateOptions,\n ): Promise<GenerateResult<T>> {\n if (!query || query.trim() === '') {\n throw new OkraRuntimeError('INVALID_REQUEST', 'generate with schema requires a non-empty query', 400);\n }\n\n const normalized = normalizeSchema(options.schema as StructuredSchema<T>);\n const result = await this.requestJson<{\n id: string;\n choices: Array<{ message: { content: string } }>;\n usage?: { prompt_tokens?: number; completion_tokens?: number; total_tokens?: number };\n }>(\n `/document/${encodeURIComponent(documentId)}/chat/completions`,\n {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n messages: [{ role: 'user', content: query }],\n response_format: {\n type: 'json_schema',\n json_schema: { name: 'result', schema: normalized.jsonSchema },\n },\n ...(options.model ? { model: options.model } : {}),\n }),\n signal: options.signal,\n },\n );\n\n const raw = result.choices?.[0]?.message?.content;\n if (!raw) {\n throw new OkraRuntimeError('INVALID_RESPONSE', 'No content in structured output response', 500);\n }\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch {\n throw new OkraRuntimeError('INVALID_RESPONSE', 'Structured output response is not valid JSON', 500);\n }\n\n let data: T;\n if (normalized.parser) {\n const zodResult = normalized.parser.safeParse(parsed);\n if (!zodResult.success) {\n throw new StructuredOutputError(\n 'SCHEMA_VALIDATION_FAILED',\n 'Client-side schema validation failed for structured output response',\n 422,\n zodResult.error.issues,\n );\n }\n data = zodResult.data;\n } else {\n data = parsed as T;\n }\n\n return {\n answer: '',\n data,\n };\n }\n\n // ─── Model Endpoint ──────────────────────────────────────────────────────\n\n modelEndpoint(documentId: string): string {\n return `${this.baseUrl}/v1/documents/${encodeURIComponent(documentId)}`;\n }\n\n // ─── Publish / Share ────────────────────────────────────────────────────\n\n async publish(documentId: string, signal?: AbortSignal): Promise<PublishResult> {\n const result = await this.requestJson<Omit<PublishResult, 'url'>>(\n `/document/${encodeURIComponent(documentId)}/publish`,\n { method: 'POST', signal },\n );\n return {\n ...result,\n url: `${this.baseUrl}/v1/documents/${encodeURIComponent(documentId)}`,\n };\n }\n\n async shareLink(documentId: string, options?: ShareLinkOptions): Promise<ShareLinkResult> {\n return this.requestJson<ShareLinkResult>(\n `/document/${encodeURIComponent(documentId)}/share-link`,\n {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n role: options?.role,\n label: options?.label,\n expiresInMs: options?.expiresInMs,\n maxViews: options?.maxViews,\n }),\n signal: options?.signal,\n },\n );\n }\n\n // ─── Public HTTP ─────────────────────────────────────────────────────────\n\n async request<T>(path: string, init: RequestInit = {}): Promise<T> {\n return this.requestJson<T>(path, init);\n }\n\n get url(): string {\n return this.baseUrl;\n }\n\n // ─── Internal HTTP ───────────────────────────────────────────────────────\n\n private authHeaders(): Record<string, string> {\n if (this.apiKey) return { Authorization: `Bearer ${this.apiKey}` };\n if (this.sharedSecret) return { 'x-document-agent-secret': this.sharedSecret };\n return {};\n }\n\n private async rawRequest(path: string, init: RequestInit): Promise<Response> {\n const headers = new Headers(init.headers);\n for (const [key, value] of Object.entries(this.authHeaders())) {\n if (!headers.has(key)) headers.set(key, value);\n }\n\n try {\n return await this.fetchImpl(`${this.baseUrl}${path}`, { ...init, headers });\n } catch (err) {\n throw new OkraRuntimeError(\n 'HTTP_ERROR',\n err instanceof Error ? err.message : String(err),\n 502,\n );\n }\n }\n\n private async requestJson<T>(path: string, init: RequestInit): Promise<T> {\n const response = await this.rawRequest(path, init);\n const text = await response.text();\n const parsed = this.parseBody(text);\n\n if (!response.ok) {\n const envelope = parsed as StructuredErrorEnvelope | null;\n const code = envelope?.code;\n const message = envelope?.message || envelope?.error || `Request failed with status ${response.status}`;\n const details = envelope?.details ?? parsed ?? text;\n if (isStructuredCode(code)) {\n throw new StructuredOutputError(code, message, response.status, details);\n }\n const runtimeCode: RuntimeErrorCode = response.status === 401 ? 'UNAUTHORIZED' : 'HTTP_ERROR';\n throw new OkraRuntimeError(runtimeCode, message, response.status, details);\n }\n\n if (parsed === null) {\n throw new OkraRuntimeError(\n 'INVALID_RESPONSE',\n `Expected JSON response for ${path}`,\n response.status,\n text,\n );\n }\n\n return parsed as T;\n }\n\n private parseBody(text: string): unknown | null {\n const trimmed = text.trim();\n if (!trimmed) return null;\n try {\n return JSON.parse(trimmed);\n } catch {\n return null;\n }\n }\n}\n"],"mappings":"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","names":["session"]}
|
|
@@ -24,12 +24,15 @@ function doc(documentId, baseUrlOrOptions = DEFAULT_BASE_URL, maybeOptions = {})
|
|
|
24
24
|
const options = typeof baseUrlOrOptions === "string" ? maybeOptions : baseUrlOrOptions;
|
|
25
25
|
const base = baseUrl.replace(/\/+$/, "");
|
|
26
26
|
const defaultProvider = options.provider;
|
|
27
|
-
const defaultImage = options.defaultImage;
|
|
27
|
+
const defaultImage = options.placeholder || options.defaultImage;
|
|
28
28
|
const providerSegment = (p) => {
|
|
29
29
|
const provider = p || defaultProvider;
|
|
30
30
|
return provider ? `/t_${provider}` : "";
|
|
31
31
|
};
|
|
32
|
-
const defaultImageSegment = () =>
|
|
32
|
+
const defaultImageSegment = (override) => {
|
|
33
|
+
const img = override || defaultImage;
|
|
34
|
+
return img ? `/d_${img}` : "";
|
|
35
|
+
};
|
|
33
36
|
const docBase = `${base}/v1/documents/${encodeURIComponent(documentId)}`;
|
|
34
37
|
const artifactBase = options.fileName ? slugifyFileStem(options.fileName) : "document";
|
|
35
38
|
const withArtifact = (path, ext, qs = "") => `${path}/${artifactBase}.${ext}${qs}`;
|
|
@@ -78,15 +81,34 @@ function doc(documentId, baseUrlOrOptions = DEFAULT_BASE_URL, maybeOptions = {})
|
|
|
78
81
|
}
|
|
79
82
|
});
|
|
80
83
|
};
|
|
84
|
+
const pgUrl = (segment, ext, placeholderOverride) => {
|
|
85
|
+
const imgSeg = defaultImageSegment(placeholderOverride);
|
|
86
|
+
const provSeg = providerSegment();
|
|
87
|
+
const seg = provSeg + imgSeg;
|
|
88
|
+
const flatPath = `${docBase}/pg_${segment}.${ext}`;
|
|
89
|
+
if (!seg) return flatPath;
|
|
90
|
+
return flatPath.replace(docBase, `${docBase}${seg}`);
|
|
91
|
+
};
|
|
92
|
+
const makePgPage = (pageNum) => ({
|
|
93
|
+
png: (opts) => pgUrl(String(pageNum), "png", opts?.placeholder),
|
|
94
|
+
md: () => pgUrl(String(pageNum), "md"),
|
|
95
|
+
json: () => pgUrl(String(pageNum), "json")
|
|
96
|
+
});
|
|
97
|
+
const makePgRange = (segment) => ({
|
|
98
|
+
md: () => pgUrl(segment, "md"),
|
|
99
|
+
json: () => pgUrl(segment, "json")
|
|
100
|
+
});
|
|
81
101
|
const pg = new Proxy({}, {
|
|
82
102
|
get(_target, prop) {
|
|
103
|
+
if (prop === "range") {
|
|
104
|
+
return (start, end) => makePgRange(`${start}-${end}`);
|
|
105
|
+
}
|
|
106
|
+
if (prop === "list") {
|
|
107
|
+
return (...pages) => makePgRange(pages.join(","));
|
|
108
|
+
}
|
|
83
109
|
const pageNum = typeof prop === "string" ? parseInt(prop, 10) : NaN;
|
|
84
110
|
if (!isNaN(pageNum)) {
|
|
85
|
-
return
|
|
86
|
-
png: () => withProvider(withArtifact(`${docBase}/pg_${pageNum}`, "png")),
|
|
87
|
-
md: () => withProvider(withArtifact(`${docBase}/pg_${pageNum}`, "md")),
|
|
88
|
-
json: () => withProvider(withArtifact(`${docBase}/pg_${pageNum}`, "json"))
|
|
89
|
-
};
|
|
111
|
+
return makePgPage(pageNum);
|
|
90
112
|
}
|
|
91
113
|
return void 0;
|
|
92
114
|
}
|
|
@@ -97,8 +119,12 @@ function doc(documentId, baseUrlOrOptions = DEFAULT_BASE_URL, maybeOptions = {})
|
|
|
97
119
|
opts?.provider
|
|
98
120
|
),
|
|
99
121
|
thumbnail: {
|
|
100
|
-
url: () =>
|
|
122
|
+
url: () => pgUrl("1", "png")
|
|
123
|
+
},
|
|
124
|
+
full: {
|
|
125
|
+
md: () => `${docBase}/full.md`
|
|
101
126
|
},
|
|
127
|
+
download: () => `${base}/document/${encodeURIComponent(documentId)}/download`,
|
|
102
128
|
pg,
|
|
103
129
|
entities: {
|
|
104
130
|
tables: makeEntityCollection("tables"),
|
|
@@ -110,4 +136,4 @@ function doc(documentId, baseUrlOrOptions = DEFAULT_BASE_URL, maybeOptions = {})
|
|
|
110
136
|
export {
|
|
111
137
|
doc
|
|
112
138
|
};
|
|
113
|
-
//# sourceMappingURL=chunk-
|
|
139
|
+
//# sourceMappingURL=chunk-5NINKIAC.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/url.ts"],"sourcesContent":["import type { DocUrlOptions, UrlBuilderOptions } from './types';\n\nconst DEFAULT_BASE_URL = 'https://api.okrapdf.com';\n\ninterface PgPage {\n png: (opts?: { placeholder?: string }) => string;\n md: () => string;\n json: () => string;\n}\n\ninterface PgPageRange {\n md: () => string;\n json: () => string;\n}\n\ninterface PgProxy {\n [index: number]: PgPage;\n range: (start: number, end: number) => PgPageRange;\n list: (...pages: number[]) => PgPageRange;\n}\n\ninterface DocumentUrl {\n /** Base document URL */\n url: (opts?: UrlBuilderOptions) => string;\n /** Thumbnail image URL (pg_1.png) */\n thumbnail: { url: () => string };\n /** Full document markdown */\n full: { md: () => string };\n /** Original PDF download (auth required) */\n download: () => string;\n /** Page access: d.pg[1].png(), d.pg[1].md(), d.pg[1].json() */\n pg: PgProxy;\n /** Entity-level access */\n entities: EntitiesProxy;\n}\n\ninterface EntitiesProxy {\n tables: EntityCollectionProxy;\n figures: EntityCollectionProxy;\n}\n\ninterface EntityCollectionProxy {\n [index: number]: {\n url: (opts?: { format?: 'json' | 'csv' | 'html' }) => string;\n };\n url: (opts?: UrlBuilderOptions) => string;\n}\n\nconst FORMAT_TO_EXT: Record<NonNullable<UrlBuilderOptions['format']>, string> = {\n json: 'json',\n csv: 'csv',\n html: 'html',\n markdown: 'md',\n png: 'png',\n};\n\nfunction slugifyFileStem(fileName: string): string {\n const leaf = fileName.split('/').pop() || fileName;\n const noExt = leaf.replace(/\\.[A-Za-z0-9]{1,8}$/, '');\n const slug = noExt\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-+|-+$/g, '')\n .slice(0, 48);\n return slug || 'document';\n}\n\nfunction extensionFor(format: string | undefined, fallback: string): string {\n if (!format) return fallback;\n const lower = format.toLowerCase();\n if (lower === 'markdown') return 'md';\n return FORMAT_TO_EXT[lower as keyof typeof FORMAT_TO_EXT] || lower;\n}\n\n/**\n * Build-time URL builder — Cloudinary for documents.\n *\n * ```tsx\n * import { doc } from 'okrapdf';\n * const d = doc('doc_7fK3x');\n * <Image src={d.thumbnail.url()} />\n * <a href={d.entities.tables[0].url({ format: 'csv' })}>CSV</a>\n * ```\n */\nexport function doc(\n documentId: string,\n baseUrlOrOptions: string | DocUrlOptions = DEFAULT_BASE_URL,\n maybeOptions: DocUrlOptions = {},\n): DocumentUrl {\n const baseUrl = typeof baseUrlOrOptions === 'string' ? baseUrlOrOptions : DEFAULT_BASE_URL;\n const options = typeof baseUrlOrOptions === 'string' ? maybeOptions : baseUrlOrOptions;\n\n const base = baseUrl.replace(/\\/+$/, '');\n const defaultProvider = options.provider;\n const defaultImage = options.placeholder || options.defaultImage;\n const providerSegment = (p?: string) => {\n const provider = p || defaultProvider;\n return provider ? `/t_${provider}` : '';\n };\n const defaultImageSegment = (override?: string) => {\n const img = override || defaultImage;\n return img ? `/d_${img}` : '';\n };\n const docBase = `${base}/v1/documents/${encodeURIComponent(documentId)}`;\n const artifactBase = options.fileName\n ? slugifyFileStem(options.fileName)\n : 'document';\n\n const withArtifact = (path: string, ext: string, qs: string = '') =>\n `${path}/${artifactBase}.${ext}${qs}`;\n\n const withProvider = (path: string, provider?: string) => {\n const seg = providerSegment(provider) + defaultImageSegment();\n if (!seg) return path;\n return path.replace(docBase, `${docBase}${seg}`);\n };\n\n const formatParams = (opts?: UrlBuilderOptions) => {\n const params = new URLSearchParams();\n if (opts?.format) params.set('format', opts.format);\n if (opts?.include?.length) params.set('include', opts.include.join(','));\n const qs = params.toString();\n return qs ? `?${qs}` : '';\n };\n\n const makeEntityCollection = (type: string): EntityCollectionProxy => {\n return new Proxy({} as EntityCollectionProxy, {\n get(_target, prop) {\n if (prop === 'url') {\n return (opts?: UrlBuilderOptions) =>\n withProvider(\n withArtifact(\n `${docBase}/entities/${type}`,\n extensionFor(opts?.format, 'json'),\n formatParams(opts),\n ),\n opts?.provider,\n );\n }\n const index = typeof prop === 'string' ? parseInt(prop, 10) : NaN;\n if (!isNaN(index)) {\n return {\n url: (opts?: { format?: string; provider?: string }) => {\n const params = opts?.format ? `?format=${opts.format}` : '';\n return withProvider(\n withArtifact(\n `${docBase}/entities/${type}/${index}`,\n extensionFor(opts?.format, 'json'),\n params,\n ),\n opts?.provider,\n );\n },\n };\n }\n return undefined;\n },\n });\n };\n\n // Build a flat pg URL: .../pg_1.png (no artifact suffix)\n const pgUrl = (segment: string, ext: string, placeholderOverride?: string) => {\n const imgSeg = defaultImageSegment(placeholderOverride);\n const provSeg = providerSegment();\n const seg = provSeg + imgSeg;\n const flatPath = `${docBase}/pg_${segment}.${ext}`;\n if (!seg) return flatPath;\n return flatPath.replace(docBase, `${docBase}${seg}`);\n };\n\n const makePgPage = (pageNum: number): PgPage => ({\n png: (opts?: { placeholder?: string }) => pgUrl(String(pageNum), 'png', opts?.placeholder),\n md: () => pgUrl(String(pageNum), 'md'),\n json: () => pgUrl(String(pageNum), 'json'),\n });\n\n const makePgRange = (segment: string): PgPageRange => ({\n md: () => pgUrl(segment, 'md'),\n json: () => pgUrl(segment, 'json'),\n });\n\n const pg: PgProxy = new Proxy({} as PgProxy, {\n get(_target, prop) {\n if (prop === 'range') {\n return (start: number, end: number) => makePgRange(`${start}-${end}`);\n }\n if (prop === 'list') {\n return (...pages: number[]) => makePgRange(pages.join(','));\n }\n const pageNum = typeof prop === 'string' ? parseInt(prop, 10) : NaN;\n if (!isNaN(pageNum)) {\n return makePgPage(pageNum);\n }\n return undefined;\n },\n });\n\n return {\n url: (opts?: UrlBuilderOptions) =>\n withProvider(\n withArtifact(docBase, extensionFor(opts?.format, 'json'), formatParams(opts)),\n opts?.provider,\n ),\n thumbnail: {\n url: () => pgUrl('1', 'png'),\n },\n full: {\n md: () => `${docBase}/full.md`,\n },\n download: () => `${base}/document/${encodeURIComponent(documentId)}/download`,\n pg,\n entities: {\n tables: makeEntityCollection('tables'),\n figures: makeEntityCollection('figures'),\n },\n };\n}\n"],"mappings":";AAEA,IAAM,mBAAmB;AA8CzB,IAAM,gBAA0E;AAAA,EAC9E,MAAM;AAAA,EACN,KAAK;AAAA,EACL,MAAM;AAAA,EACN,UAAU;AAAA,EACV,KAAK;AACP;AAEA,SAAS,gBAAgB,UAA0B;AACjD,QAAM,OAAO,SAAS,MAAM,GAAG,EAAE,IAAI,KAAK;AAC1C,QAAM,QAAQ,KAAK,QAAQ,uBAAuB,EAAE;AACpD,QAAM,OAAO,MACV,YAAY,EACZ,QAAQ,eAAe,GAAG,EAC1B,QAAQ,YAAY,EAAE,EACtB,MAAM,GAAG,EAAE;AACd,SAAO,QAAQ;AACjB;AAEA,SAAS,aAAa,QAA4B,UAA0B;AAC1E,MAAI,CAAC,OAAQ,QAAO;AACpB,QAAM,QAAQ,OAAO,YAAY;AACjC,MAAI,UAAU,WAAY,QAAO;AACjC,SAAO,cAAc,KAAmC,KAAK;AAC/D;AAYO,SAAS,IACd,YACA,mBAA2C,kBAC3C,eAA8B,CAAC,GAClB;AACb,QAAM,UAAU,OAAO,qBAAqB,WAAW,mBAAmB;AAC1E,QAAM,UAAU,OAAO,qBAAqB,WAAW,eAAe;AAEtE,QAAM,OAAO,QAAQ,QAAQ,QAAQ,EAAE;AACvC,QAAM,kBAAkB,QAAQ;AAChC,QAAM,eAAe,QAAQ,eAAe,QAAQ;AACpD,QAAM,kBAAkB,CAAC,MAAe;AACtC,UAAM,WAAW,KAAK;AACtB,WAAO,WAAW,MAAM,QAAQ,KAAK;AAAA,EACvC;AACA,QAAM,sBAAsB,CAAC,aAAsB;AACjD,UAAM,MAAM,YAAY;AACxB,WAAO,MAAM,MAAM,GAAG,KAAK;AAAA,EAC7B;AACA,QAAM,UAAU,GAAG,IAAI,iBAAiB,mBAAmB,UAAU,CAAC;AACtE,QAAM,eAAe,QAAQ,WACzB,gBAAgB,QAAQ,QAAQ,IAChC;AAEJ,QAAM,eAAe,CAAC,MAAc,KAAa,KAAa,OAC5D,GAAG,IAAI,IAAI,YAAY,IAAI,GAAG,GAAG,EAAE;AAErC,QAAM,eAAe,CAAC,MAAc,aAAsB;AACxD,UAAM,MAAM,gBAAgB,QAAQ,IAAI,oBAAoB;AAC5D,QAAI,CAAC,IAAK,QAAO;AACjB,WAAO,KAAK,QAAQ,SAAS,GAAG,OAAO,GAAG,GAAG,EAAE;AAAA,EACjD;AAEA,QAAM,eAAe,CAAC,SAA6B;AACjD,UAAM,SAAS,IAAI,gBAAgB;AACnC,QAAI,MAAM,OAAQ,QAAO,IAAI,UAAU,KAAK,MAAM;AAClD,QAAI,MAAM,SAAS,OAAQ,QAAO,IAAI,WAAW,KAAK,QAAQ,KAAK,GAAG,CAAC;AACvE,UAAM,KAAK,OAAO,SAAS;AAC3B,WAAO,KAAK,IAAI,EAAE,KAAK;AAAA,EACzB;AAEA,QAAM,uBAAuB,CAAC,SAAwC;AACpE,WAAO,IAAI,MAAM,CAAC,GAA4B;AAAA,MAC5C,IAAI,SAAS,MAAM;AACjB,YAAI,SAAS,OAAO;AAClB,iBAAO,CAAC,SACN;AAAA,YACE;AAAA,cACE,GAAG,OAAO,aAAa,IAAI;AAAA,cAC3B,aAAa,MAAM,QAAQ,MAAM;AAAA,cACjC,aAAa,IAAI;AAAA,YACnB;AAAA,YACA,MAAM;AAAA,UACR;AAAA,QACJ;AACA,cAAM,QAAQ,OAAO,SAAS,WAAW,SAAS,MAAM,EAAE,IAAI;AAC9D,YAAI,CAAC,MAAM,KAAK,GAAG;AACjB,iBAAO;AAAA,YACL,KAAK,CAAC,SAAkD;AACtD,oBAAM,SAAS,MAAM,SAAS,WAAW,KAAK,MAAM,KAAK;AACzD,qBAAO;AAAA,gBACL;AAAA,kBACE,GAAG,OAAO,aAAa,IAAI,IAAI,KAAK;AAAA,kBACpC,aAAa,MAAM,QAAQ,MAAM;AAAA,kBACjC;AAAA,gBACF;AAAA,gBACA,MAAM;AAAA,cACR;AAAA,YACF;AAAA,UACF;AAAA,QACF;AACA,eAAO;AAAA,MACT;AAAA,IACF,CAAC;AAAA,EACH;AAGA,QAAM,QAAQ,CAAC,SAAiB,KAAa,wBAAiC;AAC5E,UAAM,SAAS,oBAAoB,mBAAmB;AACtD,UAAM,UAAU,gBAAgB;AAChC,UAAM,MAAM,UAAU;AACtB,UAAM,WAAW,GAAG,OAAO,OAAO,OAAO,IAAI,GAAG;AAChD,QAAI,CAAC,IAAK,QAAO;AACjB,WAAO,SAAS,QAAQ,SAAS,GAAG,OAAO,GAAG,GAAG,EAAE;AAAA,EACrD;AAEA,QAAM,aAAa,CAAC,aAA6B;AAAA,IAC/C,KAAK,CAAC,SAAoC,MAAM,OAAO,OAAO,GAAG,OAAO,MAAM,WAAW;AAAA,IACzF,IAAI,MAAM,MAAM,OAAO,OAAO,GAAG,IAAI;AAAA,IACrC,MAAM,MAAM,MAAM,OAAO,OAAO,GAAG,MAAM;AAAA,EAC3C;AAEA,QAAM,cAAc,CAAC,aAAkC;AAAA,IACrD,IAAI,MAAM,MAAM,SAAS,IAAI;AAAA,IAC7B,MAAM,MAAM,MAAM,SAAS,MAAM;AAAA,EACnC;AAEA,QAAM,KAAc,IAAI,MAAM,CAAC,GAAc;AAAA,IAC3C,IAAI,SAAS,MAAM;AACjB,UAAI,SAAS,SAAS;AACpB,eAAO,CAAC,OAAe,QAAgB,YAAY,GAAG,KAAK,IAAI,GAAG,EAAE;AAAA,MACtE;AACA,UAAI,SAAS,QAAQ;AACnB,eAAO,IAAI,UAAoB,YAAY,MAAM,KAAK,GAAG,CAAC;AAAA,MAC5D;AACA,YAAM,UAAU,OAAO,SAAS,WAAW,SAAS,MAAM,EAAE,IAAI;AAChE,UAAI,CAAC,MAAM,OAAO,GAAG;AACnB,eAAO,WAAW,OAAO;AAAA,MAC3B;AACA,aAAO;AAAA,IACT;AAAA,EACF,CAAC;AAED,SAAO;AAAA,IACL,KAAK,CAAC,SACJ;AAAA,MACE,aAAa,SAAS,aAAa,MAAM,QAAQ,MAAM,GAAG,aAAa,IAAI,CAAC;AAAA,MAC5E,MAAM;AAAA,IACR;AAAA,IACF,WAAW;AAAA,MACT,KAAK,MAAM,MAAM,KAAK,KAAK;AAAA,IAC7B;AAAA,IACA,MAAM;AAAA,MACJ,IAAI,MAAM,GAAG,OAAO;AAAA,IACtB;AAAA,IACA,UAAU,MAAM,GAAG,IAAI,aAAa,mBAAmB,UAAU,CAAC;AAAA,IAClE;AAAA,IACA,UAAU;AAAA,MACR,QAAQ,qBAAqB,QAAQ;AAAA,MACrC,SAAS,qBAAqB,SAAS;AAAA,IACzC;AAAA,EACF;AACF;","names":[]}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
OkraClient
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-4RJBVZJL.js";
|
|
4
4
|
|
|
5
5
|
// src/providers.ts
|
|
6
6
|
function isPlainObject(value) {
|
|
@@ -81,4 +81,4 @@ export {
|
|
|
81
81
|
withQualityScore,
|
|
82
82
|
withSecret
|
|
83
83
|
};
|
|
84
|
-
//# sourceMappingURL=chunk-
|
|
84
|
+
//# sourceMappingURL=chunk-FS55NWKZ.js.map
|