@layervai/qurl 0.2.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.
@@ -0,0 +1,125 @@
1
+ import type { QURLErrorData } from "./types.js";
2
+ /**
3
+ * Sentinel `.code` values for SDK-internal failure modes (no real HTTP
4
+ * status applies). Exported as constants so consumers branching on
5
+ * `.code` don't have to duplicate string literals — e.g.
6
+ * `if (err.code === ERROR_CODE_CLIENT_VALIDATION) ...`.
7
+ *
8
+ * Server-driven `.code` values (e.g. `"rate_limited"`, `"forbidden"`)
9
+ * come from the API and aren't enumerated here — branch on the typed
10
+ * error subclass (`RateLimitError`, `AuthorizationError`, …) instead.
11
+ */
12
+ export declare const ERROR_CODE_CLIENT_VALIDATION = "client_validation";
13
+ export declare const ERROR_CODE_UNEXPECTED_RESPONSE = "unexpected_response";
14
+ export declare const ERROR_CODE_NETWORK = "network_error";
15
+ export declare const ERROR_CODE_TIMEOUT = "timeout";
16
+ export declare const ERROR_CODE_RUNTIME = "runtime_error";
17
+ /** Fallback `.code` when the server returns a non-RFC-7807 response (HTML proxy page, plaintext gateway error, JSON without `error` envelope). */
18
+ export declare const ERROR_CODE_UNKNOWN = "unknown";
19
+ /**
20
+ * Base error thrown by the qURL API client. Catch this to handle all SDK errors.
21
+ *
22
+ * **`status: 0` convention:** Client-detected failures — validation errors
23
+ * (`code: "client_validation"`), unexpected response shapes
24
+ * (`code: "unexpected_response"`), runtime capability errors
25
+ * (`code: "runtime_error"`), network errors (`code: "network_error"`), and
26
+ * timeouts (`code: "timeout"`) — all use `status: 0` because no real HTTP
27
+ * status code applies. To distinguish between these cases, branch on `.code`
28
+ * rather than `.status`. Non-zero `.status` always reflects a real HTTP
29
+ * status from the API (e.g. 400, 401, 429, 500).
30
+ *
31
+ * **`.code === "unknown"`** is a possible value when the server returns a
32
+ * non-RFC-7807 response (e.g. a Cloudflare HTML error page, a gateway
33
+ * timeout with a plaintext body, or a JSON body whose `error` envelope
34
+ * is missing). The HTTP `.status` is still real in those cases — use
35
+ * `.status` for the route, `.code` for the SDK-vs-API discriminant.
36
+ */
37
+ export declare class QURLError extends Error {
38
+ readonly status: number;
39
+ readonly code: string;
40
+ /**
41
+ * Human-readable error detail. **Always non-empty** — when the API
42
+ * omits `detail` (RFC 7807 allows this), the constructor falls back
43
+ * to `title`. Callers never need to null-check this property, even
44
+ * though `QURLErrorData.detail` is optional on the wire type.
45
+ */
46
+ readonly detail: string;
47
+ /** RFC 7807 problem-type URI, if the API includes one. */
48
+ readonly type?: string;
49
+ /** RFC 7807 occurrence URI, if the API includes one. */
50
+ readonly instance?: string;
51
+ readonly invalidFields?: Record<string, string>;
52
+ readonly requestId?: string;
53
+ readonly retryAfter?: number;
54
+ constructor(data: QURLErrorData);
55
+ }
56
+ /** 401 Unauthorized — invalid or missing API key. */
57
+ export declare class AuthenticationError extends QURLError {
58
+ constructor(data: QURLErrorData);
59
+ }
60
+ /** 403 Forbidden — valid key but insufficient permissions/scope. */
61
+ export declare class AuthorizationError extends QURLError {
62
+ constructor(data: QURLErrorData);
63
+ }
64
+ /** 404 Not Found — resource does not exist. */
65
+ export declare class NotFoundError extends QURLError {
66
+ constructor(data: QURLErrorData);
67
+ }
68
+ /**
69
+ * 400/422 — invalid request parameters. Check `invalidFields` for per-field details.
70
+ *
71
+ * **Note:** This class covers two distinct failure modes:
72
+ * - `code: "client_validation"` — client-side preflight failures (bad
73
+ * input caught before a round-trip).
74
+ * - `code: "unexpected_response"` — the server returned a response body
75
+ * whose shape doesn't match the expected contract (e.g. a proxy
76
+ * returning HTML on a passthrough status, or a batch response missing
77
+ * required fields).
78
+ *
79
+ * `instanceof ValidationError` catches both. To distinguish them, check
80
+ * `.code` rather than using `instanceof` alone.
81
+ *
82
+ * **`.status` asymmetry within `code: "unexpected_response"`:**
83
+ * - Shape-guard failure on a parsed JSON body (wrong field types,
84
+ * counts/length mismatch, per-entry contract violation): `.status`
85
+ * is `0`. The HTTP status that produced the bad body is appended
86
+ * to `.detail` as `(HTTP 400)` / `(HTTP 207)` etc. for diagnostics.
87
+ * - Non-JSON body on a 2xx or passthrough status (e.g. proxy HTML
88
+ * error page, plaintext gateway error, truncated body): `.status`
89
+ * is the actual HTTP status (e.g. `400`, `200`).
90
+ *
91
+ * Consumers branching purely on `.status` should branch on `.code`
92
+ * first, then `.detail` for shape-guard cases. See #59 for tracking
93
+ * a future unification of the two paths.
94
+ */
95
+ export declare class ValidationError extends QURLError {
96
+ constructor(data: QURLErrorData);
97
+ }
98
+ /** 429 Too Many Requests. Check `retryAfter` for the server-suggested wait time. */
99
+ export declare class RateLimitError extends QURLError {
100
+ constructor(data: QURLErrorData);
101
+ }
102
+ /** 5xx server-side error. */
103
+ export declare class ServerError extends QURLError {
104
+ constructor(data: QURLErrorData);
105
+ }
106
+ /** Transport-level error — DNS failure, connection refused, etc. */
107
+ export declare class NetworkError extends QURLError {
108
+ constructor(message: string, options?: {
109
+ cause?: unknown;
110
+ });
111
+ }
112
+ /** Request timed out. */
113
+ export declare class TimeoutError extends QURLError {
114
+ constructor(message?: string, options?: {
115
+ cause?: unknown;
116
+ });
117
+ }
118
+ /** SDK runtime capability error — unsupported JS runtime, missing Web Crypto, etc. */
119
+ export declare class RuntimeError extends QURLError {
120
+ constructor(message: string, options?: {
121
+ cause?: unknown;
122
+ });
123
+ }
124
+ /** Create the appropriate QURLError subclass for an HTTP status code. */
125
+ export declare function createError(data: QURLErrorData): QURLError;
@@ -0,0 +1,208 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RuntimeError = exports.TimeoutError = exports.NetworkError = exports.ServerError = exports.RateLimitError = exports.ValidationError = exports.NotFoundError = exports.AuthorizationError = exports.AuthenticationError = exports.QURLError = exports.ERROR_CODE_UNKNOWN = exports.ERROR_CODE_RUNTIME = exports.ERROR_CODE_TIMEOUT = exports.ERROR_CODE_NETWORK = exports.ERROR_CODE_UNEXPECTED_RESPONSE = exports.ERROR_CODE_CLIENT_VALIDATION = void 0;
4
+ exports.createError = createError;
5
+ /**
6
+ * Sentinel `.code` values for SDK-internal failure modes (no real HTTP
7
+ * status applies). Exported as constants so consumers branching on
8
+ * `.code` don't have to duplicate string literals — e.g.
9
+ * `if (err.code === ERROR_CODE_CLIENT_VALIDATION) ...`.
10
+ *
11
+ * Server-driven `.code` values (e.g. `"rate_limited"`, `"forbidden"`)
12
+ * come from the API and aren't enumerated here — branch on the typed
13
+ * error subclass (`RateLimitError`, `AuthorizationError`, …) instead.
14
+ */
15
+ exports.ERROR_CODE_CLIENT_VALIDATION = "client_validation";
16
+ exports.ERROR_CODE_UNEXPECTED_RESPONSE = "unexpected_response";
17
+ exports.ERROR_CODE_NETWORK = "network_error";
18
+ exports.ERROR_CODE_TIMEOUT = "timeout";
19
+ exports.ERROR_CODE_RUNTIME = "runtime_error";
20
+ /** Fallback `.code` when the server returns a non-RFC-7807 response (HTML proxy page, plaintext gateway error, JSON without `error` envelope). */
21
+ exports.ERROR_CODE_UNKNOWN = "unknown";
22
+ /**
23
+ * Base error thrown by the qURL API client. Catch this to handle all SDK errors.
24
+ *
25
+ * **`status: 0` convention:** Client-detected failures — validation errors
26
+ * (`code: "client_validation"`), unexpected response shapes
27
+ * (`code: "unexpected_response"`), runtime capability errors
28
+ * (`code: "runtime_error"`), network errors (`code: "network_error"`), and
29
+ * timeouts (`code: "timeout"`) — all use `status: 0` because no real HTTP
30
+ * status code applies. To distinguish between these cases, branch on `.code`
31
+ * rather than `.status`. Non-zero `.status` always reflects a real HTTP
32
+ * status from the API (e.g. 400, 401, 429, 500).
33
+ *
34
+ * **`.code === "unknown"`** is a possible value when the server returns a
35
+ * non-RFC-7807 response (e.g. a Cloudflare HTML error page, a gateway
36
+ * timeout with a plaintext body, or a JSON body whose `error` envelope
37
+ * is missing). The HTTP `.status` is still real in those cases — use
38
+ * `.status` for the route, `.code` for the SDK-vs-API discriminant.
39
+ */
40
+ class QURLError extends Error {
41
+ status;
42
+ code;
43
+ /**
44
+ * Human-readable error detail. **Always non-empty** — when the API
45
+ * omits `detail` (RFC 7807 allows this), the constructor falls back
46
+ * to `title`. Callers never need to null-check this property, even
47
+ * though `QURLErrorData.detail` is optional on the wire type.
48
+ */
49
+ detail;
50
+ /** RFC 7807 problem-type URI, if the API includes one. */
51
+ type;
52
+ /** RFC 7807 occurrence URI, if the API includes one. */
53
+ instance;
54
+ invalidFields;
55
+ requestId;
56
+ retryAfter;
57
+ constructor(data) {
58
+ // RFC 7807 leaves `detail` optional; the API can legitimately omit it and
59
+ // `title` is required, so falling back to title keeps the Error.message
60
+ // meaningful instead of "Title (400): undefined".
61
+ const detail = data.detail ?? data.title;
62
+ super(`${data.title} (${data.status}): ${detail}`);
63
+ this.name = "QURLError";
64
+ this.status = data.status;
65
+ this.code = data.code;
66
+ this.detail = detail;
67
+ this.type = data.type;
68
+ this.instance = data.instance;
69
+ this.invalidFields = data.invalid_fields;
70
+ this.requestId = data.request_id;
71
+ this.retryAfter = data.retry_after;
72
+ }
73
+ }
74
+ exports.QURLError = QURLError;
75
+ /** 401 Unauthorized — invalid or missing API key. */
76
+ class AuthenticationError extends QURLError {
77
+ constructor(data) {
78
+ super(data);
79
+ this.name = "AuthenticationError";
80
+ }
81
+ }
82
+ exports.AuthenticationError = AuthenticationError;
83
+ /** 403 Forbidden — valid key but insufficient permissions/scope. */
84
+ class AuthorizationError extends QURLError {
85
+ constructor(data) {
86
+ super(data);
87
+ this.name = "AuthorizationError";
88
+ }
89
+ }
90
+ exports.AuthorizationError = AuthorizationError;
91
+ /** 404 Not Found — resource does not exist. */
92
+ class NotFoundError extends QURLError {
93
+ constructor(data) {
94
+ super(data);
95
+ this.name = "NotFoundError";
96
+ }
97
+ }
98
+ exports.NotFoundError = NotFoundError;
99
+ /**
100
+ * 400/422 — invalid request parameters. Check `invalidFields` for per-field details.
101
+ *
102
+ * **Note:** This class covers two distinct failure modes:
103
+ * - `code: "client_validation"` — client-side preflight failures (bad
104
+ * input caught before a round-trip).
105
+ * - `code: "unexpected_response"` — the server returned a response body
106
+ * whose shape doesn't match the expected contract (e.g. a proxy
107
+ * returning HTML on a passthrough status, or a batch response missing
108
+ * required fields).
109
+ *
110
+ * `instanceof ValidationError` catches both. To distinguish them, check
111
+ * `.code` rather than using `instanceof` alone.
112
+ *
113
+ * **`.status` asymmetry within `code: "unexpected_response"`:**
114
+ * - Shape-guard failure on a parsed JSON body (wrong field types,
115
+ * counts/length mismatch, per-entry contract violation): `.status`
116
+ * is `0`. The HTTP status that produced the bad body is appended
117
+ * to `.detail` as `(HTTP 400)` / `(HTTP 207)` etc. for diagnostics.
118
+ * - Non-JSON body on a 2xx or passthrough status (e.g. proxy HTML
119
+ * error page, plaintext gateway error, truncated body): `.status`
120
+ * is the actual HTTP status (e.g. `400`, `200`).
121
+ *
122
+ * Consumers branching purely on `.status` should branch on `.code`
123
+ * first, then `.detail` for shape-guard cases. See #59 for tracking
124
+ * a future unification of the two paths.
125
+ */
126
+ class ValidationError extends QURLError {
127
+ constructor(data) {
128
+ super(data);
129
+ this.name = "ValidationError";
130
+ }
131
+ }
132
+ exports.ValidationError = ValidationError;
133
+ /** 429 Too Many Requests. Check `retryAfter` for the server-suggested wait time. */
134
+ class RateLimitError extends QURLError {
135
+ constructor(data) {
136
+ super(data);
137
+ this.name = "RateLimitError";
138
+ }
139
+ }
140
+ exports.RateLimitError = RateLimitError;
141
+ /** 5xx server-side error. */
142
+ class ServerError extends QURLError {
143
+ constructor(data) {
144
+ super(data);
145
+ this.name = "ServerError";
146
+ }
147
+ }
148
+ exports.ServerError = ServerError;
149
+ /** Transport-level error — DNS failure, connection refused, etc. */
150
+ class NetworkError extends QURLError {
151
+ constructor(message, options) {
152
+ super({ status: 0, code: exports.ERROR_CODE_NETWORK, title: "Network Error", detail: message });
153
+ this.name = "NetworkError";
154
+ if (options?.cause) {
155
+ this.cause = options.cause;
156
+ }
157
+ }
158
+ }
159
+ exports.NetworkError = NetworkError;
160
+ /** Request timed out. */
161
+ class TimeoutError extends QURLError {
162
+ constructor(message = "Request timed out", options) {
163
+ super({ status: 0, code: exports.ERROR_CODE_TIMEOUT, title: "Timeout", detail: message });
164
+ this.name = "TimeoutError";
165
+ if (options?.cause) {
166
+ this.cause = options.cause;
167
+ }
168
+ }
169
+ }
170
+ exports.TimeoutError = TimeoutError;
171
+ /** SDK runtime capability error — unsupported JS runtime, missing Web Crypto, etc. */
172
+ class RuntimeError extends QURLError {
173
+ constructor(message, options) {
174
+ super({ status: 0, code: exports.ERROR_CODE_RUNTIME, title: "Runtime Error", detail: message });
175
+ this.name = "RuntimeError";
176
+ if (options && "cause" in options) {
177
+ this.cause = options.cause;
178
+ }
179
+ }
180
+ }
181
+ exports.RuntimeError = RuntimeError;
182
+ const STATUS_ERROR_MAP = {
183
+ 400: ValidationError,
184
+ 401: AuthenticationError,
185
+ 403: AuthorizationError,
186
+ 404: NotFoundError,
187
+ 422: ValidationError,
188
+ 429: RateLimitError,
189
+ };
190
+ /** Create the appropriate QURLError subclass for an HTTP status code. */
191
+ function createError(data) {
192
+ // Route by code first for SDK-internal failure modes that aren't a
193
+ // function of the HTTP status. `unexpected_response` is the canonical
194
+ // case: a 200 body with malformed JSON, a 500 body that isn't an
195
+ // error envelope, and a 400 body that isn't a batch result are all
196
+ // the same SDK failure (server returned a shape we can't interpret).
197
+ // Routing them all to `ValidationError` keeps `instanceof
198
+ // ValidationError` complete for code === "unexpected_response", as
199
+ // documented on the class.
200
+ if (data.code === exports.ERROR_CODE_UNEXPECTED_RESPONSE) {
201
+ return new ValidationError(data);
202
+ }
203
+ if (data.status >= 500) {
204
+ return new ServerError(data);
205
+ }
206
+ const ErrorClass = STATUS_ERROR_MAP[data.status] ?? QURLError;
207
+ return new ErrorClass(data);
208
+ }
@@ -0,0 +1,4 @@
1
+ export { QURLClient } from "./client.js";
2
+ export { AuthenticationError, AuthorizationError, createError, ERROR_CODE_CLIENT_VALIDATION, ERROR_CODE_NETWORK, ERROR_CODE_RUNTIME, ERROR_CODE_TIMEOUT, ERROR_CODE_UNEXPECTED_RESPONSE, ERROR_CODE_UNKNOWN, NetworkError, NotFoundError, QURLError, RateLimitError, RuntimeError, ServerError, TimeoutError, ValidationError, } from "./errors.js";
3
+ export { VERSION } from "./version.js";
4
+ export type { AccessCode, AccessCodeListOutput, AccessGrant, AccessPolicy, AccessToken, AgentBootstrapInput, AgentBootstrapOutput, AIAgentCategory, AIAgentPolicy, ApiKey, ApiKeyListOutput, ApiKeyScope, BatchCreateInput, BatchCreateOutput, BatchItemFailure, BatchItemResult, BatchItemSuccess, BillingInvoiceListOutput, ClientOptions, ConnectorInstallation, ConnectorInstallationCapabilities, ConnectorInstallationListOutput, ConnectorInstallationStats, CreateAccessCodeInput, CreateAccessCodeOutput, CreateApiKeyInput, CreateApiKeyOutput, CreateBillingCheckoutInput, CreateInput, CreateOutput, CreateQurlForResourceInput, CreateResourceInput, CreateWebhookInput, Customer, CheckoutSession, DnsRecord, Domain, DomainCheckDetail, DomainListOutput, DomainVerifyResult, ExtendInput, Invoice, ListApiKeysInput, ListBillingInvoicesInput, ListConnectorInstallationsInput, ListDomainsInput, ListInput, ListOutput, ListWebhooksInput, ListWebhookDeliveriesInput, Meta, MintInput, MintOutput, NHPServerPeerInfo, PaginatedOutput, PortalSession, QURL, QURLErrorData, QurlSummary, Quota, RedeemAccessCodeInput, RedeemAccessCodeOutput, RegisterDomainInput, Resource, ResourceDetail, ResourceListInput, ResourceListOutput, ResourceType, RequestOptions, ResolveInput, ResolveOutput, Session, SessionListOutput, SessionTerminateOutput, TombstoneInfo, UnpaginatedOutput, UpdateApiKeyInput, UpdateCustomerInput, UpdateInput, UpdateResourceInput, UpdateResourceQurlInput, UpdateWebhookInput, UsageCostEstimate, UsageCurrentPeriod, UsageDaily, UsageDailyEntry, Webhook, WebhookDelivery, WebhookDeliveryListOutput, WebhookEventType, WebhookEventTypeInfo, WebhookListOutput, WebhookPayload, WebhookWithSecret, } from "./types.js";
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.VERSION = exports.ValidationError = exports.TimeoutError = exports.ServerError = exports.RuntimeError = exports.RateLimitError = exports.QURLError = exports.NotFoundError = exports.NetworkError = exports.ERROR_CODE_UNKNOWN = exports.ERROR_CODE_UNEXPECTED_RESPONSE = exports.ERROR_CODE_TIMEOUT = exports.ERROR_CODE_RUNTIME = exports.ERROR_CODE_NETWORK = exports.ERROR_CODE_CLIENT_VALIDATION = exports.createError = exports.AuthorizationError = exports.AuthenticationError = exports.QURLClient = void 0;
4
+ var client_js_1 = require("./client.js");
5
+ Object.defineProperty(exports, "QURLClient", { enumerable: true, get: function () { return client_js_1.QURLClient; } });
6
+ var errors_js_1 = require("./errors.js");
7
+ Object.defineProperty(exports, "AuthenticationError", { enumerable: true, get: function () { return errors_js_1.AuthenticationError; } });
8
+ Object.defineProperty(exports, "AuthorizationError", { enumerable: true, get: function () { return errors_js_1.AuthorizationError; } });
9
+ Object.defineProperty(exports, "createError", { enumerable: true, get: function () { return errors_js_1.createError; } });
10
+ Object.defineProperty(exports, "ERROR_CODE_CLIENT_VALIDATION", { enumerable: true, get: function () { return errors_js_1.ERROR_CODE_CLIENT_VALIDATION; } });
11
+ Object.defineProperty(exports, "ERROR_CODE_NETWORK", { enumerable: true, get: function () { return errors_js_1.ERROR_CODE_NETWORK; } });
12
+ Object.defineProperty(exports, "ERROR_CODE_RUNTIME", { enumerable: true, get: function () { return errors_js_1.ERROR_CODE_RUNTIME; } });
13
+ Object.defineProperty(exports, "ERROR_CODE_TIMEOUT", { enumerable: true, get: function () { return errors_js_1.ERROR_CODE_TIMEOUT; } });
14
+ Object.defineProperty(exports, "ERROR_CODE_UNEXPECTED_RESPONSE", { enumerable: true, get: function () { return errors_js_1.ERROR_CODE_UNEXPECTED_RESPONSE; } });
15
+ Object.defineProperty(exports, "ERROR_CODE_UNKNOWN", { enumerable: true, get: function () { return errors_js_1.ERROR_CODE_UNKNOWN; } });
16
+ Object.defineProperty(exports, "NetworkError", { enumerable: true, get: function () { return errors_js_1.NetworkError; } });
17
+ Object.defineProperty(exports, "NotFoundError", { enumerable: true, get: function () { return errors_js_1.NotFoundError; } });
18
+ Object.defineProperty(exports, "QURLError", { enumerable: true, get: function () { return errors_js_1.QURLError; } });
19
+ Object.defineProperty(exports, "RateLimitError", { enumerable: true, get: function () { return errors_js_1.RateLimitError; } });
20
+ Object.defineProperty(exports, "RuntimeError", { enumerable: true, get: function () { return errors_js_1.RuntimeError; } });
21
+ Object.defineProperty(exports, "ServerError", { enumerable: true, get: function () { return errors_js_1.ServerError; } });
22
+ Object.defineProperty(exports, "TimeoutError", { enumerable: true, get: function () { return errors_js_1.TimeoutError; } });
23
+ Object.defineProperty(exports, "ValidationError", { enumerable: true, get: function () { return errors_js_1.ValidationError; } });
24
+ var version_js_1 = require("./version.js");
25
+ Object.defineProperty(exports, "VERSION", { enumerable: true, get: function () { return version_js_1.VERSION; } });
@@ -0,0 +1 @@
1
+ {"type":"commonjs"}