@natsuneko-laboratory/catalyst-sdk 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +0 -0
- package/dist/index.d.mts +548 -0
- package/dist/index.d.ts +548 -0
- package/dist/index.js +821 -0
- package/dist/index.mjs +771 -0
- package/package.json +42 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,821 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/index.ts
|
|
21
|
+
var index_exports = {};
|
|
22
|
+
__export(index_exports, {
|
|
23
|
+
ApiError: () => ApiError,
|
|
24
|
+
AuthInterceptor: () => AuthInterceptor,
|
|
25
|
+
CatalystClient: () => CatalystClient,
|
|
26
|
+
CatalystEndpoint: () => CatalystEndpoint,
|
|
27
|
+
CatalystError: () => CatalystError,
|
|
28
|
+
CatalystTS: () => CatalystTS,
|
|
29
|
+
EgeriaClient: () => EgeriaClient,
|
|
30
|
+
EgeriaEndpoint: () => EgeriaEndpoint,
|
|
31
|
+
HttpClient: () => HttpClient,
|
|
32
|
+
ISSUER_CATALYST_SYSTEM_MESSAGE: () => ISSUER_CATALYST_SYSTEM_MESSAGE,
|
|
33
|
+
ISSUER_CATALYST_USER_MESSAGE: () => ISSUER_CATALYST_USER_MESSAGE,
|
|
34
|
+
ISSUER_EGERIA_SYSTEM_MESSAGE: () => ISSUER_EGERIA_SYSTEM_MESSAGE,
|
|
35
|
+
LoggingInterceptor: () => LoggingInterceptor,
|
|
36
|
+
MediaClient: () => MediaClient,
|
|
37
|
+
MediaEndpoint: () => MediaEndpoint,
|
|
38
|
+
OAuth: () => OAuth,
|
|
39
|
+
OAuthError: () => OAuthError,
|
|
40
|
+
PKCE: () => PKCE,
|
|
41
|
+
PUBLIC_API_ENDPOINT: () => PUBLIC_API_ENDPOINT,
|
|
42
|
+
PUBLIC_AUTHORIZE_ENDPOINT: () => PUBLIC_AUTHORIZE_ENDPOINT,
|
|
43
|
+
PUBLIC_GRAPHQL_ENDPOINT: () => PUBLIC_GRAPHQL_ENDPOINT,
|
|
44
|
+
SteambirdClient: () => SteambirdClient,
|
|
45
|
+
SteambirdEndpoint: () => SteambirdEndpoint,
|
|
46
|
+
UserAgentInterceptor: () => UserAgentInterceptor
|
|
47
|
+
});
|
|
48
|
+
module.exports = __toCommonJS(index_exports);
|
|
49
|
+
|
|
50
|
+
// src/types/apiError.ts
|
|
51
|
+
var ApiError = class _ApiError extends Error {
|
|
52
|
+
constructor(message, statusCode, cause) {
|
|
53
|
+
super(message);
|
|
54
|
+
this.statusCode = statusCode;
|
|
55
|
+
this.cause = cause;
|
|
56
|
+
this.name = "ApiError";
|
|
57
|
+
}
|
|
58
|
+
static invalid() {
|
|
59
|
+
return new _ApiError("Invalid response");
|
|
60
|
+
}
|
|
61
|
+
static httpError(statusCode) {
|
|
62
|
+
return new _ApiError(`HTTP Error: ${statusCode}`, statusCode);
|
|
63
|
+
}
|
|
64
|
+
static decodingError(cause) {
|
|
65
|
+
return new _ApiError("Decoding error", void 0, cause);
|
|
66
|
+
}
|
|
67
|
+
static unauthorized() {
|
|
68
|
+
return new _ApiError("Unauthorized", 401);
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
var CatalystError = class extends Error {
|
|
72
|
+
constructor(message, code) {
|
|
73
|
+
super(message);
|
|
74
|
+
this.code = code;
|
|
75
|
+
this.name = "CatalystError";
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
// src/types/constants.ts
|
|
80
|
+
var PUBLIC_API_ENDPOINT = "https://api.natsuneko.com";
|
|
81
|
+
var PUBLIC_GRAPHQL_ENDPOINT = "https://graphql.natsuneko.com";
|
|
82
|
+
var PUBLIC_AUTHORIZE_ENDPOINT = "https://accounts.natsuneko.com/authorize";
|
|
83
|
+
|
|
84
|
+
// src/clients/httpClient.ts
|
|
85
|
+
var HttpClient = class {
|
|
86
|
+
constructor(interceptors = []) {
|
|
87
|
+
this.interceptors = interceptors;
|
|
88
|
+
}
|
|
89
|
+
buildRequest(endpoint) {
|
|
90
|
+
const url = new URL(endpoint.path, PUBLIC_API_ENDPOINT);
|
|
91
|
+
if (endpoint.queryParameters != null) {
|
|
92
|
+
for (const [key, value] of Object.entries(endpoint.queryParameters)) {
|
|
93
|
+
url.searchParams.set(key, value);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
const headers = new Headers(endpoint.headers);
|
|
97
|
+
let body;
|
|
98
|
+
if (endpoint.body != null) {
|
|
99
|
+
body = JSON.stringify(endpoint.body);
|
|
100
|
+
headers.set("Content-Type", "application/json");
|
|
101
|
+
}
|
|
102
|
+
return new Request(url.toString(), {
|
|
103
|
+
method: endpoint.method,
|
|
104
|
+
headers,
|
|
105
|
+
body
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
async request(endpoint) {
|
|
109
|
+
let req = this.buildRequest(endpoint);
|
|
110
|
+
for (const interceptor of this.interceptors) {
|
|
111
|
+
req = await interceptor.adapt(req);
|
|
112
|
+
}
|
|
113
|
+
const response = await this.executeWithRetry(req, endpoint);
|
|
114
|
+
const text = await response.text();
|
|
115
|
+
if (!text) throw new Error("Empty response body");
|
|
116
|
+
try {
|
|
117
|
+
return JSON.parse(text);
|
|
118
|
+
} catch (cause) {
|
|
119
|
+
throw ApiError.decodingError(cause);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
async requestVoid(endpoint) {
|
|
123
|
+
let req = this.buildRequest(endpoint);
|
|
124
|
+
for (const interceptor of this.interceptors) {
|
|
125
|
+
req = await interceptor.adapt(req);
|
|
126
|
+
}
|
|
127
|
+
await this.executeWithRetry(req, endpoint);
|
|
128
|
+
}
|
|
129
|
+
async requestRaw(endpoint) {
|
|
130
|
+
let req = this.buildRequest(endpoint);
|
|
131
|
+
for (const interceptor of this.interceptors) {
|
|
132
|
+
req = await interceptor.adapt(req);
|
|
133
|
+
}
|
|
134
|
+
const response = await this.executeWithRetry(req, endpoint);
|
|
135
|
+
return response.arrayBuffer();
|
|
136
|
+
}
|
|
137
|
+
async executeWithRetry(req, endpoint) {
|
|
138
|
+
const response = await fetch(req);
|
|
139
|
+
if (!response.ok) {
|
|
140
|
+
const error = ApiError.httpError(response.status);
|
|
141
|
+
for (const interceptor of this.interceptors) {
|
|
142
|
+
const shouldRetry = await interceptor.retry(req, error);
|
|
143
|
+
if (shouldRetry) {
|
|
144
|
+
return this.executeWithRetry(req, endpoint);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
throw error;
|
|
148
|
+
}
|
|
149
|
+
return response;
|
|
150
|
+
}
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
// src/endpoints/catalystEndpoint.ts
|
|
154
|
+
function buildTimelineParams(opts) {
|
|
155
|
+
const params = {};
|
|
156
|
+
if (opts.since != null) params["since"] = opts.since;
|
|
157
|
+
if (opts.until != null) params["until"] = opts.until;
|
|
158
|
+
return Object.keys(params).length > 0 ? params : void 0;
|
|
159
|
+
}
|
|
160
|
+
var CatalystEndpoint = {
|
|
161
|
+
createAlbum(data) {
|
|
162
|
+
return { path: "/catalyst/v1/album", method: "POST", body: data };
|
|
163
|
+
},
|
|
164
|
+
getAlbum(id, opts = {}) {
|
|
165
|
+
return {
|
|
166
|
+
path: `/catalyst/v1/album/by/id/${id}`,
|
|
167
|
+
method: "GET",
|
|
168
|
+
queryParameters: buildTimelineParams(opts)
|
|
169
|
+
};
|
|
170
|
+
},
|
|
171
|
+
editAlbum(id, data) {
|
|
172
|
+
return { path: `/catalyst/v1/album/by/id/${id}`, method: "PATCH", body: data };
|
|
173
|
+
},
|
|
174
|
+
insertToAlbum(id, data) {
|
|
175
|
+
return { path: `/catalyst/v1/album/by/id/${id}`, method: "PUT", body: data };
|
|
176
|
+
},
|
|
177
|
+
removeFromAlbum(id, data) {
|
|
178
|
+
return { path: `/catalyst/v1/album/by/id/${id}`, method: "PUT", body: data };
|
|
179
|
+
},
|
|
180
|
+
deleteAlbum(id) {
|
|
181
|
+
return { path: `/catalyst/v1/album/by/id/${id}`, method: "DELETE" };
|
|
182
|
+
},
|
|
183
|
+
listAlbums(username, includeSmartAlbums = false) {
|
|
184
|
+
return {
|
|
185
|
+
path: `/catalyst/v1/album/by/user/${username}`,
|
|
186
|
+
method: "GET",
|
|
187
|
+
queryParameters: { include_smart_albums: String(includeSmartAlbums) }
|
|
188
|
+
};
|
|
189
|
+
},
|
|
190
|
+
searchAlbum(q, includeSmartAlbums = false) {
|
|
191
|
+
return {
|
|
192
|
+
path: "/catalyst/v1/album/search",
|
|
193
|
+
method: "GET",
|
|
194
|
+
queryParameters: { q, include_smart_album: String(includeSmartAlbums) }
|
|
195
|
+
};
|
|
196
|
+
},
|
|
197
|
+
customReactions() {
|
|
198
|
+
return { path: "/catalyst/v1/reactions", method: "GET" };
|
|
199
|
+
},
|
|
200
|
+
relationships(id) {
|
|
201
|
+
return { path: `/catalyst/v1/relationships/${id}`, method: "GET" };
|
|
202
|
+
},
|
|
203
|
+
follow(data) {
|
|
204
|
+
return { path: "/catalyst/v1/relationships", method: "POST", body: data };
|
|
205
|
+
},
|
|
206
|
+
remove(data) {
|
|
207
|
+
return { path: "/catalyst/v1/relationships", method: "DELETE", body: data };
|
|
208
|
+
},
|
|
209
|
+
createSmartAlbum(data) {
|
|
210
|
+
return { path: "/catalyst/v1/smart-album", method: "POST", body: data };
|
|
211
|
+
},
|
|
212
|
+
getSmartAlbum(id, opts = {}) {
|
|
213
|
+
return {
|
|
214
|
+
path: `/catalyst/v1/smart-album/by/id/${id}`,
|
|
215
|
+
method: "GET",
|
|
216
|
+
queryParameters: buildTimelineParams(opts)
|
|
217
|
+
};
|
|
218
|
+
},
|
|
219
|
+
editSmartAlbum(id, data) {
|
|
220
|
+
return { path: `/catalyst/v1/smart-album/by/id/${id}`, method: "PATCH", body: data };
|
|
221
|
+
},
|
|
222
|
+
deleteSmartAlbum(id) {
|
|
223
|
+
return { path: `/catalyst/v1/smart-album/by/id/${id}`, method: "DELETE" };
|
|
224
|
+
},
|
|
225
|
+
searchSmartAlbum(q) {
|
|
226
|
+
return { path: "/catalyst/v1/smart-album/search", method: "GET", queryParameters: { q } };
|
|
227
|
+
},
|
|
228
|
+
createStatus(data) {
|
|
229
|
+
return { path: "/catalyst/v1/status", method: "POST", body: data };
|
|
230
|
+
},
|
|
231
|
+
getStatus(id) {
|
|
232
|
+
return { path: `/catalyst/v1.1/status/${id}`, method: "GET" };
|
|
233
|
+
},
|
|
234
|
+
editStatus(id, data) {
|
|
235
|
+
return { path: `/catalyst/v1/status/${id}`, method: "PATCH", body: data };
|
|
236
|
+
},
|
|
237
|
+
deleteStatus(id) {
|
|
238
|
+
return { path: `/catalyst/v1/status/${id}`, method: "DELETE" };
|
|
239
|
+
},
|
|
240
|
+
isFavorited(id) {
|
|
241
|
+
return { path: `/catalyst/v1/status/${id}/favorite`, method: "GET" };
|
|
242
|
+
},
|
|
243
|
+
favorite(id) {
|
|
244
|
+
return { path: `/catalyst/v1/status/${id}/favorite`, method: "POST" };
|
|
245
|
+
},
|
|
246
|
+
unfavorite(id) {
|
|
247
|
+
return { path: `/catalyst/v1/status/${id}/favorite`, method: "DELETE" };
|
|
248
|
+
},
|
|
249
|
+
reactions(id) {
|
|
250
|
+
return { path: `/catalyst/v1/status/${id}/reactions`, method: "GET" };
|
|
251
|
+
},
|
|
252
|
+
react(id, symbol) {
|
|
253
|
+
return { path: `/catalyst/v1/status/${id}/reactions/${symbol}`, method: "POST" };
|
|
254
|
+
},
|
|
255
|
+
unreact(id, symbol) {
|
|
256
|
+
return { path: `/catalyst/v1/status/${id}/reactions/${symbol}`, method: "DELETE" };
|
|
257
|
+
},
|
|
258
|
+
contestTimeline(slug, opts = {}) {
|
|
259
|
+
return {
|
|
260
|
+
path: `/catalyst/v1/timeline/contest/by/slug/${slug}`,
|
|
261
|
+
method: "GET",
|
|
262
|
+
queryParameters: buildTimelineParams(opts)
|
|
263
|
+
};
|
|
264
|
+
},
|
|
265
|
+
favoriteTimeline(opts = {}) {
|
|
266
|
+
return {
|
|
267
|
+
path: "/catalyst/v1/timeline/favorite",
|
|
268
|
+
method: "GET",
|
|
269
|
+
queryParameters: buildTimelineParams(opts)
|
|
270
|
+
};
|
|
271
|
+
},
|
|
272
|
+
firehoseTimeline(opts = {}) {
|
|
273
|
+
return {
|
|
274
|
+
path: "/catalyst/v1.1/timeline/firehose",
|
|
275
|
+
method: "GET",
|
|
276
|
+
queryParameters: buildTimelineParams(opts)
|
|
277
|
+
};
|
|
278
|
+
},
|
|
279
|
+
galleryTimeline(opts = {}) {
|
|
280
|
+
return {
|
|
281
|
+
path: "/catalyst/v1/timeline/gallery",
|
|
282
|
+
method: "GET",
|
|
283
|
+
queryParameters: buildTimelineParams(opts)
|
|
284
|
+
};
|
|
285
|
+
},
|
|
286
|
+
homeTimeline(opts = {}) {
|
|
287
|
+
return {
|
|
288
|
+
path: "/catalyst/v1.1/timeline/home",
|
|
289
|
+
method: "GET",
|
|
290
|
+
queryParameters: buildTimelineParams(opts)
|
|
291
|
+
};
|
|
292
|
+
},
|
|
293
|
+
searchTimeline(opts = {}) {
|
|
294
|
+
const params = {};
|
|
295
|
+
if (opts.q != null) params["q"] = opts.q;
|
|
296
|
+
if (opts.exact != null) params["exact"] = String(opts.exact);
|
|
297
|
+
if (opts.since != null) params["since"] = opts.since;
|
|
298
|
+
if (opts.until != null) params["until"] = opts.until;
|
|
299
|
+
return {
|
|
300
|
+
path: "/catalyst/v1/timeline/search",
|
|
301
|
+
method: "GET",
|
|
302
|
+
queryParameters: Object.keys(params).length > 0 ? params : void 0
|
|
303
|
+
};
|
|
304
|
+
},
|
|
305
|
+
userTimeline(username, opts = {}) {
|
|
306
|
+
const params = {};
|
|
307
|
+
if (opts.trimUser != null) params["trim_user"] = String(opts.trimUser);
|
|
308
|
+
if (opts.excludeSensitive != null) params["exclude_sensitive"] = String(opts.excludeSensitive);
|
|
309
|
+
if (opts.since != null) params["since"] = opts.since;
|
|
310
|
+
if (opts.until != null) params["until"] = opts.until;
|
|
311
|
+
return {
|
|
312
|
+
path: `/catalyst/v1/timeline/user/by/username/${username}`,
|
|
313
|
+
method: "GET",
|
|
314
|
+
queryParameters: Object.keys(params).length > 0 ? params : void 0
|
|
315
|
+
};
|
|
316
|
+
},
|
|
317
|
+
userGalleryTimeline(username, opts = {}) {
|
|
318
|
+
return {
|
|
319
|
+
path: `/catalyst/v1/timeline/user/by/username/${username}/gallery`,
|
|
320
|
+
method: "GET",
|
|
321
|
+
queryParameters: buildTimelineParams(opts)
|
|
322
|
+
};
|
|
323
|
+
},
|
|
324
|
+
trend() {
|
|
325
|
+
return { path: "/catalyst/v1/trend", method: "GET" };
|
|
326
|
+
}
|
|
327
|
+
};
|
|
328
|
+
|
|
329
|
+
// src/clients/catalystClient.ts
|
|
330
|
+
var CatalystClient = class {
|
|
331
|
+
constructor(http) {
|
|
332
|
+
this.http = http;
|
|
333
|
+
}
|
|
334
|
+
// Albums
|
|
335
|
+
createAlbum(data) {
|
|
336
|
+
return this.http.request(CatalystEndpoint.createAlbum(data));
|
|
337
|
+
}
|
|
338
|
+
getAlbum(id, opts = {}) {
|
|
339
|
+
return this.http.request(CatalystEndpoint.getAlbum(id, opts));
|
|
340
|
+
}
|
|
341
|
+
editAlbum(id, data) {
|
|
342
|
+
return this.http.requestVoid(CatalystEndpoint.editAlbum(id, data));
|
|
343
|
+
}
|
|
344
|
+
insertToAlbum(id, data) {
|
|
345
|
+
return this.http.requestVoid(CatalystEndpoint.insertToAlbum(id, data));
|
|
346
|
+
}
|
|
347
|
+
removeFromAlbum(id, data) {
|
|
348
|
+
return this.http.requestVoid(CatalystEndpoint.removeFromAlbum(id, data));
|
|
349
|
+
}
|
|
350
|
+
deleteAlbum(id) {
|
|
351
|
+
return this.http.requestVoid(CatalystEndpoint.deleteAlbum(id));
|
|
352
|
+
}
|
|
353
|
+
listAlbums(username, includeSmartAlbums = true) {
|
|
354
|
+
return this.http.request(CatalystEndpoint.listAlbums(username, includeSmartAlbums));
|
|
355
|
+
}
|
|
356
|
+
searchAlbums(q, includeSmartAlbums = true) {
|
|
357
|
+
return this.http.request(CatalystEndpoint.searchAlbum(q, includeSmartAlbums));
|
|
358
|
+
}
|
|
359
|
+
// Reactions
|
|
360
|
+
customReactions() {
|
|
361
|
+
return this.http.request(CatalystEndpoint.customReactions());
|
|
362
|
+
}
|
|
363
|
+
// Relationships
|
|
364
|
+
relationships(id) {
|
|
365
|
+
return this.http.request(CatalystEndpoint.relationships(id));
|
|
366
|
+
}
|
|
367
|
+
follow(data) {
|
|
368
|
+
return this.http.requestVoid(CatalystEndpoint.follow(data));
|
|
369
|
+
}
|
|
370
|
+
remove(data) {
|
|
371
|
+
return this.http.requestVoid(CatalystEndpoint.remove(data));
|
|
372
|
+
}
|
|
373
|
+
// Smart Albums
|
|
374
|
+
createSmartAlbum(data) {
|
|
375
|
+
return this.http.request(CatalystEndpoint.createSmartAlbum(data));
|
|
376
|
+
}
|
|
377
|
+
getSmartAlbum(id, opts = {}) {
|
|
378
|
+
return this.http.request(CatalystEndpoint.getSmartAlbum(id, opts));
|
|
379
|
+
}
|
|
380
|
+
editSmartAlbum(id, data) {
|
|
381
|
+
return this.http.requestVoid(CatalystEndpoint.editSmartAlbum(id, data));
|
|
382
|
+
}
|
|
383
|
+
deleteSmartAlbum(id) {
|
|
384
|
+
return this.http.requestVoid(CatalystEndpoint.deleteSmartAlbum(id));
|
|
385
|
+
}
|
|
386
|
+
searchSmartAlbum(q) {
|
|
387
|
+
return this.http.request(CatalystEndpoint.searchSmartAlbum(q));
|
|
388
|
+
}
|
|
389
|
+
// Statuses
|
|
390
|
+
createStatus(data) {
|
|
391
|
+
return this.http.request(CatalystEndpoint.createStatus(data));
|
|
392
|
+
}
|
|
393
|
+
getStatus(id) {
|
|
394
|
+
return this.http.request(CatalystEndpoint.getStatus(id));
|
|
395
|
+
}
|
|
396
|
+
editStatus(id, data) {
|
|
397
|
+
return this.http.requestVoid(CatalystEndpoint.editStatus(id, data));
|
|
398
|
+
}
|
|
399
|
+
deleteStatus(id) {
|
|
400
|
+
return this.http.requestVoid(CatalystEndpoint.deleteStatus(id));
|
|
401
|
+
}
|
|
402
|
+
isFavorited(id) {
|
|
403
|
+
return this.http.request(CatalystEndpoint.isFavorited(id));
|
|
404
|
+
}
|
|
405
|
+
favorite(id) {
|
|
406
|
+
return this.http.requestVoid(CatalystEndpoint.favorite(id));
|
|
407
|
+
}
|
|
408
|
+
unfavorite(id) {
|
|
409
|
+
return this.http.requestVoid(CatalystEndpoint.unfavorite(id));
|
|
410
|
+
}
|
|
411
|
+
reactions(id) {
|
|
412
|
+
return this.http.request(CatalystEndpoint.reactions(id));
|
|
413
|
+
}
|
|
414
|
+
react(id, symbol) {
|
|
415
|
+
return this.http.requestVoid(CatalystEndpoint.react(id, symbol));
|
|
416
|
+
}
|
|
417
|
+
unreact(id, symbol) {
|
|
418
|
+
return this.http.requestVoid(CatalystEndpoint.unreact(id, symbol));
|
|
419
|
+
}
|
|
420
|
+
// Timelines
|
|
421
|
+
contestTimeline(slug, opts = {}) {
|
|
422
|
+
return this.http.request(CatalystEndpoint.contestTimeline(slug, opts));
|
|
423
|
+
}
|
|
424
|
+
favoriteTimeline(opts = {}) {
|
|
425
|
+
return this.http.request(CatalystEndpoint.favoriteTimeline(opts));
|
|
426
|
+
}
|
|
427
|
+
firehoseTimeline(opts = {}) {
|
|
428
|
+
return this.http.request(CatalystEndpoint.firehoseTimeline(opts));
|
|
429
|
+
}
|
|
430
|
+
galleryTimeline(opts = {}) {
|
|
431
|
+
return this.http.request(CatalystEndpoint.galleryTimeline(opts));
|
|
432
|
+
}
|
|
433
|
+
homeTimeline(opts = {}) {
|
|
434
|
+
return this.http.request(CatalystEndpoint.homeTimeline(opts));
|
|
435
|
+
}
|
|
436
|
+
searchTimeline(opts = {}) {
|
|
437
|
+
return this.http.request(CatalystEndpoint.searchTimeline(opts));
|
|
438
|
+
}
|
|
439
|
+
userTimeline(username, opts = {}) {
|
|
440
|
+
return this.http.request(CatalystEndpoint.userTimeline(username, opts));
|
|
441
|
+
}
|
|
442
|
+
userGalleryTimeline(username, opts = {}) {
|
|
443
|
+
return this.http.request(CatalystEndpoint.userGalleryTimeline(username, opts));
|
|
444
|
+
}
|
|
445
|
+
trend() {
|
|
446
|
+
return this.http.request(CatalystEndpoint.trend());
|
|
447
|
+
}
|
|
448
|
+
};
|
|
449
|
+
|
|
450
|
+
// src/endpoints/egeriaEndpoint.ts
|
|
451
|
+
var EgeriaEndpoint = {
|
|
452
|
+
me() {
|
|
453
|
+
return { path: "/egeria/v1/me", method: "GET" };
|
|
454
|
+
},
|
|
455
|
+
update(data) {
|
|
456
|
+
return { path: "/egeria/v1/me", method: "PATCH", body: data };
|
|
457
|
+
},
|
|
458
|
+
search(q) {
|
|
459
|
+
return { path: "/egeria/v1/search", method: "GET", queryParameters: { q } };
|
|
460
|
+
},
|
|
461
|
+
userById(id) {
|
|
462
|
+
return { path: `/egeria/v1/user/by/id/${id}`, method: "GET" };
|
|
463
|
+
},
|
|
464
|
+
userByUsername(username) {
|
|
465
|
+
return { path: `/egeria/v1/user/by/username/${username}`, method: "GET" };
|
|
466
|
+
}
|
|
467
|
+
};
|
|
468
|
+
|
|
469
|
+
// src/clients/egeriaClient.ts
|
|
470
|
+
var EgeriaClient = class {
|
|
471
|
+
constructor(http) {
|
|
472
|
+
this.http = http;
|
|
473
|
+
}
|
|
474
|
+
me() {
|
|
475
|
+
return this.http.request(EgeriaEndpoint.me());
|
|
476
|
+
}
|
|
477
|
+
update(data) {
|
|
478
|
+
return this.http.requestVoid(EgeriaEndpoint.update(data));
|
|
479
|
+
}
|
|
480
|
+
search(q) {
|
|
481
|
+
return this.http.request(EgeriaEndpoint.search(q));
|
|
482
|
+
}
|
|
483
|
+
userById(id) {
|
|
484
|
+
return this.http.request(EgeriaEndpoint.userById(id));
|
|
485
|
+
}
|
|
486
|
+
userByUsername(username) {
|
|
487
|
+
return this.http.request(EgeriaEndpoint.userByUsername(username));
|
|
488
|
+
}
|
|
489
|
+
};
|
|
490
|
+
|
|
491
|
+
// src/endpoints/mediaEndpoint.ts
|
|
492
|
+
var MediaEndpoint = {
|
|
493
|
+
download(data) {
|
|
494
|
+
return { path: "/media/v1/download", method: "POST", body: data };
|
|
495
|
+
},
|
|
496
|
+
delete(data) {
|
|
497
|
+
return { path: "/media/v1/upload", method: "DELETE", body: data };
|
|
498
|
+
},
|
|
499
|
+
upload() {
|
|
500
|
+
return { path: "/media/v2/upload", method: "POST" };
|
|
501
|
+
}
|
|
502
|
+
};
|
|
503
|
+
|
|
504
|
+
// src/clients/mediaClient.ts
|
|
505
|
+
var MediaClient = class {
|
|
506
|
+
constructor(http) {
|
|
507
|
+
this.http = http;
|
|
508
|
+
}
|
|
509
|
+
download(data) {
|
|
510
|
+
return this.http.requestRaw(MediaEndpoint.download(data));
|
|
511
|
+
}
|
|
512
|
+
delete(data) {
|
|
513
|
+
return this.http.requestVoid(MediaEndpoint.delete(data));
|
|
514
|
+
}
|
|
515
|
+
upload() {
|
|
516
|
+
return this.http.request(MediaEndpoint.upload());
|
|
517
|
+
}
|
|
518
|
+
};
|
|
519
|
+
|
|
520
|
+
// src/endpoints/steambirdEndpoint.ts
|
|
521
|
+
var SteambirdEndpoint = {
|
|
522
|
+
notifications(issuer, opts = {}) {
|
|
523
|
+
const params = { issuer };
|
|
524
|
+
if (opts.since != null) params["since"] = opts.since;
|
|
525
|
+
if (opts.until != null) params["until"] = opts.until;
|
|
526
|
+
return { path: "/steambird/v1/notifications", method: "GET", queryParameters: params };
|
|
527
|
+
},
|
|
528
|
+
read(id) {
|
|
529
|
+
return { path: `/steambird/v1/notifications/${id}`, method: "POST" };
|
|
530
|
+
},
|
|
531
|
+
readAll(issuer) {
|
|
532
|
+
return {
|
|
533
|
+
path: "/steambird/v1/notifications/all",
|
|
534
|
+
method: "POST",
|
|
535
|
+
queryParameters: issuer != null ? { issuer } : void 0
|
|
536
|
+
};
|
|
537
|
+
},
|
|
538
|
+
unreads(issuers = []) {
|
|
539
|
+
return {
|
|
540
|
+
path: "/steambird/v1/notifications/unread",
|
|
541
|
+
method: "GET",
|
|
542
|
+
queryParameters: issuers.length > 0 ? { issuers: issuers.join(",") } : void 0
|
|
543
|
+
};
|
|
544
|
+
}
|
|
545
|
+
};
|
|
546
|
+
|
|
547
|
+
// src/clients/steambirdClient.ts
|
|
548
|
+
var ISSUER_CATALYST_SYSTEM_MESSAGE = "natsuneko-laboratory:catalyst";
|
|
549
|
+
var ISSUER_CATALYST_USER_MESSAGE = "natsuneko-laboratory:catalyst-message";
|
|
550
|
+
var ISSUER_EGERIA_SYSTEM_MESSAGE = "natsuneko-laboratory:egeria";
|
|
551
|
+
var SteambirdClient = class {
|
|
552
|
+
constructor(http) {
|
|
553
|
+
this.http = http;
|
|
554
|
+
}
|
|
555
|
+
ISSUER_CATALYST_SYSTEM_MESSAGE = ISSUER_CATALYST_SYSTEM_MESSAGE;
|
|
556
|
+
ISSUER_CATALYST_USER_MESSAGE = ISSUER_CATALYST_USER_MESSAGE;
|
|
557
|
+
ISSUER_EGERIA_SYSTEM_MESSAGE = ISSUER_EGERIA_SYSTEM_MESSAGE;
|
|
558
|
+
notifications(issuer, opts = {}) {
|
|
559
|
+
return this.http.request(SteambirdEndpoint.notifications(issuer, opts));
|
|
560
|
+
}
|
|
561
|
+
read(id) {
|
|
562
|
+
return this.http.requestVoid(SteambirdEndpoint.read(id));
|
|
563
|
+
}
|
|
564
|
+
readAll(issuer) {
|
|
565
|
+
return this.http.requestVoid(SteambirdEndpoint.readAll(issuer));
|
|
566
|
+
}
|
|
567
|
+
unreads(issuers = []) {
|
|
568
|
+
return this.http.request(SteambirdEndpoint.unreads(issuers));
|
|
569
|
+
}
|
|
570
|
+
};
|
|
571
|
+
|
|
572
|
+
// src/interceptors/authInterceptor.ts
|
|
573
|
+
var AuthInterceptor = class {
|
|
574
|
+
constructor(tokenProvider) {
|
|
575
|
+
this.tokenProvider = tokenProvider;
|
|
576
|
+
}
|
|
577
|
+
retryCounts = /* @__PURE__ */ new Map();
|
|
578
|
+
maxRetryCount = 5;
|
|
579
|
+
async adapt(request) {
|
|
580
|
+
const token = await this.tokenProvider();
|
|
581
|
+
if (token == null) return request;
|
|
582
|
+
const headers = new Headers(request.headers);
|
|
583
|
+
headers.set("Authorization", `Bearer ${token}`);
|
|
584
|
+
return new Request(request, { headers });
|
|
585
|
+
}
|
|
586
|
+
async retry(request, error) {
|
|
587
|
+
if (!(error instanceof ApiError) || error.statusCode !== 401) return false;
|
|
588
|
+
const key = this.makeRequestKey(request);
|
|
589
|
+
const count = this.retryCounts.get(key) ?? 0;
|
|
590
|
+
if (count >= this.maxRetryCount) {
|
|
591
|
+
this.retryCounts.delete(key);
|
|
592
|
+
return false;
|
|
593
|
+
}
|
|
594
|
+
this.retryCounts.set(key, count + 1);
|
|
595
|
+
return true;
|
|
596
|
+
}
|
|
597
|
+
makeRequestKey(request) {
|
|
598
|
+
return `${request.method}:${request.url}`;
|
|
599
|
+
}
|
|
600
|
+
};
|
|
601
|
+
|
|
602
|
+
// src/interceptors/userAgentInterceptor.ts
|
|
603
|
+
var UserAgentInterceptor = class {
|
|
604
|
+
agent;
|
|
605
|
+
constructor() {
|
|
606
|
+
this.agent = "CatalystTS/0.1.0";
|
|
607
|
+
}
|
|
608
|
+
async adapt(request) {
|
|
609
|
+
const headers = new Headers(request.headers);
|
|
610
|
+
headers.set("User-Agent", this.agent);
|
|
611
|
+
return new Request(request, { headers });
|
|
612
|
+
}
|
|
613
|
+
async retry(_request, _error) {
|
|
614
|
+
return false;
|
|
615
|
+
}
|
|
616
|
+
};
|
|
617
|
+
|
|
618
|
+
// src/oauth/oauth.ts
|
|
619
|
+
var OAuthError = class extends Error {
|
|
620
|
+
constructor(message, kind, info) {
|
|
621
|
+
super(message);
|
|
622
|
+
this.kind = kind;
|
|
623
|
+
this.info = info;
|
|
624
|
+
this.name = "OAuthError";
|
|
625
|
+
}
|
|
626
|
+
};
|
|
627
|
+
var OAuth = class {
|
|
628
|
+
constructor(clientId, clientSecret) {
|
|
629
|
+
this.clientId = clientId;
|
|
630
|
+
this.clientSecret = clientSecret;
|
|
631
|
+
}
|
|
632
|
+
async getAccessTokenByCode(code, redirectUri, pkce) {
|
|
633
|
+
const body = new URLSearchParams({
|
|
634
|
+
grant_type: "authorization_code",
|
|
635
|
+
code,
|
|
636
|
+
redirect_uri: redirectUri,
|
|
637
|
+
client_id: this.clientId,
|
|
638
|
+
code_verifier: pkce.verifier
|
|
639
|
+
});
|
|
640
|
+
return this.postToken(body);
|
|
641
|
+
}
|
|
642
|
+
async getAccessTokenByRefreshToken(refreshToken) {
|
|
643
|
+
const body = new URLSearchParams({
|
|
644
|
+
grant_type: "refresh_token",
|
|
645
|
+
refresh_token: refreshToken,
|
|
646
|
+
client_id: this.clientId,
|
|
647
|
+
client_secret: this.clientSecret
|
|
648
|
+
});
|
|
649
|
+
return this.postToken(body);
|
|
650
|
+
}
|
|
651
|
+
getAuthorizeURL(redirectUri, pkce, state) {
|
|
652
|
+
const url = new URL(PUBLIC_AUTHORIZE_ENDPOINT);
|
|
653
|
+
url.searchParams.set("response_type", "code");
|
|
654
|
+
url.searchParams.set("client_id", this.clientId);
|
|
655
|
+
url.searchParams.set("redirect_uri", redirectUri);
|
|
656
|
+
url.searchParams.set("state", state);
|
|
657
|
+
url.searchParams.set("code_challenge", pkce.challenge);
|
|
658
|
+
url.searchParams.set("code_challenge_method", pkce.method);
|
|
659
|
+
return url;
|
|
660
|
+
}
|
|
661
|
+
getAuthorizationCode(callbackUrl, expectedState, expectedRedirectUri) {
|
|
662
|
+
this.verifyAuthorizationResponse(callbackUrl, expectedState, expectedRedirectUri);
|
|
663
|
+
const error = callbackUrl.searchParams.get("error");
|
|
664
|
+
if (error != null) {
|
|
665
|
+
throw new OAuthError("Authorization request failed", "authorizationRequestFailed", {
|
|
666
|
+
error,
|
|
667
|
+
description: callbackUrl.searchParams.get("error_description") ?? void 0,
|
|
668
|
+
uri: callbackUrl.searchParams.get("error_uri") ?? void 0
|
|
669
|
+
});
|
|
670
|
+
}
|
|
671
|
+
const code = callbackUrl.searchParams.get("code");
|
|
672
|
+
if (code == null) throw new OAuthError("Invalid authorization response", "invalidAuthorizationResponse");
|
|
673
|
+
return code;
|
|
674
|
+
}
|
|
675
|
+
verifyAuthorizationResponse(url, expectedState, expectedRedirectUri) {
|
|
676
|
+
if (!url.href.startsWith(expectedRedirectUri + "?")) {
|
|
677
|
+
throw new OAuthError("Invalid authorization response", "invalidAuthorizationResponse");
|
|
678
|
+
}
|
|
679
|
+
if (url.searchParams.get("state") !== expectedState) {
|
|
680
|
+
throw new OAuthError("Invalid authorization response", "invalidAuthorizationResponse");
|
|
681
|
+
}
|
|
682
|
+
}
|
|
683
|
+
async postToken(body) {
|
|
684
|
+
const response = await fetch(`${PUBLIC_API_ENDPOINT}/token`, {
|
|
685
|
+
method: "POST",
|
|
686
|
+
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
|
687
|
+
body: body.toString()
|
|
688
|
+
});
|
|
689
|
+
if (!response.ok) {
|
|
690
|
+
throw new OAuthError("Invalid token response", "invalidTokenResponse");
|
|
691
|
+
}
|
|
692
|
+
const json = await response.json();
|
|
693
|
+
return {
|
|
694
|
+
accessToken: json["access_token"],
|
|
695
|
+
refreshToken: json["refresh_token"],
|
|
696
|
+
tokenType: json["token_type"]
|
|
697
|
+
};
|
|
698
|
+
}
|
|
699
|
+
};
|
|
700
|
+
|
|
701
|
+
// src/CatalystTS.ts
|
|
702
|
+
var CatalystTS = class {
|
|
703
|
+
clientId;
|
|
704
|
+
clientSecret;
|
|
705
|
+
_accessToken;
|
|
706
|
+
_refreshToken;
|
|
707
|
+
http;
|
|
708
|
+
constructor(opts) {
|
|
709
|
+
this.clientId = opts.clientId;
|
|
710
|
+
this.clientSecret = opts.clientSecret;
|
|
711
|
+
this._accessToken = opts.accessToken;
|
|
712
|
+
this._refreshToken = opts.refreshToken;
|
|
713
|
+
const interceptors = [
|
|
714
|
+
...opts.interceptors ?? [],
|
|
715
|
+
new AuthInterceptor(() => Promise.resolve(this._accessToken)),
|
|
716
|
+
new UserAgentInterceptor()
|
|
717
|
+
];
|
|
718
|
+
this.http = new HttpClient(interceptors);
|
|
719
|
+
}
|
|
720
|
+
get accessToken() {
|
|
721
|
+
return this._accessToken;
|
|
722
|
+
}
|
|
723
|
+
get refreshToken() {
|
|
724
|
+
return this._refreshToken;
|
|
725
|
+
}
|
|
726
|
+
setCredential(accessToken, refreshToken) {
|
|
727
|
+
this._accessToken = accessToken;
|
|
728
|
+
this._refreshToken = refreshToken;
|
|
729
|
+
}
|
|
730
|
+
async refresh() {
|
|
731
|
+
if (this._refreshToken == null) throw new Error("refreshToken is not set");
|
|
732
|
+
const token = await this.oauth.getAccessTokenByRefreshToken(this._refreshToken);
|
|
733
|
+
this._accessToken = token.accessToken;
|
|
734
|
+
this._refreshToken = token.refreshToken;
|
|
735
|
+
return token;
|
|
736
|
+
}
|
|
737
|
+
get oauth() {
|
|
738
|
+
return new OAuth(this.clientId, this.clientSecret);
|
|
739
|
+
}
|
|
740
|
+
get catalyst() {
|
|
741
|
+
return new CatalystClient(this.http);
|
|
742
|
+
}
|
|
743
|
+
get egeria() {
|
|
744
|
+
return new EgeriaClient(this.http);
|
|
745
|
+
}
|
|
746
|
+
get media() {
|
|
747
|
+
return new MediaClient(this.http);
|
|
748
|
+
}
|
|
749
|
+
get steambird() {
|
|
750
|
+
return new SteambirdClient(this.http);
|
|
751
|
+
}
|
|
752
|
+
};
|
|
753
|
+
|
|
754
|
+
// src/interceptors/loggingInterceptor.ts
|
|
755
|
+
var LoggingInterceptor = class {
|
|
756
|
+
async adapt(request) {
|
|
757
|
+
console.log(`[CatalystTS] ${request.method} ${request.url}`);
|
|
758
|
+
return request;
|
|
759
|
+
}
|
|
760
|
+
async retry(request, error) {
|
|
761
|
+
console.log(`[CatalystTS] Retry ${request.method} ${request.url}`, error);
|
|
762
|
+
return false;
|
|
763
|
+
}
|
|
764
|
+
};
|
|
765
|
+
|
|
766
|
+
// src/oauth/pkce.ts
|
|
767
|
+
var import_js_sha256 = require("js-sha256");
|
|
768
|
+
var PKCE = class _PKCE {
|
|
769
|
+
constructor(verifier, challenge) {
|
|
770
|
+
this.verifier = verifier;
|
|
771
|
+
this.challenge = challenge;
|
|
772
|
+
}
|
|
773
|
+
method = "S256";
|
|
774
|
+
static async create() {
|
|
775
|
+
const verifier = _PKCE.generateVerifier();
|
|
776
|
+
const challenge = await _PKCE.computeChallenge(verifier);
|
|
777
|
+
return new _PKCE(verifier, challenge);
|
|
778
|
+
}
|
|
779
|
+
static generateVerifier() {
|
|
780
|
+
const bytes = new Uint8Array(32);
|
|
781
|
+
globalThis.crypto.getRandomValues(bytes);
|
|
782
|
+
return _PKCE.base64url(bytes);
|
|
783
|
+
}
|
|
784
|
+
static async computeChallenge(verifier) {
|
|
785
|
+
const encoded = new TextEncoder().encode(verifier);
|
|
786
|
+
const hash = import_js_sha256.sha256.create();
|
|
787
|
+
hash.update(encoded);
|
|
788
|
+
const digest = hash.array();
|
|
789
|
+
return _PKCE.base64url(new Uint8Array(digest));
|
|
790
|
+
}
|
|
791
|
+
static base64url(bytes) {
|
|
792
|
+
return btoa(String.fromCharCode(...bytes)).replace(/\+/g, "-").replace(/\//g, "_").replace(/=/g, "");
|
|
793
|
+
}
|
|
794
|
+
};
|
|
795
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
796
|
+
0 && (module.exports = {
|
|
797
|
+
ApiError,
|
|
798
|
+
AuthInterceptor,
|
|
799
|
+
CatalystClient,
|
|
800
|
+
CatalystEndpoint,
|
|
801
|
+
CatalystError,
|
|
802
|
+
CatalystTS,
|
|
803
|
+
EgeriaClient,
|
|
804
|
+
EgeriaEndpoint,
|
|
805
|
+
HttpClient,
|
|
806
|
+
ISSUER_CATALYST_SYSTEM_MESSAGE,
|
|
807
|
+
ISSUER_CATALYST_USER_MESSAGE,
|
|
808
|
+
ISSUER_EGERIA_SYSTEM_MESSAGE,
|
|
809
|
+
LoggingInterceptor,
|
|
810
|
+
MediaClient,
|
|
811
|
+
MediaEndpoint,
|
|
812
|
+
OAuth,
|
|
813
|
+
OAuthError,
|
|
814
|
+
PKCE,
|
|
815
|
+
PUBLIC_API_ENDPOINT,
|
|
816
|
+
PUBLIC_AUTHORIZE_ENDPOINT,
|
|
817
|
+
PUBLIC_GRAPHQL_ENDPOINT,
|
|
818
|
+
SteambirdClient,
|
|
819
|
+
SteambirdEndpoint,
|
|
820
|
+
UserAgentInterceptor
|
|
821
|
+
});
|