@pdfvector/instance-client 0.0.41 → 0.0.44
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/.tsc/lib/errors.d.ts +93 -0
- package/.tsc/lib/errors.js +229 -0
- package/.tsc/lib/index.d.ts +7 -62
- package/.tsc/lib/index.js +39 -101
- package/CHANGELOG.md +24 -0
- package/README.md +147 -11
- package/package.json +4 -5
- package/.tsc/lib/internal.d.ts +0 -5
- package/.tsc/lib/internal.js +0 -4
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
export type PDFVectorErrorCode = "BAD_REQUEST" | "UNAUTHORIZED" | "NOT_FOUND" | "TOO_MANY_REQUESTS" | "CONFLICT" | "NOT_IMPLEMENTED" | "UNPROCESSABLE_CONTENT" | "INTERNAL_SERVER_ERROR";
|
|
2
|
+
export interface PDFVectorErrorOptions {
|
|
3
|
+
code: PDFVectorErrorCode;
|
|
4
|
+
status: number;
|
|
5
|
+
message: string;
|
|
6
|
+
data?: Record<string, unknown> | undefined;
|
|
7
|
+
cause?: unknown;
|
|
8
|
+
}
|
|
9
|
+
type SubclassOptions = Omit<PDFVectorErrorOptions, "code" | "status">;
|
|
10
|
+
export declare class PDFVectorError extends Error {
|
|
11
|
+
readonly code: PDFVectorErrorCode;
|
|
12
|
+
readonly status: number;
|
|
13
|
+
readonly data: Record<string, unknown>;
|
|
14
|
+
readonly requestId?: number;
|
|
15
|
+
readonly documentId?: string;
|
|
16
|
+
readonly userError: boolean;
|
|
17
|
+
constructor(options: PDFVectorErrorOptions);
|
|
18
|
+
}
|
|
19
|
+
export declare class BadRequestError extends PDFVectorError {
|
|
20
|
+
constructor(options: SubclassOptions);
|
|
21
|
+
}
|
|
22
|
+
export declare class UnauthorizedError extends PDFVectorError {
|
|
23
|
+
constructor(options: SubclassOptions);
|
|
24
|
+
}
|
|
25
|
+
export declare class NotFoundError extends PDFVectorError {
|
|
26
|
+
constructor(options: SubclassOptions);
|
|
27
|
+
}
|
|
28
|
+
export declare class TooManyRequestsError extends PDFVectorError {
|
|
29
|
+
readonly limit?: number;
|
|
30
|
+
readonly resetAt?: string;
|
|
31
|
+
constructor(options: SubclassOptions);
|
|
32
|
+
}
|
|
33
|
+
export declare class ConflictError extends PDFVectorError {
|
|
34
|
+
constructor(options: SubclassOptions);
|
|
35
|
+
}
|
|
36
|
+
export declare class NotImplementedError extends PDFVectorError {
|
|
37
|
+
constructor(options: SubclassOptions);
|
|
38
|
+
}
|
|
39
|
+
export declare class UnprocessableContentError extends PDFVectorError {
|
|
40
|
+
constructor(options: SubclassOptions);
|
|
41
|
+
}
|
|
42
|
+
export declare class InternalServerError extends PDFVectorError {
|
|
43
|
+
constructor(options: SubclassOptions);
|
|
44
|
+
}
|
|
45
|
+
export declare class FileTooLargeError extends BadRequestError {
|
|
46
|
+
readonly fileSizeMB?: number;
|
|
47
|
+
readonly limitMB?: number;
|
|
48
|
+
readonly model?: string;
|
|
49
|
+
constructor(options: SubclassOptions);
|
|
50
|
+
}
|
|
51
|
+
export declare class PageLimitExceededError extends BadRequestError {
|
|
52
|
+
readonly pageCount?: number;
|
|
53
|
+
readonly pageLimit?: number;
|
|
54
|
+
readonly model?: string;
|
|
55
|
+
constructor(options: SubclassOptions);
|
|
56
|
+
}
|
|
57
|
+
export declare class PasswordProtectedError extends BadRequestError {
|
|
58
|
+
}
|
|
59
|
+
export declare class UnsupportedFormatError extends BadRequestError {
|
|
60
|
+
readonly format?: string;
|
|
61
|
+
readonly supportedFormats?: string;
|
|
62
|
+
constructor(options: SubclassOptions);
|
|
63
|
+
}
|
|
64
|
+
export declare class URLFetchError extends BadRequestError {
|
|
65
|
+
readonly url?: string;
|
|
66
|
+
readonly statusCode?: number;
|
|
67
|
+
readonly statusText?: string;
|
|
68
|
+
constructor(options: SubclassOptions);
|
|
69
|
+
}
|
|
70
|
+
export declare class TierNotSupportedError extends BadRequestError {
|
|
71
|
+
readonly documentType?: string;
|
|
72
|
+
readonly model?: string;
|
|
73
|
+
readonly allowedTypes?: string[];
|
|
74
|
+
constructor(options: SubclassOptions);
|
|
75
|
+
}
|
|
76
|
+
export declare class InvalidSchemaError extends BadRequestError {
|
|
77
|
+
readonly reason?: string;
|
|
78
|
+
constructor(options: SubclassOptions);
|
|
79
|
+
}
|
|
80
|
+
export declare class NoInputProvidedError extends BadRequestError {
|
|
81
|
+
}
|
|
82
|
+
export declare class EmptyDocumentError extends UnprocessableContentError {
|
|
83
|
+
}
|
|
84
|
+
export declare class NoTextDetectedError extends UnprocessableContentError {
|
|
85
|
+
}
|
|
86
|
+
export declare class ExtractionFailedError extends UnprocessableContentError {
|
|
87
|
+
readonly hint?: string;
|
|
88
|
+
readonly rawText?: string;
|
|
89
|
+
constructor(options: SubclassOptions);
|
|
90
|
+
}
|
|
91
|
+
export declare function fromORPCError(error: unknown): PDFVectorError | undefined;
|
|
92
|
+
export declare function isPDFVectorError(error: unknown): error is PDFVectorError;
|
|
93
|
+
export {};
|
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
import { ORPCError } from "@pdfvector/instance-contract";
|
|
2
|
+
function readNumber(data, key) {
|
|
3
|
+
const value = data?.[key];
|
|
4
|
+
return typeof value === "number" ? value : undefined;
|
|
5
|
+
}
|
|
6
|
+
function readString(data, key) {
|
|
7
|
+
const value = data?.[key];
|
|
8
|
+
return typeof value === "string" ? value : undefined;
|
|
9
|
+
}
|
|
10
|
+
function readStringArray(data, key) {
|
|
11
|
+
const value = data?.[key];
|
|
12
|
+
if (!Array.isArray(value))
|
|
13
|
+
return undefined;
|
|
14
|
+
const strings = value.filter((v) => typeof v === "string");
|
|
15
|
+
return strings.length === value.length ? strings : undefined;
|
|
16
|
+
}
|
|
17
|
+
export class PDFVectorError extends Error {
|
|
18
|
+
code;
|
|
19
|
+
status;
|
|
20
|
+
data;
|
|
21
|
+
requestId;
|
|
22
|
+
documentId;
|
|
23
|
+
userError;
|
|
24
|
+
constructor(options) {
|
|
25
|
+
super(options.message, options.cause ? { cause: options.cause } : undefined);
|
|
26
|
+
this.name = new.target.name;
|
|
27
|
+
this.code = options.code;
|
|
28
|
+
this.status = options.status;
|
|
29
|
+
this.data = options.data ?? {};
|
|
30
|
+
this.requestId = readNumber(this.data, "requestId");
|
|
31
|
+
this.documentId = readString(this.data, "documentId");
|
|
32
|
+
this.userError = this.data.userError === true;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
export class BadRequestError extends PDFVectorError {
|
|
36
|
+
constructor(options) {
|
|
37
|
+
super({ ...options, code: "BAD_REQUEST", status: 400 });
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
export class UnauthorizedError extends PDFVectorError {
|
|
41
|
+
constructor(options) {
|
|
42
|
+
super({ ...options, code: "UNAUTHORIZED", status: 401 });
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
export class NotFoundError extends PDFVectorError {
|
|
46
|
+
constructor(options) {
|
|
47
|
+
super({ ...options, code: "NOT_FOUND", status: 404 });
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
export class TooManyRequestsError extends PDFVectorError {
|
|
51
|
+
limit;
|
|
52
|
+
resetAt;
|
|
53
|
+
constructor(options) {
|
|
54
|
+
super({ ...options, code: "TOO_MANY_REQUESTS", status: 429 });
|
|
55
|
+
this.limit = readNumber(options.data, "limit");
|
|
56
|
+
this.resetAt = readString(options.data, "resetAt");
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
export class ConflictError extends PDFVectorError {
|
|
60
|
+
constructor(options) {
|
|
61
|
+
super({ ...options, code: "CONFLICT", status: 409 });
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
export class NotImplementedError extends PDFVectorError {
|
|
65
|
+
constructor(options) {
|
|
66
|
+
super({ ...options, code: "NOT_IMPLEMENTED", status: 501 });
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
export class UnprocessableContentError extends PDFVectorError {
|
|
70
|
+
constructor(options) {
|
|
71
|
+
super({ ...options, code: "UNPROCESSABLE_CONTENT", status: 422 });
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
export class InternalServerError extends PDFVectorError {
|
|
75
|
+
constructor(options) {
|
|
76
|
+
super({ ...options, code: "INTERNAL_SERVER_ERROR", status: 500 });
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
export class FileTooLargeError extends BadRequestError {
|
|
80
|
+
fileSizeMB;
|
|
81
|
+
limitMB;
|
|
82
|
+
model;
|
|
83
|
+
constructor(options) {
|
|
84
|
+
super(options);
|
|
85
|
+
this.fileSizeMB = readNumber(options.data, "fileSizeMB");
|
|
86
|
+
this.limitMB = readNumber(options.data, "limitMB");
|
|
87
|
+
this.model = readString(options.data, "model");
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
export class PageLimitExceededError extends BadRequestError {
|
|
91
|
+
pageCount;
|
|
92
|
+
pageLimit;
|
|
93
|
+
model;
|
|
94
|
+
constructor(options) {
|
|
95
|
+
super(options);
|
|
96
|
+
this.pageCount = readNumber(options.data, "pageCount");
|
|
97
|
+
this.pageLimit = readNumber(options.data, "pageLimit");
|
|
98
|
+
this.model = readString(options.data, "model");
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
export class PasswordProtectedError extends BadRequestError {
|
|
102
|
+
}
|
|
103
|
+
export class UnsupportedFormatError extends BadRequestError {
|
|
104
|
+
format;
|
|
105
|
+
supportedFormats;
|
|
106
|
+
constructor(options) {
|
|
107
|
+
super(options);
|
|
108
|
+
this.format = readString(options.data, "format");
|
|
109
|
+
this.supportedFormats = readString(options.data, "supportedFormats");
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
export class URLFetchError extends BadRequestError {
|
|
113
|
+
url;
|
|
114
|
+
statusCode;
|
|
115
|
+
statusText;
|
|
116
|
+
constructor(options) {
|
|
117
|
+
super(options);
|
|
118
|
+
this.url = readString(options.data, "url");
|
|
119
|
+
this.statusCode = readNumber(options.data, "statusCode");
|
|
120
|
+
this.statusText = readString(options.data, "statusText");
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
export class TierNotSupportedError extends BadRequestError {
|
|
124
|
+
documentType;
|
|
125
|
+
model;
|
|
126
|
+
allowedTypes;
|
|
127
|
+
constructor(options) {
|
|
128
|
+
super(options);
|
|
129
|
+
this.documentType = readString(options.data, "documentType");
|
|
130
|
+
this.model = readString(options.data, "model");
|
|
131
|
+
this.allowedTypes = readStringArray(options.data, "allowedTypes");
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
export class InvalidSchemaError extends BadRequestError {
|
|
135
|
+
reason;
|
|
136
|
+
constructor(options) {
|
|
137
|
+
super(options);
|
|
138
|
+
this.reason = readString(options.data, "reason");
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
export class NoInputProvidedError extends BadRequestError {
|
|
142
|
+
}
|
|
143
|
+
export class EmptyDocumentError extends UnprocessableContentError {
|
|
144
|
+
}
|
|
145
|
+
export class NoTextDetectedError extends UnprocessableContentError {
|
|
146
|
+
}
|
|
147
|
+
export class ExtractionFailedError extends UnprocessableContentError {
|
|
148
|
+
hint;
|
|
149
|
+
rawText;
|
|
150
|
+
constructor(options) {
|
|
151
|
+
super(options);
|
|
152
|
+
this.hint = readString(options.data, "hint");
|
|
153
|
+
this.rawText = readString(options.data, "rawText");
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
const ORPC_CODE_TO_CLASS = {
|
|
157
|
+
BAD_REQUEST: BadRequestError,
|
|
158
|
+
UNAUTHORIZED: UnauthorizedError,
|
|
159
|
+
NOT_FOUND: NotFoundError,
|
|
160
|
+
TOO_MANY_REQUESTS: TooManyRequestsError,
|
|
161
|
+
CONFLICT: ConflictError,
|
|
162
|
+
NOT_IMPLEMENTED: NotImplementedError,
|
|
163
|
+
UNPROCESSABLE_CONTENT: UnprocessableContentError,
|
|
164
|
+
INTERNAL_SERVER_ERROR: InternalServerError,
|
|
165
|
+
};
|
|
166
|
+
function isPDFVectorErrorCode(code) {
|
|
167
|
+
return code in ORPC_CODE_TO_CLASS;
|
|
168
|
+
}
|
|
169
|
+
function selectSpecializedClass(code, message, data) {
|
|
170
|
+
const lower = message.toLowerCase();
|
|
171
|
+
if (code === "BAD_REQUEST") {
|
|
172
|
+
if (lower.includes("password-protected"))
|
|
173
|
+
return PasswordProtectedError;
|
|
174
|
+
if (lower.startsWith("file too large"))
|
|
175
|
+
return FileTooLargeError;
|
|
176
|
+
if (lower.startsWith("document has") &&
|
|
177
|
+
lower.includes("page") &&
|
|
178
|
+
lower.includes("limit"))
|
|
179
|
+
return PageLimitExceededError;
|
|
180
|
+
if (lower.startsWith("file type") &&
|
|
181
|
+
lower.includes("not supported for the"))
|
|
182
|
+
return TierNotSupportedError;
|
|
183
|
+
if (lower.startsWith("invalid json schema"))
|
|
184
|
+
return InvalidSchemaError;
|
|
185
|
+
if (lower.includes("unsupported format") ||
|
|
186
|
+
lower.includes("does not contain any supported document files"))
|
|
187
|
+
return UnsupportedFormatError;
|
|
188
|
+
if (lower.startsWith("failed to fetch document from url") ||
|
|
189
|
+
lower.startsWith("url did not return a supported document") ||
|
|
190
|
+
lower.includes("returned an html page instead of a document"))
|
|
191
|
+
return URLFetchError;
|
|
192
|
+
if (lower.startsWith("no input provided") ||
|
|
193
|
+
lower.startsWith("empty document content"))
|
|
194
|
+
return NoInputProvidedError;
|
|
195
|
+
}
|
|
196
|
+
if (code === "UNPROCESSABLE_CONTENT") {
|
|
197
|
+
if (lower.includes("does not appear to contain any readable text") ||
|
|
198
|
+
lower.includes("does not appear to contain any text"))
|
|
199
|
+
return NoTextDetectedError;
|
|
200
|
+
if (lower.includes("no text content detected") ||
|
|
201
|
+
lower.includes("document appears to be empty"))
|
|
202
|
+
return EmptyDocumentError;
|
|
203
|
+
if (lower.startsWith("failed to extract structured data"))
|
|
204
|
+
return ExtractionFailedError;
|
|
205
|
+
if (data.hint !== undefined || data.rawText !== undefined)
|
|
206
|
+
return ExtractionFailedError;
|
|
207
|
+
}
|
|
208
|
+
return ORPC_CODE_TO_CLASS[code];
|
|
209
|
+
}
|
|
210
|
+
export function fromORPCError(error) {
|
|
211
|
+
if (error instanceof PDFVectorError)
|
|
212
|
+
return error;
|
|
213
|
+
if (!(error instanceof ORPCError))
|
|
214
|
+
return undefined;
|
|
215
|
+
if (!isPDFVectorErrorCode(error.code))
|
|
216
|
+
return undefined;
|
|
217
|
+
const data = error.data != null && typeof error.data === "object"
|
|
218
|
+
? error.data
|
|
219
|
+
: {};
|
|
220
|
+
const ErrorClass = selectSpecializedClass(error.code, error.message, data);
|
|
221
|
+
return new ErrorClass({
|
|
222
|
+
message: error.message,
|
|
223
|
+
data,
|
|
224
|
+
cause: error,
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
export function isPDFVectorError(error) {
|
|
228
|
+
return error instanceof PDFVectorError;
|
|
229
|
+
}
|
package/.tsc/lib/index.d.ts
CHANGED
|
@@ -1,69 +1,14 @@
|
|
|
1
|
-
import type
|
|
2
|
-
import type { contract } from "@pdfvector/instance-contract";
|
|
1
|
+
import { type ContractRouterClient, type contract } from "@pdfvector/instance-contract";
|
|
3
2
|
export interface CreateClientOptions {
|
|
4
|
-
/**
|
|
3
|
+
/** Defaults to "global.pdfvector.com". */
|
|
5
4
|
domain?: string;
|
|
6
|
-
/** API key for Bearer token authentication */
|
|
7
5
|
apiKey?: string;
|
|
8
|
-
/** @internal Server secret */
|
|
9
|
-
secret?: string;
|
|
10
|
-
/** @internal Additional headers merged into every outgoing request (e.g. forwarded IP) */
|
|
11
|
-
forwardedHeaders?: Record<string, string>;
|
|
12
6
|
}
|
|
13
|
-
/** Per-request context passed as the second argument to any API call. */
|
|
14
7
|
export interface ClientContext {
|
|
15
|
-
/**
|
|
8
|
+
/** Optional ID echoed back in responses, used for per-document usage tracking. */
|
|
16
9
|
documentId?: string;
|
|
17
10
|
}
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
* transport-layer failures (DNS, connection refused, timeouts) which surface
|
|
23
|
-
* with `code: "NETWORK_ERROR"` and `status: 0`.
|
|
24
|
-
*
|
|
25
|
-
* @example
|
|
26
|
-
* ```typescript
|
|
27
|
-
* try {
|
|
28
|
-
* await client.document.parse({ url: "..." });
|
|
29
|
-
* } catch (error) {
|
|
30
|
-
* if (error instanceof PDFVectorError) {
|
|
31
|
-
* console.error(error.code); // "UNAUTHORIZED" | "BAD_REQUEST" | "NETWORK_ERROR" | ...
|
|
32
|
-
* console.error(error.status); // 401 | 400 | 422 | 500 | 0 (network)
|
|
33
|
-
* console.error(error.message); // "Invalid API key"
|
|
34
|
-
* console.error(error.userError); // true if the error is caused by user input (illegible upload, etc.)
|
|
35
|
-
* console.error(error.data); // { requestId: 1, userError: true }
|
|
36
|
-
* }
|
|
37
|
-
* }
|
|
38
|
-
* ```
|
|
39
|
-
*/
|
|
40
|
-
export declare class PDFVectorError extends Error {
|
|
41
|
-
/** Error code identifying the type of error */
|
|
42
|
-
readonly code: string;
|
|
43
|
-
/** HTTP status code. `0` for transport-layer failures (see `NETWORK_ERROR`). */
|
|
44
|
-
readonly status: number;
|
|
45
|
-
/** Additional error data from the server (e.g., `requestId`, `userError`) */
|
|
46
|
-
readonly data: unknown;
|
|
47
|
-
/**
|
|
48
|
-
* True when the server flagged this error as caused by user input
|
|
49
|
-
* (e.g. illegible uploads, empty documents) rather than a server-side
|
|
50
|
-
* failure. Mirrors `data.userError === true`.
|
|
51
|
-
*/
|
|
52
|
-
readonly userError: boolean;
|
|
53
|
-
constructor(options: {
|
|
54
|
-
code: string;
|
|
55
|
-
message: string;
|
|
56
|
-
status: number;
|
|
57
|
-
data?: unknown;
|
|
58
|
-
});
|
|
59
|
-
/**
|
|
60
|
-
* Type guard to check if an unknown error is a PDFVectorError.
|
|
61
|
-
*/
|
|
62
|
-
static is(error: unknown): error is PDFVectorError;
|
|
63
|
-
}
|
|
64
|
-
/** @internal */
|
|
65
|
-
export declare function _buildClient(options?: CreateClientOptions): Client;
|
|
66
|
-
export declare function createClient(options?: CreateClientOptions): PublicClient;
|
|
67
|
-
type Client = ContractRouterClient<typeof contract, ClientContext>;
|
|
68
|
-
export type PublicClient = Omit<ContractRouterClient<typeof contract, ClientContext>, "admin" | "free">;
|
|
69
|
-
export type { ContractInputs, ContractOutputs, PDFVectorModel, } from "@pdfvector/instance-contract";
|
|
11
|
+
export type Client = Omit<ContractRouterClient<typeof contract, ClientContext>, "admin" | "free">;
|
|
12
|
+
export declare function createClient(options?: CreateClientOptions): Client;
|
|
13
|
+
export * from "@pdfvector/instance-contract";
|
|
14
|
+
export * from "./errors";
|
package/.tsc/lib/index.js
CHANGED
|
@@ -1,115 +1,53 @@
|
|
|
1
|
-
import { createORPCClient,
|
|
2
|
-
import {
|
|
1
|
+
import { createORPCClient, RPCLink, } from "@pdfvector/instance-contract";
|
|
2
|
+
import { fromORPCError } from "./errors";
|
|
3
3
|
const DEFAULT_DOMAIN = "global.pdfvector.com";
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
/** Additional error data from the server (e.g., `requestId`, `userError`) */
|
|
32
|
-
data;
|
|
33
|
-
/**
|
|
34
|
-
* True when the server flagged this error as caused by user input
|
|
35
|
-
* (e.g. illegible uploads, empty documents) rather than a server-side
|
|
36
|
-
* failure. Mirrors `data.userError === true`.
|
|
37
|
-
*/
|
|
38
|
-
userError;
|
|
39
|
-
constructor(options) {
|
|
40
|
-
super(options.message);
|
|
41
|
-
this.name = "PDFVectorError";
|
|
42
|
-
this.code = options.code;
|
|
43
|
-
this.status = options.status;
|
|
44
|
-
this.data = options.data;
|
|
45
|
-
this.userError =
|
|
46
|
-
options.data != null &&
|
|
47
|
-
typeof options.data === "object" &&
|
|
48
|
-
options.data.userError === true;
|
|
49
|
-
}
|
|
50
|
-
/**
|
|
51
|
-
* Type guard to check if an unknown error is a PDFVectorError.
|
|
52
|
-
*/
|
|
53
|
-
static is(error) {
|
|
54
|
-
return error instanceof PDFVectorError;
|
|
55
|
-
}
|
|
4
|
+
function wrapWithErrorMapping(target) {
|
|
5
|
+
return new Proxy(target, {
|
|
6
|
+
apply(obj, thisArg, args) {
|
|
7
|
+
try {
|
|
8
|
+
const result = Reflect.apply(obj, thisArg, args);
|
|
9
|
+
if (result instanceof Promise) {
|
|
10
|
+
return result.catch((err) => {
|
|
11
|
+
const mapped = fromORPCError(err);
|
|
12
|
+
throw mapped ?? err;
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
return result;
|
|
16
|
+
}
|
|
17
|
+
catch (err) {
|
|
18
|
+
const mapped = fromORPCError(err);
|
|
19
|
+
throw mapped ?? err;
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
get(obj, prop, receiver) {
|
|
23
|
+
const value = Reflect.get(obj, prop, receiver);
|
|
24
|
+
if (value !== null &&
|
|
25
|
+
(typeof value === "object" || typeof value === "function")) {
|
|
26
|
+
return wrapWithErrorMapping(value);
|
|
27
|
+
}
|
|
28
|
+
return value;
|
|
29
|
+
},
|
|
30
|
+
});
|
|
56
31
|
}
|
|
57
|
-
|
|
58
|
-
export function _buildClient(options) {
|
|
32
|
+
export function createClient(options) {
|
|
59
33
|
const domain = options?.domain ?? DEFAULT_DOMAIN;
|
|
60
34
|
const isLocal = domain.startsWith("localhost") || domain.startsWith("127.0.0.1");
|
|
61
35
|
const baseUrl = `${isLocal ? "http" : "https"}://${domain}`;
|
|
62
|
-
const token = options?.apiKey
|
|
63
|
-
const wrappedFetch = async (input, init) => {
|
|
64
|
-
try {
|
|
65
|
-
return await (token
|
|
66
|
-
? fetch(input, init)
|
|
67
|
-
: fetch(input, { ...init, credentials: "include" }));
|
|
68
|
-
}
|
|
69
|
-
catch (err) {
|
|
70
|
-
throw new PDFVectorError({
|
|
71
|
-
code: "NETWORK_ERROR",
|
|
72
|
-
message: err instanceof Error
|
|
73
|
-
? err.message
|
|
74
|
-
: "Network request failed before reaching the server",
|
|
75
|
-
status: 0,
|
|
76
|
-
data: { cause: err },
|
|
77
|
-
});
|
|
78
|
-
}
|
|
79
|
-
};
|
|
36
|
+
const token = options?.apiKey;
|
|
80
37
|
const link = new RPCLink({
|
|
81
38
|
url: `${baseUrl}/rpc`,
|
|
82
39
|
headers: ({ context }) => {
|
|
83
|
-
const headers = {
|
|
84
|
-
|
|
85
|
-
};
|
|
86
|
-
if (token) {
|
|
40
|
+
const headers = {};
|
|
41
|
+
if (token)
|
|
87
42
|
headers.authorization = `Bearer ${token}`;
|
|
88
|
-
|
|
89
|
-
if (context?.documentId) {
|
|
43
|
+
if (context?.documentId)
|
|
90
44
|
headers["x-pdfvector-document-id"] = context.documentId;
|
|
91
|
-
}
|
|
92
45
|
return headers;
|
|
93
46
|
},
|
|
94
|
-
fetch:
|
|
95
|
-
interceptors: [
|
|
96
|
-
onError((error) => {
|
|
97
|
-
if (error instanceof PDFVectorError) {
|
|
98
|
-
throw error;
|
|
99
|
-
}
|
|
100
|
-
if (error instanceof ORPCError) {
|
|
101
|
-
throw new PDFVectorError({
|
|
102
|
-
code: error.code,
|
|
103
|
-
message: error.message,
|
|
104
|
-
status: error.status,
|
|
105
|
-
data: error.data,
|
|
106
|
-
});
|
|
107
|
-
}
|
|
108
|
-
}),
|
|
109
|
-
],
|
|
47
|
+
fetch: (input, init) => fetch(input, token ? init : { ...init, credentials: "include" }),
|
|
110
48
|
});
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
export function createClient(options) {
|
|
114
|
-
return _buildClient(options);
|
|
49
|
+
const raw = createORPCClient(link);
|
|
50
|
+
return wrapWithErrorMapping(raw);
|
|
115
51
|
}
|
|
52
|
+
export * from "@pdfvector/instance-contract";
|
|
53
|
+
export * from "./errors";
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,29 @@
|
|
|
1
1
|
# @pdfvector/instance-client
|
|
2
2
|
|
|
3
|
+
## 0.0.44
|
|
4
|
+
### Patch Changes
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
- [#222](https://github.com/phuctm97/pdfvector/pull/222) [`3b78122`](https://github.com/phuctm97/pdfvector/commit/3b78122a35206b85be4ac61813ad1691ad57b866) Thanks [@khanhduyvt0101](https://github.com/khanhduyvt0101)! - Re-trigger releases for client, instance-client, and gateway-server (previous attempt failed at frozen-lockfile install before publish)
|
|
9
|
+
|
|
10
|
+
## 0.0.43
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
- [#221](https://github.com/phuctm97/pdfvector/pull/221) [`84b9c58`](https://github.com/phuctm97/pdfvector/commit/84b9c58ce1a4f920e163f1666f738c83b3faa5c2) Thanks [@khanhduyvt0101](https://github.com/khanhduyvt0101)! - Add typed PDFVectorError class hierarchy to instance-client SDK
|
|
16
|
+
|
|
17
|
+
## 0.0.42
|
|
18
|
+
### Patch Changes
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
- [#214](https://github.com/phuctm97/pdfvector/pull/214) [`3a1c66b`](https://github.com/phuctm97/pdfvector/commit/3a1c66bcdfade057be5f1b9170f8ed64934bf2a9) Thanks [@khanhduyvt0101](https://github.com/khanhduyvt0101)! - Fix PDFVECTOR-INSTANCE-T and slim instance-client SDK
|
|
23
|
+
|
|
24
|
+
- Updated dependencies [[`3a1c66b`](https://github.com/phuctm97/pdfvector/commit/3a1c66bcdfade057be5f1b9170f8ed64934bf2a9)]:
|
|
25
|
+
- @pdfvector/instance-contract@0.0.41
|
|
26
|
+
|
|
3
27
|
## 0.0.41
|
|
4
28
|
### Patch Changes
|
|
5
29
|
|
package/README.md
CHANGED
|
@@ -580,14 +580,12 @@ console.log(resultB.documentId); // "doc-b"
|
|
|
580
580
|
|
|
581
581
|
## Error Handling
|
|
582
582
|
|
|
583
|
-
All API errors are thrown as `PDFVectorError` instances
|
|
583
|
+
All API errors are thrown as `PDFVectorError` instances. The SDK transparently maps every server error into the most specific subclass it can, so you can branch on the type using `instanceof` and read typed metadata fields directly.
|
|
584
584
|
|
|
585
585
|
```typescript
|
|
586
586
|
import { createClient, PDFVectorError } from "@pdfvector/instance-client";
|
|
587
587
|
|
|
588
|
-
const client = createClient({
|
|
589
|
-
apiKey: "your-api-key",
|
|
590
|
-
});
|
|
588
|
+
const client = createClient({ apiKey: "your-api-key" });
|
|
591
589
|
|
|
592
590
|
try {
|
|
593
591
|
const result = await client.document.parse({
|
|
@@ -598,20 +596,72 @@ try {
|
|
|
598
596
|
if (error instanceof PDFVectorError) {
|
|
599
597
|
console.error(`API Error [${error.code}]: ${error.message}`);
|
|
600
598
|
console.error(`HTTP Status: ${error.status}`);
|
|
601
|
-
console.error(`
|
|
599
|
+
console.error(`Request ID: ${error.requestId}`); // server-assigned, useful for support
|
|
600
|
+
console.error(`Document ID: ${error.documentId}`); // echoed back if you set one
|
|
601
|
+
console.error(`User error: ${error.userError}`); // true if caused by your input
|
|
602
602
|
} else {
|
|
603
|
+
// Network errors (DNS, connection refused, timeout) bubble up as TypeError.
|
|
603
604
|
console.error("Unexpected Error:", error);
|
|
604
605
|
}
|
|
605
606
|
}
|
|
606
607
|
```
|
|
607
608
|
|
|
608
|
-
|
|
609
|
+
### Branching on specific error types
|
|
610
|
+
|
|
611
|
+
Every error class extends `PDFVectorError`, so you can use `instanceof` to handle specific cases. Specialized subclasses expose typed fields pulled from the error's `data` payload:
|
|
612
|
+
|
|
613
|
+
```typescript
|
|
614
|
+
import {
|
|
615
|
+
createClient,
|
|
616
|
+
FileTooLargeError,
|
|
617
|
+
PageLimitExceededError,
|
|
618
|
+
PasswordProtectedError,
|
|
619
|
+
URLFetchError,
|
|
620
|
+
UnauthorizedError,
|
|
621
|
+
TooManyRequestsError,
|
|
622
|
+
EmptyDocumentError,
|
|
623
|
+
ExtractionFailedError,
|
|
624
|
+
PDFVectorError,
|
|
625
|
+
} from "@pdfvector/instance-client";
|
|
626
|
+
|
|
627
|
+
try {
|
|
628
|
+
await client.document.parse({ url: "...", model: "nano" });
|
|
629
|
+
} catch (error) {
|
|
630
|
+
if (error instanceof FileTooLargeError) {
|
|
631
|
+
console.error(
|
|
632
|
+
`File ${error.fileSizeMB}MB exceeds ${error.limitMB}MB limit for the '${error.model}' model`,
|
|
633
|
+
);
|
|
634
|
+
} else if (error instanceof PageLimitExceededError) {
|
|
635
|
+
console.error(
|
|
636
|
+
`Document has ${error.pageCount} pages — ${error.model} only supports up to ${error.pageLimit}`,
|
|
637
|
+
);
|
|
638
|
+
} else if (error instanceof PasswordProtectedError) {
|
|
639
|
+
console.error("Remove the password from the file and try again");
|
|
640
|
+
} else if (error instanceof URLFetchError) {
|
|
641
|
+
console.error(`Could not fetch ${error.url}: ${error.statusCode} ${error.statusText}`);
|
|
642
|
+
} else if (error instanceof UnauthorizedError) {
|
|
643
|
+
console.error("Invalid API key — check your dashboard");
|
|
644
|
+
} else if (error instanceof TooManyRequestsError) {
|
|
645
|
+
console.error(`Rate limit ${error.limit} exceeded; resets at ${error.resetAt}`);
|
|
646
|
+
} else if (error instanceof EmptyDocumentError) {
|
|
647
|
+
console.error("The document has no readable content");
|
|
648
|
+
} else if (error instanceof ExtractionFailedError) {
|
|
649
|
+
console.error(`Extraction failed. Hint: ${error.hint}`);
|
|
650
|
+
if (error.rawText) console.error(`Model output sample: ${error.rawText}`);
|
|
651
|
+
} else if (error instanceof PDFVectorError) {
|
|
652
|
+
// Catch-all for any error code not specifically handled
|
|
653
|
+
console.error(`API Error [${error.code}]: ${error.message}`);
|
|
654
|
+
}
|
|
655
|
+
}
|
|
656
|
+
```
|
|
657
|
+
|
|
658
|
+
You can also branch on the error code if you prefer:
|
|
609
659
|
|
|
610
660
|
```typescript
|
|
611
661
|
try {
|
|
612
662
|
await client.document.parse({ url: "..." });
|
|
613
663
|
} catch (error) {
|
|
614
|
-
if (PDFVectorError
|
|
664
|
+
if (error instanceof PDFVectorError) {
|
|
615
665
|
switch (error.code) {
|
|
616
666
|
case "UNAUTHORIZED":
|
|
617
667
|
console.error("Invalid API key");
|
|
@@ -619,23 +669,83 @@ try {
|
|
|
619
669
|
case "BAD_REQUEST":
|
|
620
670
|
console.error("Validation error:", error.message);
|
|
621
671
|
break;
|
|
672
|
+
case "UNPROCESSABLE_CONTENT":
|
|
673
|
+
console.error("Could not process document:", error.message);
|
|
674
|
+
break;
|
|
622
675
|
case "INTERNAL_SERVER_ERROR":
|
|
623
|
-
console.error(
|
|
676
|
+
console.error(`Server error (requestId: ${error.requestId}):`, error.message);
|
|
624
677
|
break;
|
|
625
678
|
}
|
|
626
679
|
}
|
|
627
680
|
}
|
|
628
681
|
```
|
|
629
682
|
|
|
683
|
+
### Error Class Hierarchy
|
|
684
|
+
|
|
685
|
+
```
|
|
686
|
+
PDFVectorError
|
|
687
|
+
├── BadRequestError (400)
|
|
688
|
+
│ ├── FileTooLargeError — fileSizeMB, limitMB, model
|
|
689
|
+
│ ├── PageLimitExceededError — pageCount, pageLimit, model
|
|
690
|
+
│ ├── PasswordProtectedError
|
|
691
|
+
│ ├── UnsupportedFormatError — format, supportedFormats
|
|
692
|
+
│ ├── URLFetchError — url, statusCode, statusText
|
|
693
|
+
│ ├── TierNotSupportedError — documentType, model, allowedTypes
|
|
694
|
+
│ ├── InvalidSchemaError — reason
|
|
695
|
+
│ └── NoInputProvidedError
|
|
696
|
+
├── UnauthorizedError (401)
|
|
697
|
+
├── NotFoundError (404)
|
|
698
|
+
├── ConflictError (409)
|
|
699
|
+
├── TooManyRequestsError (429) — limit, resetAt
|
|
700
|
+
├── UnprocessableContentError (422)
|
|
701
|
+
│ ├── EmptyDocumentError
|
|
702
|
+
│ ├── NoTextDetectedError
|
|
703
|
+
│ └── ExtractionFailedError — hint, rawText
|
|
704
|
+
├── InternalServerError (500)
|
|
705
|
+
└── NotImplementedError (501)
|
|
706
|
+
```
|
|
707
|
+
|
|
708
|
+
### Common fields on every `PDFVectorError`
|
|
709
|
+
|
|
710
|
+
| Field | Type | Description |
|
|
711
|
+
|-------|------|-------------|
|
|
712
|
+
| `code` | `string` | The ORPC error code (`BAD_REQUEST`, `UNAUTHORIZED`, etc.) |
|
|
713
|
+
| `status` | `number` | HTTP status code (400, 401, 404, 409, 422, 429, 500, 501) |
|
|
714
|
+
| `message` | `string` | Human-readable error message |
|
|
715
|
+
| `data` | `Record<string, unknown>` | Raw error payload from the server |
|
|
716
|
+
| `requestId` | `number \| undefined` | Server-assigned request ID — include in support tickets |
|
|
717
|
+
| `documentId` | `string \| undefined` | Echoed back if you passed `context.documentId` |
|
|
718
|
+
| `userError` | `boolean` | `true` if the failure was caused by your input (vs. a server-side issue) |
|
|
719
|
+
| `cause` | `unknown` | Original error (the underlying `ORPCError` from the wire) |
|
|
720
|
+
|
|
721
|
+
### Type guard
|
|
722
|
+
|
|
723
|
+
If you'd rather not import `PDFVectorError` just to do an `instanceof` check, use the `isPDFVectorError` guard:
|
|
724
|
+
|
|
725
|
+
```typescript
|
|
726
|
+
import { isPDFVectorError } from "@pdfvector/instance-client";
|
|
727
|
+
|
|
728
|
+
try {
|
|
729
|
+
await client.document.parse({ url: "..." });
|
|
730
|
+
} catch (error) {
|
|
731
|
+
if (isPDFVectorError(error)) {
|
|
732
|
+
console.error(error.code, error.message, error.requestId);
|
|
733
|
+
}
|
|
734
|
+
}
|
|
735
|
+
```
|
|
736
|
+
|
|
630
737
|
### Error Codes
|
|
631
738
|
|
|
632
739
|
| Code | Status | Description |
|
|
633
740
|
|------|--------|-------------|
|
|
634
|
-
| `BAD_REQUEST` | 400 | Input validation failed (e.g., missing fields, invalid URL,
|
|
741
|
+
| `BAD_REQUEST` | 400 | Input validation failed (e.g., missing fields, invalid URL, file too large, page limit exceeded, invalid JSON Schema) |
|
|
635
742
|
| `UNAUTHORIZED` | 401 | Missing or invalid API key |
|
|
636
|
-
| `
|
|
743
|
+
| `NOT_FOUND` | 404 | Resource not found (e.g., academic paper ID, version) |
|
|
744
|
+
| `CONFLICT` | 409 | Operation conflicts with the current state |
|
|
745
|
+
| `UNPROCESSABLE_CONTENT` | 422 | Document could not be processed (empty, no readable text, extraction failed) |
|
|
637
746
|
| `TOO_MANY_REQUESTS` | 429 | Rate limit exceeded |
|
|
638
|
-
| `INTERNAL_SERVER_ERROR` | 500 | Server-side failure |
|
|
747
|
+
| `INTERNAL_SERVER_ERROR` | 500 | Server-side failure — capture the `requestId` for support |
|
|
748
|
+
| `NOT_IMPLEMENTED` | 501 | Endpoint not available on this instance |
|
|
639
749
|
|
|
640
750
|
## TypeScript Support
|
|
641
751
|
|
|
@@ -644,7 +754,32 @@ The SDK is written in TypeScript and includes full type definitions:
|
|
|
644
754
|
```typescript
|
|
645
755
|
import {
|
|
646
756
|
createClient,
|
|
757
|
+
isPDFVectorError,
|
|
758
|
+
// Base error class — all errors inherit from this
|
|
647
759
|
PDFVectorError,
|
|
760
|
+
// HTTP-aligned error categories
|
|
761
|
+
BadRequestError,
|
|
762
|
+
UnauthorizedError,
|
|
763
|
+
NotFoundError,
|
|
764
|
+
ConflictError,
|
|
765
|
+
TooManyRequestsError,
|
|
766
|
+
UnprocessableContentError,
|
|
767
|
+
InternalServerError,
|
|
768
|
+
NotImplementedError,
|
|
769
|
+
// Specialized error subclasses with typed metadata
|
|
770
|
+
FileTooLargeError,
|
|
771
|
+
PageLimitExceededError,
|
|
772
|
+
PasswordProtectedError,
|
|
773
|
+
UnsupportedFormatError,
|
|
774
|
+
URLFetchError,
|
|
775
|
+
TierNotSupportedError,
|
|
776
|
+
InvalidSchemaError,
|
|
777
|
+
NoInputProvidedError,
|
|
778
|
+
EmptyDocumentError,
|
|
779
|
+
NoTextDetectedError,
|
|
780
|
+
ExtractionFailedError,
|
|
781
|
+
// Underlying ORPC error — re-exported for advanced use cases
|
|
782
|
+
ORPCError,
|
|
648
783
|
} from "@pdfvector/instance-client";
|
|
649
784
|
|
|
650
785
|
import type {
|
|
@@ -654,6 +789,7 @@ import type {
|
|
|
654
789
|
ContractInputs,
|
|
655
790
|
ContractOutputs,
|
|
656
791
|
PDFVectorModel,
|
|
792
|
+
PDFVectorErrorCode,
|
|
657
793
|
} from "@pdfvector/instance-client";
|
|
658
794
|
```
|
|
659
795
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pdfvector/instance-client",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.44",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Official TypeScript/JavaScript SDK for PDF Vector API - Parse PDF/Word/Image/Excel documents to clean, structured markdown format and search academic publications across multiple databases",
|
|
6
6
|
"license": "MIT",
|
|
@@ -33,12 +33,11 @@
|
|
|
33
33
|
},
|
|
34
34
|
"main": ".tsc/lib/index.js",
|
|
35
35
|
"dependencies": {
|
|
36
|
-
"@
|
|
37
|
-
"@orpc/contract": "^1.13.14",
|
|
38
|
-
"@pdfvector/instance-contract": "^0.0.40"
|
|
36
|
+
"@pdfvector/instance-contract": "^0.0.41"
|
|
39
37
|
},
|
|
40
38
|
"files": [
|
|
41
39
|
".tsc",
|
|
42
|
-
"CHANGELOG.md"
|
|
40
|
+
"CHANGELOG.md",
|
|
41
|
+
"README.md"
|
|
43
42
|
]
|
|
44
43
|
}
|
package/.tsc/lib/internal.d.ts
DELETED
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
import type { ContractRouterClient } from "@orpc/contract";
|
|
2
|
-
import type { contract } from "@pdfvector/instance-contract";
|
|
3
|
-
import { type ClientContext, type CreateClientOptions } from ".";
|
|
4
|
-
export type Client = ContractRouterClient<typeof contract, ClientContext>;
|
|
5
|
-
export declare function createInternalClient(options?: CreateClientOptions): Client;
|
package/.tsc/lib/internal.js
DELETED