@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/dist/index.js ADDED
@@ -0,0 +1,329 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ AuthError: () => AuthError,
24
+ NotFoundError: () => NotFoundError,
25
+ QuotaExceededError: () => QuotaExceededError,
26
+ UnWebClient: () => UnWebClient,
27
+ UnWebError: () => UnWebError,
28
+ ValidationError: () => ValidationError
29
+ });
30
+ module.exports = __toCommonJS(index_exports);
31
+
32
+ // src/errors.ts
33
+ var UnWebError = class extends Error {
34
+ constructor(message, statusCode, response) {
35
+ super(message);
36
+ this.statusCode = statusCode;
37
+ this.response = response;
38
+ this.name = "UnWebError";
39
+ }
40
+ };
41
+ var AuthError = class extends UnWebError {
42
+ constructor(message, statusCode, response) {
43
+ super(message, statusCode, response);
44
+ this.name = "AuthError";
45
+ }
46
+ };
47
+ var QuotaExceededError = class extends UnWebError {
48
+ constructor(message, statusCode, response) {
49
+ super(message, statusCode, response);
50
+ this.name = "QuotaExceededError";
51
+ }
52
+ };
53
+ var NotFoundError = class extends UnWebError {
54
+ constructor(message, statusCode, response) {
55
+ super(message, statusCode, response);
56
+ this.name = "NotFoundError";
57
+ }
58
+ };
59
+ var ValidationError = class extends UnWebError {
60
+ constructor(message, statusCode, response) {
61
+ super(message, statusCode, response);
62
+ this.name = "ValidationError";
63
+ }
64
+ };
65
+
66
+ // src/resources/auth.ts
67
+ var AuthResource = class {
68
+ constructor(client) {
69
+ this.client = client;
70
+ }
71
+ async register(email, password, firstName = "", lastName = "") {
72
+ const data = await this.client._request("POST", "/api/auth/register", { json: { email, password, firstName, lastName }, authMode: "none" });
73
+ const token = toToken(data);
74
+ this.client._jwtToken = token.token;
75
+ return token;
76
+ }
77
+ async login(email, password) {
78
+ const data = await this.client._request("POST", "/api/auth/login", { json: { email, password }, authMode: "none" });
79
+ const token = toToken(data);
80
+ this.client._jwtToken = token.token;
81
+ return token;
82
+ }
83
+ async me() {
84
+ const data = await this.client._request("GET", "/api/auth/me", { authMode: "jwt" });
85
+ return { id: data.id ?? "", email: data.email ?? "", firstName: data.firstName ?? "", lastName: data.lastName ?? "", role: data.role ?? "" };
86
+ }
87
+ async updateProfile(update) {
88
+ const json = {};
89
+ if (update.email !== void 0) json.email = update.email;
90
+ if (update.firstName !== void 0) json.firstName = update.firstName;
91
+ if (update.lastName !== void 0) json.lastName = update.lastName;
92
+ await this.client._request("PUT", "/api/auth/profile", { json, authMode: "jwt" });
93
+ }
94
+ async changePassword(currentPassword, newPassword) {
95
+ await this.client._request("POST", "/api/auth/change-password", { json: { currentPassword, newPassword }, authMode: "jwt" });
96
+ }
97
+ };
98
+ function toToken(data) {
99
+ return { token: data.token ?? "", userId: data.userId ?? "", email: data.email ?? "" };
100
+ }
101
+
102
+ // src/resources/convert.ts
103
+ var import_node_fs = require("fs");
104
+ var ConvertResource = class {
105
+ constructor(client) {
106
+ this.client = client;
107
+ }
108
+ async paste(html) {
109
+ const data = await this.client._request("POST", "/api/convert/paste", { json: { html } });
110
+ return toResult(data);
111
+ }
112
+ async url(url) {
113
+ const data = await this.client._request("POST", "/api/convert/url", { json: { url } });
114
+ return toResult(data);
115
+ }
116
+ async upload(content, fileName) {
117
+ let buffer;
118
+ let name;
119
+ if (typeof content === "string") {
120
+ buffer = (0, import_node_fs.readFileSync)(content);
121
+ name = content.split(/[\\/]/).pop() ?? "upload.html";
122
+ } else {
123
+ buffer = content;
124
+ name = fileName ?? "upload.html";
125
+ }
126
+ const formData = new FormData();
127
+ formData.append("file", new Blob([new Uint8Array(buffer)]), name);
128
+ const data = await this.client._request("POST", "/api/convert/upload", { body: formData, authMode: "api_key" });
129
+ return toResult(data);
130
+ }
131
+ };
132
+ function toResult(data) {
133
+ return {
134
+ markdown: data.markdown ?? "",
135
+ warnings: data.warnings ?? [],
136
+ qualityScore: data.qualityScore ?? 100
137
+ };
138
+ }
139
+
140
+ // src/resources/crawl.ts
141
+ var CrawlResource = class {
142
+ constructor(client) {
143
+ this.client = client;
144
+ }
145
+ async start(startUrl, options = {}) {
146
+ const json = {
147
+ startUrl,
148
+ allowedPath: options.allowedPath ?? "/",
149
+ maxPages: options.maxPages ?? 100,
150
+ exportFormat: options.exportFormat ?? "raw-md",
151
+ ignoreRobotsTxt: options.ignoreRobotsTxt ?? false
152
+ };
153
+ if (options.webhookUrl) json.webhookUrl = options.webhookUrl;
154
+ const data = await this.client._request("POST", "/api/crawl", { json });
155
+ return toJob(data);
156
+ }
157
+ async status(jobId) {
158
+ const data = await this.client._request("GET", `/api/crawl/${jobId}/status`);
159
+ return toJob(data);
160
+ }
161
+ async list(options = {}) {
162
+ const params = { skip: options.skip ?? 0, take: options.take ?? 20 };
163
+ if (options.status) params.status = options.status;
164
+ const data = await this.client._request("GET", "/api/crawl", { params });
165
+ return { jobs: (data.jobs ?? []).map(toJob), totalCount: data.totalCount ?? 0 };
166
+ }
167
+ async download(jobId) {
168
+ const data = await this.client._request("GET", `/api/crawl/${jobId}/download`);
169
+ return { downloadUrl: data.downloadUrl ?? "", expiresAt: data.expiresAt, sizeBytes: data.sizeBytes, contentType: data.contentType ?? "application/zip", fileName: data.fileName ?? "" };
170
+ }
171
+ async cancel(jobId) {
172
+ await this.client._request("DELETE", `/api/crawl/${jobId}`);
173
+ }
174
+ };
175
+ function toJob(data) {
176
+ return {
177
+ jobId: data.jobId ?? "",
178
+ status: data.status ?? "",
179
+ pagesCrawled: data.pagesCrawled ?? 0,
180
+ pagesQueued: data.pagesQueued ?? 0,
181
+ startUrl: data.startUrl ?? "",
182
+ allowedPath: data.allowedPath ?? "",
183
+ maxPages: data.maxPages ?? 0,
184
+ exportFormat: data.exportFormat ?? "",
185
+ errorMessage: data.errorMessage,
186
+ createdAt: data.createdAt,
187
+ startedAt: data.startedAt,
188
+ completedAt: data.completedAt,
189
+ durationSeconds: data.durationSeconds,
190
+ outputSizeBytes: data.outputSizeBytes
191
+ };
192
+ }
193
+
194
+ // src/resources/keys.ts
195
+ var KeysResource = class {
196
+ constructor(client) {
197
+ this.client = client;
198
+ }
199
+ async list() {
200
+ const data = await this.client._request("GET", "/api/keys", { authMode: "jwt" });
201
+ return data.map((k) => ({
202
+ id: k.id ?? "",
203
+ name: k.name ?? "",
204
+ keyPrefix: k.keyPrefix ?? "",
205
+ createdAt: k.createdAt,
206
+ lastUsedAt: k.lastUsedAt,
207
+ isRevoked: k.isRevoked ?? false
208
+ }));
209
+ }
210
+ async create(name) {
211
+ const data = await this.client._request("POST", "/api/keys", { json: { name }, authMode: "jwt" });
212
+ return { id: data.id ?? "", name: data.name ?? "", key: data.key ?? "", keyPrefix: data.keyPrefix ?? "" };
213
+ }
214
+ async revoke(keyId) {
215
+ await this.client._request("DELETE", `/api/keys/${keyId}`, { authMode: "jwt" });
216
+ }
217
+ };
218
+
219
+ // src/resources/subscription.ts
220
+ var SubscriptionResource = class {
221
+ constructor(client) {
222
+ this.client = client;
223
+ }
224
+ async get() {
225
+ const data = await this.client._request("GET", "/api/subscription", { authMode: "jwt" });
226
+ return { tier: data.tier ?? "Free", status: data.status ?? "", monthlyCredits: data.monthlyCredits ?? 0, creditsUsed: data.creditsUsed ?? 0, allowsOverage: data.allowsOverage ?? false };
227
+ }
228
+ async checkout(tier) {
229
+ const data = await this.client._request("POST", "/api/subscription/checkout", { json: { tier }, authMode: "jwt" });
230
+ return data.checkoutUrl ?? "";
231
+ }
232
+ async cancel() {
233
+ await this.client._request("POST", "/api/subscription/cancel", { authMode: "jwt" });
234
+ }
235
+ };
236
+
237
+ // src/resources/usage.ts
238
+ var UsageResource = class {
239
+ constructor(client) {
240
+ this.client = client;
241
+ }
242
+ async current() {
243
+ const data = await this.client._request("GET", "/api/usage/current", { authMode: "jwt" });
244
+ return { creditsUsed: data.creditsUsed ?? 0, creditsLimit: data.creditsLimit ?? 0, overageCreditsUsed: data.overageCreditsUsed ?? 0, billingCycleStart: data.billingCycleStart, billingCycleEnd: data.billingCycleEnd };
245
+ }
246
+ async stats() {
247
+ return this.client._request("GET", "/api/usage/stats", { authMode: "jwt" });
248
+ }
249
+ async history() {
250
+ return this.client._request("GET", "/api/usage/history", { authMode: "jwt" });
251
+ }
252
+ };
253
+
254
+ // src/client.ts
255
+ var DEFAULT_BASE_URL = "https://api.unweb.info";
256
+ var UnWebClient = class {
257
+ /** @internal */
258
+ _apiKey;
259
+ /** @internal */
260
+ _baseUrl;
261
+ /** @internal */
262
+ _timeout;
263
+ /** @internal */
264
+ _jwtToken;
265
+ convert;
266
+ crawl;
267
+ auth;
268
+ keys;
269
+ usage;
270
+ subscription;
271
+ constructor(options = {}) {
272
+ this._apiKey = options.apiKey;
273
+ this._baseUrl = (options.baseUrl ?? DEFAULT_BASE_URL).replace(/\/+$/, "");
274
+ this._timeout = options.timeout ?? 3e4;
275
+ this.convert = new ConvertResource(this);
276
+ this.crawl = new CrawlResource(this);
277
+ this.auth = new AuthResource(this);
278
+ this.keys = new KeysResource(this);
279
+ this.usage = new UsageResource(this);
280
+ this.subscription = new SubscriptionResource(this);
281
+ }
282
+ /** @internal */
283
+ async _request(method, path, options = {}) {
284
+ const { json, body, params, authMode = "api_key", headers: extraHeaders } = options;
285
+ let url = `${this._baseUrl}${path}`;
286
+ if (params) {
287
+ const qs = new URLSearchParams();
288
+ for (const [k, v] of Object.entries(params)) qs.set(k, String(v));
289
+ url += `?${qs.toString()}`;
290
+ }
291
+ const headers = { ...extraHeaders };
292
+ if (authMode === "api_key" && this._apiKey) headers["X-API-Key"] = this._apiKey;
293
+ else if (authMode === "jwt" && this._jwtToken) headers["Authorization"] = `Bearer ${this._jwtToken}`;
294
+ let fetchBody = body;
295
+ if (json) {
296
+ headers["Content-Type"] = "application/json";
297
+ fetchBody = JSON.stringify(json);
298
+ }
299
+ const controller = new AbortController();
300
+ const timeoutId = setTimeout(() => controller.abort(), this._timeout);
301
+ try {
302
+ const response = await fetch(url, { method, headers, body: fetchBody, signal: controller.signal });
303
+ if (response.status === 204) return {};
304
+ const data = response.headers.get("content-type")?.includes("application/json") ? await response.json() : {};
305
+ if (response.ok) return data;
306
+ const msg = data.detail ?? data.error ?? data.title ?? JSON.stringify(data);
307
+ const errors = data.errors;
308
+ const errorMsg = errors ? Array.isArray(errors) ? errors.join("; ") : String(errors) : msg;
309
+ if (response.status === 400) throw new ValidationError(errorMsg, 400, data);
310
+ if (response.status === 401) throw new AuthError(errorMsg, 401, data);
311
+ if (response.status === 403) throw new AuthError(errorMsg, 403, data);
312
+ if (response.status === 404) throw new NotFoundError(errorMsg, 404, data);
313
+ if (response.status === 429) throw new QuotaExceededError(errorMsg, 429, data);
314
+ throw new UnWebError(errorMsg, response.status, data);
315
+ } finally {
316
+ clearTimeout(timeoutId);
317
+ }
318
+ }
319
+ };
320
+ // Annotate the CommonJS export names for ESM import in node:
321
+ 0 && (module.exports = {
322
+ AuthError,
323
+ NotFoundError,
324
+ QuotaExceededError,
325
+ UnWebClient,
326
+ UnWebError,
327
+ ValidationError
328
+ });
329
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/errors.ts","../src/resources/auth.ts","../src/resources/convert.ts","../src/resources/crawl.ts","../src/resources/keys.ts","../src/resources/subscription.ts","../src/resources/usage.ts","../src/client.ts"],"sourcesContent":["export { UnWebClient } from './client.js';\nexport type { UnWebClientOptions } from './types.js';\nexport * from './types.js';\nexport * from './errors.js';\n","export class UnWebError extends Error {\n constructor(\n message: string,\n public readonly statusCode?: number,\n public readonly response?: Record<string, unknown>,\n ) {\n super(message);\n this.name = 'UnWebError';\n }\n}\n\nexport class AuthError extends UnWebError {\n constructor(message: string, statusCode?: number, response?: Record<string, unknown>) {\n super(message, statusCode, response);\n this.name = 'AuthError';\n }\n}\n\nexport class QuotaExceededError extends UnWebError {\n constructor(message: string, statusCode?: number, response?: Record<string, unknown>) {\n super(message, statusCode, response);\n this.name = 'QuotaExceededError';\n }\n}\n\nexport class NotFoundError extends UnWebError {\n constructor(message: string, statusCode?: number, response?: Record<string, unknown>) {\n super(message, statusCode, response);\n this.name = 'NotFoundError';\n }\n}\n\nexport class ValidationError extends UnWebError {\n constructor(message: string, statusCode?: number, response?: Record<string, unknown>) {\n super(message, statusCode, response);\n this.name = 'ValidationError';\n }\n}\n","import type { UnWebClient } from '../client.js';\nimport type { AuthToken, UserProfile, ProfileUpdate } from '../types.js';\n\nexport class AuthResource {\n constructor(private client: UnWebClient) {}\n\n async register(email: string, password: string, firstName = '', lastName = ''): Promise<AuthToken> {\n const data = await this.client._request('POST', '/api/auth/register', { json: { email, password, firstName, lastName }, authMode: 'none' });\n const token = toToken(data);\n this.client._jwtToken = token.token;\n return token;\n }\n\n async login(email: string, password: string): Promise<AuthToken> {\n const data = await this.client._request('POST', '/api/auth/login', { json: { email, password }, authMode: 'none' });\n const token = toToken(data);\n this.client._jwtToken = token.token;\n return token;\n }\n\n async me(): Promise<UserProfile> {\n const data = await this.client._request('GET', '/api/auth/me', { authMode: 'jwt' });\n return { id: (data.id as string) ?? '', email: (data.email as string) ?? '', firstName: (data.firstName as string) ?? '', lastName: (data.lastName as string) ?? '', role: (data.role as string) ?? '' };\n }\n\n async updateProfile(update: ProfileUpdate): Promise<void> {\n const json: Record<string, unknown> = {};\n if (update.email !== undefined) json.email = update.email;\n if (update.firstName !== undefined) json.firstName = update.firstName;\n if (update.lastName !== undefined) json.lastName = update.lastName;\n await this.client._request('PUT', '/api/auth/profile', { json, authMode: 'jwt' });\n }\n\n async changePassword(currentPassword: string, newPassword: string): Promise<void> {\n await this.client._request('POST', '/api/auth/change-password', { json: { currentPassword, newPassword }, authMode: 'jwt' });\n }\n}\n\nfunction toToken(data: Record<string, unknown>): AuthToken {\n return { token: (data.token as string) ?? '', userId: (data.userId as string) ?? '', email: (data.email as string) ?? '' };\n}\n","import type { UnWebClient } from '../client.js';\nimport type { ConversionResult } from '../types.js';\nimport { readFileSync } from 'node:fs';\n\nexport class ConvertResource {\n constructor(private client: UnWebClient) {}\n\n async paste(html: string): Promise<ConversionResult> {\n const data = await this.client._request('POST', '/api/convert/paste', { json: { html } });\n return toResult(data);\n }\n\n async url(url: string): Promise<ConversionResult> {\n const data = await this.client._request('POST', '/api/convert/url', { json: { url } });\n return toResult(data);\n }\n\n async upload(content: Buffer | string, fileName?: string): Promise<ConversionResult> {\n let buffer: Buffer;\n let name: string;\n if (typeof content === 'string') {\n buffer = readFileSync(content);\n name = content.split(/[\\\\/]/).pop() ?? 'upload.html';\n } else {\n buffer = content;\n name = fileName ?? 'upload.html';\n }\n const formData = new FormData();\n formData.append('file', new Blob([new Uint8Array(buffer)]), name);\n const data = await this.client._request('POST', '/api/convert/upload', { body: formData, authMode: 'api_key' });\n return toResult(data);\n }\n}\n\nfunction toResult(data: Record<string, unknown>): ConversionResult {\n return {\n markdown: (data.markdown as string) ?? '',\n warnings: (data.warnings as string[]) ?? [],\n qualityScore: (data.qualityScore as number) ?? 100,\n };\n}\n","import type { UnWebClient } from '../client.js';\nimport type { CrawlJob, CrawlJobList, CrawlDownload, CrawlStartOptions, CrawlListOptions } from '../types.js';\n\nexport class CrawlResource {\n constructor(private client: UnWebClient) {}\n\n async start(startUrl: string, options: CrawlStartOptions = {}): Promise<CrawlJob> {\n const json: Record<string, unknown> = {\n startUrl,\n allowedPath: options.allowedPath ?? '/',\n maxPages: options.maxPages ?? 100,\n exportFormat: options.exportFormat ?? 'raw-md',\n ignoreRobotsTxt: options.ignoreRobotsTxt ?? false,\n };\n if (options.webhookUrl) json.webhookUrl = options.webhookUrl;\n const data = await this.client._request('POST', '/api/crawl', { json });\n return toJob(data);\n }\n\n async status(jobId: string): Promise<CrawlJob> {\n const data = await this.client._request('GET', `/api/crawl/${jobId}/status`);\n return toJob(data);\n }\n\n async list(options: CrawlListOptions = {}): Promise<CrawlJobList> {\n const params: Record<string, string | number> = { skip: options.skip ?? 0, take: options.take ?? 20 };\n if (options.status) params.status = options.status;\n const data = await this.client._request('GET', '/api/crawl', { params });\n return { jobs: ((data.jobs as Record<string, unknown>[]) ?? []).map(toJob), totalCount: (data.totalCount as number) ?? 0 };\n }\n\n async download(jobId: string): Promise<CrawlDownload> {\n const data = await this.client._request('GET', `/api/crawl/${jobId}/download`);\n return { downloadUrl: (data.downloadUrl as string) ?? '', expiresAt: data.expiresAt as string | undefined, sizeBytes: data.sizeBytes as number | undefined, contentType: (data.contentType as string) ?? 'application/zip', fileName: (data.fileName as string) ?? '' };\n }\n\n async cancel(jobId: string): Promise<void> {\n await this.client._request('DELETE', `/api/crawl/${jobId}`);\n }\n}\n\nfunction toJob(data: Record<string, unknown>): CrawlJob {\n return {\n jobId: (data.jobId as string) ?? '', status: (data.status as string) ?? '',\n pagesCrawled: (data.pagesCrawled as number) ?? 0, pagesQueued: (data.pagesQueued as number) ?? 0,\n startUrl: (data.startUrl as string) ?? '', allowedPath: (data.allowedPath as string) ?? '',\n maxPages: (data.maxPages as number) ?? 0, exportFormat: (data.exportFormat as string) ?? '',\n errorMessage: data.errorMessage as string | undefined, createdAt: data.createdAt as string | undefined,\n startedAt: data.startedAt as string | undefined, completedAt: data.completedAt as string | undefined,\n durationSeconds: data.durationSeconds as number | undefined, outputSizeBytes: data.outputSizeBytes as number | undefined,\n };\n}\n","import type { UnWebClient } from '../client.js';\nimport type { ApiKey, ApiKeyCreated } from '../types.js';\n\nexport class KeysResource {\n constructor(private client: UnWebClient) {}\n\n async list(): Promise<ApiKey[]> {\n const data = await this.client._request('GET', '/api/keys', { authMode: 'jwt' });\n return (data as unknown as Record<string, unknown>[]).map((k) => ({\n id: (k.id as string) ?? '', name: (k.name as string) ?? '', keyPrefix: (k.keyPrefix as string) ?? '',\n createdAt: k.createdAt as string | undefined, lastUsedAt: k.lastUsedAt as string | undefined, isRevoked: (k.isRevoked as boolean) ?? false,\n }));\n }\n\n async create(name: string): Promise<ApiKeyCreated> {\n const data = await this.client._request('POST', '/api/keys', { json: { name }, authMode: 'jwt' });\n return { id: (data.id as string) ?? '', name: (data.name as string) ?? '', key: (data.key as string) ?? '', keyPrefix: (data.keyPrefix as string) ?? '' };\n }\n\n async revoke(keyId: string): Promise<void> {\n await this.client._request('DELETE', `/api/keys/${keyId}`, { authMode: 'jwt' });\n }\n}\n","import type { UnWebClient } from '../client.js';\nimport type { Subscription } from '../types.js';\n\nexport class SubscriptionResource {\n constructor(private client: UnWebClient) {}\n\n async get(): Promise<Subscription> {\n const data = await this.client._request('GET', '/api/subscription', { authMode: 'jwt' });\n return { tier: (data.tier as string) ?? 'Free', status: (data.status as string) ?? '', monthlyCredits: (data.monthlyCredits as number) ?? 0, creditsUsed: (data.creditsUsed as number) ?? 0, allowsOverage: (data.allowsOverage as boolean) ?? false };\n }\n\n async checkout(tier: string): Promise<string> {\n const data = await this.client._request('POST', '/api/subscription/checkout', { json: { tier }, authMode: 'jwt' });\n return (data.checkoutUrl as string) ?? '';\n }\n\n async cancel(): Promise<void> {\n await this.client._request('POST', '/api/subscription/cancel', { authMode: 'jwt' });\n }\n}\n","import type { UnWebClient } from '../client.js';\nimport type { UsageCurrent } from '../types.js';\n\nexport class UsageResource {\n constructor(private client: UnWebClient) {}\n\n async current(): Promise<UsageCurrent> {\n const data = await this.client._request('GET', '/api/usage/current', { authMode: 'jwt' });\n return { creditsUsed: (data.creditsUsed as number) ?? 0, creditsLimit: (data.creditsLimit as number) ?? 0, overageCreditsUsed: (data.overageCreditsUsed as number) ?? 0, billingCycleStart: data.billingCycleStart as string | undefined, billingCycleEnd: data.billingCycleEnd as string | undefined };\n }\n\n async stats(): Promise<Record<string, unknown>> {\n return this.client._request('GET', '/api/usage/stats', { authMode: 'jwt' });\n }\n\n async history(): Promise<Record<string, unknown>> {\n return this.client._request('GET', '/api/usage/history', { authMode: 'jwt' });\n }\n}\n","import { AuthError, NotFoundError, QuotaExceededError, UnWebError, ValidationError } from './errors.js';\nimport type { UnWebClientOptions } from './types.js';\nimport { AuthResource } from './resources/auth.js';\nimport { ConvertResource } from './resources/convert.js';\nimport { CrawlResource } from './resources/crawl.js';\nimport { KeysResource } from './resources/keys.js';\nimport { SubscriptionResource } from './resources/subscription.js';\nimport { UsageResource } from './resources/usage.js';\n\nconst DEFAULT_BASE_URL = 'https://api.unweb.info';\n\nexport class UnWebClient {\n /** @internal */ _apiKey: string | undefined;\n /** @internal */ _baseUrl: string;\n /** @internal */ _timeout: number;\n /** @internal */ _jwtToken: string | undefined;\n\n readonly convert: ConvertResource;\n readonly crawl: CrawlResource;\n readonly auth: AuthResource;\n readonly keys: KeysResource;\n readonly usage: UsageResource;\n readonly subscription: SubscriptionResource;\n\n constructor(options: UnWebClientOptions = {}) {\n this._apiKey = options.apiKey;\n this._baseUrl = (options.baseUrl ?? DEFAULT_BASE_URL).replace(/\\/+$/, '');\n this._timeout = options.timeout ?? 30_000;\n\n this.convert = new ConvertResource(this);\n this.crawl = new CrawlResource(this);\n this.auth = new AuthResource(this);\n this.keys = new KeysResource(this);\n this.usage = new UsageResource(this);\n this.subscription = new SubscriptionResource(this);\n }\n\n /** @internal */\n async _request(\n method: string,\n path: string,\n options: {\n json?: Record<string, unknown>;\n body?: BodyInit;\n params?: Record<string, string | number>;\n authMode?: 'api_key' | 'jwt' | 'none';\n headers?: Record<string, string>;\n } = {},\n ): Promise<Record<string, unknown>> {\n const { json, body, params, authMode = 'api_key', headers: extraHeaders } = options;\n\n let url = `${this._baseUrl}${path}`;\n if (params) {\n const qs = new URLSearchParams();\n for (const [k, v] of Object.entries(params)) qs.set(k, String(v));\n url += `?${qs.toString()}`;\n }\n\n const headers: Record<string, string> = { ...extraHeaders };\n if (authMode === 'api_key' && this._apiKey) headers['X-API-Key'] = this._apiKey;\n else if (authMode === 'jwt' && this._jwtToken) headers['Authorization'] = `Bearer ${this._jwtToken}`;\n\n let fetchBody: BodyInit | undefined = body;\n if (json) {\n headers['Content-Type'] = 'application/json';\n fetchBody = JSON.stringify(json);\n }\n\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this._timeout);\n\n try {\n const response = await fetch(url, { method, headers, body: fetchBody, signal: controller.signal });\n if (response.status === 204) return {};\n\n const data = response.headers.get('content-type')?.includes('application/json')\n ? await response.json()\n : {};\n\n if (response.ok) return data as Record<string, unknown>;\n\n const msg = (data as any).detail ?? (data as any).error ?? (data as any).title ?? JSON.stringify(data);\n const errors = (data as any).errors;\n const errorMsg = errors ? (Array.isArray(errors) ? errors.join('; ') : String(errors)) : msg;\n\n if (response.status === 400) throw new ValidationError(errorMsg, 400, data as any);\n if (response.status === 401) throw new AuthError(errorMsg, 401, data as any);\n if (response.status === 403) throw new AuthError(errorMsg, 403, data as any);\n if (response.status === 404) throw new NotFoundError(errorMsg, 404, data as any);\n if (response.status === 429) throw new QuotaExceededError(errorMsg, 429, data as any);\n throw new UnWebError(errorMsg, response.status, data as any);\n } finally {\n clearTimeout(timeoutId);\n }\n }\n}\n"],"mappings":"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","names":[]}
package/dist/index.mjs ADDED
@@ -0,0 +1,297 @@
1
+ // src/errors.ts
2
+ var UnWebError = class extends Error {
3
+ constructor(message, statusCode, response) {
4
+ super(message);
5
+ this.statusCode = statusCode;
6
+ this.response = response;
7
+ this.name = "UnWebError";
8
+ }
9
+ };
10
+ var AuthError = class extends UnWebError {
11
+ constructor(message, statusCode, response) {
12
+ super(message, statusCode, response);
13
+ this.name = "AuthError";
14
+ }
15
+ };
16
+ var QuotaExceededError = class extends UnWebError {
17
+ constructor(message, statusCode, response) {
18
+ super(message, statusCode, response);
19
+ this.name = "QuotaExceededError";
20
+ }
21
+ };
22
+ var NotFoundError = class extends UnWebError {
23
+ constructor(message, statusCode, response) {
24
+ super(message, statusCode, response);
25
+ this.name = "NotFoundError";
26
+ }
27
+ };
28
+ var ValidationError = class extends UnWebError {
29
+ constructor(message, statusCode, response) {
30
+ super(message, statusCode, response);
31
+ this.name = "ValidationError";
32
+ }
33
+ };
34
+
35
+ // src/resources/auth.ts
36
+ var AuthResource = class {
37
+ constructor(client) {
38
+ this.client = client;
39
+ }
40
+ async register(email, password, firstName = "", lastName = "") {
41
+ const data = await this.client._request("POST", "/api/auth/register", { json: { email, password, firstName, lastName }, authMode: "none" });
42
+ const token = toToken(data);
43
+ this.client._jwtToken = token.token;
44
+ return token;
45
+ }
46
+ async login(email, password) {
47
+ const data = await this.client._request("POST", "/api/auth/login", { json: { email, password }, authMode: "none" });
48
+ const token = toToken(data);
49
+ this.client._jwtToken = token.token;
50
+ return token;
51
+ }
52
+ async me() {
53
+ const data = await this.client._request("GET", "/api/auth/me", { authMode: "jwt" });
54
+ return { id: data.id ?? "", email: data.email ?? "", firstName: data.firstName ?? "", lastName: data.lastName ?? "", role: data.role ?? "" };
55
+ }
56
+ async updateProfile(update) {
57
+ const json = {};
58
+ if (update.email !== void 0) json.email = update.email;
59
+ if (update.firstName !== void 0) json.firstName = update.firstName;
60
+ if (update.lastName !== void 0) json.lastName = update.lastName;
61
+ await this.client._request("PUT", "/api/auth/profile", { json, authMode: "jwt" });
62
+ }
63
+ async changePassword(currentPassword, newPassword) {
64
+ await this.client._request("POST", "/api/auth/change-password", { json: { currentPassword, newPassword }, authMode: "jwt" });
65
+ }
66
+ };
67
+ function toToken(data) {
68
+ return { token: data.token ?? "", userId: data.userId ?? "", email: data.email ?? "" };
69
+ }
70
+
71
+ // src/resources/convert.ts
72
+ import { readFileSync } from "fs";
73
+ var ConvertResource = class {
74
+ constructor(client) {
75
+ this.client = client;
76
+ }
77
+ async paste(html) {
78
+ const data = await this.client._request("POST", "/api/convert/paste", { json: { html } });
79
+ return toResult(data);
80
+ }
81
+ async url(url) {
82
+ const data = await this.client._request("POST", "/api/convert/url", { json: { url } });
83
+ return toResult(data);
84
+ }
85
+ async upload(content, fileName) {
86
+ let buffer;
87
+ let name;
88
+ if (typeof content === "string") {
89
+ buffer = readFileSync(content);
90
+ name = content.split(/[\\/]/).pop() ?? "upload.html";
91
+ } else {
92
+ buffer = content;
93
+ name = fileName ?? "upload.html";
94
+ }
95
+ const formData = new FormData();
96
+ formData.append("file", new Blob([new Uint8Array(buffer)]), name);
97
+ const data = await this.client._request("POST", "/api/convert/upload", { body: formData, authMode: "api_key" });
98
+ return toResult(data);
99
+ }
100
+ };
101
+ function toResult(data) {
102
+ return {
103
+ markdown: data.markdown ?? "",
104
+ warnings: data.warnings ?? [],
105
+ qualityScore: data.qualityScore ?? 100
106
+ };
107
+ }
108
+
109
+ // src/resources/crawl.ts
110
+ var CrawlResource = class {
111
+ constructor(client) {
112
+ this.client = client;
113
+ }
114
+ async start(startUrl, options = {}) {
115
+ const json = {
116
+ startUrl,
117
+ allowedPath: options.allowedPath ?? "/",
118
+ maxPages: options.maxPages ?? 100,
119
+ exportFormat: options.exportFormat ?? "raw-md",
120
+ ignoreRobotsTxt: options.ignoreRobotsTxt ?? false
121
+ };
122
+ if (options.webhookUrl) json.webhookUrl = options.webhookUrl;
123
+ const data = await this.client._request("POST", "/api/crawl", { json });
124
+ return toJob(data);
125
+ }
126
+ async status(jobId) {
127
+ const data = await this.client._request("GET", `/api/crawl/${jobId}/status`);
128
+ return toJob(data);
129
+ }
130
+ async list(options = {}) {
131
+ const params = { skip: options.skip ?? 0, take: options.take ?? 20 };
132
+ if (options.status) params.status = options.status;
133
+ const data = await this.client._request("GET", "/api/crawl", { params });
134
+ return { jobs: (data.jobs ?? []).map(toJob), totalCount: data.totalCount ?? 0 };
135
+ }
136
+ async download(jobId) {
137
+ const data = await this.client._request("GET", `/api/crawl/${jobId}/download`);
138
+ return { downloadUrl: data.downloadUrl ?? "", expiresAt: data.expiresAt, sizeBytes: data.sizeBytes, contentType: data.contentType ?? "application/zip", fileName: data.fileName ?? "" };
139
+ }
140
+ async cancel(jobId) {
141
+ await this.client._request("DELETE", `/api/crawl/${jobId}`);
142
+ }
143
+ };
144
+ function toJob(data) {
145
+ return {
146
+ jobId: data.jobId ?? "",
147
+ status: data.status ?? "",
148
+ pagesCrawled: data.pagesCrawled ?? 0,
149
+ pagesQueued: data.pagesQueued ?? 0,
150
+ startUrl: data.startUrl ?? "",
151
+ allowedPath: data.allowedPath ?? "",
152
+ maxPages: data.maxPages ?? 0,
153
+ exportFormat: data.exportFormat ?? "",
154
+ errorMessage: data.errorMessage,
155
+ createdAt: data.createdAt,
156
+ startedAt: data.startedAt,
157
+ completedAt: data.completedAt,
158
+ durationSeconds: data.durationSeconds,
159
+ outputSizeBytes: data.outputSizeBytes
160
+ };
161
+ }
162
+
163
+ // src/resources/keys.ts
164
+ var KeysResource = class {
165
+ constructor(client) {
166
+ this.client = client;
167
+ }
168
+ async list() {
169
+ const data = await this.client._request("GET", "/api/keys", { authMode: "jwt" });
170
+ return data.map((k) => ({
171
+ id: k.id ?? "",
172
+ name: k.name ?? "",
173
+ keyPrefix: k.keyPrefix ?? "",
174
+ createdAt: k.createdAt,
175
+ lastUsedAt: k.lastUsedAt,
176
+ isRevoked: k.isRevoked ?? false
177
+ }));
178
+ }
179
+ async create(name) {
180
+ const data = await this.client._request("POST", "/api/keys", { json: { name }, authMode: "jwt" });
181
+ return { id: data.id ?? "", name: data.name ?? "", key: data.key ?? "", keyPrefix: data.keyPrefix ?? "" };
182
+ }
183
+ async revoke(keyId) {
184
+ await this.client._request("DELETE", `/api/keys/${keyId}`, { authMode: "jwt" });
185
+ }
186
+ };
187
+
188
+ // src/resources/subscription.ts
189
+ var SubscriptionResource = class {
190
+ constructor(client) {
191
+ this.client = client;
192
+ }
193
+ async get() {
194
+ const data = await this.client._request("GET", "/api/subscription", { authMode: "jwt" });
195
+ return { tier: data.tier ?? "Free", status: data.status ?? "", monthlyCredits: data.monthlyCredits ?? 0, creditsUsed: data.creditsUsed ?? 0, allowsOverage: data.allowsOverage ?? false };
196
+ }
197
+ async checkout(tier) {
198
+ const data = await this.client._request("POST", "/api/subscription/checkout", { json: { tier }, authMode: "jwt" });
199
+ return data.checkoutUrl ?? "";
200
+ }
201
+ async cancel() {
202
+ await this.client._request("POST", "/api/subscription/cancel", { authMode: "jwt" });
203
+ }
204
+ };
205
+
206
+ // src/resources/usage.ts
207
+ var UsageResource = class {
208
+ constructor(client) {
209
+ this.client = client;
210
+ }
211
+ async current() {
212
+ const data = await this.client._request("GET", "/api/usage/current", { authMode: "jwt" });
213
+ return { creditsUsed: data.creditsUsed ?? 0, creditsLimit: data.creditsLimit ?? 0, overageCreditsUsed: data.overageCreditsUsed ?? 0, billingCycleStart: data.billingCycleStart, billingCycleEnd: data.billingCycleEnd };
214
+ }
215
+ async stats() {
216
+ return this.client._request("GET", "/api/usage/stats", { authMode: "jwt" });
217
+ }
218
+ async history() {
219
+ return this.client._request("GET", "/api/usage/history", { authMode: "jwt" });
220
+ }
221
+ };
222
+
223
+ // src/client.ts
224
+ var DEFAULT_BASE_URL = "https://api.unweb.info";
225
+ var UnWebClient = class {
226
+ /** @internal */
227
+ _apiKey;
228
+ /** @internal */
229
+ _baseUrl;
230
+ /** @internal */
231
+ _timeout;
232
+ /** @internal */
233
+ _jwtToken;
234
+ convert;
235
+ crawl;
236
+ auth;
237
+ keys;
238
+ usage;
239
+ subscription;
240
+ constructor(options = {}) {
241
+ this._apiKey = options.apiKey;
242
+ this._baseUrl = (options.baseUrl ?? DEFAULT_BASE_URL).replace(/\/+$/, "");
243
+ this._timeout = options.timeout ?? 3e4;
244
+ this.convert = new ConvertResource(this);
245
+ this.crawl = new CrawlResource(this);
246
+ this.auth = new AuthResource(this);
247
+ this.keys = new KeysResource(this);
248
+ this.usage = new UsageResource(this);
249
+ this.subscription = new SubscriptionResource(this);
250
+ }
251
+ /** @internal */
252
+ async _request(method, path, options = {}) {
253
+ const { json, body, params, authMode = "api_key", headers: extraHeaders } = options;
254
+ let url = `${this._baseUrl}${path}`;
255
+ if (params) {
256
+ const qs = new URLSearchParams();
257
+ for (const [k, v] of Object.entries(params)) qs.set(k, String(v));
258
+ url += `?${qs.toString()}`;
259
+ }
260
+ const headers = { ...extraHeaders };
261
+ if (authMode === "api_key" && this._apiKey) headers["X-API-Key"] = this._apiKey;
262
+ else if (authMode === "jwt" && this._jwtToken) headers["Authorization"] = `Bearer ${this._jwtToken}`;
263
+ let fetchBody = body;
264
+ if (json) {
265
+ headers["Content-Type"] = "application/json";
266
+ fetchBody = JSON.stringify(json);
267
+ }
268
+ const controller = new AbortController();
269
+ const timeoutId = setTimeout(() => controller.abort(), this._timeout);
270
+ try {
271
+ const response = await fetch(url, { method, headers, body: fetchBody, signal: controller.signal });
272
+ if (response.status === 204) return {};
273
+ const data = response.headers.get("content-type")?.includes("application/json") ? await response.json() : {};
274
+ if (response.ok) return data;
275
+ const msg = data.detail ?? data.error ?? data.title ?? JSON.stringify(data);
276
+ const errors = data.errors;
277
+ const errorMsg = errors ? Array.isArray(errors) ? errors.join("; ") : String(errors) : msg;
278
+ if (response.status === 400) throw new ValidationError(errorMsg, 400, data);
279
+ if (response.status === 401) throw new AuthError(errorMsg, 401, data);
280
+ if (response.status === 403) throw new AuthError(errorMsg, 403, data);
281
+ if (response.status === 404) throw new NotFoundError(errorMsg, 404, data);
282
+ if (response.status === 429) throw new QuotaExceededError(errorMsg, 429, data);
283
+ throw new UnWebError(errorMsg, response.status, data);
284
+ } finally {
285
+ clearTimeout(timeoutId);
286
+ }
287
+ }
288
+ };
289
+ export {
290
+ AuthError,
291
+ NotFoundError,
292
+ QuotaExceededError,
293
+ UnWebClient,
294
+ UnWebError,
295
+ ValidationError
296
+ };
297
+ //# sourceMappingURL=index.mjs.map