minifetch-api 0.0.1 → 1.0.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 Lauren Garcia
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 CHANGED
@@ -1,26 +1,120 @@
1
- # Minifetch.com API
1
+ # Minifetch API
2
+ <div align=center>
3
+ <img src="https://minifetch.com/minifetch-dog-logo--whitebg.png" width="70" />
4
+ </div>
2
5
 
3
- Works with x402 payments on Base Sepolia Testnet (only) so far. Testnet API endpoints are not exposed. Check back again later!
6
+ **Fetch & extract data from web pages.** [Minifetch.com](https://minifetch.com) provides composable extraction APIs that humans and AI Agents can autonomously discover, orchestrate, and pay for— making web pages simple to access. We offer competitive prices.
4
7
 
5
- This client based on x402 payments [example client code](https://github.com/coinbase/x402/blob/main/examples/typescript/clients/fetch).
8
+ **Full [API docs are here](https://minifetch.com/docs/api)**, including example response data & prices. For AI Agents, read the [LLMs.txt](https://minifetch.com/llms.txt).
9
+
10
+ **Payments** work with [x402](https://www.x402.org/) USDC stablecoin micropayments on Coinbase's Base & Solana blockchain networks. Transaction fees are free. If you'd like to use a traditional credit card & API key instead, sign up for the waitlist and we'll let you know when it's ready: [forms.gle/rkMi7T23bHJc8XFw9](https://forms.gle/rkMi7T23bHJc8XFw9)
11
+
12
+ **Bulk fetch and extract** for building datasets is coming soon, sign up for the waitlist and we'll let you know when it's ready: [forms.gle/rkMi7T23bHJc8XFw9](https://forms.gle/rkMi7T23bHJc8XFw9)
6
13
 
7
14
  ## Prerequisites
8
15
 
9
- - Node.js v20+ (install via [nvm](https://github.com/nvm-sh/nvm))
10
- - pnpm v10 (install via [pnpm.io/installation](https://pnpm.io/installation))
11
- - A valid Ethereum private key for making USDC payments on Base Sepolia Testnet (only) -- live production client coming soon!
16
+ - Node.js v18+ & NPM
17
+ - A valid Ethereum or Solana private key for making USDC payments.
12
18
 
13
- ## Setup
19
+ ## Install
14
20
 
15
- 1. Copy `.env-local` to `.env-base-testnet` and add your Ethereum private key:
16
- ```bash
17
- cp .env-local .env-base-testnet
18
- ```
21
+ `npm install minifetch-api --save`
22
+
23
+ ## Quick Start
19
24
 
20
- 2. Start the example client:
21
- ```bash
22
- pnpm install
23
- pnpm dev:testnet:check
24
- pnpm dev:testnet
25
+ ```js
26
+ import Minifetch from "minifetch-api";
27
+
28
+ // Inititialize the client with your network choice & private key.
29
+ // - Network options: "base" or "solana"
30
+ // - Use private key from account that has a small amt of USDC
31
+ const client = new Minifetch({
32
+ network: "base",
33
+ privateKey: process.env.BASE_PRIVATE_KEY,
34
+ });
35
+
36
+ try {
37
+ const url = "example.com";
38
+ const response = await client.checkAndExtractPreview(url);
39
+ // 200 "ok" responses will return the data and x402 payment info:
40
+ console.log("data: ", response.data);
41
+ console.log("payment info: ", response.payment);
42
+ } catch (err) {
43
+ // No payment or charges for errors!
44
+ console.log(err);
45
+ }
25
46
  ```
26
47
 
48
+ ### Client Methods Available
49
+
50
+ After you initialize the client (above), you have the following methods available to use. The "checkAndExtract" API methods provided help you avoid paying for blocked URLs and return more granular info about why a URL may or may not return data. There is no charge for blocked upstream URLs.
51
+
52
+ [Price list and example data for each method is here.](https://minifetch.com/docs/api#example-data)
53
+
54
+ Requests exceeding rate limits return `503` errors. This is intentional — back off and retry, max 5-10 queries per second. We'll add bulk fetch and extract in the future. Sign up for the [waitlist here](https://forms.gle/rkMi7T23bHJc8XFw9).
55
+
56
+ - `client.checkAndExtractUrlPreview(url)`
57
+ - Extracts a light, token-efficient preview of a URL: title, description, and image (only).
58
+
59
+ - `client.checkAndExtractUrlContent(url, options)`
60
+ - Options: `includeMediaUrls: true`, defaults to false
61
+ - Extracts a clean, token-efficient content summary as markdown from a URL. Removes ads, nav, scripts. Much more efficient than raw HTML fetches for LLMs.
62
+
63
+ - `client.checkAndExtractUrlLinks(url)`
64
+ - Extracts all links from a URL categorized by type (internal/external/anchor) with SEO metadata. Detects image links, nofollow attributes, and analyzes external domain distribution.
65
+
66
+ - `client.checkAndExtractUrlMetadata(url, options)`
67
+ - Options: `includeResponseBody: true`, defaults to false
68
+ - Extracts rich structured metadata from a URL: title, description, og/twitter tags, json-ld, images, headings, response headers, and more. Perfect for SEO research or metadata indexing & analysis. Largest response size of the client methods available.
69
+
70
+ For maximum control, you can also use the following methods directly:
71
+
72
+ - `client.preflightCheck(url)`
73
+ - Standalone call to check if a URL is allowed to be fetched according to the website's robots.txt file. Use this free endpoint before using our other paid endpoints to avoid spending extra on un-fetchable URLs
74
+ - `client.extractUrlPreview(url)`
75
+ - `client.extractUrlContent(url, options)`
76
+ - Options: `includeMediaUrls: true`, defaults to false
77
+ - `client.extractUrlLinks(url)`
78
+ - `client.extractUrlMetadata(url, options)`
79
+ - Options: `includeResponseBody: true`, defaults to false
80
+
81
+ ### Error Types
82
+ When you wrap the functions above in a try/catch, here are the errors you may encounter:
83
+
84
+ - **"RobotsBlockedError: URL is blocked by robots.txt"**
85
+ - URL is explicitly blocked by the website's robots.txt will error like this.
86
+ - **"Network Error: 402 Payment Required"**
87
+ - Check your wallet -- likely you ran out of USDC to pay!
88
+ - **"Network Error: 502 Bad Gateway"**
89
+ - URLs that pass the robots.txt check but are blocked anyway via 403 or other tactics may error like this.
90
+ - **"503 Service Temporarily Unavailable"**
91
+ - Likely encountering Minifetch rate-limiting or upstream timeout errors on the target URL. You may try again but limit requests to 5-10 at a time. Bulk fetches coming soon.
92
+ - **"InvalidURLError: Invalid url ${url}"**
93
+ - The URL you passed in is malformed in some way, correct it and try again.
94
+
95
+ ### Service Limitations
96
+ Minifetch only extracts publicly available metadata and content from pages accessible without authentication and javascript execution.
97
+
98
+ What Minifetch does NOT do:
99
+
100
+ - Ignore robots.txt directives
101
+ - Access authenticated or logged-in content
102
+ - Create accounts or log into user sessions
103
+ - Perform transactional actions (checkout, bidding, purchasing, form submissions)
104
+ - Bypass paywalls or access restricted content
105
+
106
+ What Minifetch does NOT do *currently* but may offer in the future as an add-on:
107
+ - Javascript execution
108
+
109
+ ## x402 Best Practices
110
+
111
+ - LLMs & Agents should *never* have direct access to your private key. They *will* expose it!
112
+ - Only keep a small amount of USDC in the account whose private key you use.
113
+ - Keep that account separate from the rest of your onchain funds.
114
+ - Pass your private key into the Minifetch API Client via an [environment variable](https://developer.vonage.com/en/blog/how-to-use-environment-variables-in-javascript-with-dotenv).
115
+
116
+ ---
117
+ **License**
118
+
119
+ MIT / Copyright (c) 2026 Lauren Garcia
120
+ This package is an API client for Minifetch.com. The client code is open source, but use of the Minifetch API is subject to the [Minifetch.com Terms of Service](https://minifetch.com/terms-of-service).
@@ -0,0 +1,266 @@
1
+ import { initConfig } from "./init.js";
2
+ import { validateAndNormalizeUrl } from "./utils/validation.js";
3
+ import { handlePayment } from "./utils/payment.js";
4
+ import { InvalidUrlError, RobotsBlockedError, PaymentFailedError, ExtractionFailedError, NetworkError, } from "./types/errors.js";
5
+ /**
6
+ * Main Minifetch API client
7
+ * Provides methods to check URLs and extract metadata/links/preview/content
8
+ */
9
+ export class MinifetchClient {
10
+ config;
11
+ baseUrl;
12
+ /**
13
+ *
14
+ * @param config
15
+ */
16
+ constructor(config) {
17
+ this.config = initConfig(config);
18
+ this.baseUrl = this.config.apiBaseUrl;
19
+ }
20
+ /**
21
+ * Check if URL is allowed by robots.txt (free preflight check)
22
+ *
23
+ * @param url
24
+ * @throws {InvalidUrlError} if URL is invalid
25
+ * @throws {NetworkError} if request fails
26
+ */
27
+ async preflightUrlCheck(url) {
28
+ try {
29
+ // Validate and normalize URL
30
+ const normalizedUrl = validateAndNormalizeUrl(url);
31
+ // Build request URL (free endpoint, no payment)
32
+ const endpoint = `/api/v1/free/preflight/url-check?url=${encodeURIComponent(normalizedUrl)}`;
33
+ const requestUrl = `${this.baseUrl}${endpoint}`;
34
+ const response = await fetch(requestUrl);
35
+ if (!response.ok) {
36
+ throw new NetworkError(`Preflight check failed: ${response.status} ${response.statusText}`);
37
+ }
38
+ const data = (await response.json());
39
+ return data;
40
+ }
41
+ catch (error) {
42
+ if (error instanceof InvalidUrlError || error instanceof NetworkError) {
43
+ throw error;
44
+ }
45
+ throw new NetworkError(`Preflight check failed: ${error instanceof Error ? error.message : "Unknown error"}`);
46
+ }
47
+ }
48
+ /**
49
+ * Extract URL metadata (paid, requires x402 payment)
50
+ *
51
+ * @param url
52
+ * @param options
53
+ * @param options.includeResponseBody
54
+ * @throws {InvalidUrlError} if URL is invalid
55
+ * @throws {PaymentFailedError} if payment fails
56
+ * @throws {ExtractionFailedError} if extraction fails
57
+ */
58
+ async extractUrlMetadata(url, options) {
59
+ try {
60
+ // Validate and normalize URL
61
+ const normalizedUrl = validateAndNormalizeUrl(url);
62
+ // Build request URL with optional params
63
+ const params = new URLSearchParams({ url: normalizedUrl });
64
+ if (options?.includeResponseBody) {
65
+ params.set("includeResponseBody", "true");
66
+ }
67
+ // Build request URL - convert params to string
68
+ const endpoint = `/api/v1/x402/extract/url-metadata?${params.toString()}`;
69
+ const requestUrl = `${this.baseUrl}${endpoint}`;
70
+ // Make request with x402 payment handling
71
+ const { response, payment } = await handlePayment(requestUrl, this.config);
72
+ // Check if extraction succeeded
73
+ if (!response.ok) {
74
+ throw new ExtractionFailedError(normalizedUrl, `Metadata extraction failed: ${response.status} ${response.statusText}`);
75
+ }
76
+ const data = (await response.json());
77
+ return {
78
+ success: data.success,
79
+ results: data.results,
80
+ payment,
81
+ };
82
+ }
83
+ catch (error) {
84
+ if (error instanceof InvalidUrlError ||
85
+ error instanceof ExtractionFailedError ||
86
+ error instanceof PaymentFailedError ||
87
+ error instanceof NetworkError) {
88
+ throw error;
89
+ }
90
+ throw new ExtractionFailedError(url, `Metadata extraction failed: ${error instanceof Error ? error.message : "Unknown error"}`);
91
+ }
92
+ }
93
+ /**
94
+ * Extract URL links (paid, requires x402 payment)
95
+ *
96
+ * @param url
97
+ * @throws {InvalidUrlError} if URL is invalid
98
+ * @throws {PaymentFailedError} if payment fails
99
+ * @throws {ExtractionFailedError} if extraction fails
100
+ */
101
+ async extractUrlLinks(url) {
102
+ try {
103
+ const normalizedUrl = validateAndNormalizeUrl(url);
104
+ const endpoint = `/api/v1/x402/extract/url-links?url=${encodeURIComponent(normalizedUrl)}`;
105
+ const requestUrl = `${this.baseUrl}${endpoint}`;
106
+ // Make request with x402 payment handling
107
+ const { response, payment } = await handlePayment(requestUrl, this.config);
108
+ if (!response.ok) {
109
+ throw new ExtractionFailedError(normalizedUrl, `Links extraction failed: ${response.status} ${response.statusText}`);
110
+ }
111
+ const data = (await response.json());
112
+ return {
113
+ success: data.success,
114
+ results: data.results,
115
+ payment,
116
+ };
117
+ }
118
+ catch (error) {
119
+ if (error instanceof InvalidUrlError ||
120
+ error instanceof ExtractionFailedError ||
121
+ error instanceof PaymentFailedError ||
122
+ error instanceof NetworkError) {
123
+ throw error;
124
+ }
125
+ throw new ExtractionFailedError(url, `Links extraction failed: ${error instanceof Error ? error.message : "Unknown error"}`);
126
+ }
127
+ }
128
+ /**
129
+ * Extract URL preview (paid, requires x402 payment)
130
+ *
131
+ * @param url
132
+ * @throws {InvalidUrlError} if URL is invalid
133
+ * @throws {PaymentFailedError} if payment fails
134
+ * @throws {ExtractionFailedError} if extraction fails
135
+ */
136
+ async extractUrlPreview(url) {
137
+ try {
138
+ // Validate and normalize URL
139
+ const normalizedUrl = validateAndNormalizeUrl(url);
140
+ // Build request URL
141
+ const endpoint = `/api/v1/x402/extract/url-preview?url=${encodeURIComponent(normalizedUrl)}`;
142
+ const requestUrl = `${this.baseUrl}${endpoint}`;
143
+ // Make request with x402 payment handling
144
+ const { response, payment } = await handlePayment(requestUrl, this.config);
145
+ // Check if extraction succeeded
146
+ if (!response.ok) {
147
+ throw new ExtractionFailedError(normalizedUrl, `Preview extraction failed: ${response.status} ${response.statusText}`);
148
+ }
149
+ const data = (await response.json());
150
+ return {
151
+ success: data.success,
152
+ results: data.results,
153
+ payment,
154
+ };
155
+ }
156
+ catch (error) {
157
+ if (error instanceof InvalidUrlError ||
158
+ error instanceof ExtractionFailedError ||
159
+ error instanceof PaymentFailedError ||
160
+ error instanceof NetworkError) {
161
+ throw error;
162
+ }
163
+ throw new ExtractionFailedError(url, `Preview extraction failed: ${error instanceof Error ? error.message : "Unknown error"}`);
164
+ }
165
+ }
166
+ /**
167
+ * Extract URL content as markdown (paid, requires x402 payment)
168
+ *
169
+ * @param url
170
+ * @param options
171
+ * @param options.includeMediaUrls
172
+ * @throws {InvalidUrlError} if URL is invalid
173
+ * @throws {PaymentFailedError} if payment fails
174
+ * @throws {ExtractionFailedError} if extraction fails
175
+ */
176
+ async extractUrlContent(url, options) {
177
+ try {
178
+ // Validate and normalize URL
179
+ const normalizedUrl = validateAndNormalizeUrl(url);
180
+ // Build request URL with optional params
181
+ const params = new URLSearchParams({ url: normalizedUrl });
182
+ if (options?.includeMediaUrls) {
183
+ params.set("includeMediaUrls", "true");
184
+ }
185
+ const endpoint = `/api/v1/x402/extract/url-content?${params.toString()}`;
186
+ const requestUrl = `${this.baseUrl}${endpoint}`;
187
+ // Make request with x402 payment handling
188
+ const { response, payment } = await handlePayment(requestUrl, this.config);
189
+ // Check if extraction succeeded
190
+ if (!response.ok) {
191
+ throw new ExtractionFailedError(normalizedUrl, `Content extraction failed: ${response.status} ${response.statusText}`);
192
+ }
193
+ const data = (await response.json());
194
+ return {
195
+ success: data.success,
196
+ results: data.results,
197
+ payment,
198
+ };
199
+ }
200
+ catch (error) {
201
+ if (error instanceof InvalidUrlError ||
202
+ error instanceof ExtractionFailedError ||
203
+ error instanceof PaymentFailedError ||
204
+ error instanceof NetworkError) {
205
+ throw error;
206
+ }
207
+ throw new ExtractionFailedError(url, `Content extraction failed: ${error instanceof Error ? error.message : "Unknown error"}`);
208
+ }
209
+ }
210
+ /**
211
+ * Check URL and extract metadata in one call
212
+ * Throws RobotsBlockedError if robots.txt blocks the URL
213
+ *
214
+ * @param url
215
+ * @param options
216
+ * @param options.includeResponseBody
217
+ */
218
+ async checkAndExtractUrlMetadata(url, options) {
219
+ const checkResponse = await this.preflightUrlCheck(url);
220
+ if (!checkResponse.results[0]?.data?.allowed) {
221
+ throw new RobotsBlockedError(url, checkResponse.results[0]?.data?.message || "URL is blocked by robots.txt");
222
+ }
223
+ return this.extractUrlMetadata(url, options);
224
+ }
225
+ /**
226
+ * Check URL and extract links in one call
227
+ * Throws RobotsBlockedError if robots.txt blocks the URL
228
+ *
229
+ * @param url
230
+ */
231
+ async checkAndExtractUrlLinks(url) {
232
+ const checkResponse = await this.preflightUrlCheck(url);
233
+ if (!checkResponse.results[0]?.data?.allowed) {
234
+ throw new RobotsBlockedError(url, checkResponse.results[0]?.data?.message || "URL is blocked by robots.txt");
235
+ }
236
+ return this.extractUrlLinks(url);
237
+ }
238
+ /**
239
+ * Check URL and extract preview in one call
240
+ * Throws RobotsBlockedError if robots.txt blocks the URL
241
+ *
242
+ * @param url
243
+ */
244
+ async checkAndExtractUrlPreview(url) {
245
+ const checkResponse = await this.preflightUrlCheck(url);
246
+ if (!checkResponse.results[0]?.data?.allowed) {
247
+ throw new RobotsBlockedError(url, checkResponse.results[0]?.data?.message || "URL is blocked by robots.txt");
248
+ }
249
+ return this.extractUrlPreview(url);
250
+ }
251
+ /**
252
+ * Check URL and extract content in one call
253
+ * Throws RobotsBlockedError if robots.txt blocks the URL
254
+ *
255
+ * @param url
256
+ * @param options
257
+ * @param options.includeMediaUrls
258
+ */
259
+ async checkAndExtractUrlContent(url, options) {
260
+ const checkResponse = await this.preflightUrlCheck(url);
261
+ if (!checkResponse.results[0]?.data?.allowed) {
262
+ throw new RobotsBlockedError(url, checkResponse.results[0]?.data?.message || "URL is blocked by robots.txt");
263
+ }
264
+ return this.extractUrlContent(url, options);
265
+ }
266
+ }
@@ -0,0 +1,2 @@
1
+ export { MinifetchClient } from "./client.js";
2
+ export { MinifetchClient as default } from "./client.js";
@@ -0,0 +1,70 @@
1
+ import { VALID_NETWORKS } from "./types/config.js";
2
+ import { ConfigurationError } from "./types/errors.js";
3
+ /**
4
+ * Default configuration values
5
+ * Exported for testing purposes
6
+ */
7
+ export const DEFAULTS = {
8
+ network: "base",
9
+ apiBaseUrls: {
10
+ "base-sepolia": "http://localhost:4021",
11
+ "solana-devnet": "http://localhost:4021",
12
+ base: "https://minifetch.com",
13
+ solana: "https://minifetch.com",
14
+ },
15
+ explorerUrls: {
16
+ "base-sepolia": "https://sepolia.basescan.org/tx",
17
+ "solana-devnet": "https://explorer.solana.com/tx?cluster=devnet",
18
+ base: "https://basescan.org/tx",
19
+ solana: "https://explorer.solana.com/tx",
20
+ },
21
+ };
22
+ /**
23
+ * Validate & initialize client configuration
24
+ *
25
+ * @param config
26
+ */
27
+ export function initConfig(config) {
28
+ // Validate private key is provided
29
+ if (!config.privateKey || config.privateKey.trim() === "") {
30
+ throw new ConfigurationError("Private key is required");
31
+ }
32
+ // Validate network
33
+ const network = config.network || DEFAULTS.network;
34
+ if (!VALID_NETWORKS.includes(network)) {
35
+ throw new ConfigurationError(`Invalid network: "${network}". Must be one of: ${VALID_NETWORKS.join(", ")}`);
36
+ }
37
+ // Validate private key format based on network
38
+ validatePrivateKey(config.privateKey, network);
39
+ // Build initalized config
40
+ const apiBaseUrl = DEFAULTS.apiBaseUrls[network];
41
+ const explorerUrl = DEFAULTS.explorerUrls[network];
42
+ // console.log(`config.ts: network: ${network} apiBaseUrl: ${apiBaseUrl}`)
43
+ return {
44
+ network,
45
+ privateKey: config.privateKey,
46
+ apiBaseUrl,
47
+ explorerUrl,
48
+ };
49
+ }
50
+ /**
51
+ * Validate private key format for the given network
52
+ *
53
+ * @param privateKey
54
+ * @param network
55
+ */
56
+ function validatePrivateKey(privateKey, network) {
57
+ if (network === "solana" || network === "solana-devnet") {
58
+ // Solana: base58 encoded, typically 88 characters
59
+ if (!/^[1-9A-HJ-NP-Za-km-z]{87,88}$/.test(privateKey)) {
60
+ throw new ConfigurationError("Invalid Solana private key format (expected base58 string)");
61
+ }
62
+ }
63
+ else {
64
+ // EVM: hex string, 64 characters (with or without 0x prefix)
65
+ const cleanKey = privateKey.startsWith("0x") ? privateKey.slice(2) : privateKey;
66
+ if (!/^[0-9a-fA-F]{64}$/.test(cleanKey)) {
67
+ throw new ConfigurationError("Invalid EVM private key format (expected hex string that starts with 0x)");
68
+ }
69
+ }
70
+ }
@@ -0,0 +1 @@
1
+ export const VALID_NETWORKS = ["base", "base-sepolia", "solana", "solana-devnet"];
@@ -0,0 +1,122 @@
1
+ /**
2
+ * Base error class for all Minifetch errors
3
+ */
4
+ export class MinifetchError extends Error {
5
+ /**
6
+ *
7
+ * @param message
8
+ */
9
+ constructor(message) {
10
+ super(message);
11
+ this.name = "MinifetchError";
12
+ Object.setPrototypeOf(this, MinifetchError.prototype);
13
+ }
14
+ }
15
+ /**
16
+ * Thrown when URL validation fails
17
+ */
18
+ export class InvalidUrlError extends MinifetchError {
19
+ url;
20
+ /**
21
+ *
22
+ * @param url
23
+ * @param message
24
+ */
25
+ constructor(url, message) {
26
+ super(message || `Invalid url: ${url}`);
27
+ this.name = "InvalidUrlError";
28
+ this.url = url;
29
+ Object.setPrototypeOf(this, InvalidUrlError.prototype);
30
+ }
31
+ }
32
+ /**
33
+ * Thrown when robots.txt blocks the request
34
+ */
35
+ export class RobotsBlockedError extends MinifetchError {
36
+ url;
37
+ /**
38
+ *
39
+ * @param url
40
+ * @param message
41
+ */
42
+ constructor(url, message) {
43
+ super(message || `URL is blocked by robots.txt`);
44
+ this.name = "RobotsBlockedError";
45
+ this.url = url;
46
+ Object.setPrototypeOf(this, RobotsBlockedError.prototype);
47
+ }
48
+ }
49
+ /**
50
+ * Thrown when payment fails
51
+ */
52
+ export class PaymentFailedError extends MinifetchError {
53
+ network;
54
+ originalError;
55
+ /**
56
+ *
57
+ * @param message
58
+ * @param network
59
+ * @param originalError
60
+ */
61
+ constructor(message, network, originalError) {
62
+ super(message);
63
+ this.name = "PaymentFailedError";
64
+ this.network = network;
65
+ this.originalError = originalError;
66
+ Object.setPrototypeOf(this, PaymentFailedError.prototype);
67
+ }
68
+ }
69
+ /**
70
+ * Thrown when extraction/fetch fails
71
+ */
72
+ export class ExtractionFailedError extends MinifetchError {
73
+ url;
74
+ statusCode;
75
+ originalError;
76
+ /**
77
+ *
78
+ * @param url
79
+ * @param message
80
+ * @param statusCode
81
+ * @param originalError
82
+ */
83
+ constructor(url, message, statusCode, originalError) {
84
+ super(message);
85
+ this.name = "ExtractionFailedError";
86
+ this.url = url;
87
+ this.statusCode = statusCode;
88
+ this.originalError = originalError;
89
+ Object.setPrototypeOf(this, ExtractionFailedError.prototype);
90
+ }
91
+ }
92
+ /**
93
+ * Thrown when configuration is invalid
94
+ */
95
+ export class ConfigurationError extends MinifetchError {
96
+ /**
97
+ *
98
+ * @param message
99
+ */
100
+ constructor(message) {
101
+ super(message);
102
+ this.name = "ConfigurationError";
103
+ Object.setPrototypeOf(this, ConfigurationError.prototype);
104
+ }
105
+ }
106
+ /**
107
+ * Thrown when network/API communication fails
108
+ */
109
+ export class NetworkError extends MinifetchError {
110
+ originalError;
111
+ /**
112
+ *
113
+ * @param message
114
+ * @param originalError
115
+ */
116
+ constructor(message, originalError) {
117
+ super(message);
118
+ this.name = "NetworkError";
119
+ this.originalError = originalError;
120
+ Object.setPrototypeOf(this, NetworkError.prototype);
121
+ }
122
+ }
@@ -0,0 +1 @@
1
+ export {};