@x402jobs/sdk 0.1.0 → 0.2.1
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/README.md +31 -34
- package/dist/index.d.mts +60 -39
- package/dist/index.d.ts +60 -39
- package/dist/index.js +120 -135
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +119 -132
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -10,12 +10,16 @@ npm install @x402jobs/sdk
|
|
|
10
10
|
|
|
11
11
|
## Quick Start
|
|
12
12
|
|
|
13
|
+
```javascript
|
|
14
|
+
import { X402Jobs } from '@x402jobs/sdk'
|
|
15
|
+
|
|
16
|
+
const x402 = new X402Jobs({ apiKey: 'your-api-key' })
|
|
17
|
+
```
|
|
18
|
+
|
|
13
19
|
### Check if a resource is reliable
|
|
14
20
|
|
|
15
21
|
```javascript
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
const score = await check('https://api.example.com/resource')
|
|
22
|
+
const score = await x402.check('https://api.example.com/resource')
|
|
19
23
|
// {
|
|
20
24
|
// url: "https://api.example.com/resource",
|
|
21
25
|
// success_rate: 0.94,
|
|
@@ -28,17 +32,13 @@ const score = await check('https://api.example.com/resource')
|
|
|
28
32
|
### Browse top resources
|
|
29
33
|
|
|
30
34
|
```javascript
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
const top = await check.top({ limit: 20 })
|
|
35
|
+
const top = await x402.check.top({ limit: 20 })
|
|
34
36
|
```
|
|
35
37
|
|
|
36
38
|
### Search resources
|
|
37
39
|
|
|
38
40
|
```javascript
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
const results = await resources.search({
|
|
41
|
+
const results = await x402.resources.search({
|
|
42
42
|
query: 'image generation',
|
|
43
43
|
minSuccessRate: 0.9
|
|
44
44
|
})
|
|
@@ -47,11 +47,7 @@ const results = await resources.search({
|
|
|
47
47
|
### Register your resource
|
|
48
48
|
|
|
49
49
|
```javascript
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
configure({ apiKey: 'your-api-key' })
|
|
53
|
-
|
|
54
|
-
await resources.register({
|
|
50
|
+
await x402.resources.register({
|
|
55
51
|
url: 'https://my-api.com/endpoint',
|
|
56
52
|
name: 'My API',
|
|
57
53
|
price: '$0.01'
|
|
@@ -68,19 +64,28 @@ We ran the transactions. We paid the fees. Now you get the data.
|
|
|
68
64
|
|
|
69
65
|
## API Reference
|
|
70
66
|
|
|
71
|
-
###
|
|
67
|
+
### Constructor
|
|
72
68
|
|
|
73
|
-
|
|
74
|
-
|
|
69
|
+
```javascript
|
|
70
|
+
const x402 = new X402Jobs({
|
|
71
|
+
apiKey: 'sk_...', // API key for authenticated access
|
|
72
|
+
baseUrl: 'https://...', // Custom API URL (optional)
|
|
73
|
+
})
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### Trust / Verification (`x402.check`)
|
|
77
|
+
|
|
78
|
+
| Method | Description |
|
|
79
|
+
|--------|-------------|
|
|
75
80
|
| `check(url)` | Get reliability score for a resource |
|
|
76
81
|
| `check.many(urls)` | Check multiple resources |
|
|
77
82
|
| `check.exists(url)` | Check if resource is indexed |
|
|
78
83
|
| `check.top(options)` | Get top-ranked resources |
|
|
79
84
|
|
|
80
|
-
### Resources
|
|
85
|
+
### Resources (`x402.resources`)
|
|
81
86
|
|
|
82
|
-
|
|
|
83
|
-
|
|
87
|
+
| Method | Description |
|
|
88
|
+
|--------|-------------|
|
|
84
89
|
| `resources.list()` | Get all resources |
|
|
85
90
|
| `resources.get(url)` | Get single resource |
|
|
86
91
|
| `resources.search(options)` | Search resources |
|
|
@@ -88,20 +93,15 @@ We ran the transactions. We paid the fees. Now you get the data.
|
|
|
88
93
|
| `resources.update(id, input)` | Update resource |
|
|
89
94
|
| `resources.delete(id)` | Delete resource |
|
|
90
95
|
|
|
91
|
-
### Configuration
|
|
92
|
-
|
|
93
|
-
| Function | Description |
|
|
94
|
-
|----------|-------------|
|
|
95
|
-
| `configure({ apiKey })` | Set API key for unlimited access |
|
|
96
|
-
| `configure({ baseUrl })` | Set custom API URL |
|
|
97
|
-
|
|
98
96
|
## Error Handling
|
|
99
97
|
|
|
100
98
|
```javascript
|
|
101
|
-
import { X402Error } from '@x402jobs/sdk'
|
|
99
|
+
import { X402Jobs, X402Error } from '@x402jobs/sdk'
|
|
100
|
+
|
|
101
|
+
const x402 = new X402Jobs({ apiKey: 'sk_...' })
|
|
102
102
|
|
|
103
103
|
try {
|
|
104
|
-
const score = await check(url)
|
|
104
|
+
const score = await x402.check(url)
|
|
105
105
|
} catch (err) {
|
|
106
106
|
if (err instanceof X402Error) {
|
|
107
107
|
console.log(err.code) // Error code
|
|
@@ -128,11 +128,8 @@ try {
|
|
|
128
128
|
Full TypeScript support with exported types:
|
|
129
129
|
|
|
130
130
|
```typescript
|
|
131
|
-
import
|
|
132
|
-
|
|
133
|
-
Resource,
|
|
134
|
-
ResourceSearchOptions
|
|
135
|
-
} from '@x402jobs/sdk'
|
|
131
|
+
import { X402Jobs } from '@x402jobs/sdk'
|
|
132
|
+
import type { Score, Resource, ClientOptions } from '@x402jobs/sdk'
|
|
136
133
|
```
|
|
137
134
|
|
|
138
135
|
## Docs
|
package/dist/index.d.mts
CHANGED
|
@@ -11,19 +11,24 @@ interface TopOptions {
|
|
|
11
11
|
}
|
|
12
12
|
interface Resource {
|
|
13
13
|
id: string;
|
|
14
|
-
url: string;
|
|
15
14
|
name: string;
|
|
16
|
-
description
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
15
|
+
description?: string;
|
|
16
|
+
resource_url: string;
|
|
17
|
+
network?: string;
|
|
18
|
+
category?: string;
|
|
19
|
+
price?: string;
|
|
20
|
+
icon_url?: string | null;
|
|
21
|
+
owner_id?: string;
|
|
22
|
+
created_at?: string;
|
|
23
|
+
updated_at?: string;
|
|
24
|
+
success_rate?: number | null;
|
|
25
|
+
calls?: number;
|
|
26
|
+
value_processed?: string;
|
|
27
|
+
last_called?: string | null;
|
|
28
|
+
}
|
|
29
|
+
interface ResourceListOptions {
|
|
30
|
+
limit?: number;
|
|
31
|
+
sort?: 'popular' | 'recent' | 'name';
|
|
27
32
|
}
|
|
28
33
|
interface ResourceSearchOptions {
|
|
29
34
|
query?: string;
|
|
@@ -51,43 +56,59 @@ interface ResourceUpdateInput {
|
|
|
51
56
|
interface WalletConfig {
|
|
52
57
|
[key: string]: unknown;
|
|
53
58
|
}
|
|
54
|
-
interface
|
|
59
|
+
interface ClientOptions {
|
|
55
60
|
apiKey?: string;
|
|
56
61
|
baseUrl?: string;
|
|
57
62
|
wallet?: WalletConfig;
|
|
58
63
|
}
|
|
59
64
|
type ErrorCode = 'NOT_FOUND' | 'PAYMENT_REQUIRED' | 'RATE_LIMITED' | 'UNAUTHORIZED' | 'FORBIDDEN' | 'VALIDATION_ERROR' | 'SERVER_ERROR';
|
|
60
65
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
66
|
+
type HttpMethod = 'GET' | 'POST' | 'PATCH' | 'DELETE';
|
|
67
|
+
interface RequestOptions {
|
|
68
|
+
method?: HttpMethod;
|
|
69
|
+
body?: unknown;
|
|
70
|
+
params?: Record<string, string | number | boolean | undefined>;
|
|
71
|
+
}
|
|
72
|
+
declare class HttpClient {
|
|
73
|
+
private baseUrl;
|
|
74
|
+
private apiKey;
|
|
75
|
+
constructor(options?: ClientOptions);
|
|
76
|
+
private buildUrl;
|
|
77
|
+
private getHeaders;
|
|
78
|
+
private parseResponse;
|
|
79
|
+
request<T>(path: string, options?: RequestOptions): Promise<T>;
|
|
80
|
+
get<T>(path: string, params?: RequestOptions['params']): Promise<T>;
|
|
81
|
+
post<T>(path: string, body?: unknown): Promise<T>;
|
|
82
|
+
patch<T>(path: string, body?: unknown): Promise<T>;
|
|
83
|
+
delete<T>(path: string): Promise<T>;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
interface CheckAPI {
|
|
87
|
+
(url: string): Promise<Score>;
|
|
88
|
+
many(urls: string[]): Promise<Score[]>;
|
|
89
|
+
exists(url: string): Promise<boolean>;
|
|
90
|
+
top(options?: TopOptions): Promise<Score[]>;
|
|
91
|
+
}
|
|
71
92
|
|
|
72
93
|
type GetInput = string | {
|
|
73
94
|
id: string;
|
|
74
95
|
};
|
|
75
|
-
declare
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
register: typeof register;
|
|
86
|
-
update: typeof update;
|
|
87
|
-
delete: typeof remove;
|
|
88
|
-
};
|
|
96
|
+
declare class ResourcesAPI {
|
|
97
|
+
private http;
|
|
98
|
+
constructor(http: HttpClient);
|
|
99
|
+
list(options?: ResourceListOptions): Promise<Resource[]>;
|
|
100
|
+
get(input: GetInput): Promise<Resource>;
|
|
101
|
+
search(options?: ResourceSearchOptions): Promise<Resource[]>;
|
|
102
|
+
register(input: ResourceCreateInput): Promise<Resource>;
|
|
103
|
+
update(id: string, input: ResourceUpdateInput): Promise<Resource>;
|
|
104
|
+
delete(id: string): Promise<void>;
|
|
105
|
+
}
|
|
89
106
|
|
|
90
|
-
declare
|
|
107
|
+
declare class X402Jobs {
|
|
108
|
+
readonly check: CheckAPI;
|
|
109
|
+
readonly resources: ResourcesAPI;
|
|
110
|
+
constructor(options?: ClientOptions);
|
|
111
|
+
}
|
|
91
112
|
|
|
92
113
|
declare class X402Error extends Error {
|
|
93
114
|
readonly code: ErrorCode;
|
|
@@ -103,4 +124,4 @@ declare class X402Error extends Error {
|
|
|
103
124
|
static fromStatus(status: number, message?: string): X402Error;
|
|
104
125
|
}
|
|
105
126
|
|
|
106
|
-
export { type
|
|
127
|
+
export { type ClientOptions, type ErrorCode, type Resource, type ResourceCreateInput, type ResourceListOptions, type ResourceSearchOptions, type ResourceUpdateInput, type Score, type TopOptions, type WalletConfig, X402Error, X402Jobs };
|
package/dist/index.d.ts
CHANGED
|
@@ -11,19 +11,24 @@ interface TopOptions {
|
|
|
11
11
|
}
|
|
12
12
|
interface Resource {
|
|
13
13
|
id: string;
|
|
14
|
-
url: string;
|
|
15
14
|
name: string;
|
|
16
|
-
description
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
15
|
+
description?: string;
|
|
16
|
+
resource_url: string;
|
|
17
|
+
network?: string;
|
|
18
|
+
category?: string;
|
|
19
|
+
price?: string;
|
|
20
|
+
icon_url?: string | null;
|
|
21
|
+
owner_id?: string;
|
|
22
|
+
created_at?: string;
|
|
23
|
+
updated_at?: string;
|
|
24
|
+
success_rate?: number | null;
|
|
25
|
+
calls?: number;
|
|
26
|
+
value_processed?: string;
|
|
27
|
+
last_called?: string | null;
|
|
28
|
+
}
|
|
29
|
+
interface ResourceListOptions {
|
|
30
|
+
limit?: number;
|
|
31
|
+
sort?: 'popular' | 'recent' | 'name';
|
|
27
32
|
}
|
|
28
33
|
interface ResourceSearchOptions {
|
|
29
34
|
query?: string;
|
|
@@ -51,43 +56,59 @@ interface ResourceUpdateInput {
|
|
|
51
56
|
interface WalletConfig {
|
|
52
57
|
[key: string]: unknown;
|
|
53
58
|
}
|
|
54
|
-
interface
|
|
59
|
+
interface ClientOptions {
|
|
55
60
|
apiKey?: string;
|
|
56
61
|
baseUrl?: string;
|
|
57
62
|
wallet?: WalletConfig;
|
|
58
63
|
}
|
|
59
64
|
type ErrorCode = 'NOT_FOUND' | 'PAYMENT_REQUIRED' | 'RATE_LIMITED' | 'UNAUTHORIZED' | 'FORBIDDEN' | 'VALIDATION_ERROR' | 'SERVER_ERROR';
|
|
60
65
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
66
|
+
type HttpMethod = 'GET' | 'POST' | 'PATCH' | 'DELETE';
|
|
67
|
+
interface RequestOptions {
|
|
68
|
+
method?: HttpMethod;
|
|
69
|
+
body?: unknown;
|
|
70
|
+
params?: Record<string, string | number | boolean | undefined>;
|
|
71
|
+
}
|
|
72
|
+
declare class HttpClient {
|
|
73
|
+
private baseUrl;
|
|
74
|
+
private apiKey;
|
|
75
|
+
constructor(options?: ClientOptions);
|
|
76
|
+
private buildUrl;
|
|
77
|
+
private getHeaders;
|
|
78
|
+
private parseResponse;
|
|
79
|
+
request<T>(path: string, options?: RequestOptions): Promise<T>;
|
|
80
|
+
get<T>(path: string, params?: RequestOptions['params']): Promise<T>;
|
|
81
|
+
post<T>(path: string, body?: unknown): Promise<T>;
|
|
82
|
+
patch<T>(path: string, body?: unknown): Promise<T>;
|
|
83
|
+
delete<T>(path: string): Promise<T>;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
interface CheckAPI {
|
|
87
|
+
(url: string): Promise<Score>;
|
|
88
|
+
many(urls: string[]): Promise<Score[]>;
|
|
89
|
+
exists(url: string): Promise<boolean>;
|
|
90
|
+
top(options?: TopOptions): Promise<Score[]>;
|
|
91
|
+
}
|
|
71
92
|
|
|
72
93
|
type GetInput = string | {
|
|
73
94
|
id: string;
|
|
74
95
|
};
|
|
75
|
-
declare
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
register: typeof register;
|
|
86
|
-
update: typeof update;
|
|
87
|
-
delete: typeof remove;
|
|
88
|
-
};
|
|
96
|
+
declare class ResourcesAPI {
|
|
97
|
+
private http;
|
|
98
|
+
constructor(http: HttpClient);
|
|
99
|
+
list(options?: ResourceListOptions): Promise<Resource[]>;
|
|
100
|
+
get(input: GetInput): Promise<Resource>;
|
|
101
|
+
search(options?: ResourceSearchOptions): Promise<Resource[]>;
|
|
102
|
+
register(input: ResourceCreateInput): Promise<Resource>;
|
|
103
|
+
update(id: string, input: ResourceUpdateInput): Promise<Resource>;
|
|
104
|
+
delete(id: string): Promise<void>;
|
|
105
|
+
}
|
|
89
106
|
|
|
90
|
-
declare
|
|
107
|
+
declare class X402Jobs {
|
|
108
|
+
readonly check: CheckAPI;
|
|
109
|
+
readonly resources: ResourcesAPI;
|
|
110
|
+
constructor(options?: ClientOptions);
|
|
111
|
+
}
|
|
91
112
|
|
|
92
113
|
declare class X402Error extends Error {
|
|
93
114
|
readonly code: ErrorCode;
|
|
@@ -103,4 +124,4 @@ declare class X402Error extends Error {
|
|
|
103
124
|
static fromStatus(status: number, message?: string): X402Error;
|
|
104
125
|
}
|
|
105
126
|
|
|
106
|
-
export { type
|
|
127
|
+
export { type ClientOptions, type ErrorCode, type Resource, type ResourceCreateInput, type ResourceListOptions, type ResourceSearchOptions, type ResourceUpdateInput, type Score, type TopOptions, type WalletConfig, X402Error, X402Jobs };
|
package/dist/index.js
CHANGED
|
@@ -21,34 +21,10 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
21
21
|
var index_exports = {};
|
|
22
22
|
__export(index_exports, {
|
|
23
23
|
X402Error: () => X402Error,
|
|
24
|
-
|
|
25
|
-
configure: () => configure,
|
|
26
|
-
resources: () => resources
|
|
24
|
+
X402Jobs: () => X402Jobs
|
|
27
25
|
});
|
|
28
26
|
module.exports = __toCommonJS(index_exports);
|
|
29
27
|
|
|
30
|
-
// src/config.ts
|
|
31
|
-
var DEFAULT_BASE_URL = "https://x402.jobs/api/v1";
|
|
32
|
-
var config = {
|
|
33
|
-
apiKey: null,
|
|
34
|
-
baseUrl: DEFAULT_BASE_URL,
|
|
35
|
-
wallet: null
|
|
36
|
-
};
|
|
37
|
-
function configure(options) {
|
|
38
|
-
if (options.apiKey !== void 0) {
|
|
39
|
-
config.apiKey = options.apiKey;
|
|
40
|
-
}
|
|
41
|
-
if (options.baseUrl !== void 0) {
|
|
42
|
-
config.baseUrl = options.baseUrl.replace(/\/$/, "");
|
|
43
|
-
}
|
|
44
|
-
if (options.wallet !== void 0) {
|
|
45
|
-
config.wallet = options.wallet;
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
function getConfig() {
|
|
49
|
-
return config;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
28
|
// src/errors.ts
|
|
53
29
|
var X402Error = class _X402Error extends Error {
|
|
54
30
|
constructor(code, message, status) {
|
|
@@ -102,137 +78,146 @@ var X402Error = class _X402Error extends Error {
|
|
|
102
78
|
};
|
|
103
79
|
|
|
104
80
|
// src/http.ts
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
81
|
+
var DEFAULT_BASE_URL = "https://api.x402.jobs/api/v1";
|
|
82
|
+
var HttpClient = class {
|
|
83
|
+
constructor(options = {}) {
|
|
84
|
+
this.baseUrl = (options.baseUrl ?? DEFAULT_BASE_URL).replace(/\/$/, "");
|
|
85
|
+
this.apiKey = options.apiKey;
|
|
86
|
+
}
|
|
87
|
+
buildUrl(path, params) {
|
|
88
|
+
const url = new URL(path, this.baseUrl);
|
|
89
|
+
if (params) {
|
|
90
|
+
for (const [key, value] of Object.entries(params)) {
|
|
91
|
+
if (value !== void 0) {
|
|
92
|
+
url.searchParams.set(key, String(value));
|
|
93
|
+
}
|
|
112
94
|
}
|
|
113
95
|
}
|
|
96
|
+
return url.toString();
|
|
97
|
+
}
|
|
98
|
+
getHeaders() {
|
|
99
|
+
const headers = {
|
|
100
|
+
"Content-Type": "application/json",
|
|
101
|
+
Accept: "application/json"
|
|
102
|
+
};
|
|
103
|
+
if (this.apiKey) {
|
|
104
|
+
headers["Authorization"] = `Bearer ${this.apiKey}`;
|
|
105
|
+
}
|
|
106
|
+
return headers;
|
|
114
107
|
}
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
headers["Authorization"] = `Bearer ${apiKey}`;
|
|
125
|
-
}
|
|
126
|
-
return headers;
|
|
127
|
-
}
|
|
128
|
-
async function parseResponse(response) {
|
|
129
|
-
const contentType = response.headers.get("content-type");
|
|
130
|
-
if (!contentType?.includes("application/json")) {
|
|
108
|
+
async parseResponse(response) {
|
|
109
|
+
const contentType = response.headers.get("content-type");
|
|
110
|
+
if (!contentType?.includes("application/json")) {
|
|
111
|
+
if (!response.ok) {
|
|
112
|
+
throw X402Error.fromStatus(response.status, response.statusText);
|
|
113
|
+
}
|
|
114
|
+
return void 0;
|
|
115
|
+
}
|
|
116
|
+
const data = await response.json();
|
|
131
117
|
if (!response.ok) {
|
|
132
|
-
|
|
118
|
+
const errorData = data;
|
|
119
|
+
const message = errorData?.error?.message ?? response.statusText;
|
|
120
|
+
throw X402Error.fromStatus(response.status, message);
|
|
133
121
|
}
|
|
134
|
-
return
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
const
|
|
139
|
-
const
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
method,
|
|
150
|
-
headers
|
|
151
|
-
};
|
|
152
|
-
if (body !== void 0) {
|
|
153
|
-
fetchOptions.body = JSON.stringify(body);
|
|
122
|
+
return data;
|
|
123
|
+
}
|
|
124
|
+
async request(path, options = {}) {
|
|
125
|
+
const { method = "GET", body, params } = options;
|
|
126
|
+
const url = this.buildUrl(path, params);
|
|
127
|
+
const headers = this.getHeaders();
|
|
128
|
+
const fetchOptions = {
|
|
129
|
+
method,
|
|
130
|
+
headers
|
|
131
|
+
};
|
|
132
|
+
if (body !== void 0) {
|
|
133
|
+
fetchOptions.body = JSON.stringify(body);
|
|
134
|
+
}
|
|
135
|
+
const response = await fetch(url, fetchOptions);
|
|
136
|
+
return this.parseResponse(response);
|
|
154
137
|
}
|
|
155
|
-
const response = await fetch(url, fetchOptions);
|
|
156
|
-
return parseResponse(response);
|
|
157
|
-
}
|
|
158
|
-
var http = {
|
|
159
138
|
get(path, params) {
|
|
160
|
-
return request(path, { method: "GET", params });
|
|
161
|
-
}
|
|
139
|
+
return this.request(path, { method: "GET", params });
|
|
140
|
+
}
|
|
162
141
|
post(path, body) {
|
|
163
|
-
return request(path, { method: "POST", body });
|
|
164
|
-
}
|
|
142
|
+
return this.request(path, { method: "POST", body });
|
|
143
|
+
}
|
|
165
144
|
patch(path, body) {
|
|
166
|
-
return request(path, { method: "PATCH", body });
|
|
167
|
-
}
|
|
145
|
+
return this.request(path, { method: "PATCH", body });
|
|
146
|
+
}
|
|
168
147
|
delete(path) {
|
|
169
|
-
return request(path, { method: "DELETE" });
|
|
148
|
+
return this.request(path, { method: "DELETE" });
|
|
170
149
|
}
|
|
171
150
|
};
|
|
172
151
|
|
|
173
152
|
// src/check.ts
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
153
|
+
function createCheckAPI(http) {
|
|
154
|
+
const check = async (url) => {
|
|
155
|
+
return http.get("/resources/score", { url });
|
|
156
|
+
};
|
|
157
|
+
check.many = async (urls) => {
|
|
158
|
+
return Promise.all(urls.map((url) => check(url)));
|
|
159
|
+
};
|
|
160
|
+
check.exists = async (url) => {
|
|
161
|
+
const result = await http.get("/resources/exists", { url });
|
|
162
|
+
return result.exists;
|
|
163
|
+
};
|
|
164
|
+
check.top = async (options = {}) => {
|
|
165
|
+
const { limit = 20, category } = options;
|
|
166
|
+
return http.get("/resources/top", { limit, category });
|
|
167
|
+
};
|
|
168
|
+
return check;
|
|
187
169
|
}
|
|
188
|
-
var check = Object.assign(checkUrl, {
|
|
189
|
-
many: checkMany,
|
|
190
|
-
exists: checkExists,
|
|
191
|
-
top: checkTop
|
|
192
|
-
});
|
|
193
170
|
|
|
194
171
|
// src/resources.ts
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
172
|
+
var ResourcesAPI = class {
|
|
173
|
+
constructor(http) {
|
|
174
|
+
this.http = http;
|
|
175
|
+
}
|
|
176
|
+
async list(options = {}) {
|
|
177
|
+
const params = {};
|
|
178
|
+
if (options.limit !== void 0) params["limit"] = options.limit;
|
|
179
|
+
if (options.sort) params["sort"] = options.sort;
|
|
180
|
+
const response = await this.http.get("/resources", params);
|
|
181
|
+
return response.resources;
|
|
182
|
+
}
|
|
183
|
+
async get(input) {
|
|
184
|
+
if (typeof input === "string") {
|
|
185
|
+
return this.http.get("/resources", { url: input });
|
|
186
|
+
}
|
|
187
|
+
return this.http.get(`/resources/${input.id}`);
|
|
188
|
+
}
|
|
189
|
+
async search(options = {}) {
|
|
190
|
+
const params = {};
|
|
191
|
+
if (options.query) params["q"] = options.query;
|
|
192
|
+
if (options.category) params["category"] = options.category;
|
|
193
|
+
if (options.minSuccessRate !== void 0) params["min_success_rate"] = options.minSuccessRate;
|
|
194
|
+
if (options.minCalls !== void 0) params["min_calls"] = options.minCalls;
|
|
195
|
+
if (options.limit !== void 0) params["limit"] = options.limit;
|
|
196
|
+
if (options.offset !== void 0) params["offset"] = options.offset;
|
|
197
|
+
return this.http.get("/resources/search", params);
|
|
198
|
+
}
|
|
199
|
+
async register(input) {
|
|
200
|
+
return this.http.post("/resources", input);
|
|
201
|
+
}
|
|
202
|
+
async update(id, input) {
|
|
203
|
+
return this.http.patch(`/resources/${id}`, input);
|
|
204
|
+
}
|
|
205
|
+
async delete(id) {
|
|
206
|
+
await this.http.delete(`/resources/${id}`);
|
|
207
|
+
}
|
|
208
|
+
};
|
|
209
|
+
|
|
210
|
+
// src/client.ts
|
|
211
|
+
var X402Jobs = class {
|
|
212
|
+
constructor(options = {}) {
|
|
213
|
+
const http = new HttpClient(options);
|
|
214
|
+
this.check = createCheckAPI(http);
|
|
215
|
+
this.resources = new ResourcesAPI(http);
|
|
201
216
|
}
|
|
202
|
-
return http.get(`/resources/${input.id}`);
|
|
203
|
-
}
|
|
204
|
-
async function search(options = {}) {
|
|
205
|
-
const params = {};
|
|
206
|
-
if (options.query) params["q"] = options.query;
|
|
207
|
-
if (options.category) params["category"] = options.category;
|
|
208
|
-
if (options.minSuccessRate !== void 0) params["min_success_rate"] = options.minSuccessRate;
|
|
209
|
-
if (options.minCalls !== void 0) params["min_calls"] = options.minCalls;
|
|
210
|
-
if (options.limit !== void 0) params["limit"] = options.limit;
|
|
211
|
-
if (options.offset !== void 0) params["offset"] = options.offset;
|
|
212
|
-
return http.get("/resources/search", params);
|
|
213
|
-
}
|
|
214
|
-
async function register(input) {
|
|
215
|
-
return http.post("/resources", input);
|
|
216
|
-
}
|
|
217
|
-
async function update(id, input) {
|
|
218
|
-
return http.patch(`/resources/${id}`, input);
|
|
219
|
-
}
|
|
220
|
-
async function remove(id) {
|
|
221
|
-
await http.delete(`/resources/${id}`);
|
|
222
|
-
}
|
|
223
|
-
var resources = {
|
|
224
|
-
list,
|
|
225
|
-
get,
|
|
226
|
-
search,
|
|
227
|
-
register,
|
|
228
|
-
update,
|
|
229
|
-
delete: remove
|
|
230
217
|
};
|
|
231
218
|
// Annotate the CommonJS export names for ESM import in node:
|
|
232
219
|
0 && (module.exports = {
|
|
233
220
|
X402Error,
|
|
234
|
-
|
|
235
|
-
configure,
|
|
236
|
-
resources
|
|
221
|
+
X402Jobs
|
|
237
222
|
});
|
|
238
223
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/config.ts","../src/errors.ts","../src/http.ts","../src/check.ts","../src/resources.ts"],"sourcesContent":["// Main exports\nexport { check } from './check'\nexport { resources } from './resources'\nexport { configure } from './config'\nexport { X402Error } from './errors'\n\n// Type exports\nexport type {\n Score,\n TopOptions,\n Resource,\n ResourceSearchOptions,\n ResourceCreateInput,\n ResourceUpdateInput,\n ConfigOptions,\n WalletConfig,\n ErrorCode,\n} from './types'\n","import type { ConfigOptions, WalletConfig } from './types'\n\nconst DEFAULT_BASE_URL = 'https://x402.jobs/api/v1'\n\ninterface InternalConfig {\n apiKey: string | null\n baseUrl: string\n wallet: WalletConfig | null\n}\n\nconst config: InternalConfig = {\n apiKey: null,\n baseUrl: DEFAULT_BASE_URL,\n wallet: null,\n}\n\nexport function configure(options: ConfigOptions): void {\n if (options.apiKey !== undefined) {\n config.apiKey = options.apiKey\n }\n if (options.baseUrl !== undefined) {\n config.baseUrl = options.baseUrl.replace(/\\/$/, '') // Remove trailing slash\n }\n if (options.wallet !== undefined) {\n config.wallet = options.wallet\n }\n}\n\nexport function getConfig(): Readonly<InternalConfig> {\n return config\n}\n\nexport function resetConfig(): void {\n config.apiKey = null\n config.baseUrl = DEFAULT_BASE_URL\n config.wallet = null\n}\n","import type { ErrorCode } from './types'\n\nexport class X402Error extends Error {\n readonly code: ErrorCode\n readonly status: number\n\n constructor(code: ErrorCode, message: string, status: number) {\n super(message)\n this.name = 'X402Error'\n this.code = code\n this.status = status\n\n // Maintains proper stack trace for where error was thrown (V8 engines)\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, X402Error)\n }\n }\n\n static notFound(message = 'Resource not found'): X402Error {\n return new X402Error('NOT_FOUND', message, 404)\n }\n\n static paymentRequired(message = 'Payment required'): X402Error {\n return new X402Error('PAYMENT_REQUIRED', message, 402)\n }\n\n static rateLimited(message = 'Too many requests'): X402Error {\n return new X402Error('RATE_LIMITED', message, 429)\n }\n\n static unauthorized(message = 'Invalid or missing API key'): X402Error {\n return new X402Error('UNAUTHORIZED', message, 401)\n }\n\n static forbidden(message = 'Access denied'): X402Error {\n return new X402Error('FORBIDDEN', message, 403)\n }\n\n static validationError(message: string): X402Error {\n return new X402Error('VALIDATION_ERROR', message, 400)\n }\n\n static serverError(message = 'Internal server error'): X402Error {\n return new X402Error('SERVER_ERROR', message, 500)\n }\n\n static fromStatus(status: number, message?: string): X402Error {\n switch (status) {\n case 400:\n return X402Error.validationError(message ?? 'Invalid request')\n case 401:\n return X402Error.unauthorized(message)\n case 402:\n return X402Error.paymentRequired(message)\n case 403:\n return X402Error.forbidden(message)\n case 404:\n return X402Error.notFound(message)\n case 429:\n return X402Error.rateLimited(message)\n default:\n return X402Error.serverError(message)\n }\n }\n}\n","import { getConfig } from './config'\nimport { X402Error } from './errors'\n\ntype HttpMethod = 'GET' | 'POST' | 'PATCH' | 'DELETE'\n\ninterface RequestOptions {\n method?: HttpMethod\n body?: unknown\n params?: Record<string, string | number | boolean | undefined>\n}\n\nfunction buildUrl(path: string, params?: RequestOptions['params']): string {\n const { baseUrl } = getConfig()\n const url = new URL(path, baseUrl)\n\n if (params) {\n for (const [key, value] of Object.entries(params)) {\n if (value !== undefined) {\n url.searchParams.set(key, String(value))\n }\n }\n }\n\n return url.toString()\n}\n\nfunction getHeaders(): Record<string, string> {\n const { apiKey } = getConfig()\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n Accept: 'application/json',\n }\n\n if (apiKey) {\n headers['Authorization'] = `Bearer ${apiKey}`\n }\n\n return headers\n}\n\nasync function parseResponse<T>(response: Response): Promise<T> {\n const contentType = response.headers.get('content-type')\n\n if (!contentType?.includes('application/json')) {\n if (!response.ok) {\n throw X402Error.fromStatus(response.status, response.statusText)\n }\n return undefined as T\n }\n\n const data = (await response.json()) as { error?: { code?: string; message?: string } } | T\n\n if (!response.ok) {\n const errorData = data as { error?: { code?: string; message?: string } }\n const message = errorData?.error?.message ?? response.statusText\n throw X402Error.fromStatus(response.status, message)\n }\n\n return data as T\n}\n\nexport async function request<T>(\n path: string,\n options: RequestOptions = {}\n): Promise<T> {\n const { method = 'GET', body, params } = options\n const url = buildUrl(path, params)\n const headers = getHeaders()\n\n const fetchOptions: RequestInit = {\n method,\n headers,\n }\n\n if (body !== undefined) {\n fetchOptions.body = JSON.stringify(body)\n }\n\n const response = await fetch(url, fetchOptions)\n return parseResponse<T>(response)\n}\n\nexport const http = {\n get<T>(path: string, params?: RequestOptions['params']): Promise<T> {\n return request<T>(path, { method: 'GET', params })\n },\n\n post<T>(path: string, body?: unknown): Promise<T> {\n return request<T>(path, { method: 'POST', body })\n },\n\n patch<T>(path: string, body?: unknown): Promise<T> {\n return request<T>(path, { method: 'PATCH', body })\n },\n\n delete<T>(path: string): Promise<T> {\n return request<T>(path, { method: 'DELETE' })\n },\n}\n","import { http } from './http'\nimport type { Score, TopOptions } from './types'\n\nasync function checkUrl(url: string): Promise<Score> {\n return http.get<Score>('/resources/score', { url })\n}\n\nasync function checkMany(urls: string[]): Promise<Score[]> {\n // Phase 2: Use batch endpoint when available\n // For now, run checks in parallel\n return Promise.all(urls.map((url) => checkUrl(url)))\n}\n\nasync function checkExists(url: string): Promise<boolean> {\n const result = await http.get<{ exists: boolean }>('/resources/exists', { url })\n return result.exists\n}\n\nasync function checkTop(options: TopOptions = {}): Promise<Score[]> {\n const { limit = 20, category } = options\n return http.get<Score[]>('/resources/top', { limit, category })\n}\n\n// Create the check function with additional methods attached\ntype CheckFunction = typeof checkUrl & {\n many: typeof checkMany\n exists: typeof checkExists\n top: typeof checkTop\n}\n\nexport const check: CheckFunction = Object.assign(checkUrl, {\n many: checkMany,\n exists: checkExists,\n top: checkTop,\n})\n","import { http } from './http'\nimport type {\n Resource,\n ResourceSearchOptions,\n ResourceCreateInput,\n ResourceUpdateInput,\n} from './types'\n\ntype GetInput = string | { id: string }\n\nasync function list(): Promise<Resource[]> {\n return http.get<Resource[]>('/resources')\n}\n\nasync function get(input: GetInput): Promise<Resource> {\n if (typeof input === 'string') {\n // Treat string as URL\n return http.get<Resource>('/resources', { url: input })\n }\n // Get by ID\n return http.get<Resource>(`/resources/${input.id}`)\n}\n\nasync function search(options: ResourceSearchOptions = {}): Promise<Resource[]> {\n const params: Record<string, string | number | undefined> = {}\n\n if (options.query) params['q'] = options.query\n if (options.category) params['category'] = options.category\n if (options.minSuccessRate !== undefined) params['min_success_rate'] = options.minSuccessRate\n if (options.minCalls !== undefined) params['min_calls'] = options.minCalls\n if (options.limit !== undefined) params['limit'] = options.limit\n if (options.offset !== undefined) params['offset'] = options.offset\n\n return http.get<Resource[]>('/resources/search', params)\n}\n\nasync function register(input: ResourceCreateInput): Promise<Resource> {\n return http.post<Resource>('/resources', input)\n}\n\nasync function update(id: string, input: ResourceUpdateInput): Promise<Resource> {\n return http.patch<Resource>(`/resources/${id}`, input)\n}\n\nasync function remove(id: string): Promise<void> {\n await http.delete(`/resources/${id}`)\n}\n\nexport const resources = {\n list,\n get,\n search,\n register,\n update,\n delete: remove,\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/errors.ts","../src/http.ts","../src/check.ts","../src/resources.ts","../src/client.ts"],"sourcesContent":["// Main export\nexport { X402Jobs } from './client'\n\n// Error class\nexport { X402Error } from './errors'\n\n// Type exports\nexport type {\n Score,\n TopOptions,\n Resource,\n ResourceListOptions,\n ResourceSearchOptions,\n ResourceCreateInput,\n ResourceUpdateInput,\n ClientOptions,\n WalletConfig,\n ErrorCode,\n} from './types'\n","import type { ErrorCode } from './types'\n\nexport class X402Error extends Error {\n readonly code: ErrorCode\n readonly status: number\n\n constructor(code: ErrorCode, message: string, status: number) {\n super(message)\n this.name = 'X402Error'\n this.code = code\n this.status = status\n\n // Maintains proper stack trace for where error was thrown (V8 engines)\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, X402Error)\n }\n }\n\n static notFound(message = 'Resource not found'): X402Error {\n return new X402Error('NOT_FOUND', message, 404)\n }\n\n static paymentRequired(message = 'Payment required'): X402Error {\n return new X402Error('PAYMENT_REQUIRED', message, 402)\n }\n\n static rateLimited(message = 'Too many requests'): X402Error {\n return new X402Error('RATE_LIMITED', message, 429)\n }\n\n static unauthorized(message = 'Invalid or missing API key'): X402Error {\n return new X402Error('UNAUTHORIZED', message, 401)\n }\n\n static forbidden(message = 'Access denied'): X402Error {\n return new X402Error('FORBIDDEN', message, 403)\n }\n\n static validationError(message: string): X402Error {\n return new X402Error('VALIDATION_ERROR', message, 400)\n }\n\n static serverError(message = 'Internal server error'): X402Error {\n return new X402Error('SERVER_ERROR', message, 500)\n }\n\n static fromStatus(status: number, message?: string): X402Error {\n switch (status) {\n case 400:\n return X402Error.validationError(message ?? 'Invalid request')\n case 401:\n return X402Error.unauthorized(message)\n case 402:\n return X402Error.paymentRequired(message)\n case 403:\n return X402Error.forbidden(message)\n case 404:\n return X402Error.notFound(message)\n case 429:\n return X402Error.rateLimited(message)\n default:\n return X402Error.serverError(message)\n }\n }\n}\n","import { X402Error } from './errors'\nimport type { ClientOptions } from './types'\n\ntype HttpMethod = 'GET' | 'POST' | 'PATCH' | 'DELETE'\n\ninterface RequestOptions {\n method?: HttpMethod\n body?: unknown\n params?: Record<string, string | number | boolean | undefined>\n}\n\nconst DEFAULT_BASE_URL = 'https://api.x402.jobs/api/v1'\n\nexport class HttpClient {\n private baseUrl: string\n private apiKey: string | undefined\n\n constructor(options: ClientOptions = {}) {\n this.baseUrl = (options.baseUrl ?? DEFAULT_BASE_URL).replace(/\\/$/, '')\n this.apiKey = options.apiKey\n }\n\n private buildUrl(path: string, params?: RequestOptions['params']): string {\n const url = new URL(path, this.baseUrl)\n\n if (params) {\n for (const [key, value] of Object.entries(params)) {\n if (value !== undefined) {\n url.searchParams.set(key, String(value))\n }\n }\n }\n\n return url.toString()\n }\n\n private getHeaders(): Record<string, string> {\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n Accept: 'application/json',\n }\n\n if (this.apiKey) {\n headers['Authorization'] = `Bearer ${this.apiKey}`\n }\n\n return headers\n }\n\n private async parseResponse<T>(response: Response): Promise<T> {\n const contentType = response.headers.get('content-type')\n\n if (!contentType?.includes('application/json')) {\n if (!response.ok) {\n throw X402Error.fromStatus(response.status, response.statusText)\n }\n return undefined as T\n }\n\n const data = (await response.json()) as { error?: { code?: string; message?: string } } | T\n\n if (!response.ok) {\n const errorData = data as { error?: { code?: string; message?: string } }\n const message = errorData?.error?.message ?? response.statusText\n throw X402Error.fromStatus(response.status, message)\n }\n\n return data as T\n }\n\n async request<T>(path: string, options: RequestOptions = {}): Promise<T> {\n const { method = 'GET', body, params } = options\n const url = this.buildUrl(path, params)\n const headers = this.getHeaders()\n\n const fetchOptions: RequestInit = {\n method,\n headers,\n }\n\n if (body !== undefined) {\n fetchOptions.body = JSON.stringify(body)\n }\n\n const response = await fetch(url, fetchOptions)\n return this.parseResponse<T>(response)\n }\n\n get<T>(path: string, params?: RequestOptions['params']): Promise<T> {\n return this.request<T>(path, { method: 'GET', params })\n }\n\n post<T>(path: string, body?: unknown): Promise<T> {\n return this.request<T>(path, { method: 'POST', body })\n }\n\n patch<T>(path: string, body?: unknown): Promise<T> {\n return this.request<T>(path, { method: 'PATCH', body })\n }\n\n delete<T>(path: string): Promise<T> {\n return this.request<T>(path, { method: 'DELETE' })\n }\n}\n","import type { HttpClient } from './http'\nimport type { Score, TopOptions } from './types'\n\nexport interface CheckAPI {\n (url: string): Promise<Score>\n many(urls: string[]): Promise<Score[]>\n exists(url: string): Promise<boolean>\n top(options?: TopOptions): Promise<Score[]>\n}\n\nexport function createCheckAPI(http: HttpClient): CheckAPI {\n const check = async (url: string): Promise<Score> => {\n return http.get<Score>('/resources/score', { url })\n }\n\n check.many = async (urls: string[]): Promise<Score[]> => {\n return Promise.all(urls.map((url) => check(url)))\n }\n\n check.exists = async (url: string): Promise<boolean> => {\n const result = await http.get<{ exists: boolean }>('/resources/exists', { url })\n return result.exists\n }\n\n check.top = async (options: TopOptions = {}): Promise<Score[]> => {\n const { limit = 20, category } = options\n return http.get<Score[]>('/resources/top', { limit, category })\n }\n\n return check\n}\n","import type { HttpClient } from './http'\nimport type {\n Resource,\n ResourceListOptions,\n ResourceSearchOptions,\n ResourceCreateInput,\n ResourceUpdateInput,\n} from './types'\n\ntype GetInput = string | { id: string }\n\nexport class ResourcesAPI {\n constructor(private http: HttpClient) {}\n\n async list(options: ResourceListOptions = {}): Promise<Resource[]> {\n const params: Record<string, string | number | undefined> = {}\n if (options.limit !== undefined) params['limit'] = options.limit\n if (options.sort) params['sort'] = options.sort\n const response = await this.http.get<{ resources: Resource[] }>('/resources', params)\n return response.resources\n }\n\n async get(input: GetInput): Promise<Resource> {\n if (typeof input === 'string') {\n return this.http.get<Resource>('/resources', { url: input })\n }\n return this.http.get<Resource>(`/resources/${input.id}`)\n }\n\n async search(options: ResourceSearchOptions = {}): Promise<Resource[]> {\n const params: Record<string, string | number | undefined> = {}\n\n if (options.query) params['q'] = options.query\n if (options.category) params['category'] = options.category\n if (options.minSuccessRate !== undefined) params['min_success_rate'] = options.minSuccessRate\n if (options.minCalls !== undefined) params['min_calls'] = options.minCalls\n if (options.limit !== undefined) params['limit'] = options.limit\n if (options.offset !== undefined) params['offset'] = options.offset\n\n return this.http.get<Resource[]>('/resources/search', params)\n }\n\n async register(input: ResourceCreateInput): Promise<Resource> {\n return this.http.post<Resource>('/resources', input)\n }\n\n async update(id: string, input: ResourceUpdateInput): Promise<Resource> {\n return this.http.patch<Resource>(`/resources/${id}`, input)\n }\n\n async delete(id: string): Promise<void> {\n await this.http.delete(`/resources/${id}`)\n }\n}\n","import { HttpClient } from './http'\nimport { createCheckAPI, type CheckAPI } from './check'\nimport { ResourcesAPI } from './resources'\nimport type { ClientOptions } from './types'\n\nexport class X402Jobs {\n readonly check: CheckAPI\n readonly resources: ResourcesAPI\n\n constructor(options: ClientOptions = {}) {\n const http = new HttpClient(options)\n this.check = createCheckAPI(http)\n this.resources = new ResourcesAPI(http)\n }\n}\n"],"mappings":"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","names":[]}
|
package/dist/index.mjs
CHANGED
|
@@ -1,25 +1,3 @@
|
|
|
1
|
-
// src/config.ts
|
|
2
|
-
var DEFAULT_BASE_URL = "https://x402.jobs/api/v1";
|
|
3
|
-
var config = {
|
|
4
|
-
apiKey: null,
|
|
5
|
-
baseUrl: DEFAULT_BASE_URL,
|
|
6
|
-
wallet: null
|
|
7
|
-
};
|
|
8
|
-
function configure(options) {
|
|
9
|
-
if (options.apiKey !== void 0) {
|
|
10
|
-
config.apiKey = options.apiKey;
|
|
11
|
-
}
|
|
12
|
-
if (options.baseUrl !== void 0) {
|
|
13
|
-
config.baseUrl = options.baseUrl.replace(/\/$/, "");
|
|
14
|
-
}
|
|
15
|
-
if (options.wallet !== void 0) {
|
|
16
|
-
config.wallet = options.wallet;
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
function getConfig() {
|
|
20
|
-
return config;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
1
|
// src/errors.ts
|
|
24
2
|
var X402Error = class _X402Error extends Error {
|
|
25
3
|
constructor(code, message, status) {
|
|
@@ -73,136 +51,145 @@ var X402Error = class _X402Error extends Error {
|
|
|
73
51
|
};
|
|
74
52
|
|
|
75
53
|
// src/http.ts
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
54
|
+
var DEFAULT_BASE_URL = "https://api.x402.jobs/api/v1";
|
|
55
|
+
var HttpClient = class {
|
|
56
|
+
constructor(options = {}) {
|
|
57
|
+
this.baseUrl = (options.baseUrl ?? DEFAULT_BASE_URL).replace(/\/$/, "");
|
|
58
|
+
this.apiKey = options.apiKey;
|
|
59
|
+
}
|
|
60
|
+
buildUrl(path, params) {
|
|
61
|
+
const url = new URL(path, this.baseUrl);
|
|
62
|
+
if (params) {
|
|
63
|
+
for (const [key, value] of Object.entries(params)) {
|
|
64
|
+
if (value !== void 0) {
|
|
65
|
+
url.searchParams.set(key, String(value));
|
|
66
|
+
}
|
|
83
67
|
}
|
|
84
68
|
}
|
|
69
|
+
return url.toString();
|
|
70
|
+
}
|
|
71
|
+
getHeaders() {
|
|
72
|
+
const headers = {
|
|
73
|
+
"Content-Type": "application/json",
|
|
74
|
+
Accept: "application/json"
|
|
75
|
+
};
|
|
76
|
+
if (this.apiKey) {
|
|
77
|
+
headers["Authorization"] = `Bearer ${this.apiKey}`;
|
|
78
|
+
}
|
|
79
|
+
return headers;
|
|
85
80
|
}
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
headers["Authorization"] = `Bearer ${apiKey}`;
|
|
96
|
-
}
|
|
97
|
-
return headers;
|
|
98
|
-
}
|
|
99
|
-
async function parseResponse(response) {
|
|
100
|
-
const contentType = response.headers.get("content-type");
|
|
101
|
-
if (!contentType?.includes("application/json")) {
|
|
81
|
+
async parseResponse(response) {
|
|
82
|
+
const contentType = response.headers.get("content-type");
|
|
83
|
+
if (!contentType?.includes("application/json")) {
|
|
84
|
+
if (!response.ok) {
|
|
85
|
+
throw X402Error.fromStatus(response.status, response.statusText);
|
|
86
|
+
}
|
|
87
|
+
return void 0;
|
|
88
|
+
}
|
|
89
|
+
const data = await response.json();
|
|
102
90
|
if (!response.ok) {
|
|
103
|
-
|
|
91
|
+
const errorData = data;
|
|
92
|
+
const message = errorData?.error?.message ?? response.statusText;
|
|
93
|
+
throw X402Error.fromStatus(response.status, message);
|
|
104
94
|
}
|
|
105
|
-
return
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
const
|
|
110
|
-
const
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
method,
|
|
121
|
-
headers
|
|
122
|
-
};
|
|
123
|
-
if (body !== void 0) {
|
|
124
|
-
fetchOptions.body = JSON.stringify(body);
|
|
95
|
+
return data;
|
|
96
|
+
}
|
|
97
|
+
async request(path, options = {}) {
|
|
98
|
+
const { method = "GET", body, params } = options;
|
|
99
|
+
const url = this.buildUrl(path, params);
|
|
100
|
+
const headers = this.getHeaders();
|
|
101
|
+
const fetchOptions = {
|
|
102
|
+
method,
|
|
103
|
+
headers
|
|
104
|
+
};
|
|
105
|
+
if (body !== void 0) {
|
|
106
|
+
fetchOptions.body = JSON.stringify(body);
|
|
107
|
+
}
|
|
108
|
+
const response = await fetch(url, fetchOptions);
|
|
109
|
+
return this.parseResponse(response);
|
|
125
110
|
}
|
|
126
|
-
const response = await fetch(url, fetchOptions);
|
|
127
|
-
return parseResponse(response);
|
|
128
|
-
}
|
|
129
|
-
var http = {
|
|
130
111
|
get(path, params) {
|
|
131
|
-
return request(path, { method: "GET", params });
|
|
132
|
-
}
|
|
112
|
+
return this.request(path, { method: "GET", params });
|
|
113
|
+
}
|
|
133
114
|
post(path, body) {
|
|
134
|
-
return request(path, { method: "POST", body });
|
|
135
|
-
}
|
|
115
|
+
return this.request(path, { method: "POST", body });
|
|
116
|
+
}
|
|
136
117
|
patch(path, body) {
|
|
137
|
-
return request(path, { method: "PATCH", body });
|
|
138
|
-
}
|
|
118
|
+
return this.request(path, { method: "PATCH", body });
|
|
119
|
+
}
|
|
139
120
|
delete(path) {
|
|
140
|
-
return request(path, { method: "DELETE" });
|
|
121
|
+
return this.request(path, { method: "DELETE" });
|
|
141
122
|
}
|
|
142
123
|
};
|
|
143
124
|
|
|
144
125
|
// src/check.ts
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
126
|
+
function createCheckAPI(http) {
|
|
127
|
+
const check = async (url) => {
|
|
128
|
+
return http.get("/resources/score", { url });
|
|
129
|
+
};
|
|
130
|
+
check.many = async (urls) => {
|
|
131
|
+
return Promise.all(urls.map((url) => check(url)));
|
|
132
|
+
};
|
|
133
|
+
check.exists = async (url) => {
|
|
134
|
+
const result = await http.get("/resources/exists", { url });
|
|
135
|
+
return result.exists;
|
|
136
|
+
};
|
|
137
|
+
check.top = async (options = {}) => {
|
|
138
|
+
const { limit = 20, category } = options;
|
|
139
|
+
return http.get("/resources/top", { limit, category });
|
|
140
|
+
};
|
|
141
|
+
return check;
|
|
158
142
|
}
|
|
159
|
-
var check = Object.assign(checkUrl, {
|
|
160
|
-
many: checkMany,
|
|
161
|
-
exists: checkExists,
|
|
162
|
-
top: checkTop
|
|
163
|
-
});
|
|
164
143
|
|
|
165
144
|
// src/resources.ts
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
145
|
+
var ResourcesAPI = class {
|
|
146
|
+
constructor(http) {
|
|
147
|
+
this.http = http;
|
|
148
|
+
}
|
|
149
|
+
async list(options = {}) {
|
|
150
|
+
const params = {};
|
|
151
|
+
if (options.limit !== void 0) params["limit"] = options.limit;
|
|
152
|
+
if (options.sort) params["sort"] = options.sort;
|
|
153
|
+
const response = await this.http.get("/resources", params);
|
|
154
|
+
return response.resources;
|
|
155
|
+
}
|
|
156
|
+
async get(input) {
|
|
157
|
+
if (typeof input === "string") {
|
|
158
|
+
return this.http.get("/resources", { url: input });
|
|
159
|
+
}
|
|
160
|
+
return this.http.get(`/resources/${input.id}`);
|
|
161
|
+
}
|
|
162
|
+
async search(options = {}) {
|
|
163
|
+
const params = {};
|
|
164
|
+
if (options.query) params["q"] = options.query;
|
|
165
|
+
if (options.category) params["category"] = options.category;
|
|
166
|
+
if (options.minSuccessRate !== void 0) params["min_success_rate"] = options.minSuccessRate;
|
|
167
|
+
if (options.minCalls !== void 0) params["min_calls"] = options.minCalls;
|
|
168
|
+
if (options.limit !== void 0) params["limit"] = options.limit;
|
|
169
|
+
if (options.offset !== void 0) params["offset"] = options.offset;
|
|
170
|
+
return this.http.get("/resources/search", params);
|
|
171
|
+
}
|
|
172
|
+
async register(input) {
|
|
173
|
+
return this.http.post("/resources", input);
|
|
174
|
+
}
|
|
175
|
+
async update(id, input) {
|
|
176
|
+
return this.http.patch(`/resources/${id}`, input);
|
|
177
|
+
}
|
|
178
|
+
async delete(id) {
|
|
179
|
+
await this.http.delete(`/resources/${id}`);
|
|
180
|
+
}
|
|
181
|
+
};
|
|
182
|
+
|
|
183
|
+
// src/client.ts
|
|
184
|
+
var X402Jobs = class {
|
|
185
|
+
constructor(options = {}) {
|
|
186
|
+
const http = new HttpClient(options);
|
|
187
|
+
this.check = createCheckAPI(http);
|
|
188
|
+
this.resources = new ResourcesAPI(http);
|
|
172
189
|
}
|
|
173
|
-
return http.get(`/resources/${input.id}`);
|
|
174
|
-
}
|
|
175
|
-
async function search(options = {}) {
|
|
176
|
-
const params = {};
|
|
177
|
-
if (options.query) params["q"] = options.query;
|
|
178
|
-
if (options.category) params["category"] = options.category;
|
|
179
|
-
if (options.minSuccessRate !== void 0) params["min_success_rate"] = options.minSuccessRate;
|
|
180
|
-
if (options.minCalls !== void 0) params["min_calls"] = options.minCalls;
|
|
181
|
-
if (options.limit !== void 0) params["limit"] = options.limit;
|
|
182
|
-
if (options.offset !== void 0) params["offset"] = options.offset;
|
|
183
|
-
return http.get("/resources/search", params);
|
|
184
|
-
}
|
|
185
|
-
async function register(input) {
|
|
186
|
-
return http.post("/resources", input);
|
|
187
|
-
}
|
|
188
|
-
async function update(id, input) {
|
|
189
|
-
return http.patch(`/resources/${id}`, input);
|
|
190
|
-
}
|
|
191
|
-
async function remove(id) {
|
|
192
|
-
await http.delete(`/resources/${id}`);
|
|
193
|
-
}
|
|
194
|
-
var resources = {
|
|
195
|
-
list,
|
|
196
|
-
get,
|
|
197
|
-
search,
|
|
198
|
-
register,
|
|
199
|
-
update,
|
|
200
|
-
delete: remove
|
|
201
190
|
};
|
|
202
191
|
export {
|
|
203
192
|
X402Error,
|
|
204
|
-
|
|
205
|
-
configure,
|
|
206
|
-
resources
|
|
193
|
+
X402Jobs
|
|
207
194
|
};
|
|
208
195
|
//# sourceMappingURL=index.mjs.map
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/config.ts","../src/errors.ts","../src/http.ts","../src/check.ts","../src/resources.ts"],"sourcesContent":["import type { ConfigOptions, WalletConfig } from './types'\n\nconst DEFAULT_BASE_URL = 'https://x402.jobs/api/v1'\n\ninterface InternalConfig {\n apiKey: string | null\n baseUrl: string\n wallet: WalletConfig | null\n}\n\nconst config: InternalConfig = {\n apiKey: null,\n baseUrl: DEFAULT_BASE_URL,\n wallet: null,\n}\n\nexport function configure(options: ConfigOptions): void {\n if (options.apiKey !== undefined) {\n config.apiKey = options.apiKey\n }\n if (options.baseUrl !== undefined) {\n config.baseUrl = options.baseUrl.replace(/\\/$/, '') // Remove trailing slash\n }\n if (options.wallet !== undefined) {\n config.wallet = options.wallet\n }\n}\n\nexport function getConfig(): Readonly<InternalConfig> {\n return config\n}\n\nexport function resetConfig(): void {\n config.apiKey = null\n config.baseUrl = DEFAULT_BASE_URL\n config.wallet = null\n}\n","import type { ErrorCode } from './types'\n\nexport class X402Error extends Error {\n readonly code: ErrorCode\n readonly status: number\n\n constructor(code: ErrorCode, message: string, status: number) {\n super(message)\n this.name = 'X402Error'\n this.code = code\n this.status = status\n\n // Maintains proper stack trace for where error was thrown (V8 engines)\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, X402Error)\n }\n }\n\n static notFound(message = 'Resource not found'): X402Error {\n return new X402Error('NOT_FOUND', message, 404)\n }\n\n static paymentRequired(message = 'Payment required'): X402Error {\n return new X402Error('PAYMENT_REQUIRED', message, 402)\n }\n\n static rateLimited(message = 'Too many requests'): X402Error {\n return new X402Error('RATE_LIMITED', message, 429)\n }\n\n static unauthorized(message = 'Invalid or missing API key'): X402Error {\n return new X402Error('UNAUTHORIZED', message, 401)\n }\n\n static forbidden(message = 'Access denied'): X402Error {\n return new X402Error('FORBIDDEN', message, 403)\n }\n\n static validationError(message: string): X402Error {\n return new X402Error('VALIDATION_ERROR', message, 400)\n }\n\n static serverError(message = 'Internal server error'): X402Error {\n return new X402Error('SERVER_ERROR', message, 500)\n }\n\n static fromStatus(status: number, message?: string): X402Error {\n switch (status) {\n case 400:\n return X402Error.validationError(message ?? 'Invalid request')\n case 401:\n return X402Error.unauthorized(message)\n case 402:\n return X402Error.paymentRequired(message)\n case 403:\n return X402Error.forbidden(message)\n case 404:\n return X402Error.notFound(message)\n case 429:\n return X402Error.rateLimited(message)\n default:\n return X402Error.serverError(message)\n }\n }\n}\n","import { getConfig } from './config'\nimport { X402Error } from './errors'\n\ntype HttpMethod = 'GET' | 'POST' | 'PATCH' | 'DELETE'\n\ninterface RequestOptions {\n method?: HttpMethod\n body?: unknown\n params?: Record<string, string | number | boolean | undefined>\n}\n\nfunction buildUrl(path: string, params?: RequestOptions['params']): string {\n const { baseUrl } = getConfig()\n const url = new URL(path, baseUrl)\n\n if (params) {\n for (const [key, value] of Object.entries(params)) {\n if (value !== undefined) {\n url.searchParams.set(key, String(value))\n }\n }\n }\n\n return url.toString()\n}\n\nfunction getHeaders(): Record<string, string> {\n const { apiKey } = getConfig()\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n Accept: 'application/json',\n }\n\n if (apiKey) {\n headers['Authorization'] = `Bearer ${apiKey}`\n }\n\n return headers\n}\n\nasync function parseResponse<T>(response: Response): Promise<T> {\n const contentType = response.headers.get('content-type')\n\n if (!contentType?.includes('application/json')) {\n if (!response.ok) {\n throw X402Error.fromStatus(response.status, response.statusText)\n }\n return undefined as T\n }\n\n const data = (await response.json()) as { error?: { code?: string; message?: string } } | T\n\n if (!response.ok) {\n const errorData = data as { error?: { code?: string; message?: string } }\n const message = errorData?.error?.message ?? response.statusText\n throw X402Error.fromStatus(response.status, message)\n }\n\n return data as T\n}\n\nexport async function request<T>(\n path: string,\n options: RequestOptions = {}\n): Promise<T> {\n const { method = 'GET', body, params } = options\n const url = buildUrl(path, params)\n const headers = getHeaders()\n\n const fetchOptions: RequestInit = {\n method,\n headers,\n }\n\n if (body !== undefined) {\n fetchOptions.body = JSON.stringify(body)\n }\n\n const response = await fetch(url, fetchOptions)\n return parseResponse<T>(response)\n}\n\nexport const http = {\n get<T>(path: string, params?: RequestOptions['params']): Promise<T> {\n return request<T>(path, { method: 'GET', params })\n },\n\n post<T>(path: string, body?: unknown): Promise<T> {\n return request<T>(path, { method: 'POST', body })\n },\n\n patch<T>(path: string, body?: unknown): Promise<T> {\n return request<T>(path, { method: 'PATCH', body })\n },\n\n delete<T>(path: string): Promise<T> {\n return request<T>(path, { method: 'DELETE' })\n },\n}\n","import { http } from './http'\nimport type { Score, TopOptions } from './types'\n\nasync function checkUrl(url: string): Promise<Score> {\n return http.get<Score>('/resources/score', { url })\n}\n\nasync function checkMany(urls: string[]): Promise<Score[]> {\n // Phase 2: Use batch endpoint when available\n // For now, run checks in parallel\n return Promise.all(urls.map((url) => checkUrl(url)))\n}\n\nasync function checkExists(url: string): Promise<boolean> {\n const result = await http.get<{ exists: boolean }>('/resources/exists', { url })\n return result.exists\n}\n\nasync function checkTop(options: TopOptions = {}): Promise<Score[]> {\n const { limit = 20, category } = options\n return http.get<Score[]>('/resources/top', { limit, category })\n}\n\n// Create the check function with additional methods attached\ntype CheckFunction = typeof checkUrl & {\n many: typeof checkMany\n exists: typeof checkExists\n top: typeof checkTop\n}\n\nexport const check: CheckFunction = Object.assign(checkUrl, {\n many: checkMany,\n exists: checkExists,\n top: checkTop,\n})\n","import { http } from './http'\nimport type {\n Resource,\n ResourceSearchOptions,\n ResourceCreateInput,\n ResourceUpdateInput,\n} from './types'\n\ntype GetInput = string | { id: string }\n\nasync function list(): Promise<Resource[]> {\n return http.get<Resource[]>('/resources')\n}\n\nasync function get(input: GetInput): Promise<Resource> {\n if (typeof input === 'string') {\n // Treat string as URL\n return http.get<Resource>('/resources', { url: input })\n }\n // Get by ID\n return http.get<Resource>(`/resources/${input.id}`)\n}\n\nasync function search(options: ResourceSearchOptions = {}): Promise<Resource[]> {\n const params: Record<string, string | number | undefined> = {}\n\n if (options.query) params['q'] = options.query\n if (options.category) params['category'] = options.category\n if (options.minSuccessRate !== undefined) params['min_success_rate'] = options.minSuccessRate\n if (options.minCalls !== undefined) params['min_calls'] = options.minCalls\n if (options.limit !== undefined) params['limit'] = options.limit\n if (options.offset !== undefined) params['offset'] = options.offset\n\n return http.get<Resource[]>('/resources/search', params)\n}\n\nasync function register(input: ResourceCreateInput): Promise<Resource> {\n return http.post<Resource>('/resources', input)\n}\n\nasync function update(id: string, input: ResourceUpdateInput): Promise<Resource> {\n return http.patch<Resource>(`/resources/${id}`, input)\n}\n\nasync function remove(id: string): Promise<void> {\n await http.delete(`/resources/${id}`)\n}\n\nexport const resources = {\n list,\n get,\n search,\n register,\n update,\n delete: remove,\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/errors.ts","../src/http.ts","../src/check.ts","../src/resources.ts","../src/client.ts"],"sourcesContent":["import type { ErrorCode } from './types'\n\nexport class X402Error extends Error {\n readonly code: ErrorCode\n readonly status: number\n\n constructor(code: ErrorCode, message: string, status: number) {\n super(message)\n this.name = 'X402Error'\n this.code = code\n this.status = status\n\n // Maintains proper stack trace for where error was thrown (V8 engines)\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, X402Error)\n }\n }\n\n static notFound(message = 'Resource not found'): X402Error {\n return new X402Error('NOT_FOUND', message, 404)\n }\n\n static paymentRequired(message = 'Payment required'): X402Error {\n return new X402Error('PAYMENT_REQUIRED', message, 402)\n }\n\n static rateLimited(message = 'Too many requests'): X402Error {\n return new X402Error('RATE_LIMITED', message, 429)\n }\n\n static unauthorized(message = 'Invalid or missing API key'): X402Error {\n return new X402Error('UNAUTHORIZED', message, 401)\n }\n\n static forbidden(message = 'Access denied'): X402Error {\n return new X402Error('FORBIDDEN', message, 403)\n }\n\n static validationError(message: string): X402Error {\n return new X402Error('VALIDATION_ERROR', message, 400)\n }\n\n static serverError(message = 'Internal server error'): X402Error {\n return new X402Error('SERVER_ERROR', message, 500)\n }\n\n static fromStatus(status: number, message?: string): X402Error {\n switch (status) {\n case 400:\n return X402Error.validationError(message ?? 'Invalid request')\n case 401:\n return X402Error.unauthorized(message)\n case 402:\n return X402Error.paymentRequired(message)\n case 403:\n return X402Error.forbidden(message)\n case 404:\n return X402Error.notFound(message)\n case 429:\n return X402Error.rateLimited(message)\n default:\n return X402Error.serverError(message)\n }\n }\n}\n","import { X402Error } from './errors'\nimport type { ClientOptions } from './types'\n\ntype HttpMethod = 'GET' | 'POST' | 'PATCH' | 'DELETE'\n\ninterface RequestOptions {\n method?: HttpMethod\n body?: unknown\n params?: Record<string, string | number | boolean | undefined>\n}\n\nconst DEFAULT_BASE_URL = 'https://api.x402.jobs/api/v1'\n\nexport class HttpClient {\n private baseUrl: string\n private apiKey: string | undefined\n\n constructor(options: ClientOptions = {}) {\n this.baseUrl = (options.baseUrl ?? DEFAULT_BASE_URL).replace(/\\/$/, '')\n this.apiKey = options.apiKey\n }\n\n private buildUrl(path: string, params?: RequestOptions['params']): string {\n const url = new URL(path, this.baseUrl)\n\n if (params) {\n for (const [key, value] of Object.entries(params)) {\n if (value !== undefined) {\n url.searchParams.set(key, String(value))\n }\n }\n }\n\n return url.toString()\n }\n\n private getHeaders(): Record<string, string> {\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n Accept: 'application/json',\n }\n\n if (this.apiKey) {\n headers['Authorization'] = `Bearer ${this.apiKey}`\n }\n\n return headers\n }\n\n private async parseResponse<T>(response: Response): Promise<T> {\n const contentType = response.headers.get('content-type')\n\n if (!contentType?.includes('application/json')) {\n if (!response.ok) {\n throw X402Error.fromStatus(response.status, response.statusText)\n }\n return undefined as T\n }\n\n const data = (await response.json()) as { error?: { code?: string; message?: string } } | T\n\n if (!response.ok) {\n const errorData = data as { error?: { code?: string; message?: string } }\n const message = errorData?.error?.message ?? response.statusText\n throw X402Error.fromStatus(response.status, message)\n }\n\n return data as T\n }\n\n async request<T>(path: string, options: RequestOptions = {}): Promise<T> {\n const { method = 'GET', body, params } = options\n const url = this.buildUrl(path, params)\n const headers = this.getHeaders()\n\n const fetchOptions: RequestInit = {\n method,\n headers,\n }\n\n if (body !== undefined) {\n fetchOptions.body = JSON.stringify(body)\n }\n\n const response = await fetch(url, fetchOptions)\n return this.parseResponse<T>(response)\n }\n\n get<T>(path: string, params?: RequestOptions['params']): Promise<T> {\n return this.request<T>(path, { method: 'GET', params })\n }\n\n post<T>(path: string, body?: unknown): Promise<T> {\n return this.request<T>(path, { method: 'POST', body })\n }\n\n patch<T>(path: string, body?: unknown): Promise<T> {\n return this.request<T>(path, { method: 'PATCH', body })\n }\n\n delete<T>(path: string): Promise<T> {\n return this.request<T>(path, { method: 'DELETE' })\n }\n}\n","import type { HttpClient } from './http'\nimport type { Score, TopOptions } from './types'\n\nexport interface CheckAPI {\n (url: string): Promise<Score>\n many(urls: string[]): Promise<Score[]>\n exists(url: string): Promise<boolean>\n top(options?: TopOptions): Promise<Score[]>\n}\n\nexport function createCheckAPI(http: HttpClient): CheckAPI {\n const check = async (url: string): Promise<Score> => {\n return http.get<Score>('/resources/score', { url })\n }\n\n check.many = async (urls: string[]): Promise<Score[]> => {\n return Promise.all(urls.map((url) => check(url)))\n }\n\n check.exists = async (url: string): Promise<boolean> => {\n const result = await http.get<{ exists: boolean }>('/resources/exists', { url })\n return result.exists\n }\n\n check.top = async (options: TopOptions = {}): Promise<Score[]> => {\n const { limit = 20, category } = options\n return http.get<Score[]>('/resources/top', { limit, category })\n }\n\n return check\n}\n","import type { HttpClient } from './http'\nimport type {\n Resource,\n ResourceListOptions,\n ResourceSearchOptions,\n ResourceCreateInput,\n ResourceUpdateInput,\n} from './types'\n\ntype GetInput = string | { id: string }\n\nexport class ResourcesAPI {\n constructor(private http: HttpClient) {}\n\n async list(options: ResourceListOptions = {}): Promise<Resource[]> {\n const params: Record<string, string | number | undefined> = {}\n if (options.limit !== undefined) params['limit'] = options.limit\n if (options.sort) params['sort'] = options.sort\n const response = await this.http.get<{ resources: Resource[] }>('/resources', params)\n return response.resources\n }\n\n async get(input: GetInput): Promise<Resource> {\n if (typeof input === 'string') {\n return this.http.get<Resource>('/resources', { url: input })\n }\n return this.http.get<Resource>(`/resources/${input.id}`)\n }\n\n async search(options: ResourceSearchOptions = {}): Promise<Resource[]> {\n const params: Record<string, string | number | undefined> = {}\n\n if (options.query) params['q'] = options.query\n if (options.category) params['category'] = options.category\n if (options.minSuccessRate !== undefined) params['min_success_rate'] = options.minSuccessRate\n if (options.minCalls !== undefined) params['min_calls'] = options.minCalls\n if (options.limit !== undefined) params['limit'] = options.limit\n if (options.offset !== undefined) params['offset'] = options.offset\n\n return this.http.get<Resource[]>('/resources/search', params)\n }\n\n async register(input: ResourceCreateInput): Promise<Resource> {\n return this.http.post<Resource>('/resources', input)\n }\n\n async update(id: string, input: ResourceUpdateInput): Promise<Resource> {\n return this.http.patch<Resource>(`/resources/${id}`, input)\n }\n\n async delete(id: string): Promise<void> {\n await this.http.delete(`/resources/${id}`)\n }\n}\n","import { HttpClient } from './http'\nimport { createCheckAPI, type CheckAPI } from './check'\nimport { ResourcesAPI } from './resources'\nimport type { ClientOptions } from './types'\n\nexport class X402Jobs {\n readonly check: CheckAPI\n readonly resources: ResourcesAPI\n\n constructor(options: ClientOptions = {}) {\n const http = new HttpClient(options)\n this.check = createCheckAPI(http)\n this.resources = new ResourcesAPI(http)\n }\n}\n"],"mappings":"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","names":[]}
|