rettiwt-api 6.3.0-alpha.0 → 7.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 +81 -31
- package/dist/Rettiwt.d.ts +6 -2
- package/dist/Rettiwt.js +7 -3
- package/dist/Rettiwt.js.map +1 -1
- package/dist/cli.js +3 -1
- package/dist/cli.js.map +1 -1
- package/dist/collections/Extractors.d.ts +15 -2
- package/dist/collections/Extractors.js +12 -1
- package/dist/collections/Extractors.js.map +1 -1
- package/dist/collections/Groups.js +8 -0
- package/dist/collections/Groups.js.map +1 -1
- package/dist/collections/Requests.js +8 -0
- package/dist/collections/Requests.js.map +1 -1
- package/dist/commands/Space.d.ts +10 -0
- package/dist/commands/Space.js +38 -0
- package/dist/commands/Space.js.map +1 -0
- package/dist/commands/User.js +139 -0
- package/dist/commands/User.js.map +1 -1
- package/dist/enums/Resource.d.ts +8 -1
- package/dist/enums/Resource.js +8 -0
- package/dist/enums/Resource.js.map +1 -1
- package/dist/index.d.ts +11 -1
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -1
- package/dist/models/RettiwtConfig.d.ts +26 -3
- package/dist/models/RettiwtConfig.js +68 -3
- package/dist/models/RettiwtConfig.js.map +1 -1
- package/dist/models/args/FetchArgs.d.ts +3 -0
- package/dist/models/args/FetchArgs.js +6 -0
- package/dist/models/args/FetchArgs.js.map +1 -1
- package/dist/models/args/PostArgs.d.ts +24 -1
- package/dist/models/args/PostArgs.js +52 -1
- package/dist/models/args/PostArgs.js.map +1 -1
- package/dist/models/data/Space.d.ts +70 -0
- package/dist/models/data/Space.js +177 -0
- package/dist/models/data/Space.js.map +1 -0
- package/dist/models/data/UserAbout.d.ts +44 -0
- package/dist/models/data/UserAbout.js +129 -0
- package/dist/models/data/UserAbout.js.map +1 -0
- package/dist/requests/Space.d.ts +15 -0
- package/dist/requests/Space.js +74 -0
- package/dist/requests/Space.js.map +1 -0
- package/dist/requests/Tweet.d.ts +4 -0
- package/dist/requests/Tweet.js +57 -0
- package/dist/requests/Tweet.js.map +1 -1
- package/dist/requests/User.d.ts +21 -0
- package/dist/requests/User.js +64 -0
- package/dist/requests/User.js.map +1 -1
- package/dist/services/internal/AuthService.d.ts +25 -0
- package/dist/services/internal/AuthService.js +121 -0
- package/dist/services/internal/AuthService.js.map +1 -1
- package/dist/services/public/DirectMessageService.js +3 -3
- package/dist/services/public/DirectMessageService.js.map +1 -1
- package/dist/services/public/FetcherService.d.ts +4 -3
- package/dist/services/public/FetcherService.js +22 -16
- package/dist/services/public/FetcherService.js.map +1 -1
- package/dist/services/public/ListService.js +5 -5
- package/dist/services/public/ListService.js.map +1 -1
- package/dist/services/public/SpaceService.d.ts +42 -0
- package/dist/services/public/SpaceService.js +60 -0
- package/dist/services/public/SpaceService.js.map +1 -0
- package/dist/services/public/TweetService.js +26 -23
- package/dist/services/public/TweetService.js.map +1 -1
- package/dist/services/public/UserService.d.ts +79 -0
- package/dist/services/public/UserService.js +203 -23
- package/dist/services/public/UserService.js.map +1 -1
- package/dist/types/RettiwtConfig.d.ts +33 -3
- package/dist/types/args/FetchArgs.d.ts +35 -1
- package/dist/types/args/PostArgs.d.ts +44 -1
- package/dist/types/data/Space.d.ts +89 -0
- package/dist/types/data/Space.js +3 -0
- package/dist/types/data/Space.js.map +1 -0
- package/dist/types/data/UserAbout.d.ts +68 -0
- package/dist/types/data/UserAbout.js +3 -0
- package/dist/types/data/UserAbout.js.map +1 -0
- package/dist/types/raw/base/Space.d.ts +43 -22
- package/dist/types/raw/space/AudioSpaceById.d.ts +50 -0
- package/dist/types/raw/space/AudioSpaceById.js +4 -0
- package/dist/types/raw/space/AudioSpaceById.js.map +1 -0
- package/dist/types/raw/space/Details.d.ts +2 -309
- package/dist/types/raw/tweet/Post.d.ts +16 -1
- package/dist/types/raw/user/About.d.ts +65 -0
- package/dist/types/raw/user/About.js +4 -0
- package/dist/types/raw/user/About.js.map +1 -0
- package/dist/types/raw/user/ChangePassword.d.ts +8 -0
- package/dist/types/raw/user/ChangePassword.js +3 -0
- package/dist/types/raw/user/ChangePassword.js.map +1 -0
- package/dist/types/raw/user/ProfileUpdate.d.ts +1 -0
- package/dist/types/raw/user/Settings.d.ts +21 -0
- package/dist/types/raw/user/Settings.js +4 -0
- package/dist/types/raw/user/Settings.js.map +1 -0
- package/package.json +6 -4
- package/src/Rettiwt.ts +10 -3
- package/src/cli.ts +3 -1
- package/src/collections/Extractors.ts +22 -3
- package/src/collections/Groups.ts +8 -0
- package/src/collections/Requests.ts +11 -0
- package/src/commands/Space.ts +46 -0
- package/src/commands/User.ts +159 -0
- package/src/enums/Resource.ts +9 -0
- package/src/index.ts +11 -1
- package/src/models/RettiwtConfig.ts +81 -6
- package/src/models/args/FetchArgs.ts +6 -0
- package/src/models/args/PostArgs.ts +58 -1
- package/src/models/data/Space.ts +201 -0
- package/src/models/data/UserAbout.ts +161 -0
- package/src/requests/Space.ts +76 -0
- package/src/requests/Tweet.ts +59 -0
- package/src/requests/User.ts +69 -0
- package/src/services/internal/AuthService.ts +149 -1
- package/src/services/public/DirectMessageService.ts +3 -3
- package/src/services/public/FetcherService.ts +25 -18
- package/src/services/public/ListService.ts +5 -5
- package/src/services/public/SpaceService.ts +65 -0
- package/src/services/public/TweetService.ts +27 -24
- package/src/services/public/UserService.ts +247 -23
- package/src/types/RettiwtConfig.ts +35 -3
- package/src/types/args/FetchArgs.ts +41 -1
- package/src/types/args/PostArgs.ts +50 -1
- package/src/types/data/Space.ts +122 -0
- package/src/types/data/UserAbout.ts +87 -0
- package/src/types/raw/base/Space.ts +42 -22
- package/src/types/raw/space/AudioSpaceById.ts +57 -0
- package/src/types/raw/space/Details.ts +3 -352
- package/src/types/raw/tweet/Post.ts +19 -1
- package/src/types/raw/user/About.ts +77 -0
- package/src/types/raw/user/ChangePassword.ts +8 -0
- package/src/types/raw/user/ProfileUpdate.ts +1 -0
- package/src/types/raw/user/Settings.ts +23 -0
- package/tsconfig.json +2 -2
package/src/index.ts
CHANGED
|
@@ -26,14 +26,17 @@ export * from './models/data/DirectMessage';
|
|
|
26
26
|
export * from './models/data/Inbox';
|
|
27
27
|
export * from './models/data/List';
|
|
28
28
|
export * from './models/data/Notification';
|
|
29
|
+
export * from './models/data/Space';
|
|
29
30
|
export * from './models/data/Tweet';
|
|
30
31
|
export * from './models/data/User';
|
|
32
|
+
export * from './models/data/UserAbout';
|
|
31
33
|
export * from './models/errors/TwitterError';
|
|
32
34
|
|
|
33
35
|
// REQUESTS
|
|
34
36
|
export * from './requests/DirectMessage';
|
|
35
37
|
export * from './requests/List';
|
|
36
38
|
export * from './requests/Media';
|
|
39
|
+
export * from './requests/Space';
|
|
37
40
|
export * from './requests/Tweet';
|
|
38
41
|
export * from './requests/User';
|
|
39
42
|
|
|
@@ -41,6 +44,7 @@ export * from './requests/User';
|
|
|
41
44
|
export * from './services/public/DirectMessageService';
|
|
42
45
|
export * from './services/public/FetcherService';
|
|
43
46
|
export * from './services/public/ListService';
|
|
47
|
+
export * from './services/public/SpaceService';
|
|
44
48
|
export * from './services/public/TweetService';
|
|
45
49
|
export * from './services/public/UserService';
|
|
46
50
|
|
|
@@ -55,8 +59,10 @@ export * from './types/data/DirectMessage';
|
|
|
55
59
|
export * from './types/data/Inbox';
|
|
56
60
|
export * from './types/data/List';
|
|
57
61
|
export * from './types/data/Notification';
|
|
62
|
+
export * from './types/data/Space';
|
|
58
63
|
export * from './types/data/Tweet';
|
|
59
64
|
export * from './types/data/User';
|
|
65
|
+
export * from './types/data/UserAbout';
|
|
60
66
|
export * from './types/errors/TwitterError';
|
|
61
67
|
export * from './types/params/Variables';
|
|
62
68
|
export { IAnalytics as IRawAnalytics } from './types/raw/base/Analytic';
|
|
@@ -68,7 +74,7 @@ export { IList as IRawList } from './types/raw/base/List';
|
|
|
68
74
|
export { IMedia as IRawMedia } from './types/raw/base/Media';
|
|
69
75
|
export { IMessage as IRawMessage } from './types/raw/base/Message';
|
|
70
76
|
export { INotification as IRawNotification } from './types/raw/base/Notification';
|
|
71
|
-
export {
|
|
77
|
+
export { IRawSpace } from './types/raw/base/Space';
|
|
72
78
|
export { ITweet as IRawTweet } from './types/raw/base/Tweet';
|
|
73
79
|
export { IUser as IRawUser } from './types/raw/base/User';
|
|
74
80
|
export { IDataResult as IRawDataResult } from './types/raw/composite/DataResult';
|
|
@@ -83,6 +89,7 @@ export { IListTweetsResponse as IRawListTweetsResponse } from './types/raw/list/
|
|
|
83
89
|
export { IMediaFinalizeUploadResponse as IRawMediaFinalizeUploadResponse } from './types/raw/media/FinalizeUpload';
|
|
84
90
|
export { IMediaInitializeUploadResponse as IRawMediaInitializeUploadResponse } from './types/raw/media/InitalizeUpload';
|
|
85
91
|
export { IMediaLiveVideoStreamResponse as IRawMediaLiveVideoStreamResponse } from './types/raw/media/LiveVideoStream';
|
|
92
|
+
export { IAudioSpaceByIdResponse as IRawSpaceDetailsResponse } from './types/raw/space/AudioSpaceById';
|
|
86
93
|
export { ITweetDetailsResponse as IRawTweetDetailsResponse } from './types/raw/tweet/Details';
|
|
87
94
|
export { ITweetDetailsBulkResponse as IRawTweetDetailsBulkResponse } from './types/raw/tweet/DetailsBulk';
|
|
88
95
|
export { ITweetLikeResponse as IRawTweetLikeResponse } from './types/raw/tweet/Like';
|
|
@@ -97,6 +104,7 @@ export { ITweetUnlikeResponse as IRawTweetUnlikeResponse } from './types/raw/twe
|
|
|
97
104
|
export { ITweetUnpostResponse as IRawTweetUnpostResponse } from './types/raw/tweet/Unpost';
|
|
98
105
|
export { ITweetUnretweetResponse as IRawTweetUnretweetResponse } from './types/raw/tweet/Unretweet';
|
|
99
106
|
export { ITweetUnscheduleResponse as ITRawTweetUnscheduleResponse } from './types/raw/tweet/Unschedule';
|
|
107
|
+
export { IUserAboutResponse as IRawUserAboutResponse } from './types/raw/user/About';
|
|
100
108
|
export { IUserAffiliatesResponse as IRawUserAffiliatesResponse } from './types/raw/user/Affiliates';
|
|
101
109
|
export { IUserAnalyticsResponse as IRawUserAnalyticsResponse } from './types/raw/user/Analytics';
|
|
102
110
|
export { IUserBookmarkFoldersResponse as IRawUserBookmarkFoldersResponse } from './types/raw/user/BookmarkFolders';
|
|
@@ -120,6 +128,8 @@ export { IUserTweetsResponse as IRawUserTweetsResponse } from './types/raw/user/
|
|
|
120
128
|
export { IUserTweetsAndRepliesResponse as IRawUserTweetsAndRepliesResponse } from './types/raw/user/TweetsAndReplies';
|
|
121
129
|
export { IUserUnfollowResponse as IRawUserUnfollowResponse } from './types/raw/user/Unfollow';
|
|
122
130
|
export { IUserProfileUpdateResponse as IRawUserProfileUpdateResponse } from './types/raw/user/ProfileUpdate';
|
|
131
|
+
export { IUserSettingsResponse as IRawUserSettingsResponse } from './types/raw/user/Settings';
|
|
132
|
+
export { IUserChangePasswordResponse as IRawUserChangePasswordResponse } from './types/raw/user/ChangePassword';
|
|
123
133
|
export * from './types/ErrorHandler';
|
|
124
134
|
export * from './types/RettiwtConfig';
|
|
125
135
|
export { IConversationTimelineResponse as IRawConversationTimelineResponse } from './types/raw/dm/Conversation';
|
|
@@ -1,6 +1,10 @@
|
|
|
1
|
-
import { Agent } from '
|
|
1
|
+
import { Agent as HttpAgent } from 'http';
|
|
2
|
+
import { Agent as HttpsAgent } from 'https';
|
|
2
3
|
|
|
4
|
+
import { AxiosProxyConfig, AxiosResponse } from 'axios';
|
|
5
|
+
import { HttpProxyAgent } from 'http-proxy-agent';
|
|
3
6
|
import { HttpsProxyAgent } from 'https-proxy-agent';
|
|
7
|
+
import { SocksProxyAgent } from 'socks-proxy-agent';
|
|
4
8
|
|
|
5
9
|
import { AuthService } from '../services/internal/AuthService';
|
|
6
10
|
import { IErrorHandler } from '../types/ErrorHandler';
|
|
@@ -34,7 +38,9 @@ export class RettiwtConfig implements IRettiwtConfig {
|
|
|
34
38
|
// Parameters for internal use
|
|
35
39
|
private _apiKey?: string;
|
|
36
40
|
private _headers: { [key: string]: string };
|
|
37
|
-
private
|
|
41
|
+
private _httpAgent: HttpAgent;
|
|
42
|
+
private _httpsAgent: HttpsAgent;
|
|
43
|
+
private _proxy?: AxiosProxyConfig | string | null;
|
|
38
44
|
private _userId: string | undefined;
|
|
39
45
|
|
|
40
46
|
// Parameters that can be set once, upon initialization
|
|
@@ -42,6 +48,7 @@ export class RettiwtConfig implements IRettiwtConfig {
|
|
|
42
48
|
public readonly errorHandler?: IErrorHandler;
|
|
43
49
|
public readonly logging?: boolean;
|
|
44
50
|
public readonly maxRetries: number;
|
|
51
|
+
public readonly responseMiddleware?: (response: AxiosResponse) => void | Promise<void>;
|
|
45
52
|
public readonly timeout?: number;
|
|
46
53
|
|
|
47
54
|
/**
|
|
@@ -49,11 +56,12 @@ export class RettiwtConfig implements IRettiwtConfig {
|
|
|
49
56
|
*/
|
|
50
57
|
public constructor(config?: IRettiwtConfig) {
|
|
51
58
|
this._apiKey = config?.apiKey;
|
|
52
|
-
this.
|
|
59
|
+
this._proxy = config?.proxy;
|
|
53
60
|
this._userId = config?.apiKey ? AuthService.getUserId(config?.apiKey) : undefined;
|
|
54
61
|
this.delay = config?.delay ?? 0;
|
|
55
62
|
this.maxRetries = config?.maxRetries ?? 0;
|
|
56
63
|
this.errorHandler = config?.errorHandler;
|
|
64
|
+
this.responseMiddleware = config?.responseMiddleware;
|
|
57
65
|
this.logging = config?.logging;
|
|
58
66
|
this.timeout = config?.timeout;
|
|
59
67
|
this.apiKey = config?.apiKey;
|
|
@@ -61,18 +69,49 @@ export class RettiwtConfig implements IRettiwtConfig {
|
|
|
61
69
|
...DefaultHeaders,
|
|
62
70
|
...config?.headers,
|
|
63
71
|
};
|
|
72
|
+
|
|
73
|
+
// Initializing the HTTP(S) agent(s)
|
|
74
|
+
const agents = this._getRequestAgents(config?.proxy);
|
|
75
|
+
this._httpAgent = agents.httpAgent;
|
|
76
|
+
this._httpsAgent = agents.httpsAgent;
|
|
64
77
|
}
|
|
65
78
|
|
|
66
79
|
public get apiKey(): string | undefined {
|
|
67
80
|
return this._apiKey;
|
|
68
81
|
}
|
|
69
82
|
|
|
83
|
+
/**
|
|
84
|
+
* The Axios proxy configuration to use.
|
|
85
|
+
*
|
|
86
|
+
* @remarks
|
|
87
|
+
* <br>
|
|
88
|
+
* - If `proxy` is set, Axios' built-in env-variable-based proxy is disabled.
|
|
89
|
+
*/
|
|
90
|
+
public get axiosProxyConfig(): AxiosProxyConfig | false | undefined {
|
|
91
|
+
// If user explicitly set to null or a proxy URL, disable Axios' built-in proxy
|
|
92
|
+
if (this._proxy === null || typeof this._proxy === 'string') {
|
|
93
|
+
return false;
|
|
94
|
+
}
|
|
95
|
+
// If user has set an AxiosProxyConfig, use that
|
|
96
|
+
if (this._proxy !== undefined) {
|
|
97
|
+
return this._proxy;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// Default: Let axios use it's built-in env-variable-based proxy.
|
|
101
|
+
return undefined;
|
|
102
|
+
}
|
|
103
|
+
|
|
70
104
|
public get headers(): { [key: string]: string } {
|
|
71
105
|
return this._headers;
|
|
72
106
|
}
|
|
73
107
|
|
|
108
|
+
/** The HTTP agent instance to use. */
|
|
109
|
+
public get httpAgent(): HttpAgent {
|
|
110
|
+
return this._httpAgent;
|
|
111
|
+
}
|
|
112
|
+
|
|
74
113
|
/** The HTTPS agent instance to use. */
|
|
75
|
-
public get httpsAgent():
|
|
114
|
+
public get httpsAgent(): HttpsAgent {
|
|
76
115
|
return this._httpsAgent;
|
|
77
116
|
}
|
|
78
117
|
|
|
@@ -93,8 +132,44 @@ export class RettiwtConfig implements IRettiwtConfig {
|
|
|
93
132
|
};
|
|
94
133
|
}
|
|
95
134
|
|
|
96
|
-
public set
|
|
97
|
-
|
|
135
|
+
public set proxy(proxy: AxiosProxyConfig | string | null | undefined) {
|
|
136
|
+
// Update HTTP(s) agents
|
|
137
|
+
const agents = this._getRequestAgents(proxy);
|
|
138
|
+
this._httpAgent = agents.httpAgent;
|
|
139
|
+
this._httpsAgent = agents.httpsAgent;
|
|
140
|
+
|
|
141
|
+
this._proxy = proxy;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Returns the appropriate HTTP(s) agents based on the type of proxy config.
|
|
146
|
+
*
|
|
147
|
+
* @param proxy - The proxy configuration.
|
|
148
|
+
*
|
|
149
|
+
* @returns The HTTP(s) agents.
|
|
150
|
+
*/
|
|
151
|
+
private _getRequestAgents(proxy?: AxiosProxyConfig | string | null): {
|
|
152
|
+
httpAgent: HttpAgent;
|
|
153
|
+
httpsAgent: HttpsAgent;
|
|
154
|
+
} {
|
|
155
|
+
let httpAgent: HttpAgent | undefined;
|
|
156
|
+
let httpsAgent: HttpsAgent | undefined;
|
|
157
|
+
|
|
158
|
+
if (typeof proxy === 'string' && (proxy.startsWith('http://') || proxy.startsWith('https://'))) {
|
|
159
|
+
httpAgent = new HttpProxyAgent(proxy);
|
|
160
|
+
httpsAgent = new HttpsProxyAgent(proxy);
|
|
161
|
+
} else if (typeof proxy === 'string' && proxy.startsWith('socks')) {
|
|
162
|
+
httpAgent = new SocksProxyAgent(proxy);
|
|
163
|
+
httpsAgent = new SocksProxyAgent(proxy);
|
|
164
|
+
} else {
|
|
165
|
+
httpAgent = new HttpAgent();
|
|
166
|
+
httpsAgent = new HttpsAgent();
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
return {
|
|
170
|
+
httpAgent: httpAgent,
|
|
171
|
+
httpsAgent: httpsAgent,
|
|
172
|
+
};
|
|
98
173
|
}
|
|
99
174
|
}
|
|
100
175
|
|
|
@@ -17,11 +17,14 @@ export class FetchArgs implements IFetchArgs {
|
|
|
17
17
|
public granularity?: RawAnalyticsGranularity;
|
|
18
18
|
public id?: string;
|
|
19
19
|
public ids?: string[];
|
|
20
|
+
public isMetatagsQuery?: boolean;
|
|
20
21
|
public maxId?: string;
|
|
21
22
|
public metrics?: RawAnalyticsMetric[];
|
|
22
23
|
public showVerifiedFollowers?: boolean;
|
|
23
24
|
public sortBy?: TweetRepliesSortType;
|
|
24
25
|
public toTime?: Date;
|
|
26
|
+
public withListeners?: boolean;
|
|
27
|
+
public withReplays?: boolean;
|
|
25
28
|
|
|
26
29
|
/**
|
|
27
30
|
* @param args - Additional user-defined arguments for fetching the resource.
|
|
@@ -29,6 +32,7 @@ export class FetchArgs implements IFetchArgs {
|
|
|
29
32
|
public constructor(args: IFetchArgs) {
|
|
30
33
|
this.id = args.id;
|
|
31
34
|
this.ids = args.ids;
|
|
35
|
+
this.isMetatagsQuery = args.isMetatagsQuery;
|
|
32
36
|
this.count = args.count;
|
|
33
37
|
this.cursor = args.cursor;
|
|
34
38
|
this.filter = args.filter ? new TweetFilter(args.filter) : undefined;
|
|
@@ -41,6 +45,8 @@ export class FetchArgs implements IFetchArgs {
|
|
|
41
45
|
this.activeConversationId = args.activeConversationId;
|
|
42
46
|
this.conversationId = args.conversationId;
|
|
43
47
|
this.maxId = args.maxId;
|
|
48
|
+
this.withListeners = args.withListeners;
|
|
49
|
+
this.withReplays = args.withReplays;
|
|
44
50
|
}
|
|
45
51
|
}
|
|
46
52
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { INewTweet, INewTweetMedia, IPostArgs, IUploadArgs } from '../../types/args/PostArgs';
|
|
1
|
+
import { IChangePasswordArgs, INewTweet, INewTweetMedia, IPostArgs, IUploadArgs } from '../../types/args/PostArgs';
|
|
2
2
|
|
|
3
3
|
import { ProfileUpdateOptions } from './ProfileArgs';
|
|
4
4
|
|
|
@@ -8,12 +8,16 @@ import { ProfileUpdateOptions } from './ProfileArgs';
|
|
|
8
8
|
* @public
|
|
9
9
|
*/
|
|
10
10
|
export class PostArgs implements IPostArgs {
|
|
11
|
+
public changePassword?: ChangePasswordArgs;
|
|
11
12
|
public conversationId?: string;
|
|
12
13
|
public id?: string;
|
|
14
|
+
public profileBanner?: string;
|
|
15
|
+
public profileImage?: string;
|
|
13
16
|
public profileOptions?: ProfileUpdateOptions;
|
|
14
17
|
public tweet?: NewTweet;
|
|
15
18
|
public upload?: UploadArgs;
|
|
16
19
|
public userId?: string;
|
|
20
|
+
public username?: string;
|
|
17
21
|
|
|
18
22
|
/**
|
|
19
23
|
* @param resource - The resource to be posted.
|
|
@@ -24,8 +28,36 @@ export class PostArgs implements IPostArgs {
|
|
|
24
28
|
this.tweet = args.tweet ? new NewTweet(args.tweet) : undefined;
|
|
25
29
|
this.upload = args.upload ? new UploadArgs(args.upload) : undefined;
|
|
26
30
|
this.userId = args.userId;
|
|
31
|
+
this.username = PostArgs._validateNonEmptyString(args.username, 'Username');
|
|
27
32
|
this.conversationId = args.conversationId;
|
|
28
33
|
this.profileOptions = args.profileOptions ? new ProfileUpdateOptions(args.profileOptions) : undefined;
|
|
34
|
+
this.profileImage = PostArgs._validateNonEmptyString(args.profileImage, 'Profile image');
|
|
35
|
+
this.profileBanner = PostArgs._validateNonEmptyString(args.profileBanner, 'Profile banner');
|
|
36
|
+
this.changePassword = args.changePassword ? new ChangePasswordArgs(args.changePassword) : undefined;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Validates if a data value is a valid string.
|
|
41
|
+
*
|
|
42
|
+
* @param value - The data to validate.
|
|
43
|
+
* @param fieldName - The field name whose value is to be validated.
|
|
44
|
+
*
|
|
45
|
+
* @returns The validated, parsed string. If data was `undefined`, returns `undefined`.
|
|
46
|
+
*/
|
|
47
|
+
private static _validateNonEmptyString(value: unknown, fieldName: string): string | undefined {
|
|
48
|
+
if (value === undefined) {
|
|
49
|
+
return undefined;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
if (typeof value !== 'string') {
|
|
53
|
+
throw new Error(`${fieldName} must be a string`);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
if (value.trim().length === 0) {
|
|
57
|
+
throw new Error(`${fieldName} cannot be empty`);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return value;
|
|
29
61
|
}
|
|
30
62
|
}
|
|
31
63
|
|
|
@@ -91,3 +123,28 @@ export class UploadArgs implements IUploadArgs {
|
|
|
91
123
|
this.id = args.id;
|
|
92
124
|
}
|
|
93
125
|
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* The args for changing authenticated user's password.
|
|
129
|
+
*
|
|
130
|
+
* @public
|
|
131
|
+
*/
|
|
132
|
+
export class ChangePasswordArgs implements IChangePasswordArgs {
|
|
133
|
+
public currentPassword: string;
|
|
134
|
+
public newPassword: string;
|
|
135
|
+
|
|
136
|
+
public constructor(args: IChangePasswordArgs) {
|
|
137
|
+
if (!args.currentPassword || args.currentPassword.trim().length === 0) {
|
|
138
|
+
throw new Error('Current password cannot be empty');
|
|
139
|
+
}
|
|
140
|
+
if (!args.newPassword || args.newPassword.trim().length === 0) {
|
|
141
|
+
throw new Error('New password cannot be empty');
|
|
142
|
+
}
|
|
143
|
+
if (args.newPassword.length < 8) {
|
|
144
|
+
throw new Error('New password must be at least 8 characters long');
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
this.currentPassword = args.currentPassword;
|
|
148
|
+
this.newPassword = args.newPassword;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
import { LogActions } from '../../enums/Logging';
|
|
2
|
+
import { LogService } from '../../services/internal/LogService';
|
|
3
|
+
import { ISpace, ISpaceParticipant, ISpaceParticipants } from '../../types/data/Space';
|
|
4
|
+
import {
|
|
5
|
+
IAudioSpace,
|
|
6
|
+
IAudioSpaceByIdResponse,
|
|
7
|
+
IAudioSpaceParticipant,
|
|
8
|
+
IAudioSpaceParticipants,
|
|
9
|
+
} from '../../types/raw/space/AudioSpaceById';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* The details of a single Space.
|
|
13
|
+
*
|
|
14
|
+
* @public
|
|
15
|
+
*/
|
|
16
|
+
export class Space implements ISpace {
|
|
17
|
+
/** The raw space details. */
|
|
18
|
+
private readonly _raw: IAudioSpace;
|
|
19
|
+
|
|
20
|
+
public conversationControls?: number;
|
|
21
|
+
public createdAt?: string;
|
|
22
|
+
public creatorId?: string;
|
|
23
|
+
public disallowJoin?: boolean;
|
|
24
|
+
public endedAt?: string;
|
|
25
|
+
public id: string;
|
|
26
|
+
public isEmployeeOnly?: boolean;
|
|
27
|
+
public isLocked?: boolean;
|
|
28
|
+
public isMuted?: boolean;
|
|
29
|
+
public isSpaceAvailableForClipping?: boolean;
|
|
30
|
+
public isSpaceAvailableForReplay?: boolean;
|
|
31
|
+
public isSubscribed?: boolean;
|
|
32
|
+
public mediaKey?: string;
|
|
33
|
+
public noIncognito?: boolean;
|
|
34
|
+
public participantCount?: number;
|
|
35
|
+
public participants?: ISpaceParticipants;
|
|
36
|
+
public scheduledStart?: string;
|
|
37
|
+
public startedAt?: string;
|
|
38
|
+
public state?: string;
|
|
39
|
+
public title?: string;
|
|
40
|
+
public totalLiveListeners?: number;
|
|
41
|
+
public totalReplayWatched?: number;
|
|
42
|
+
public updatedAt?: string;
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* @param space - The raw space details.
|
|
46
|
+
*/
|
|
47
|
+
public constructor(space: IAudioSpace) {
|
|
48
|
+
this._raw = { ...space };
|
|
49
|
+
|
|
50
|
+
const metadata = space.metadata;
|
|
51
|
+
|
|
52
|
+
this.id = metadata?.rest_id ?? '';
|
|
53
|
+
this.state = metadata?.state;
|
|
54
|
+
this.title = metadata?.title;
|
|
55
|
+
this.mediaKey = metadata?.media_key;
|
|
56
|
+
this.createdAt = Space._timestampToIso(metadata?.created_at);
|
|
57
|
+
this.scheduledStart = Space._timestampToIso(metadata?.scheduled_start);
|
|
58
|
+
this.startedAt = Space._timestampToIso(metadata?.started_at);
|
|
59
|
+
this.endedAt = Space._timestampToIso(metadata?.ended_at);
|
|
60
|
+
this.updatedAt = Space._timestampToIso(metadata?.updated_at);
|
|
61
|
+
this.creatorId = metadata?.creator_results?.result?.rest_id ?? metadata?.creator_id;
|
|
62
|
+
this.conversationControls = metadata?.conversation_controls;
|
|
63
|
+
this.disallowJoin = metadata?.disallow_join;
|
|
64
|
+
this.isEmployeeOnly = metadata?.is_employee_only;
|
|
65
|
+
this.isLocked = metadata?.is_locked;
|
|
66
|
+
this.isMuted = metadata?.is_muted;
|
|
67
|
+
this.isSpaceAvailableForClipping = metadata?.is_space_available_for_clipping;
|
|
68
|
+
this.isSpaceAvailableForReplay = metadata?.is_space_available_for_replay;
|
|
69
|
+
this.noIncognito = metadata?.no_incognito;
|
|
70
|
+
this.totalLiveListeners = metadata?.total_live_listeners;
|
|
71
|
+
this.totalReplayWatched = metadata?.total_replay_watched;
|
|
72
|
+
this.participantCount = space.participants?.total ?? metadata?.participant_count;
|
|
73
|
+
this.isSubscribed = space.is_subscribed;
|
|
74
|
+
this.participants = Space._mapParticipants(space.participants);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/** The raw space details. */
|
|
78
|
+
public get raw(): IAudioSpace {
|
|
79
|
+
return { ...this._raw };
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Maps a raw participant to a deserialized participant.
|
|
84
|
+
*
|
|
85
|
+
* @param participant - The raw participant data.
|
|
86
|
+
*/
|
|
87
|
+
private static _mapParticipant(participant: IAudioSpaceParticipant): ISpaceParticipant {
|
|
88
|
+
const userId = participant.user_results?.rest_id ?? participant.user_results?.result?.rest_id;
|
|
89
|
+
|
|
90
|
+
return {
|
|
91
|
+
id: userId,
|
|
92
|
+
screenName: participant.twitter_screen_name,
|
|
93
|
+
displayName: participant.display_name,
|
|
94
|
+
avatarUrl: participant.avatar_url,
|
|
95
|
+
isVerified: participant.is_verified,
|
|
96
|
+
isMutedByAdmin: participant.is_muted_by_admin,
|
|
97
|
+
isMutedByGuest: participant.is_muted_by_guest,
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Maps raw participants to deserialized participants.
|
|
103
|
+
*
|
|
104
|
+
* @param participants - The raw participants data.
|
|
105
|
+
*/
|
|
106
|
+
private static _mapParticipants(participants?: IAudioSpaceParticipants): ISpaceParticipants | undefined {
|
|
107
|
+
if (!participants) {
|
|
108
|
+
return undefined;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
return {
|
|
112
|
+
total: participants.total,
|
|
113
|
+
admins: (participants.admins ?? []).map((participant) => Space._mapParticipant(participant)),
|
|
114
|
+
speakers: (participants.speakers ?? []).map((participant) => Space._mapParticipant(participant)),
|
|
115
|
+
listeners: (participants.listeners ?? []).map((participant) => Space._mapParticipant(participant)),
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Convert timestamp to ISO string.
|
|
121
|
+
*
|
|
122
|
+
* @param value - The timestamp value.
|
|
123
|
+
*/
|
|
124
|
+
private static _timestampToIso(value?: number | string): string | undefined {
|
|
125
|
+
if (value == undefined) {
|
|
126
|
+
return undefined;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
const numeric = typeof value === 'string' ? Number(value) : value;
|
|
130
|
+
|
|
131
|
+
if (!Number.isNaN(numeric)) {
|
|
132
|
+
return new Date(numeric).toISOString();
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
const parsed = new Date(value);
|
|
136
|
+
|
|
137
|
+
if (!Number.isNaN(parsed.getTime())) {
|
|
138
|
+
return parsed.toISOString();
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
return undefined;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Extracts and deserializes a single target space from the given raw response data.
|
|
146
|
+
*
|
|
147
|
+
* @param response - The raw response data.
|
|
148
|
+
*
|
|
149
|
+
* @returns The target deserialized space.
|
|
150
|
+
*/
|
|
151
|
+
public static single(response: IAudioSpaceByIdResponse): Space | undefined {
|
|
152
|
+
const audioSpace = response.data?.audioSpace;
|
|
153
|
+
const spaceId = audioSpace?.metadata?.rest_id;
|
|
154
|
+
|
|
155
|
+
if (audioSpace && spaceId) {
|
|
156
|
+
// Logging
|
|
157
|
+
LogService.log(LogActions.DESERIALIZE, { id: spaceId });
|
|
158
|
+
|
|
159
|
+
return new Space(audioSpace);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// Logging
|
|
163
|
+
LogService.log(LogActions.WARNING, {
|
|
164
|
+
action: LogActions.DESERIALIZE,
|
|
165
|
+
message: 'Space not found, skipping',
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
return undefined;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* @returns A serializable JSON representation of `this` object.
|
|
173
|
+
*/
|
|
174
|
+
public toJSON(): ISpace {
|
|
175
|
+
return {
|
|
176
|
+
id: this.id,
|
|
177
|
+
state: this.state,
|
|
178
|
+
title: this.title,
|
|
179
|
+
mediaKey: this.mediaKey,
|
|
180
|
+
createdAt: this.createdAt,
|
|
181
|
+
scheduledStart: this.scheduledStart,
|
|
182
|
+
startedAt: this.startedAt,
|
|
183
|
+
endedAt: this.endedAt,
|
|
184
|
+
updatedAt: this.updatedAt,
|
|
185
|
+
creatorId: this.creatorId,
|
|
186
|
+
conversationControls: this.conversationControls,
|
|
187
|
+
disallowJoin: this.disallowJoin,
|
|
188
|
+
isEmployeeOnly: this.isEmployeeOnly,
|
|
189
|
+
isLocked: this.isLocked,
|
|
190
|
+
isMuted: this.isMuted,
|
|
191
|
+
isSpaceAvailableForClipping: this.isSpaceAvailableForClipping,
|
|
192
|
+
isSpaceAvailableForReplay: this.isSpaceAvailableForReplay,
|
|
193
|
+
noIncognito: this.noIncognito,
|
|
194
|
+
totalLiveListeners: this.totalLiveListeners,
|
|
195
|
+
totalReplayWatched: this.totalReplayWatched,
|
|
196
|
+
participantCount: this.participantCount,
|
|
197
|
+
isSubscribed: this.isSubscribed,
|
|
198
|
+
participants: this.participants,
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
}
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
import { LogActions } from '../../enums/Logging';
|
|
2
|
+
import { LogService } from '../../services/internal/LogService';
|
|
3
|
+
import {
|
|
4
|
+
IUserAbout,
|
|
5
|
+
IUserAboutProfile,
|
|
6
|
+
IUserAboutUsernameChanges,
|
|
7
|
+
IUserAboutVerificationInfo,
|
|
8
|
+
} from '../../types/data/UserAbout';
|
|
9
|
+
import { IUserAboutResponse, IUserAboutResult } from '../../types/raw/user/About';
|
|
10
|
+
|
|
11
|
+
/* eslint-disable @typescript-eslint/naming-convention */
|
|
12
|
+
type IRawUsernameChanges = {
|
|
13
|
+
count?: string;
|
|
14
|
+
last_changed_at_msec?: string;
|
|
15
|
+
};
|
|
16
|
+
/* eslint-enable @typescript-eslint/naming-convention */
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* The about profile details of a single user.
|
|
20
|
+
*
|
|
21
|
+
* @public
|
|
22
|
+
*/
|
|
23
|
+
export class UserAbout implements IUserAbout {
|
|
24
|
+
/** The raw about profile details. */
|
|
25
|
+
private readonly _raw: IUserAboutResult;
|
|
26
|
+
|
|
27
|
+
public aboutProfile?: IUserAboutProfile;
|
|
28
|
+
public createdAt: string;
|
|
29
|
+
public fullName: string;
|
|
30
|
+
public id: string;
|
|
31
|
+
public isProtected?: boolean;
|
|
32
|
+
public isVerified: boolean;
|
|
33
|
+
public profileImage: string;
|
|
34
|
+
public profileImageShape?: string;
|
|
35
|
+
public userName: string;
|
|
36
|
+
public verificationInfo?: IUserAboutVerificationInfo;
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* @param user - The raw about profile details.
|
|
40
|
+
*/
|
|
41
|
+
public constructor(user: IUserAboutResult) {
|
|
42
|
+
this._raw = { ...user };
|
|
43
|
+
|
|
44
|
+
this.id = user.rest_id ?? user.id ?? '';
|
|
45
|
+
this.userName = user.core?.screen_name ?? '';
|
|
46
|
+
this.fullName = user.core?.name ?? '';
|
|
47
|
+
this.createdAt = new Date(user.core?.created_at ?? 0).toISOString();
|
|
48
|
+
this.profileImage = user.avatar?.image_url ?? '';
|
|
49
|
+
this.profileImageShape = user.profile_image_shape;
|
|
50
|
+
this.isVerified = user.is_blue_verified ?? false;
|
|
51
|
+
this.isProtected = user.privacy?.protected;
|
|
52
|
+
this.aboutProfile = UserAbout._buildAboutProfile(user);
|
|
53
|
+
this.verificationInfo = UserAbout._buildVerificationInfo(user);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/** The raw about profile details. */
|
|
57
|
+
public get raw(): IUserAboutResult {
|
|
58
|
+
return { ...this._raw };
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
private static _buildAboutProfile(user: IUserAboutResult): IUserAboutProfile | undefined {
|
|
62
|
+
const profile = user.about_profile;
|
|
63
|
+
|
|
64
|
+
if (!profile) {
|
|
65
|
+
return undefined;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const usernameChanges = UserAbout._buildUsernameChanges(profile.username_changes);
|
|
69
|
+
|
|
70
|
+
return {
|
|
71
|
+
createdCountryAccurate: profile.created_country_accurate,
|
|
72
|
+
accountBasedIn: profile.account_based_in,
|
|
73
|
+
locationAccurate: profile.location_accurate,
|
|
74
|
+
learnMoreUrl: profile.learn_more_url,
|
|
75
|
+
source: profile.source,
|
|
76
|
+
usernameChanges: usernameChanges,
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
private static _buildUsernameChanges(changes?: IRawUsernameChanges): IUserAboutUsernameChanges | undefined {
|
|
81
|
+
if (!changes) {
|
|
82
|
+
return undefined;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
return {
|
|
86
|
+
count: UserAbout._toNumber(changes.count),
|
|
87
|
+
lastChangedAt: UserAbout._toIsoFromMsec(changes.last_changed_at_msec),
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
private static _buildVerificationInfo(user: IUserAboutResult): IUserAboutVerificationInfo | undefined {
|
|
92
|
+
const info = user.verification_info;
|
|
93
|
+
|
|
94
|
+
if (!info) {
|
|
95
|
+
return undefined;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
return {
|
|
99
|
+
isIdentityVerified: info.is_identity_verified,
|
|
100
|
+
verifiedSince: UserAbout._toIsoFromMsec(info.reason?.verified_since_msec),
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
private static _toIsoFromMsec(value?: string | number): string | undefined {
|
|
105
|
+
const parsed = UserAbout._toNumber(value);
|
|
106
|
+
|
|
107
|
+
return parsed === undefined ? undefined : new Date(parsed).toISOString();
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
private static _toNumber(value?: string | number): number | undefined {
|
|
111
|
+
if (value === undefined || value === null) {
|
|
112
|
+
return undefined;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
const parsed = typeof value === 'number' ? value : Number(value);
|
|
116
|
+
|
|
117
|
+
return Number.isFinite(parsed) ? parsed : undefined;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Extracts and deserializes a single target user about profile from the given raw response data.
|
|
122
|
+
*
|
|
123
|
+
* @param response - The raw response data.
|
|
124
|
+
*
|
|
125
|
+
* @returns The target deserialized user about profile.
|
|
126
|
+
*/
|
|
127
|
+
public static single(response: NonNullable<unknown>): UserAbout | undefined {
|
|
128
|
+
const result = (response as IUserAboutResponse)?.data?.user_result_by_screen_name?.result;
|
|
129
|
+
|
|
130
|
+
if (!result || result.__typename !== 'User') {
|
|
131
|
+
LogService.log(LogActions.WARNING, {
|
|
132
|
+
action: LogActions.DESERIALIZE,
|
|
133
|
+
message: `User not found, skipping`,
|
|
134
|
+
});
|
|
135
|
+
return undefined;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// Logging
|
|
139
|
+
LogService.log(LogActions.DESERIALIZE, { id: result.rest_id ?? result.id });
|
|
140
|
+
|
|
141
|
+
return new UserAbout(result);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* @returns A serializable JSON representation of `this` object.
|
|
146
|
+
*/
|
|
147
|
+
public toJSON(): IUserAbout {
|
|
148
|
+
return {
|
|
149
|
+
id: this.id,
|
|
150
|
+
userName: this.userName,
|
|
151
|
+
fullName: this.fullName,
|
|
152
|
+
createdAt: this.createdAt,
|
|
153
|
+
profileImage: this.profileImage,
|
|
154
|
+
profileImageShape: this.profileImageShape,
|
|
155
|
+
isVerified: this.isVerified,
|
|
156
|
+
isProtected: this.isProtected,
|
|
157
|
+
aboutProfile: this.aboutProfile,
|
|
158
|
+
verificationInfo: this.verificationInfo,
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
}
|