stophy 0.2.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/README.md +59 -69
- package/dist/index.cjs +562 -282
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +22754 -664
- package/dist/index.d.ts +22754 -664
- package/dist/index.js +562 -282
- package/dist/index.js.map +1 -1
- package/package.json +13 -10
package/dist/index.cjs
CHANGED
|
@@ -2,344 +2,624 @@
|
|
|
2
2
|
|
|
3
3
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
4
|
|
|
5
|
-
var clientFetch = require('@hey-api/client-fetch');
|
|
6
|
-
|
|
7
|
-
// src/generated/client.gen.ts
|
|
8
|
-
var client = clientFetch.createClient(
|
|
9
|
-
clientFetch.createConfig({
|
|
10
|
-
baseUrl: "https://api.stophy.dev"
|
|
11
|
-
})
|
|
12
|
-
);
|
|
13
|
-
|
|
14
|
-
// src/generated/sdk.gen.ts
|
|
15
|
-
var getVideo = (options) => {
|
|
16
|
-
return (options.client ?? client).post({
|
|
17
|
-
security: [
|
|
18
|
-
{
|
|
19
|
-
scheme: "bearer",
|
|
20
|
-
type: "http"
|
|
21
|
-
}
|
|
22
|
-
],
|
|
23
|
-
url: "/v1/video",
|
|
24
|
-
...options,
|
|
25
|
-
headers: {
|
|
26
|
-
"Content-Type": "application/json",
|
|
27
|
-
...options?.headers
|
|
28
|
-
}
|
|
29
|
-
});
|
|
30
|
-
};
|
|
31
|
-
var searchVideos = (options) => {
|
|
32
|
-
return (options.client ?? client).post({
|
|
33
|
-
security: [
|
|
34
|
-
{
|
|
35
|
-
scheme: "bearer",
|
|
36
|
-
type: "http"
|
|
37
|
-
}
|
|
38
|
-
],
|
|
39
|
-
url: "/v1/search",
|
|
40
|
-
...options,
|
|
41
|
-
headers: {
|
|
42
|
-
"Content-Type": "application/json",
|
|
43
|
-
...options?.headers
|
|
44
|
-
}
|
|
45
|
-
});
|
|
46
|
-
};
|
|
47
|
-
var getChannel = (options) => {
|
|
48
|
-
return (options.client ?? client).post({
|
|
49
|
-
security: [
|
|
50
|
-
{
|
|
51
|
-
scheme: "bearer",
|
|
52
|
-
type: "http"
|
|
53
|
-
}
|
|
54
|
-
],
|
|
55
|
-
url: "/v1/channel",
|
|
56
|
-
...options,
|
|
57
|
-
headers: {
|
|
58
|
-
"Content-Type": "application/json",
|
|
59
|
-
...options?.headers
|
|
60
|
-
}
|
|
61
|
-
});
|
|
62
|
-
};
|
|
63
|
-
var getPlaylist = (options) => {
|
|
64
|
-
return (options.client ?? client).post({
|
|
65
|
-
security: [
|
|
66
|
-
{
|
|
67
|
-
scheme: "bearer",
|
|
68
|
-
type: "http"
|
|
69
|
-
}
|
|
70
|
-
],
|
|
71
|
-
url: "/v1/playlist",
|
|
72
|
-
...options,
|
|
73
|
-
headers: {
|
|
74
|
-
"Content-Type": "application/json",
|
|
75
|
-
...options?.headers
|
|
76
|
-
}
|
|
77
|
-
});
|
|
78
|
-
};
|
|
79
|
-
var getSuggestions = (options) => {
|
|
80
|
-
return (options.client ?? client).get({
|
|
81
|
-
security: [
|
|
82
|
-
{
|
|
83
|
-
scheme: "bearer",
|
|
84
|
-
type: "http"
|
|
85
|
-
}
|
|
86
|
-
],
|
|
87
|
-
url: "/v1/suggest",
|
|
88
|
-
...options
|
|
89
|
-
});
|
|
90
|
-
};
|
|
91
|
-
var getCredits = (options) => {
|
|
92
|
-
return (options?.client ?? client).get({
|
|
93
|
-
security: [
|
|
94
|
-
{
|
|
95
|
-
scheme: "bearer",
|
|
96
|
-
type: "http"
|
|
97
|
-
}
|
|
98
|
-
],
|
|
99
|
-
url: "/v1/credits",
|
|
100
|
-
...options
|
|
101
|
-
});
|
|
102
|
-
};
|
|
103
|
-
var getLogs = (options) => {
|
|
104
|
-
return (options?.client ?? client).get({
|
|
105
|
-
security: [
|
|
106
|
-
{
|
|
107
|
-
scheme: "bearer",
|
|
108
|
-
type: "http"
|
|
109
|
-
}
|
|
110
|
-
],
|
|
111
|
-
url: "/v1/logs",
|
|
112
|
-
...options
|
|
113
|
-
});
|
|
114
|
-
};
|
|
115
|
-
var getUsage = (options) => {
|
|
116
|
-
return (options?.client ?? client).get({
|
|
117
|
-
security: [
|
|
118
|
-
{
|
|
119
|
-
scheme: "bearer",
|
|
120
|
-
type: "http"
|
|
121
|
-
}
|
|
122
|
-
],
|
|
123
|
-
url: "/v1/usage",
|
|
124
|
-
...options
|
|
125
|
-
});
|
|
126
|
-
};
|
|
127
|
-
|
|
128
5
|
// src/errors.ts
|
|
129
6
|
var StophyError = class extends Error {
|
|
130
7
|
code;
|
|
8
|
+
retryable;
|
|
9
|
+
retryAfterSeconds;
|
|
131
10
|
status;
|
|
132
11
|
requestId;
|
|
133
|
-
details;
|
|
134
12
|
constructor(message, options) {
|
|
135
13
|
super(message);
|
|
136
14
|
this.name = "StophyError";
|
|
137
15
|
this.status = options.status;
|
|
138
16
|
this.code = options.code;
|
|
17
|
+
this.retryable = options.retryable;
|
|
18
|
+
this.retryAfterSeconds = options.retryAfterSeconds;
|
|
139
19
|
this.requestId = options.requestId;
|
|
140
|
-
this.details = options.details;
|
|
141
20
|
}
|
|
142
21
|
};
|
|
143
22
|
|
|
144
|
-
// src/
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
options.maxRetries ?? 2,
|
|
157
|
-
options.retryInitialDelayMs ?? 500
|
|
158
|
-
)
|
|
159
|
-
})
|
|
23
|
+
// src/account.ts
|
|
24
|
+
function usage(call) {
|
|
25
|
+
return call({ method: "GET", path: "/v1/usage" }).then(parseUsage);
|
|
26
|
+
}
|
|
27
|
+
function logs(call, query) {
|
|
28
|
+
const params = {};
|
|
29
|
+
if (query?.apiKeyId !== void 0) params.apiKeyId = query.apiKeyId;
|
|
30
|
+
if (query?.days !== void 0) params.days = query.days;
|
|
31
|
+
if (query?.endpoint !== void 0) params.endpoint = query.endpoint;
|
|
32
|
+
if (query?.page !== void 0) params.page = query.page;
|
|
33
|
+
return call({ method: "GET", path: "/v1/logs", query: params }).then(
|
|
34
|
+
parseLogs
|
|
160
35
|
);
|
|
161
36
|
}
|
|
162
|
-
function
|
|
163
|
-
if (
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
37
|
+
function parseUsage(value) {
|
|
38
|
+
if (!isRecord(value)) return unexpected("usage");
|
|
39
|
+
const balanceMicros = numberField(value, "balanceMicros");
|
|
40
|
+
const creditsUsed = numberField(value, "creditsUsed");
|
|
41
|
+
const requestCount = numberField(value, "requestCount");
|
|
42
|
+
return { balanceMicros, creditsUsed, requestCount };
|
|
43
|
+
}
|
|
44
|
+
function parseLogs(value) {
|
|
45
|
+
if (!isRecord(value) || !Array.isArray(value.logs) || !Array.isArray(value.endpoints)) {
|
|
46
|
+
return unexpected("logs");
|
|
47
|
+
}
|
|
48
|
+
return {
|
|
49
|
+
endpoints: value.endpoints.map((item) => {
|
|
50
|
+
if (typeof item !== "string") return unexpected("logs.endpoints");
|
|
51
|
+
return item;
|
|
52
|
+
}),
|
|
53
|
+
logs: value.logs.map(parseLog),
|
|
54
|
+
page: numberField(value, "page"),
|
|
55
|
+
pageSize: numberField(value, "pageSize"),
|
|
56
|
+
total: numberField(value, "total"),
|
|
57
|
+
totalPages: numberField(value, "totalPages")
|
|
181
58
|
};
|
|
182
59
|
}
|
|
183
|
-
function
|
|
184
|
-
|
|
185
|
-
return
|
|
60
|
+
function parseLog(value) {
|
|
61
|
+
if (!isRecord(value)) return unexpected("logs.logs");
|
|
62
|
+
return {
|
|
63
|
+
apiKeyId: stringOrNull(value, "apiKeyId"),
|
|
64
|
+
apiKeyName: stringOrNull(value, "apiKeyName"),
|
|
65
|
+
createdAt: stringField(value, "createdAt"),
|
|
66
|
+
credits: numberField(value, "credits"),
|
|
67
|
+
durationMs: numberOrNull(value, "durationMs"),
|
|
68
|
+
endpoint: stringField(value, "endpoint"),
|
|
69
|
+
id: stringField(value, "id"),
|
|
70
|
+
method: stringField(value, "method"),
|
|
71
|
+
response: stringField(value, "response"),
|
|
72
|
+
status: numberField(value, "status")
|
|
73
|
+
};
|
|
186
74
|
}
|
|
187
|
-
function
|
|
188
|
-
const
|
|
189
|
-
if (
|
|
190
|
-
|
|
191
|
-
if (!Number.isNaN(seconds)) return seconds * 1e3;
|
|
192
|
-
const date = Date.parse(header);
|
|
193
|
-
return Number.isNaN(date) ? null : Math.max(0, date - Date.now());
|
|
75
|
+
function numberField(record, field) {
|
|
76
|
+
const value = record[field];
|
|
77
|
+
if (typeof value !== "number") return unexpected(field);
|
|
78
|
+
return value;
|
|
194
79
|
}
|
|
195
|
-
function
|
|
196
|
-
|
|
80
|
+
function numberOrNull(record, field) {
|
|
81
|
+
const value = record[field];
|
|
82
|
+
if (value === null) return null;
|
|
83
|
+
if (typeof value !== "number") return unexpected(field);
|
|
84
|
+
return value;
|
|
197
85
|
}
|
|
198
|
-
function
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
throw new StophyError(
|
|
203
|
-
error.error ?? `Stophy request failed with status ${result.response.status}`,
|
|
204
|
-
{
|
|
205
|
-
status: result.response.status,
|
|
206
|
-
code: error.code,
|
|
207
|
-
requestId: result.response.headers.get("x-request-id") ?? void 0,
|
|
208
|
-
details: error.details
|
|
209
|
-
}
|
|
210
|
-
);
|
|
86
|
+
function stringField(record, field) {
|
|
87
|
+
const value = record[field];
|
|
88
|
+
if (typeof value !== "string") return unexpected(field);
|
|
89
|
+
return value;
|
|
211
90
|
}
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
91
|
+
function stringOrNull(record, field) {
|
|
92
|
+
const value = record[field];
|
|
93
|
+
if (value === null) return null;
|
|
94
|
+
if (typeof value !== "string") return unexpected(field);
|
|
95
|
+
return value;
|
|
216
96
|
}
|
|
217
|
-
function
|
|
218
|
-
|
|
97
|
+
function unexpected(field) {
|
|
98
|
+
throw new StophyError(`Stophy returned an unexpected ${field}`, {
|
|
99
|
+
status: 200,
|
|
100
|
+
retryable: false
|
|
101
|
+
});
|
|
219
102
|
}
|
|
220
|
-
function
|
|
221
|
-
return
|
|
103
|
+
function isRecord(value) {
|
|
104
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
222
105
|
}
|
|
223
106
|
|
|
224
|
-
// src/
|
|
225
|
-
function
|
|
226
|
-
|
|
227
|
-
|
|
107
|
+
// src/bind.ts
|
|
108
|
+
function post(path, call) {
|
|
109
|
+
function run(body, options) {
|
|
110
|
+
return call({ method: "POST", path, body, options });
|
|
111
|
+
}
|
|
112
|
+
return run;
|
|
228
113
|
}
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
114
|
+
function postOptional(path, call) {
|
|
115
|
+
function run(body, options) {
|
|
116
|
+
if (isMarkdownOptions(body) && options === void 0) {
|
|
117
|
+
return call({ method: "POST", path, body: {}, options: body });
|
|
118
|
+
}
|
|
119
|
+
return call({ method: "POST", path, body: body ?? {}, options });
|
|
120
|
+
}
|
|
121
|
+
return run;
|
|
234
122
|
}
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
if (typeof queryOrBody === "string" && !queryOrBody.trim()) {
|
|
239
|
-
throw new Error("query cannot be empty");
|
|
123
|
+
function get(path, call) {
|
|
124
|
+
function run(options) {
|
|
125
|
+
return call({ method: "GET", path, options });
|
|
240
126
|
}
|
|
241
|
-
|
|
242
|
-
|
|
127
|
+
return run;
|
|
128
|
+
}
|
|
129
|
+
function isMarkdownOptions(value) {
|
|
130
|
+
if (typeof value !== "object" || value === null) return false;
|
|
131
|
+
return "format" in value && value.format === "markdown";
|
|
243
132
|
}
|
|
244
133
|
|
|
245
|
-
// src/
|
|
246
|
-
function
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
134
|
+
// src/generated/surface.gen.ts
|
|
135
|
+
function bindSurface(call) {
|
|
136
|
+
return {
|
|
137
|
+
endpoints: get("/v1/endpoints", call),
|
|
138
|
+
web: {
|
|
139
|
+
search: post("/v1/web/search", call),
|
|
140
|
+
news: postOptional("/v1/web/news", call),
|
|
141
|
+
contacts: post("/v1/web/contacts", call)
|
|
142
|
+
},
|
|
143
|
+
youtube: {
|
|
144
|
+
search: post("/v1/youtube/search", call),
|
|
145
|
+
video: post("/v1/youtube/video", call),
|
|
146
|
+
transcript: post("/v1/youtube/transcript", call),
|
|
147
|
+
comments: Object.assign(post("/v1/youtube/comments", call), {
|
|
148
|
+
replies: post("/v1/youtube/comments/replies", call)
|
|
149
|
+
}),
|
|
150
|
+
channel: post("/v1/youtube/channel", call),
|
|
151
|
+
playlist: post("/v1/youtube/playlist", call),
|
|
152
|
+
suggest: post("/v1/youtube/suggest", call)
|
|
153
|
+
},
|
|
154
|
+
reddit: {
|
|
155
|
+
search: post("/v1/reddit/search", call),
|
|
156
|
+
post: post("/v1/reddit/post", call),
|
|
157
|
+
comments: {
|
|
158
|
+
more: post("/v1/reddit/comments/more", call)
|
|
159
|
+
},
|
|
160
|
+
subreddit: post("/v1/reddit/subreddit", call),
|
|
161
|
+
user: post("/v1/reddit/user", call),
|
|
162
|
+
domain: post("/v1/reddit/domain", call)
|
|
163
|
+
},
|
|
164
|
+
maps: {
|
|
165
|
+
search: post("/v1/maps/search", call),
|
|
166
|
+
place: post("/v1/maps/place", call),
|
|
167
|
+
reviews: post("/v1/maps/reviews", call)
|
|
168
|
+
},
|
|
169
|
+
instagram: {
|
|
170
|
+
profile: post("/v1/instagram/profile", call),
|
|
171
|
+
posts: post("/v1/instagram/posts", call),
|
|
172
|
+
post: post("/v1/instagram/post", call),
|
|
173
|
+
url: post("/v1/instagram/url", call),
|
|
174
|
+
search: post("/v1/instagram/search", call),
|
|
175
|
+
transcript: post("/v1/instagram/transcript", call),
|
|
176
|
+
comments: Object.assign(post("/v1/instagram/comments", call), {
|
|
177
|
+
replies: post("/v1/instagram/comments/replies", call)
|
|
178
|
+
})
|
|
179
|
+
},
|
|
180
|
+
tiktok: {
|
|
181
|
+
profile: post("/v1/tiktok/profile", call),
|
|
182
|
+
video: post("/v1/tiktok/video", call),
|
|
183
|
+
url: post("/v1/tiktok/url", call),
|
|
184
|
+
transcript: post("/v1/tiktok/transcript", call),
|
|
185
|
+
posts: post("/v1/tiktok/posts", call),
|
|
186
|
+
hashtag: post("/v1/tiktok/hashtag", call),
|
|
187
|
+
comments: Object.assign(post("/v1/tiktok/comments", call), {
|
|
188
|
+
replies: post("/v1/tiktok/comments/replies", call)
|
|
189
|
+
}),
|
|
190
|
+
search: post("/v1/tiktok/search", call),
|
|
191
|
+
ads: {
|
|
192
|
+
search: postOptional("/v1/tiktok/ads/search", call),
|
|
193
|
+
ad: post("/v1/tiktok/ads/ad", call)
|
|
194
|
+
}
|
|
195
|
+
},
|
|
196
|
+
bluesky: {
|
|
197
|
+
profile: post("/v1/bluesky/profile", call),
|
|
198
|
+
posts: post("/v1/bluesky/posts", call),
|
|
199
|
+
post: post("/v1/bluesky/post", call),
|
|
200
|
+
followers: post("/v1/bluesky/followers", call)
|
|
201
|
+
},
|
|
202
|
+
mastodon: {
|
|
203
|
+
profile: post("/v1/mastodon/profile", call),
|
|
204
|
+
posts: post("/v1/mastodon/posts", call),
|
|
205
|
+
post: post("/v1/mastodon/post", call),
|
|
206
|
+
hashtag: post("/v1/mastodon/hashtag", call)
|
|
207
|
+
},
|
|
208
|
+
threads: {
|
|
209
|
+
profile: post("/v1/threads/profile", call),
|
|
210
|
+
posts: post("/v1/threads/posts", call),
|
|
211
|
+
post: post("/v1/threads/post", call),
|
|
212
|
+
search: post("/v1/threads/search", call)
|
|
213
|
+
},
|
|
214
|
+
telegram: {
|
|
215
|
+
channel: post("/v1/telegram/channel", call),
|
|
216
|
+
posts: post("/v1/telegram/posts", call),
|
|
217
|
+
post: post("/v1/telegram/post", call)
|
|
218
|
+
},
|
|
219
|
+
meta: {
|
|
220
|
+
ads: {
|
|
221
|
+
search: post("/v1/meta/ads/search", call),
|
|
222
|
+
page: post("/v1/meta/ads/page", call),
|
|
223
|
+
ad: post("/v1/meta/ads/ad", call)
|
|
224
|
+
}
|
|
225
|
+
},
|
|
226
|
+
linkedin: {
|
|
227
|
+
jobs: {
|
|
228
|
+
search: postOptional("/v1/linkedin/jobs/search", call),
|
|
229
|
+
job: post("/v1/linkedin/jobs/job", call)
|
|
230
|
+
},
|
|
231
|
+
ads: {
|
|
232
|
+
search: postOptional("/v1/linkedin/ads/search", call),
|
|
233
|
+
ad: post("/v1/linkedin/ads/ad", call)
|
|
234
|
+
},
|
|
235
|
+
company: Object.assign(post("/v1/linkedin/company", call), {
|
|
236
|
+
posts: post("/v1/linkedin/company/posts", call)
|
|
237
|
+
}),
|
|
238
|
+
profile: post("/v1/linkedin/profile", call),
|
|
239
|
+
posts: postOptional("/v1/linkedin/posts", call)
|
|
240
|
+
},
|
|
241
|
+
zillow: {
|
|
242
|
+
search: postOptional("/v1/zillow/search", call),
|
|
243
|
+
property: post("/v1/zillow/property", call)
|
|
244
|
+
},
|
|
245
|
+
google: {
|
|
246
|
+
ads: {
|
|
247
|
+
advertisers: post("/v1/google/ads/advertisers", call),
|
|
248
|
+
search: postOptional("/v1/google/ads/search", call),
|
|
249
|
+
ad: post("/v1/google/ads/ad", call)
|
|
250
|
+
},
|
|
251
|
+
suggest: post("/v1/google/suggest", call),
|
|
252
|
+
trends: {
|
|
253
|
+
interest: post("/v1/google/trends/interest", call),
|
|
254
|
+
regions: post("/v1/google/trends/regions", call),
|
|
255
|
+
related: post("/v1/google/trends/related", call),
|
|
256
|
+
trending: postOptional("/v1/google/trends/trending", call)
|
|
257
|
+
}
|
|
258
|
+
},
|
|
259
|
+
upwork: {
|
|
260
|
+
search: postOptional("/v1/upwork/search", call),
|
|
261
|
+
job: post("/v1/upwork/job", call)
|
|
262
|
+
},
|
|
263
|
+
amazon: {
|
|
264
|
+
suggest: post("/v1/amazon/suggest", call),
|
|
265
|
+
search: postOptional("/v1/amazon/search", call),
|
|
266
|
+
product: post("/v1/amazon/product", call),
|
|
267
|
+
bestsellers: post("/v1/amazon/bestsellers", call)
|
|
268
|
+
},
|
|
269
|
+
site: {
|
|
270
|
+
map: post("/v1/site/map", call),
|
|
271
|
+
seo: post("/v1/site/seo", call)
|
|
272
|
+
},
|
|
273
|
+
domain: {
|
|
274
|
+
whois: post("/v1/domain/whois", call),
|
|
275
|
+
dns: post("/v1/domain/dns", call),
|
|
276
|
+
tech: post("/v1/domain/tech", call)
|
|
277
|
+
},
|
|
278
|
+
email: {
|
|
279
|
+
check: post("/v1/email/check", call)
|
|
280
|
+
},
|
|
281
|
+
crypto: {
|
|
282
|
+
coins: postOptional("/v1/crypto/coins", call),
|
|
283
|
+
coin: post("/v1/crypto/coin", call),
|
|
284
|
+
history: post("/v1/crypto/history", call),
|
|
285
|
+
trending: postOptional("/v1/crypto/trending", call),
|
|
286
|
+
categories: postOptional("/v1/crypto/categories", call),
|
|
287
|
+
movers: postOptional("/v1/crypto/movers", call),
|
|
288
|
+
new: postOptional("/v1/crypto/new", call),
|
|
289
|
+
dex: {
|
|
290
|
+
search: post("/v1/crypto/dex/search", call),
|
|
291
|
+
pairs: post("/v1/crypto/dex/pairs", call),
|
|
292
|
+
token: post("/v1/crypto/dex/token", call),
|
|
293
|
+
new: postOptional("/v1/crypto/dex/new", call)
|
|
294
|
+
},
|
|
295
|
+
pump: {
|
|
296
|
+
coins: postOptional("/v1/crypto/pump/coins", call),
|
|
297
|
+
coin: post("/v1/crypto/pump/coin", call),
|
|
298
|
+
trades: post("/v1/crypto/pump/trades", call)
|
|
299
|
+
},
|
|
300
|
+
wallet: post("/v1/crypto/wallet", call),
|
|
301
|
+
token: {
|
|
302
|
+
holders: post("/v1/crypto/token/holders", call)
|
|
303
|
+
},
|
|
304
|
+
binance: {
|
|
305
|
+
announcements: postOptional("/v1/crypto/binance/announcements", call)
|
|
306
|
+
}
|
|
307
|
+
},
|
|
308
|
+
indeed: {
|
|
309
|
+
search: postOptional("/v1/indeed/search", call),
|
|
310
|
+
job: post("/v1/indeed/job", call)
|
|
311
|
+
},
|
|
312
|
+
tripadvisor: {
|
|
313
|
+
search: post("/v1/tripadvisor/search", call),
|
|
314
|
+
place: post("/v1/tripadvisor/place", call),
|
|
315
|
+
reviews: post("/v1/tripadvisor/reviews", call)
|
|
316
|
+
},
|
|
317
|
+
googletravel: {
|
|
318
|
+
flights: post("/v1/googletravel/flights", call)
|
|
319
|
+
},
|
|
320
|
+
shopify: {
|
|
321
|
+
products: post("/v1/shopify/products", call),
|
|
322
|
+
collections: post("/v1/shopify/collections", call),
|
|
323
|
+
store: post("/v1/shopify/store", call)
|
|
324
|
+
},
|
|
325
|
+
walmart: {
|
|
326
|
+
search: post("/v1/walmart/search", call),
|
|
327
|
+
product: post("/v1/walmart/product", call)
|
|
328
|
+
},
|
|
329
|
+
aliexpress: {
|
|
330
|
+
search: post("/v1/aliexpress/search", call),
|
|
331
|
+
product: post("/v1/aliexpress/product", call)
|
|
332
|
+
},
|
|
333
|
+
appstore: {
|
|
334
|
+
app: post("/v1/appstore/app", call),
|
|
335
|
+
search: post("/v1/appstore/search", call),
|
|
336
|
+
reviews: post("/v1/appstore/reviews", call),
|
|
337
|
+
top: postOptional("/v1/appstore/top", call)
|
|
338
|
+
},
|
|
339
|
+
googleplay: {
|
|
340
|
+
app: post("/v1/googleplay/app", call),
|
|
341
|
+
search: post("/v1/googleplay/search", call),
|
|
342
|
+
reviews: post("/v1/googleplay/reviews", call)
|
|
343
|
+
},
|
|
344
|
+
airbnb: {
|
|
345
|
+
search: post("/v1/airbnb/search", call),
|
|
346
|
+
listing: post("/v1/airbnb/listing", call),
|
|
347
|
+
calendar: post("/v1/airbnb/calendar", call),
|
|
348
|
+
reviews: post("/v1/airbnb/reviews", call)
|
|
349
|
+
},
|
|
350
|
+
redfin: {
|
|
351
|
+
search: post("/v1/redfin/search", call),
|
|
352
|
+
property: post("/v1/redfin/property", call)
|
|
353
|
+
},
|
|
354
|
+
realtor: {
|
|
355
|
+
search: post("/v1/realtor/search", call),
|
|
356
|
+
property: post("/v1/realtor/property", call)
|
|
357
|
+
},
|
|
358
|
+
rightmove: {
|
|
359
|
+
search: post("/v1/rightmove/search", call),
|
|
360
|
+
property: post("/v1/rightmove/property", call)
|
|
361
|
+
},
|
|
362
|
+
immoscout: {
|
|
363
|
+
search: post("/v1/immoscout/search", call),
|
|
364
|
+
listing: post("/v1/immoscout/listing", call)
|
|
365
|
+
},
|
|
366
|
+
pinterest: {
|
|
367
|
+
search: post("/v1/pinterest/search", call),
|
|
368
|
+
pin: post("/v1/pinterest/pin", call),
|
|
369
|
+
board: post("/v1/pinterest/board", call),
|
|
370
|
+
user: post("/v1/pinterest/user", call),
|
|
371
|
+
ads: {
|
|
372
|
+
search: post("/v1/pinterest/ads/search", call),
|
|
373
|
+
ad: post("/v1/pinterest/ads/ad", call)
|
|
374
|
+
}
|
|
375
|
+
},
|
|
376
|
+
x: {
|
|
377
|
+
tweet: post("/v1/x/tweet", call)
|
|
378
|
+
},
|
|
379
|
+
kick: {
|
|
380
|
+
channel: post("/v1/kick/channel", call),
|
|
381
|
+
videos: post("/v1/kick/videos", call),
|
|
382
|
+
clips: post("/v1/kick/clips", call)
|
|
383
|
+
},
|
|
384
|
+
finance: {
|
|
385
|
+
quote: post("/v1/finance/quote", call),
|
|
386
|
+
history: post("/v1/finance/history", call),
|
|
387
|
+
search: post("/v1/finance/search", call),
|
|
388
|
+
profile: post("/v1/finance/profile", call)
|
|
389
|
+
},
|
|
390
|
+
microsoft: {
|
|
391
|
+
ads: {
|
|
392
|
+
search: postOptional("/v1/microsoft/ads/search", call),
|
|
393
|
+
ad: post("/v1/microsoft/ads/ad", call),
|
|
394
|
+
advertisers: post("/v1/microsoft/ads/advertisers", call)
|
|
395
|
+
}
|
|
396
|
+
},
|
|
397
|
+
snapchat: {
|
|
398
|
+
profile: post("/v1/snapchat/profile", call),
|
|
399
|
+
ads: {
|
|
400
|
+
search: post("/v1/snapchat/ads/search", call),
|
|
401
|
+
ad: post("/v1/snapchat/ads/ad", call)
|
|
402
|
+
}
|
|
403
|
+
},
|
|
404
|
+
tumblr: {
|
|
405
|
+
blog: post("/v1/tumblr/blog", call),
|
|
406
|
+
posts: post("/v1/tumblr/posts", call),
|
|
407
|
+
post: post("/v1/tumblr/post", call),
|
|
408
|
+
search: post("/v1/tumblr/search", call)
|
|
409
|
+
},
|
|
410
|
+
quora: {
|
|
411
|
+
question: post("/v1/quora/question", call)
|
|
412
|
+
}
|
|
413
|
+
};
|
|
252
414
|
}
|
|
253
415
|
|
|
254
|
-
//
|
|
255
|
-
|
|
256
|
-
|
|
416
|
+
// package.json
|
|
417
|
+
var version = "1.0.0";
|
|
418
|
+
|
|
419
|
+
// src/transport.ts
|
|
420
|
+
var DEFAULT_BASE_URL = "https://api.stophy.dev";
|
|
421
|
+
var DEFAULT_TIMEOUT_MS = 3e4;
|
|
422
|
+
var MAX_RETRY_WAIT_SECONDS = 60;
|
|
423
|
+
var RETRYABLE_STATUS = /* @__PURE__ */ new Set([429, 500, 502, 503, 504]);
|
|
424
|
+
var USER_AGENT = `stophy-typescript/${version}`;
|
|
425
|
+
function createCaller(options) {
|
|
426
|
+
const baseFetch = options.fetch ?? globalThis.fetch;
|
|
427
|
+
const baseUrl = (options.baseUrl ?? DEFAULT_BASE_URL).replace(/\/$/, "");
|
|
428
|
+
const retry = {
|
|
429
|
+
maxRetries: options.maxRetries ?? 2,
|
|
430
|
+
initialDelayMs: options.retryInitialDelayMs ?? 500,
|
|
431
|
+
timeoutMs: options.timeoutMs ?? DEFAULT_TIMEOUT_MS
|
|
432
|
+
};
|
|
433
|
+
return async (spec) => {
|
|
434
|
+
const markdown = spec.options?.format === "markdown";
|
|
435
|
+
const headers = new Headers(options.headers);
|
|
436
|
+
if (typeof document === "undefined" && !headers.has("user-agent")) {
|
|
437
|
+
headers.set("user-agent", USER_AGENT);
|
|
438
|
+
}
|
|
439
|
+
if (options.apiKey) {
|
|
440
|
+
headers.set("authorization", `Bearer ${options.apiKey}`);
|
|
441
|
+
}
|
|
442
|
+
headers.set("accept", markdown ? "text/markdown" : "application/json");
|
|
443
|
+
if (spec.body !== void 0)
|
|
444
|
+
headers.set("content-type", "application/json");
|
|
445
|
+
const url = withQuery(`${baseUrl}${spec.path}`, spec.query);
|
|
446
|
+
return send(
|
|
447
|
+
baseFetch,
|
|
448
|
+
url,
|
|
449
|
+
(signal) => ({
|
|
450
|
+
method: spec.method,
|
|
451
|
+
headers,
|
|
452
|
+
body: spec.body === void 0 ? void 0 : JSON.stringify(spec.body),
|
|
453
|
+
signal
|
|
454
|
+
}),
|
|
455
|
+
markdown,
|
|
456
|
+
spec.options?.signal,
|
|
457
|
+
retry
|
|
458
|
+
);
|
|
459
|
+
};
|
|
257
460
|
}
|
|
258
|
-
function
|
|
259
|
-
|
|
461
|
+
async function send(baseFetch, url, init, markdown, signal, retry) {
|
|
462
|
+
for (let n = 0; ; n += 1) {
|
|
463
|
+
const deadline = withDeadline(signal, retry.timeoutMs);
|
|
464
|
+
let waitMs;
|
|
465
|
+
try {
|
|
466
|
+
const response = await baseFetch(url, init(deadline.signal)).catch(
|
|
467
|
+
(error) => {
|
|
468
|
+
if (deadline.signal.aborted || n >= retry.maxRetries) throw error;
|
|
469
|
+
return void 0;
|
|
470
|
+
}
|
|
471
|
+
);
|
|
472
|
+
if (response === void 0) {
|
|
473
|
+
waitMs = backoffMs(n, retry.initialDelayMs);
|
|
474
|
+
} else if (n < retry.maxRetries && RETRYABLE_STATUS.has(response.status)) {
|
|
475
|
+
const error = await errorFrom(response);
|
|
476
|
+
const seconds = error.retryAfterSeconds;
|
|
477
|
+
if (seconds !== void 0 && seconds > MAX_RETRY_WAIT_SECONDS) {
|
|
478
|
+
throw error;
|
|
479
|
+
}
|
|
480
|
+
waitMs = seconds === void 0 ? backoffMs(n, retry.initialDelayMs) : seconds * 1e3;
|
|
481
|
+
} else {
|
|
482
|
+
return await readBody(response, markdown);
|
|
483
|
+
}
|
|
484
|
+
} finally {
|
|
485
|
+
deadline.clear();
|
|
486
|
+
}
|
|
487
|
+
await sleep(waitMs);
|
|
488
|
+
}
|
|
260
489
|
}
|
|
261
|
-
function
|
|
262
|
-
|
|
490
|
+
function withDeadline(signal, timeoutMs) {
|
|
491
|
+
const controller = new AbortController();
|
|
492
|
+
const abort = () => controller.abort(signal?.reason);
|
|
493
|
+
if (signal?.aborted) abort();
|
|
494
|
+
else signal?.addEventListener("abort", abort, { once: true });
|
|
495
|
+
const timer = setTimeout(
|
|
496
|
+
() => controller.abort(
|
|
497
|
+
new DOMException(
|
|
498
|
+
`Stophy request timed out after ${timeoutMs} ms`,
|
|
499
|
+
"TimeoutError"
|
|
500
|
+
)
|
|
501
|
+
),
|
|
502
|
+
timeoutMs
|
|
503
|
+
);
|
|
504
|
+
return {
|
|
505
|
+
signal: controller.signal,
|
|
506
|
+
clear: () => {
|
|
507
|
+
clearTimeout(timer);
|
|
508
|
+
signal?.removeEventListener("abort", abort);
|
|
509
|
+
}
|
|
510
|
+
};
|
|
263
511
|
}
|
|
264
|
-
function
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
512
|
+
async function readBody(response, markdown) {
|
|
513
|
+
if (!response.ok) throw await errorFrom(response);
|
|
514
|
+
const text = await response.text();
|
|
515
|
+
if (markdown) return text;
|
|
516
|
+
if (!text) {
|
|
517
|
+
throw failed(response, "Stophy returned an empty response", {});
|
|
518
|
+
}
|
|
519
|
+
try {
|
|
520
|
+
return JSON.parse(text);
|
|
521
|
+
} catch {
|
|
522
|
+
throw failed(response, "Stophy returned a non-JSON response", {});
|
|
523
|
+
}
|
|
270
524
|
}
|
|
271
|
-
function
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
525
|
+
async function errorFrom(response) {
|
|
526
|
+
const text = await response.text();
|
|
527
|
+
let body;
|
|
528
|
+
if (text) {
|
|
529
|
+
try {
|
|
530
|
+
body = JSON.parse(text);
|
|
531
|
+
} catch {
|
|
532
|
+
body = void 0;
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
const error = readError(body);
|
|
536
|
+
const retryAfterSeconds = error.retryAfterSeconds ?? headerRetryAfter(response);
|
|
537
|
+
return failed(
|
|
538
|
+
response,
|
|
539
|
+
error.message ?? `Stophy request failed with status ${response.status}`,
|
|
540
|
+
{
|
|
541
|
+
code: error.code,
|
|
542
|
+
retryable: error.retryable ?? RETRYABLE_STATUS.has(response.status),
|
|
543
|
+
retryAfterSeconds,
|
|
544
|
+
requestId: error.requestId ?? headerRequestId(response)
|
|
545
|
+
}
|
|
546
|
+
);
|
|
276
547
|
}
|
|
277
|
-
function
|
|
278
|
-
return
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
548
|
+
function failed(response, message, options) {
|
|
549
|
+
return new StophyError(message, {
|
|
550
|
+
status: response.status,
|
|
551
|
+
code: options.code,
|
|
552
|
+
retryable: options.retryable ?? false,
|
|
553
|
+
retryAfterSeconds: options.retryAfterSeconds,
|
|
554
|
+
requestId: options.requestId ?? headerRequestId(response)
|
|
282
555
|
});
|
|
283
556
|
}
|
|
557
|
+
function readError(body) {
|
|
558
|
+
if (!isRecord2(body) || !isRecord2(body.error)) return {};
|
|
559
|
+
const error = body.error;
|
|
560
|
+
return {
|
|
561
|
+
code: typeof error.code === "string" ? error.code : void 0,
|
|
562
|
+
message: typeof error.message === "string" ? error.message : void 0,
|
|
563
|
+
retryable: typeof error.retryable === "boolean" ? error.retryable : void 0,
|
|
564
|
+
retryAfterSeconds: typeof error.retryAfterSeconds === "number" ? error.retryAfterSeconds : void 0,
|
|
565
|
+
requestId: typeof error.requestId === "string" ? error.requestId : void 0
|
|
566
|
+
};
|
|
567
|
+
}
|
|
568
|
+
function isRecord2(value) {
|
|
569
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
570
|
+
}
|
|
571
|
+
function headerRequestId(response) {
|
|
572
|
+
return response.headers.get("x-request-id") ?? void 0;
|
|
573
|
+
}
|
|
574
|
+
function headerRetryAfter(response) {
|
|
575
|
+
const header = response.headers.get("retry-after");
|
|
576
|
+
if (!header) return void 0;
|
|
577
|
+
const seconds = Number(header);
|
|
578
|
+
if (Number.isFinite(seconds)) return seconds;
|
|
579
|
+
const date = Date.parse(header);
|
|
580
|
+
if (Number.isNaN(date)) return void 0;
|
|
581
|
+
return Math.max(0, Math.ceil((date - Date.now()) / 1e3));
|
|
582
|
+
}
|
|
583
|
+
function withQuery(url, query) {
|
|
584
|
+
if (!query) return url;
|
|
585
|
+
const params = new URLSearchParams();
|
|
586
|
+
for (const [key, value] of Object.entries(query)) {
|
|
587
|
+
if (value !== void 0) params.set(key, String(value));
|
|
588
|
+
}
|
|
589
|
+
const text = params.toString();
|
|
590
|
+
return text ? `${url}?${text}` : url;
|
|
591
|
+
}
|
|
592
|
+
function backoffMs(attempt, base) {
|
|
593
|
+
const window = base * 2 ** attempt;
|
|
594
|
+
return window / 2 + Math.random() * (window / 2);
|
|
595
|
+
}
|
|
596
|
+
function sleep(ms) {
|
|
597
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
598
|
+
}
|
|
284
599
|
|
|
285
600
|
// src/client.ts
|
|
286
601
|
function env(name) {
|
|
287
602
|
return typeof process === "undefined" ? void 0 : process.env[name];
|
|
288
603
|
}
|
|
289
604
|
var Stophy = class {
|
|
290
|
-
|
|
605
|
+
#call;
|
|
291
606
|
constructor(input = {}) {
|
|
292
607
|
const options = typeof input === "string" ? { apiKey: input } : input;
|
|
293
608
|
const apiKey = options.apiKey?.trim() || env("STOPHY_API_KEY")?.trim();
|
|
294
|
-
|
|
295
|
-
throw new Error(
|
|
296
|
-
"Stophy: provide `apiKey` or set the STOPHY_API_KEY environment variable."
|
|
297
|
-
);
|
|
298
|
-
}
|
|
299
|
-
this.client = createTransport({
|
|
609
|
+
this.#call = createCaller({
|
|
300
610
|
...options,
|
|
301
611
|
apiKey,
|
|
302
612
|
baseUrl: options.baseUrl ?? env("STOPHY_BASE_URL")
|
|
303
613
|
});
|
|
614
|
+
Object.assign(this, bindSurface(this.#call));
|
|
304
615
|
}
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
videoDetails(videoUrl) {
|
|
309
|
-
return videoDetails(this.client, videoUrl);
|
|
310
|
-
}
|
|
311
|
-
transcript(videoUrl) {
|
|
312
|
-
return transcript(this.client, videoUrl);
|
|
313
|
-
}
|
|
314
|
-
comments(videoUrl, options) {
|
|
315
|
-
return comments(this.client, videoUrl, options);
|
|
316
|
-
}
|
|
317
|
-
replies(continuationToken) {
|
|
318
|
-
return replies(this.client, continuationToken);
|
|
319
|
-
}
|
|
320
|
-
liveChat(videoUrl, options) {
|
|
321
|
-
return liveChat(this.client, videoUrl, options);
|
|
322
|
-
}
|
|
323
|
-
async search(queryOrBody, options) {
|
|
324
|
-
return search(this.client, queryOrBody, options);
|
|
325
|
-
}
|
|
326
|
-
async channel(urlOrBody, options) {
|
|
327
|
-
return channel(this.client, urlOrBody, options);
|
|
328
|
-
}
|
|
329
|
-
async playlist(urlOrBody, options) {
|
|
330
|
-
return playlist(this.client, urlOrBody, options);
|
|
331
|
-
}
|
|
332
|
-
async suggest(queryOrOptions, options) {
|
|
333
|
-
return suggest(this.client, queryOrOptions, options);
|
|
334
|
-
}
|
|
335
|
-
credits() {
|
|
336
|
-
return credits(this.client);
|
|
616
|
+
/** Current balance and lifetime usage. Requires an API key. */
|
|
617
|
+
usage() {
|
|
618
|
+
return usage(this.#call);
|
|
337
619
|
}
|
|
620
|
+
/** Recent metered requests. Requires an API key. */
|
|
338
621
|
logs(query) {
|
|
339
|
-
return logs(this
|
|
340
|
-
}
|
|
341
|
-
usage(query) {
|
|
342
|
-
return usage(this.client, query);
|
|
622
|
+
return logs(this.#call, query);
|
|
343
623
|
}
|
|
344
624
|
};
|
|
345
625
|
|