@mbsoftsystems/unweb 0.1.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.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 MBSoft Systems
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,281 @@
1
+ # UnWeb TypeScript SDK
2
+
3
+ [![CI](https://github.com/mbsoft-systems/unweb-js/actions/workflows/ci.yml/badge.svg)](https://github.com/mbsoft-systems/unweb-js/actions/workflows/ci.yml)
4
+ [![npm version](https://img.shields.io/npm/v/unweb.svg)](https://www.npmjs.com/package/unweb)
5
+ [![Node 18+](https://img.shields.io/badge/node-18%2B-blue.svg)](https://nodejs.org/)
6
+ [![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](https://opensource.org/licenses/MIT)
7
+
8
+ TypeScript SDK for the [UnWeb API](https://unweb.info) — convert HTML to clean, LLM-ready Markdown for RAG pipelines, AI agents, and documentation ingestion.
9
+
10
+ ## Installation
11
+
12
+ ```bash
13
+ npm install unweb
14
+ ```
15
+
16
+ ## Quick Start
17
+
18
+ ```typescript
19
+ import { UnWebClient } from 'unweb';
20
+
21
+ const client = new UnWebClient({ apiKey: 'unweb_your_key_here' });
22
+
23
+ // Convert HTML to Markdown
24
+ const result = await client.convert.paste('<h1>Hello World</h1><p>Clean markdown output.</p>');
25
+ console.log(result.markdown); // "# Hello World\n\nClean markdown output."
26
+ console.log(result.qualityScore); // 100
27
+
28
+ // Convert a webpage
29
+ const page = await client.convert.url('https://example.com/article');
30
+ console.log(page.markdown);
31
+
32
+ // Upload an HTML file
33
+ const file = await client.convert.upload('./page.html');
34
+ console.log(file.markdown);
35
+ ```
36
+
37
+ Get your free API key at [app.unweb.info](https://app.unweb.info) (500 credits/month, no credit card required).
38
+
39
+ ## Features
40
+
41
+ - **Conversions** — Paste HTML, fetch URLs, or upload files. Returns clean CommonMark with quality scores.
42
+ - **Web Crawler** — Crawl entire documentation sites with BFS traversal. Export as raw Markdown, LangChain JSONL, or LlamaIndex JSON.
43
+ - **Webhook Notifications** — Get notified when crawl jobs complete via HTTPS webhooks.
44
+ - **Dashboard Access** — Manage API keys, view usage, and handle subscriptions programmatically.
45
+ - **Quality Scores** — Every conversion returns a 0–100 quality score detecting JS-rendered pages and content extraction issues.
46
+ - **Fully Typed** — Complete TypeScript types for all requests and responses.
47
+
48
+ ## API Reference
49
+
50
+ ### Conversions
51
+
52
+ All conversion methods return a `ConversionResult` with `markdown`, `warnings`, and `qualityScore`.
53
+
54
+ ```typescript
55
+ import { UnWebClient } from 'unweb';
56
+
57
+ const client = new UnWebClient({ apiKey: 'unweb_...' });
58
+
59
+ // Paste raw HTML
60
+ const result = await client.convert.paste('<h1>Title</h1><p>Content</p>');
61
+ result.markdown; // "# Title\n\nContent"
62
+ result.qualityScore; // 0–100
63
+ result.warnings; // ["Content auto-detected using: <main> element"]
64
+
65
+ // Convert from URL (fetches and converts server-side)
66
+ const page = await client.convert.url('https://docs.python.org/3/tutorial/index.html');
67
+
68
+ // Upload an HTML file (pass file path or Buffer)
69
+ const uploaded = await client.convert.upload('./downloaded-page.html');
70
+
71
+ // Upload from a Buffer
72
+ const buf = Buffer.from('<h1>Hello</h1>');
73
+ const fromBuf = await client.convert.upload(buf, 'hello.html');
74
+ ```
75
+
76
+ ### Web Crawler
77
+
78
+ Crawl documentation sites and download results as a ZIP archive.
79
+
80
+ ```typescript
81
+ // Start a crawl job
82
+ let job = await client.crawl.start('https://docs.example.com', {
83
+ allowedPath: '/docs/', // Only crawl URLs under this path
84
+ maxPages: 100, // Page limit
85
+ exportFormat: 'raw-md', // "raw-md" | "langchain" | "llamaindex"
86
+ webhookUrl: 'https://your-app.com/hooks/crawl', // Optional completion webhook
87
+ });
88
+ console.log(`Job started: ${job.jobId}`);
89
+
90
+ // Poll until complete
91
+ while (job.status !== 'Completed' && job.status !== 'Failed' && job.status !== 'Cancelled') {
92
+ await new Promise((r) => setTimeout(r, 5000));
93
+ job = await client.crawl.status(job.jobId);
94
+ console.log(` ${job.status}: ${job.pagesCrawled} pages crawled`);
95
+ }
96
+
97
+ // Download results
98
+ if (job.status === 'Completed') {
99
+ const download = await client.crawl.download(job.jobId);
100
+ console.log(`Download ZIP: ${download.downloadUrl}`);
101
+ console.log(`Size: ${download.sizeBytes} bytes`);
102
+ }
103
+
104
+ // List all your crawl jobs
105
+ const jobs = await client.crawl.list({ status: 'Completed' });
106
+ for (const j of jobs.jobs) {
107
+ console.log(` ${j.jobId}: ${j.pagesCrawled} pages`);
108
+ }
109
+
110
+ // Cancel a running job
111
+ await client.crawl.cancel(job.jobId);
112
+ ```
113
+
114
+ **Export formats:**
115
+
116
+ | Format | Output | Use case |
117
+ |--------|--------|----------|
118
+ | `raw-md` | ZIP with `.md` files + manifest | General purpose |
119
+ | `langchain` | JSONL compatible with LangChain document loaders | RAG with LangChain |
120
+ | `llamaindex` | JSON compatible with LlamaIndex readers | RAG with LlamaIndex |
121
+
122
+ ### Authentication
123
+
124
+ The SDK uses **API keys** for conversion and crawler endpoints (set once in the constructor). For dashboard endpoints (usage, keys, subscription), authenticate with email/password to get a JWT:
125
+
126
+ ```typescript
127
+ // API key auth (conversions + crawler) — set in constructor
128
+ const client = new UnWebClient({ apiKey: 'unweb_...' });
129
+
130
+ // JWT auth (dashboard endpoints) — login first
131
+ await client.auth.login('you@example.com', 'your-password');
132
+
133
+ // Now dashboard endpoints work
134
+ const usage = await client.usage.current();
135
+ const keys = await client.keys.list();
136
+ ```
137
+
138
+ ```typescript
139
+ // Register a new account
140
+ const token = await client.auth.register('new@example.com', 'password', 'First', 'Last');
141
+
142
+ // Get current user profile
143
+ const profile = await client.auth.me();
144
+ console.log(`${profile.firstName} (${profile.email})`);
145
+
146
+ // Update profile
147
+ await client.auth.updateProfile({ firstName: 'NewName' });
148
+
149
+ // Change password
150
+ await client.auth.changePassword('old-password', 'new-password');
151
+ ```
152
+
153
+ ### API Key Management
154
+
155
+ Requires JWT auth (`client.auth.login(...)` first).
156
+
157
+ ```typescript
158
+ // List API keys
159
+ const keys = await client.keys.list();
160
+ for (const key of keys) {
161
+ console.log(` ${key.name}: ${key.keyPrefix}...`);
162
+ }
163
+
164
+ // Create a new API key (full key only shown once)
165
+ const newKey = await client.keys.create('Production Key');
166
+ console.log(`Key: ${newKey.key}`); // Save this — not retrievable later
167
+
168
+ // Revoke an API key
169
+ await client.keys.revoke('key-id-here');
170
+ ```
171
+
172
+ ### Usage Tracking
173
+
174
+ Requires JWT auth.
175
+
176
+ ```typescript
177
+ const usage = await client.usage.current();
178
+ console.log(`Credits used: ${usage.creditsUsed}/${usage.creditsLimit}`);
179
+ console.log(`Overage: ${usage.overageCreditsUsed}`);
180
+ console.log(`Billing cycle: ${usage.billingCycleStart} – ${usage.billingCycleEnd}`);
181
+
182
+ // Detailed stats and history (returns raw objects)
183
+ const stats = await client.usage.stats();
184
+ const history = await client.usage.history();
185
+ ```
186
+
187
+ ### Subscription
188
+
189
+ Requires JWT auth.
190
+
191
+ ```typescript
192
+ const sub = await client.subscription.get();
193
+ console.log(`Tier: ${sub.tier}`); // Free | Starter | Pro | Scale
194
+ console.log(`Credits: ${sub.creditsUsed}/${sub.monthlyCredits}`);
195
+ console.log(`Overage: ${sub.allowsOverage}`);
196
+
197
+ // Get a checkout URL to upgrade
198
+ const url = await client.subscription.checkout('Pro');
199
+ console.log(`Upgrade: ${url}`);
200
+
201
+ // Cancel subscription
202
+ await client.subscription.cancel();
203
+ ```
204
+
205
+ ## Error Handling
206
+
207
+ The SDK throws typed exceptions for all API errors:
208
+
209
+ ```typescript
210
+ import {
211
+ UnWebClient,
212
+ UnWebError,
213
+ AuthError,
214
+ QuotaExceededError,
215
+ ValidationError,
216
+ NotFoundError,
217
+ } from 'unweb';
218
+
219
+ const client = new UnWebClient({ apiKey: 'unweb_...' });
220
+
221
+ try {
222
+ const result = await client.convert.paste('');
223
+ } catch (e) {
224
+ if (e instanceof ValidationError) {
225
+ console.error(`Bad request: ${e.message}`); // 400
226
+ } else if (e instanceof AuthError) {
227
+ console.error(`Auth failed: ${e.message}`); // 401 / 403
228
+ } else if (e instanceof QuotaExceededError) {
229
+ console.error(`Quota exceeded: ${e.message}`); // 429
230
+ } else if (e instanceof NotFoundError) {
231
+ console.error(`Not found: ${e.message}`); // 404
232
+ } else if (e instanceof UnWebError) {
233
+ console.error(`API error (${e.statusCode}): ${e.message}`);
234
+ }
235
+ }
236
+
237
+ // All exceptions expose:
238
+ // e.statusCode — HTTP status code
239
+ // e.response — Raw response body object
240
+ ```
241
+
242
+ ## Configuration
243
+
244
+ ```typescript
245
+ const client = new UnWebClient({
246
+ apiKey: 'unweb_...', // API key for conversions/crawler
247
+ baseUrl: 'https://api.unweb.info', // Default API URL
248
+ timeout: 30_000, // Request timeout in milliseconds (default: 30s)
249
+ });
250
+ ```
251
+
252
+ You can also read the API key from an environment variable:
253
+
254
+ ```typescript
255
+ const client = new UnWebClient({
256
+ apiKey: process.env.UNWEB_API_KEY,
257
+ });
258
+ ```
259
+
260
+ ## Pricing
261
+
262
+ | Tier | Credits/month | Price |
263
+ |------|--------------|-------|
264
+ | Free | 500 | $0 |
265
+ | Starter | 2,000 | $12/mo |
266
+ | Pro | 15,000 | $39/mo |
267
+ | Scale | 60,000 | $99/mo |
268
+
269
+ Different operations cost different credits. Paid plans include overage billing so your pipelines never stop. See [unweb.info](https://unweb.info) for details.
270
+
271
+ ## Links
272
+
273
+ - [UnWeb Homepage](https://unweb.info)
274
+ - [API Documentation](https://docs.unweb.info)
275
+ - [Dashboard](https://app.unweb.info) (get your API key)
276
+ - [Python SDK](https://github.com/mbsoft-systems/unweb-python)
277
+ - [Report Issues](https://github.com/mbsoft-systems/unweb-js/issues)
278
+
279
+ ## License
280
+
281
+ MIT — see [LICENSE](LICENSE) for details.
@@ -0,0 +1,188 @@
1
+ interface ConversionResult {
2
+ markdown: string;
3
+ warnings: string[];
4
+ qualityScore: number;
5
+ }
6
+ interface CrawlJob {
7
+ jobId: string;
8
+ status: string;
9
+ pagesCrawled: number;
10
+ pagesQueued: number;
11
+ startUrl: string;
12
+ allowedPath: string;
13
+ maxPages: number;
14
+ exportFormat: string;
15
+ errorMessage?: string;
16
+ createdAt?: string;
17
+ startedAt?: string;
18
+ completedAt?: string;
19
+ durationSeconds?: number;
20
+ outputSizeBytes?: number;
21
+ }
22
+ interface CrawlJobList {
23
+ jobs: CrawlJob[];
24
+ totalCount: number;
25
+ }
26
+ interface CrawlDownload {
27
+ downloadUrl: string;
28
+ expiresAt?: string;
29
+ sizeBytes?: number;
30
+ contentType: string;
31
+ fileName: string;
32
+ }
33
+ interface CrawlStartOptions {
34
+ allowedPath?: string;
35
+ maxPages?: number;
36
+ exportFormat?: string;
37
+ ignoreRobotsTxt?: boolean;
38
+ webhookUrl?: string;
39
+ }
40
+ interface CrawlListOptions {
41
+ status?: string;
42
+ skip?: number;
43
+ take?: number;
44
+ }
45
+ interface AuthToken {
46
+ token: string;
47
+ userId: string;
48
+ email: string;
49
+ }
50
+ interface UserProfile {
51
+ id: string;
52
+ email: string;
53
+ firstName: string;
54
+ lastName: string;
55
+ role: string;
56
+ }
57
+ interface ProfileUpdate {
58
+ email?: string;
59
+ firstName?: string;
60
+ lastName?: string;
61
+ }
62
+ interface ApiKey {
63
+ id: string;
64
+ name: string;
65
+ keyPrefix: string;
66
+ createdAt?: string;
67
+ lastUsedAt?: string;
68
+ isRevoked: boolean;
69
+ }
70
+ interface ApiKeyCreated {
71
+ id: string;
72
+ name: string;
73
+ key: string;
74
+ keyPrefix: string;
75
+ }
76
+ interface UsageCurrent {
77
+ creditsUsed: number;
78
+ creditsLimit: number;
79
+ overageCreditsUsed: number;
80
+ billingCycleStart?: string;
81
+ billingCycleEnd?: string;
82
+ }
83
+ interface Subscription {
84
+ tier: string;
85
+ status: string;
86
+ monthlyCredits: number;
87
+ creditsUsed: number;
88
+ allowsOverage: boolean;
89
+ }
90
+ interface UnWebClientOptions {
91
+ apiKey?: string;
92
+ baseUrl?: string;
93
+ timeout?: number;
94
+ }
95
+
96
+ declare class AuthResource {
97
+ private client;
98
+ constructor(client: UnWebClient);
99
+ register(email: string, password: string, firstName?: string, lastName?: string): Promise<AuthToken>;
100
+ login(email: string, password: string): Promise<AuthToken>;
101
+ me(): Promise<UserProfile>;
102
+ updateProfile(update: ProfileUpdate): Promise<void>;
103
+ changePassword(currentPassword: string, newPassword: string): Promise<void>;
104
+ }
105
+
106
+ declare class ConvertResource {
107
+ private client;
108
+ constructor(client: UnWebClient);
109
+ paste(html: string): Promise<ConversionResult>;
110
+ url(url: string): Promise<ConversionResult>;
111
+ upload(content: Buffer | string, fileName?: string): Promise<ConversionResult>;
112
+ }
113
+
114
+ declare class CrawlResource {
115
+ private client;
116
+ constructor(client: UnWebClient);
117
+ start(startUrl: string, options?: CrawlStartOptions): Promise<CrawlJob>;
118
+ status(jobId: string): Promise<CrawlJob>;
119
+ list(options?: CrawlListOptions): Promise<CrawlJobList>;
120
+ download(jobId: string): Promise<CrawlDownload>;
121
+ cancel(jobId: string): Promise<void>;
122
+ }
123
+
124
+ declare class KeysResource {
125
+ private client;
126
+ constructor(client: UnWebClient);
127
+ list(): Promise<ApiKey[]>;
128
+ create(name: string): Promise<ApiKeyCreated>;
129
+ revoke(keyId: string): Promise<void>;
130
+ }
131
+
132
+ declare class SubscriptionResource {
133
+ private client;
134
+ constructor(client: UnWebClient);
135
+ get(): Promise<Subscription>;
136
+ checkout(tier: string): Promise<string>;
137
+ cancel(): Promise<void>;
138
+ }
139
+
140
+ declare class UsageResource {
141
+ private client;
142
+ constructor(client: UnWebClient);
143
+ current(): Promise<UsageCurrent>;
144
+ stats(): Promise<Record<string, unknown>>;
145
+ history(): Promise<Record<string, unknown>>;
146
+ }
147
+
148
+ declare class UnWebClient {
149
+ /** @internal */ _apiKey: string | undefined;
150
+ /** @internal */ _baseUrl: string;
151
+ /** @internal */ _timeout: number;
152
+ /** @internal */ _jwtToken: string | undefined;
153
+ readonly convert: ConvertResource;
154
+ readonly crawl: CrawlResource;
155
+ readonly auth: AuthResource;
156
+ readonly keys: KeysResource;
157
+ readonly usage: UsageResource;
158
+ readonly subscription: SubscriptionResource;
159
+ constructor(options?: UnWebClientOptions);
160
+ /** @internal */
161
+ _request(method: string, path: string, options?: {
162
+ json?: Record<string, unknown>;
163
+ body?: BodyInit;
164
+ params?: Record<string, string | number>;
165
+ authMode?: 'api_key' | 'jwt' | 'none';
166
+ headers?: Record<string, string>;
167
+ }): Promise<Record<string, unknown>>;
168
+ }
169
+
170
+ declare class UnWebError extends Error {
171
+ readonly statusCode?: number | undefined;
172
+ readonly response?: Record<string, unknown> | undefined;
173
+ constructor(message: string, statusCode?: number | undefined, response?: Record<string, unknown> | undefined);
174
+ }
175
+ declare class AuthError extends UnWebError {
176
+ constructor(message: string, statusCode?: number, response?: Record<string, unknown>);
177
+ }
178
+ declare class QuotaExceededError extends UnWebError {
179
+ constructor(message: string, statusCode?: number, response?: Record<string, unknown>);
180
+ }
181
+ declare class NotFoundError extends UnWebError {
182
+ constructor(message: string, statusCode?: number, response?: Record<string, unknown>);
183
+ }
184
+ declare class ValidationError extends UnWebError {
185
+ constructor(message: string, statusCode?: number, response?: Record<string, unknown>);
186
+ }
187
+
188
+ export { type ApiKey, type ApiKeyCreated, AuthError, type AuthToken, type ConversionResult, type CrawlDownload, type CrawlJob, type CrawlJobList, type CrawlListOptions, type CrawlStartOptions, NotFoundError, type ProfileUpdate, QuotaExceededError, type Subscription, UnWebClient, type UnWebClientOptions, UnWebError, type UsageCurrent, type UserProfile, ValidationError };
@@ -0,0 +1,188 @@
1
+ interface ConversionResult {
2
+ markdown: string;
3
+ warnings: string[];
4
+ qualityScore: number;
5
+ }
6
+ interface CrawlJob {
7
+ jobId: string;
8
+ status: string;
9
+ pagesCrawled: number;
10
+ pagesQueued: number;
11
+ startUrl: string;
12
+ allowedPath: string;
13
+ maxPages: number;
14
+ exportFormat: string;
15
+ errorMessage?: string;
16
+ createdAt?: string;
17
+ startedAt?: string;
18
+ completedAt?: string;
19
+ durationSeconds?: number;
20
+ outputSizeBytes?: number;
21
+ }
22
+ interface CrawlJobList {
23
+ jobs: CrawlJob[];
24
+ totalCount: number;
25
+ }
26
+ interface CrawlDownload {
27
+ downloadUrl: string;
28
+ expiresAt?: string;
29
+ sizeBytes?: number;
30
+ contentType: string;
31
+ fileName: string;
32
+ }
33
+ interface CrawlStartOptions {
34
+ allowedPath?: string;
35
+ maxPages?: number;
36
+ exportFormat?: string;
37
+ ignoreRobotsTxt?: boolean;
38
+ webhookUrl?: string;
39
+ }
40
+ interface CrawlListOptions {
41
+ status?: string;
42
+ skip?: number;
43
+ take?: number;
44
+ }
45
+ interface AuthToken {
46
+ token: string;
47
+ userId: string;
48
+ email: string;
49
+ }
50
+ interface UserProfile {
51
+ id: string;
52
+ email: string;
53
+ firstName: string;
54
+ lastName: string;
55
+ role: string;
56
+ }
57
+ interface ProfileUpdate {
58
+ email?: string;
59
+ firstName?: string;
60
+ lastName?: string;
61
+ }
62
+ interface ApiKey {
63
+ id: string;
64
+ name: string;
65
+ keyPrefix: string;
66
+ createdAt?: string;
67
+ lastUsedAt?: string;
68
+ isRevoked: boolean;
69
+ }
70
+ interface ApiKeyCreated {
71
+ id: string;
72
+ name: string;
73
+ key: string;
74
+ keyPrefix: string;
75
+ }
76
+ interface UsageCurrent {
77
+ creditsUsed: number;
78
+ creditsLimit: number;
79
+ overageCreditsUsed: number;
80
+ billingCycleStart?: string;
81
+ billingCycleEnd?: string;
82
+ }
83
+ interface Subscription {
84
+ tier: string;
85
+ status: string;
86
+ monthlyCredits: number;
87
+ creditsUsed: number;
88
+ allowsOverage: boolean;
89
+ }
90
+ interface UnWebClientOptions {
91
+ apiKey?: string;
92
+ baseUrl?: string;
93
+ timeout?: number;
94
+ }
95
+
96
+ declare class AuthResource {
97
+ private client;
98
+ constructor(client: UnWebClient);
99
+ register(email: string, password: string, firstName?: string, lastName?: string): Promise<AuthToken>;
100
+ login(email: string, password: string): Promise<AuthToken>;
101
+ me(): Promise<UserProfile>;
102
+ updateProfile(update: ProfileUpdate): Promise<void>;
103
+ changePassword(currentPassword: string, newPassword: string): Promise<void>;
104
+ }
105
+
106
+ declare class ConvertResource {
107
+ private client;
108
+ constructor(client: UnWebClient);
109
+ paste(html: string): Promise<ConversionResult>;
110
+ url(url: string): Promise<ConversionResult>;
111
+ upload(content: Buffer | string, fileName?: string): Promise<ConversionResult>;
112
+ }
113
+
114
+ declare class CrawlResource {
115
+ private client;
116
+ constructor(client: UnWebClient);
117
+ start(startUrl: string, options?: CrawlStartOptions): Promise<CrawlJob>;
118
+ status(jobId: string): Promise<CrawlJob>;
119
+ list(options?: CrawlListOptions): Promise<CrawlJobList>;
120
+ download(jobId: string): Promise<CrawlDownload>;
121
+ cancel(jobId: string): Promise<void>;
122
+ }
123
+
124
+ declare class KeysResource {
125
+ private client;
126
+ constructor(client: UnWebClient);
127
+ list(): Promise<ApiKey[]>;
128
+ create(name: string): Promise<ApiKeyCreated>;
129
+ revoke(keyId: string): Promise<void>;
130
+ }
131
+
132
+ declare class SubscriptionResource {
133
+ private client;
134
+ constructor(client: UnWebClient);
135
+ get(): Promise<Subscription>;
136
+ checkout(tier: string): Promise<string>;
137
+ cancel(): Promise<void>;
138
+ }
139
+
140
+ declare class UsageResource {
141
+ private client;
142
+ constructor(client: UnWebClient);
143
+ current(): Promise<UsageCurrent>;
144
+ stats(): Promise<Record<string, unknown>>;
145
+ history(): Promise<Record<string, unknown>>;
146
+ }
147
+
148
+ declare class UnWebClient {
149
+ /** @internal */ _apiKey: string | undefined;
150
+ /** @internal */ _baseUrl: string;
151
+ /** @internal */ _timeout: number;
152
+ /** @internal */ _jwtToken: string | undefined;
153
+ readonly convert: ConvertResource;
154
+ readonly crawl: CrawlResource;
155
+ readonly auth: AuthResource;
156
+ readonly keys: KeysResource;
157
+ readonly usage: UsageResource;
158
+ readonly subscription: SubscriptionResource;
159
+ constructor(options?: UnWebClientOptions);
160
+ /** @internal */
161
+ _request(method: string, path: string, options?: {
162
+ json?: Record<string, unknown>;
163
+ body?: BodyInit;
164
+ params?: Record<string, string | number>;
165
+ authMode?: 'api_key' | 'jwt' | 'none';
166
+ headers?: Record<string, string>;
167
+ }): Promise<Record<string, unknown>>;
168
+ }
169
+
170
+ declare class UnWebError extends Error {
171
+ readonly statusCode?: number | undefined;
172
+ readonly response?: Record<string, unknown> | undefined;
173
+ constructor(message: string, statusCode?: number | undefined, response?: Record<string, unknown> | undefined);
174
+ }
175
+ declare class AuthError extends UnWebError {
176
+ constructor(message: string, statusCode?: number, response?: Record<string, unknown>);
177
+ }
178
+ declare class QuotaExceededError extends UnWebError {
179
+ constructor(message: string, statusCode?: number, response?: Record<string, unknown>);
180
+ }
181
+ declare class NotFoundError extends UnWebError {
182
+ constructor(message: string, statusCode?: number, response?: Record<string, unknown>);
183
+ }
184
+ declare class ValidationError extends UnWebError {
185
+ constructor(message: string, statusCode?: number, response?: Record<string, unknown>);
186
+ }
187
+
188
+ export { type ApiKey, type ApiKeyCreated, AuthError, type AuthToken, type ConversionResult, type CrawlDownload, type CrawlJob, type CrawlJobList, type CrawlListOptions, type CrawlStartOptions, NotFoundError, type ProfileUpdate, QuotaExceededError, type Subscription, UnWebClient, type UnWebClientOptions, UnWebError, type UsageCurrent, type UserProfile, ValidationError };