@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.
@@ -0,0 +1,548 @@
1
+ type HttpMethod = "GET" | "POST" | "PUT" | "PATCH" | "DELETE";
2
+
3
+ interface Endpoint {
4
+ readonly path: string;
5
+ readonly method: HttpMethod;
6
+ readonly headers?: Record<string, string>;
7
+ readonly queryParameters?: Record<string, string>;
8
+ readonly body?: unknown;
9
+ }
10
+
11
+ interface RequestInterceptor {
12
+ adapt(request: Request): Promise<Request>;
13
+ retry(request: Request, error: unknown): Promise<boolean>;
14
+ }
15
+
16
+ declare class HttpClient {
17
+ private readonly interceptors;
18
+ constructor(interceptors?: RequestInterceptor[]);
19
+ private buildRequest;
20
+ request<T>(endpoint: Endpoint): Promise<T>;
21
+ requestVoid(endpoint: Endpoint): Promise<void>;
22
+ requestRaw(endpoint: Endpoint): Promise<ArrayBuffer>;
23
+ private executeWithRetry;
24
+ }
25
+
26
+ interface Identity {
27
+ id: string;
28
+ }
29
+
30
+ interface EgeriaUserProfile {
31
+ iconUrl: string;
32
+ bannerUrl: string;
33
+ bio: string;
34
+ website: string;
35
+ additionalWebsites: string[];
36
+ }
37
+ interface EgeriaUser {
38
+ id: string;
39
+ screenName: string;
40
+ displayName: string;
41
+ profile?: EgeriaUserProfile;
42
+ }
43
+ interface EgeriaUserWrapper {
44
+ user: EgeriaUser;
45
+ }
46
+ interface EgeriaUsers {
47
+ users: EgeriaUser[];
48
+ }
49
+ interface EgeriaUpdateProfileRequest {
50
+ screenName?: string;
51
+ displayName?: string;
52
+ profile?: EgeriaUserProfile;
53
+ }
54
+
55
+ interface MediaMetadata {
56
+ width?: number;
57
+ height?: number;
58
+ isSensitive: boolean;
59
+ isSpoiler: boolean;
60
+ }
61
+ interface Media {
62
+ id: string;
63
+ alt: string;
64
+ url: string;
65
+ metadata?: MediaMetadata;
66
+ privacyMetadata?: boolean;
67
+ }
68
+ interface MediaUploadUrls {
69
+ url: string;
70
+ signedUrl: string;
71
+ }
72
+ interface CatalystMediaWithMetadata {
73
+ url: string;
74
+ alt: string;
75
+ width: number;
76
+ height: number;
77
+ bytes: number;
78
+ }
79
+ interface MediaDeleteRequest {
80
+ url: string;
81
+ }
82
+ interface MediaDownloadRequest {
83
+ url: string;
84
+ }
85
+
86
+ type CatalystStatusPrivacy = "public" | "quiet_public" | "followers" | "private";
87
+ interface CatalystStatus {
88
+ id: string;
89
+ body: string;
90
+ user?: EgeriaUser;
91
+ medias: Media[];
92
+ createdAt: string;
93
+ updatedAt?: string;
94
+ }
95
+ interface CatalystStatusWrapper {
96
+ status: CatalystStatus;
97
+ }
98
+ interface CatalystStatuses {
99
+ statuses: CatalystStatus[];
100
+ }
101
+ interface CatalystCreateStatusRequest {
102
+ description: string;
103
+ isNsfw: boolean;
104
+ isSpoiler: boolean;
105
+ isSubmitToContest: boolean;
106
+ isHidingLikeAndViewCount: boolean;
107
+ isPrivateMetadata?: boolean;
108
+ isAllowComments: boolean;
109
+ privacy?: CatalystStatusPrivacy;
110
+ contestId?: string;
111
+ media: CatalystMediaWithMetadata[];
112
+ }
113
+ interface CatalystEditStatusRequest {
114
+ description: string;
115
+ }
116
+
117
+ type CatalystAlbumDisplayMode = "timeline" | "grid" | "gallery";
118
+ interface CatalystAlbum {
119
+ id: string;
120
+ name: string;
121
+ description: string;
122
+ isPublic: boolean;
123
+ mode: CatalystAlbumDisplayMode;
124
+ user: EgeriaUser;
125
+ statuses: CatalystStatus[];
126
+ }
127
+ interface CatalystSmartAlbum {
128
+ id: string;
129
+ name: string;
130
+ description: string;
131
+ isAllowNsfw: boolean;
132
+ isAllowOthers: boolean;
133
+ since?: string;
134
+ until?: string;
135
+ isPublic: boolean;
136
+ mode: CatalystAlbumDisplayMode;
137
+ user?: EgeriaUser;
138
+ type?: string;
139
+ statuses: CatalystStatus[];
140
+ hashtags: string[];
141
+ }
142
+ interface CatalystSmartAlbums {
143
+ albums: CatalystSmartAlbum[];
144
+ }
145
+ interface CatalystCreateAlbumRequest {
146
+ title: string;
147
+ description: string;
148
+ isPublic: boolean;
149
+ mode: CatalystAlbumDisplayMode;
150
+ }
151
+ interface CatalystEditAlbumRequest {
152
+ title: string;
153
+ description: string;
154
+ isPublic: boolean;
155
+ mode: CatalystAlbumDisplayMode;
156
+ }
157
+ interface CatalystInsertToAlbumRequest {
158
+ insert: string;
159
+ }
160
+ interface CatalystRemoveFromAlbumRequest {
161
+ remove: string;
162
+ }
163
+ interface CatalystCreateSmartAlbumRequest {
164
+ title: string;
165
+ description: string;
166
+ hashtags: string[];
167
+ since?: string;
168
+ until?: string;
169
+ isAllowNsfw?: boolean;
170
+ isAllowOthers?: boolean;
171
+ isPublic: boolean;
172
+ mode?: CatalystAlbumDisplayMode;
173
+ }
174
+ interface CatalystEditSmartAlbumRequest {
175
+ title: string;
176
+ description: string;
177
+ hashtags: string[];
178
+ since?: string;
179
+ until?: string;
180
+ isAllowNsfw?: boolean;
181
+ isAllowOthers?: boolean;
182
+ isPublic: boolean;
183
+ mode?: CatalystAlbumDisplayMode;
184
+ }
185
+
186
+ interface CatalystReaction {
187
+ name: string;
188
+ symbol: string;
189
+ url: string;
190
+ count: number;
191
+ hasSelfReaction?: boolean;
192
+ }
193
+ interface CatalystReactions {
194
+ reactions: Record<string, CatalystReaction>;
195
+ }
196
+ interface CatalystCustomReaction {
197
+ name: string;
198
+ symbol: string;
199
+ url: string;
200
+ }
201
+
202
+ interface CatalystRelationships {
203
+ isMyself: boolean;
204
+ isFollowing: boolean;
205
+ isFollowed: boolean;
206
+ }
207
+ interface CatalystRelationshipRequest {
208
+ userId: string;
209
+ }
210
+
211
+ declare class CatalystClient {
212
+ private readonly http;
213
+ constructor(http: HttpClient);
214
+ createAlbum(data: CatalystCreateAlbumRequest): Promise<Identity>;
215
+ getAlbum(id: string, opts?: {
216
+ since?: string;
217
+ until?: string;
218
+ }): Promise<CatalystAlbum>;
219
+ editAlbum(id: string, data: CatalystEditAlbumRequest): Promise<void>;
220
+ insertToAlbum(id: string, data: CatalystInsertToAlbumRequest): Promise<void>;
221
+ removeFromAlbum(id: string, data: CatalystRemoveFromAlbumRequest): Promise<void>;
222
+ deleteAlbum(id: string): Promise<void>;
223
+ listAlbums(username: string, includeSmartAlbums?: boolean): Promise<CatalystSmartAlbums>;
224
+ searchAlbums(q: string, includeSmartAlbums?: boolean): Promise<CatalystSmartAlbums>;
225
+ customReactions(): Promise<CatalystCustomReaction[]>;
226
+ relationships(id: string): Promise<CatalystRelationships>;
227
+ follow(data: CatalystRelationshipRequest): Promise<void>;
228
+ remove(data: CatalystRelationshipRequest): Promise<void>;
229
+ createSmartAlbum(data: CatalystCreateSmartAlbumRequest): Promise<Identity>;
230
+ getSmartAlbum(id: string, opts?: {
231
+ since?: string;
232
+ until?: string;
233
+ }): Promise<CatalystSmartAlbum>;
234
+ editSmartAlbum(id: string, data: CatalystEditSmartAlbumRequest): Promise<void>;
235
+ deleteSmartAlbum(id: string): Promise<void>;
236
+ searchSmartAlbum(q: string): Promise<CatalystSmartAlbums>;
237
+ createStatus(data: CatalystCreateStatusRequest): Promise<Identity>;
238
+ getStatus(id: string): Promise<CatalystStatusWrapper>;
239
+ editStatus(id: string, data: CatalystEditStatusRequest): Promise<void>;
240
+ deleteStatus(id: string): Promise<void>;
241
+ isFavorited(id: string): Promise<boolean>;
242
+ favorite(id: string): Promise<void>;
243
+ unfavorite(id: string): Promise<void>;
244
+ reactions(id: string): Promise<CatalystReactions>;
245
+ react(id: string, symbol: string): Promise<void>;
246
+ unreact(id: string, symbol: string): Promise<void>;
247
+ contestTimeline(slug: string, opts?: {
248
+ since?: string;
249
+ until?: string;
250
+ }): Promise<CatalystStatuses>;
251
+ favoriteTimeline(opts?: {
252
+ since?: string;
253
+ until?: string;
254
+ }): Promise<CatalystStatuses>;
255
+ firehoseTimeline(opts?: {
256
+ since?: string;
257
+ until?: string;
258
+ }): Promise<CatalystStatus[]>;
259
+ galleryTimeline(opts?: {
260
+ since?: string;
261
+ until?: string;
262
+ }): Promise<CatalystStatuses>;
263
+ homeTimeline(opts?: {
264
+ since?: string;
265
+ until?: string;
266
+ }): Promise<CatalystStatus[]>;
267
+ searchTimeline(opts?: {
268
+ q?: string;
269
+ exact?: boolean;
270
+ since?: string;
271
+ until?: string;
272
+ }): Promise<CatalystStatuses>;
273
+ userTimeline(username: string, opts?: {
274
+ trimUser?: boolean;
275
+ excludeSensitive?: boolean;
276
+ since?: string;
277
+ until?: string;
278
+ }): Promise<CatalystStatuses>;
279
+ userGalleryTimeline(username: string, opts?: {
280
+ since?: string;
281
+ until?: string;
282
+ }): Promise<CatalystStatuses>;
283
+ trend(): Promise<string[]>;
284
+ }
285
+
286
+ declare class EgeriaClient {
287
+ private readonly http;
288
+ constructor(http: HttpClient);
289
+ me(): Promise<EgeriaUserWrapper | undefined>;
290
+ update(data: EgeriaUpdateProfileRequest): Promise<void>;
291
+ search(q: string): Promise<EgeriaUsers>;
292
+ userById(id: string): Promise<EgeriaUserWrapper | undefined>;
293
+ userByUsername(username: string): Promise<EgeriaUserWrapper | undefined>;
294
+ }
295
+
296
+ declare class MediaClient {
297
+ private readonly http;
298
+ constructor(http: HttpClient);
299
+ download(data: MediaDownloadRequest): Promise<ArrayBuffer>;
300
+ delete(data: MediaDeleteRequest): Promise<void>;
301
+ upload(): Promise<MediaUploadUrls>;
302
+ }
303
+
304
+ interface NotificationGroup {
305
+ id: string;
306
+ body: string;
307
+ occurredBy: EgeriaUser;
308
+ isRead: boolean;
309
+ }
310
+ interface Notification {
311
+ id: string;
312
+ title: string;
313
+ isGrouped: boolean;
314
+ belongsTo: Record<string, unknown>;
315
+ entities: NotificationGroup[];
316
+ hasMore: boolean;
317
+ read: boolean;
318
+ }
319
+ interface Notifications {
320
+ notifications: Notification[];
321
+ }
322
+ interface NotificationUnreadCount {
323
+ unread: number;
324
+ }
325
+
326
+ declare const ISSUER_CATALYST_SYSTEM_MESSAGE = "natsuneko-laboratory:catalyst";
327
+ declare const ISSUER_CATALYST_USER_MESSAGE = "natsuneko-laboratory:catalyst-message";
328
+ declare const ISSUER_EGERIA_SYSTEM_MESSAGE = "natsuneko-laboratory:egeria";
329
+ declare class SteambirdClient {
330
+ private readonly http;
331
+ readonly ISSUER_CATALYST_SYSTEM_MESSAGE = "natsuneko-laboratory:catalyst";
332
+ readonly ISSUER_CATALYST_USER_MESSAGE = "natsuneko-laboratory:catalyst-message";
333
+ readonly ISSUER_EGERIA_SYSTEM_MESSAGE = "natsuneko-laboratory:egeria";
334
+ constructor(http: HttpClient);
335
+ notifications(issuer: string, opts?: {
336
+ since?: string;
337
+ until?: string;
338
+ }): Promise<Notifications>;
339
+ read(id: string): Promise<void>;
340
+ readAll(issuer?: string): Promise<void>;
341
+ unreads(issuers?: string[]): Promise<NotificationUnreadCount>;
342
+ }
343
+
344
+ interface Token {
345
+ accessToken: string;
346
+ refreshToken: string;
347
+ tokenType: string;
348
+ }
349
+
350
+ declare class PKCE {
351
+ readonly verifier: string;
352
+ readonly challenge: string;
353
+ readonly method = "S256";
354
+ private constructor();
355
+ static create(): Promise<PKCE>;
356
+ private static generateVerifier;
357
+ private static computeChallenge;
358
+ private static base64url;
359
+ }
360
+
361
+ declare class OAuthError extends Error {
362
+ readonly kind: "authorizationRequestFailed" | "invalidAuthorizationResponse" | "invalidTokenResponse";
363
+ readonly info?: {
364
+ error: string;
365
+ description?: string;
366
+ uri?: string;
367
+ } | undefined;
368
+ constructor(message: string, kind: "authorizationRequestFailed" | "invalidAuthorizationResponse" | "invalidTokenResponse", info?: {
369
+ error: string;
370
+ description?: string;
371
+ uri?: string;
372
+ } | undefined);
373
+ }
374
+ declare class OAuth {
375
+ private readonly clientId;
376
+ private readonly clientSecret;
377
+ constructor(clientId: string, clientSecret: string);
378
+ getAccessTokenByCode(code: string, redirectUri: string, pkce: PKCE): Promise<Token>;
379
+ getAccessTokenByRefreshToken(refreshToken: string): Promise<Token>;
380
+ getAuthorizeURL(redirectUri: string, pkce: PKCE, state: string): URL;
381
+ getAuthorizationCode(callbackUrl: URL, expectedState: string, expectedRedirectUri: string): string;
382
+ private verifyAuthorizationResponse;
383
+ private postToken;
384
+ }
385
+
386
+ interface CatalystTSOptions {
387
+ clientId: string;
388
+ clientSecret: string;
389
+ accessToken?: string;
390
+ refreshToken?: string;
391
+ interceptors?: RequestInterceptor[];
392
+ }
393
+ declare class CatalystTS {
394
+ readonly clientId: string;
395
+ readonly clientSecret: string;
396
+ private _accessToken;
397
+ private _refreshToken;
398
+ private readonly http;
399
+ constructor(opts: CatalystTSOptions);
400
+ get accessToken(): string | undefined;
401
+ get refreshToken(): string | undefined;
402
+ setCredential(accessToken: string, refreshToken: string): void;
403
+ refresh(): Promise<Token>;
404
+ get oauth(): OAuth;
405
+ get catalyst(): CatalystClient;
406
+ get egeria(): EgeriaClient;
407
+ get media(): MediaClient;
408
+ get steambird(): SteambirdClient;
409
+ }
410
+
411
+ declare class ApiError extends Error {
412
+ readonly statusCode?: number | undefined;
413
+ readonly cause?: unknown | undefined;
414
+ constructor(message: string, statusCode?: number | undefined, cause?: unknown | undefined);
415
+ static invalid(): ApiError;
416
+ static httpError(statusCode: number): ApiError;
417
+ static decodingError(cause: unknown): ApiError;
418
+ static unauthorized(): ApiError;
419
+ }
420
+ declare class CatalystError extends Error {
421
+ readonly code?: number | undefined;
422
+ constructor(message: string, code?: number | undefined);
423
+ }
424
+
425
+ declare const PUBLIC_API_ENDPOINT = "https://api.natsuneko.com";
426
+ declare const PUBLIC_GRAPHQL_ENDPOINT = "https://graphql.natsuneko.com";
427
+ declare const PUBLIC_AUTHORIZE_ENDPOINT = "https://accounts.natsuneko.com/authorize";
428
+
429
+ declare const CatalystEndpoint: {
430
+ readonly createAlbum: (data: CatalystCreateAlbumRequest) => Endpoint;
431
+ readonly getAlbum: (id: string, opts?: {
432
+ since?: string;
433
+ until?: string;
434
+ }) => Endpoint;
435
+ readonly editAlbum: (id: string, data: CatalystEditAlbumRequest) => Endpoint;
436
+ readonly insertToAlbum: (id: string, data: CatalystInsertToAlbumRequest) => Endpoint;
437
+ readonly removeFromAlbum: (id: string, data: CatalystRemoveFromAlbumRequest) => Endpoint;
438
+ readonly deleteAlbum: (id: string) => Endpoint;
439
+ readonly listAlbums: (username: string, includeSmartAlbums?: boolean) => Endpoint;
440
+ readonly searchAlbum: (q: string, includeSmartAlbums?: boolean) => Endpoint;
441
+ readonly customReactions: () => Endpoint;
442
+ readonly relationships: (id: string) => Endpoint;
443
+ readonly follow: (data: CatalystRelationshipRequest) => Endpoint;
444
+ readonly remove: (data: CatalystRelationshipRequest) => Endpoint;
445
+ readonly createSmartAlbum: (data: CatalystCreateSmartAlbumRequest) => Endpoint;
446
+ readonly getSmartAlbum: (id: string, opts?: {
447
+ since?: string;
448
+ until?: string;
449
+ }) => Endpoint;
450
+ readonly editSmartAlbum: (id: string, data: CatalystEditSmartAlbumRequest) => Endpoint;
451
+ readonly deleteSmartAlbum: (id: string) => Endpoint;
452
+ readonly searchSmartAlbum: (q: string) => Endpoint;
453
+ readonly createStatus: (data: CatalystCreateStatusRequest) => Endpoint;
454
+ readonly getStatus: (id: string) => Endpoint;
455
+ readonly editStatus: (id: string, data: CatalystEditStatusRequest) => Endpoint;
456
+ readonly deleteStatus: (id: string) => Endpoint;
457
+ readonly isFavorited: (id: string) => Endpoint;
458
+ readonly favorite: (id: string) => Endpoint;
459
+ readonly unfavorite: (id: string) => Endpoint;
460
+ readonly reactions: (id: string) => Endpoint;
461
+ readonly react: (id: string, symbol: string) => Endpoint;
462
+ readonly unreact: (id: string, symbol: string) => Endpoint;
463
+ readonly contestTimeline: (slug: string, opts?: {
464
+ since?: string;
465
+ until?: string;
466
+ }) => Endpoint;
467
+ readonly favoriteTimeline: (opts?: {
468
+ since?: string;
469
+ until?: string;
470
+ }) => Endpoint;
471
+ readonly firehoseTimeline: (opts?: {
472
+ since?: string;
473
+ until?: string;
474
+ }) => Endpoint;
475
+ readonly galleryTimeline: (opts?: {
476
+ since?: string;
477
+ until?: string;
478
+ }) => Endpoint;
479
+ readonly homeTimeline: (opts?: {
480
+ since?: string;
481
+ until?: string;
482
+ }) => Endpoint;
483
+ readonly searchTimeline: (opts?: {
484
+ q?: string;
485
+ exact?: boolean;
486
+ since?: string;
487
+ until?: string;
488
+ }) => Endpoint;
489
+ readonly userTimeline: (username: string, opts?: {
490
+ trimUser?: boolean;
491
+ excludeSensitive?: boolean;
492
+ since?: string;
493
+ until?: string;
494
+ }) => Endpoint;
495
+ readonly userGalleryTimeline: (username: string, opts?: {
496
+ since?: string;
497
+ until?: string;
498
+ }) => Endpoint;
499
+ readonly trend: () => Endpoint;
500
+ };
501
+
502
+ declare const EgeriaEndpoint: {
503
+ readonly me: () => Endpoint;
504
+ readonly update: (data: EgeriaUpdateProfileRequest) => Endpoint;
505
+ readonly search: (q: string) => Endpoint;
506
+ readonly userById: (id: string) => Endpoint;
507
+ readonly userByUsername: (username: string) => Endpoint;
508
+ };
509
+
510
+ declare const MediaEndpoint: {
511
+ readonly download: (data: MediaDownloadRequest) => Endpoint;
512
+ readonly delete: (data: MediaDeleteRequest) => Endpoint;
513
+ readonly upload: () => Endpoint;
514
+ };
515
+
516
+ declare const SteambirdEndpoint: {
517
+ readonly notifications: (issuer: string, opts?: {
518
+ since?: string;
519
+ until?: string;
520
+ }) => Endpoint;
521
+ readonly read: (id: string) => Endpoint;
522
+ readonly readAll: (issuer?: string) => Endpoint;
523
+ readonly unreads: (issuers?: string[]) => Endpoint;
524
+ };
525
+
526
+ declare class AuthInterceptor implements RequestInterceptor {
527
+ private readonly tokenProvider;
528
+ private readonly retryCounts;
529
+ private readonly maxRetryCount;
530
+ constructor(tokenProvider: () => Promise<string | undefined>);
531
+ adapt(request: Request): Promise<Request>;
532
+ retry(request: Request, error: unknown): Promise<boolean>;
533
+ private makeRequestKey;
534
+ }
535
+
536
+ declare class UserAgentInterceptor implements RequestInterceptor {
537
+ private readonly agent;
538
+ constructor();
539
+ adapt(request: Request): Promise<Request>;
540
+ retry(_request: Request, _error: unknown): Promise<boolean>;
541
+ }
542
+
543
+ declare class LoggingInterceptor implements RequestInterceptor {
544
+ adapt(request: Request): Promise<Request>;
545
+ retry(request: Request, error: unknown): Promise<boolean>;
546
+ }
547
+
548
+ export { ApiError, AuthInterceptor, type CatalystAlbum, type CatalystAlbumDisplayMode, CatalystClient, type CatalystCreateAlbumRequest, type CatalystCreateSmartAlbumRequest, type CatalystCreateStatusRequest, type CatalystCustomReaction, type CatalystEditAlbumRequest, type CatalystEditSmartAlbumRequest, type CatalystEditStatusRequest, CatalystEndpoint, CatalystError, type CatalystInsertToAlbumRequest, type CatalystMediaWithMetadata, type CatalystReaction, type CatalystReactions, type CatalystRelationshipRequest, type CatalystRelationships, type CatalystRemoveFromAlbumRequest, type CatalystSmartAlbum, type CatalystSmartAlbums, type CatalystStatus, type CatalystStatusPrivacy, type CatalystStatusWrapper, type CatalystStatuses, CatalystTS, type CatalystTSOptions, EgeriaClient, EgeriaEndpoint, type EgeriaUpdateProfileRequest, type EgeriaUser, type EgeriaUserProfile, type EgeriaUserWrapper, type EgeriaUsers, type Endpoint, HttpClient, type HttpMethod, ISSUER_CATALYST_SYSTEM_MESSAGE, ISSUER_CATALYST_USER_MESSAGE, ISSUER_EGERIA_SYSTEM_MESSAGE, type Identity, LoggingInterceptor, type Media, MediaClient, type MediaDeleteRequest, type MediaDownloadRequest, MediaEndpoint, type MediaMetadata, type MediaUploadUrls, type Notification, type NotificationGroup, type NotificationUnreadCount, type Notifications, OAuth, OAuthError, PKCE, PUBLIC_API_ENDPOINT, PUBLIC_AUTHORIZE_ENDPOINT, PUBLIC_GRAPHQL_ENDPOINT, type RequestInterceptor, SteambirdClient, SteambirdEndpoint, type Token, UserAgentInterceptor };