@hardlydifficult/social 1.0.59 → 1.0.60
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 +88 -165
- package/dist/SocialClient.d.ts +10 -7
- package/dist/SocialClient.d.ts.map +1 -1
- package/dist/SocialClient.js +29 -5
- package/dist/SocialClient.js.map +1 -1
- package/dist/SocialLikeWatcher.d.ts +5 -5
- package/dist/SocialLikeWatcher.d.ts.map +1 -1
- package/dist/SocialLikeWatcher.js +5 -4
- package/dist/SocialLikeWatcher.js.map +1 -1
- package/dist/SocialProviderClient.d.ts +4 -8
- package/dist/SocialProviderClient.d.ts.map +1 -1
- package/dist/index.d.ts +8 -9
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +11 -13
- package/dist/index.js.map +1 -1
- package/dist/mastodon/MastodonSocialClient.d.ts +7 -8
- package/dist/mastodon/MastodonSocialClient.d.ts.map +1 -1
- package/dist/mastodon/MastodonSocialClient.js +12 -3
- package/dist/mastodon/MastodonSocialClient.js.map +1 -1
- package/dist/types.d.ts +11 -4
- package/dist/types.d.ts.map +1 -1
- package/dist/x/XSocialClient.d.ts +7 -8
- package/dist/x/XSocialClient.d.ts.map +1 -1
- package/dist/x/XSocialClient.js +18 -9
- package/dist/x/XSocialClient.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,16 +1,13 @@
|
|
|
1
1
|
# @hardlydifficult/social
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Opinionated social read client for X.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
This package is intentionally narrow:
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
-
|
|
10
|
-
-
|
|
11
|
-
- Watch for newly liked posts
|
|
12
|
-
|
|
13
|
-
Write operations (posting, liking, reposting) are intentionally not included yet.
|
|
7
|
+
- One provider: X
|
|
8
|
+
- One factory: `createSocial()`
|
|
9
|
+
- Terse methods: `post()`, `timeline()`, `likes()`
|
|
10
|
+
- Like watching that starts immediately
|
|
14
11
|
|
|
15
12
|
## Installation
|
|
16
13
|
|
|
@@ -20,212 +17,138 @@ npm install @hardlydifficult/social
|
|
|
20
17
|
|
|
21
18
|
## Quick Start
|
|
22
19
|
|
|
23
|
-
```
|
|
24
|
-
import {
|
|
20
|
+
```ts
|
|
21
|
+
import { createSocial } from "@hardlydifficult/social";
|
|
25
22
|
|
|
26
|
-
const
|
|
27
|
-
bearerToken: process.env.X_BEARER_TOKEN
|
|
23
|
+
const social = createSocial({
|
|
24
|
+
bearerToken: process.env.X_BEARER_TOKEN,
|
|
28
25
|
});
|
|
29
26
|
|
|
30
|
-
const
|
|
31
|
-
|
|
27
|
+
const posts = await social.timeline(10);
|
|
28
|
+
const liked = await social.likes(10);
|
|
29
|
+
const post = await social.post("1234567890");
|
|
32
30
|
```
|
|
33
31
|
|
|
34
|
-
|
|
32
|
+
If you omit `bearerToken`, the client reads `X_BEARER_TOKEN` from the environment.
|
|
35
33
|
|
|
36
|
-
|
|
34
|
+
## API
|
|
37
35
|
|
|
38
|
-
|
|
36
|
+
### `createSocial(options?)`
|
|
39
37
|
|
|
40
|
-
|
|
41
|
-
import { createXClient } from '@hardlydifficult/social';
|
|
38
|
+
Creates the default client. X is the only supported provider today, so the options are X-specific without extra nesting.
|
|
42
39
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
// Get posts where the user was liked (via polling-like interface)
|
|
49
|
-
const likedPosts = await client.getLikedPosts();
|
|
40
|
+
```ts
|
|
41
|
+
const social = createSocial({
|
|
42
|
+
bearerToken: process.env.X_BEARER_TOKEN,
|
|
43
|
+
limit: 25,
|
|
44
|
+
});
|
|
50
45
|
```
|
|
51
46
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
All provider implementations must implement `SocialProviderClient`, which requires:
|
|
55
|
-
|
|
56
|
-
- `getTimeline()`: Fetch recent posts
|
|
57
|
-
- `getLikedPosts()`: Fetch posts the authenticated user has liked
|
|
58
|
-
- `getPost(postId: string)`: Fetch a specific post
|
|
47
|
+
Options:
|
|
59
48
|
|
|
60
|
-
|
|
61
|
-
|
|
49
|
+
- `bearerToken?: string`
|
|
50
|
+
- `limit?: number`
|
|
62
51
|
|
|
63
|
-
|
|
64
|
-
interface MyProvider implements SocialProviderClient {
|
|
65
|
-
getTimeline(): Promise<SocialPost[]>;
|
|
66
|
-
getLikedPosts(): Promise<SocialPost[]>;
|
|
67
|
-
getPost(id: string): Promise<SocialPost | undefined>;
|
|
68
|
-
}
|
|
69
|
-
```
|
|
70
|
-
|
|
71
|
-
## Types
|
|
52
|
+
`maxResults` is still accepted as a compatibility alias for `limit`.
|
|
72
53
|
|
|
73
|
-
###
|
|
54
|
+
### `social.post(id)`
|
|
74
55
|
|
|
75
|
-
|
|
56
|
+
Fetch a single post.
|
|
76
57
|
|
|
77
|
-
```
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
interface SocialPost {
|
|
81
|
-
id: string;
|
|
82
|
-
text: string;
|
|
83
|
-
createdAt: Date;
|
|
84
|
-
author: {
|
|
85
|
-
username: string;
|
|
86
|
-
displayName?: string;
|
|
87
|
-
avatarUrl?: string;
|
|
88
|
-
};
|
|
89
|
-
media?: { url: string; type: 'image' | 'video' }[];
|
|
90
|
-
}
|
|
58
|
+
```ts
|
|
59
|
+
const post = await social.post("123");
|
|
91
60
|
```
|
|
92
61
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
The `XSocialClient` implements the provider interface against the X/Twitter API.
|
|
96
|
-
|
|
97
|
-
### Constructor Options
|
|
62
|
+
### `social.timeline(limitOrOptions?)`
|
|
98
63
|
|
|
99
|
-
|
|
100
|
-
|--------|------|----------|-------------|
|
|
101
|
-
| `bearerToken` | `string` | ✅ | Twitter API bearer token |
|
|
102
|
-
| `userId` | `string` | ❌ | User ID; falls back to `/2/users/me` if not provided |
|
|
64
|
+
Fetch the authenticated user timeline.
|
|
103
65
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
const client = createXClient({
|
|
110
|
-
bearerToken: process.env.X_BEARER_TOKEN!,
|
|
111
|
-
});
|
|
112
|
-
|
|
113
|
-
// Fetch timeline
|
|
114
|
-
const posts = await client.getTimeline();
|
|
115
|
-
|
|
116
|
-
// Fetch liked posts for this user
|
|
117
|
-
const likedPosts = await client.getLikedPosts();
|
|
66
|
+
```ts
|
|
67
|
+
const recent = await social.timeline();
|
|
68
|
+
const firstTen = await social.timeline(10);
|
|
69
|
+
const custom = await social.timeline({ limit: 5 });
|
|
118
70
|
```
|
|
119
71
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
`SocialLikeWatcher` polls the provider for new liked posts and emits events when new ones are detected.
|
|
72
|
+
### `social.likes(limitOrOptions?)`
|
|
123
73
|
|
|
124
|
-
|
|
74
|
+
Fetch posts liked by the authenticated user.
|
|
125
75
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
| `pollIntervalMs` | `number` | ❌ | `60_000` | Polling interval in milliseconds |
|
|
130
|
-
| `initialLikeIds` | `string[]` | ❌ | `[]` | Pre-known liked post IDs (for resume) |
|
|
131
|
-
|
|
132
|
-
### Event Emitter API
|
|
133
|
-
|
|
134
|
-
```typescript
|
|
135
|
-
import { createXClient, SocialLikeWatcher } from '@hardlydifficult/social';
|
|
136
|
-
|
|
137
|
-
const client = createXClient({ bearerToken: process.env.X_BEARER_TOKEN! });
|
|
138
|
-
const watcher = new SocialLikeWatcher(client, { pollIntervalMs: 30_000 });
|
|
139
|
-
|
|
140
|
-
watcher.on('newLike', (post) => {
|
|
141
|
-
console.log(`New like detected: ${post.text}`);
|
|
142
|
-
});
|
|
143
|
-
|
|
144
|
-
watcher.on('error', (err) => {
|
|
145
|
-
console.error('Watcher error:', err);
|
|
146
|
-
});
|
|
147
|
-
|
|
148
|
-
watcher.start();
|
|
149
|
-
// Wait for likes...
|
|
150
|
-
// watcher.stop();
|
|
76
|
+
```ts
|
|
77
|
+
const liked = await social.likes();
|
|
78
|
+
const latestLiked = await social.likes(20);
|
|
151
79
|
```
|
|
152
80
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
The package exports convenience factory functions to construct platform-specific clients:
|
|
81
|
+
### `social.watchLikes(onLike, options?)`
|
|
156
82
|
|
|
157
|
-
|
|
158
|
-
|---------|---------|-------------|
|
|
159
|
-
| `createXClient(options)` | `SocialClient` | Constructs X/Twitter client with default implementation |
|
|
160
|
-
| `createMastodonClient(options)` | `never` | Currently throws "not implemented" error |
|
|
83
|
+
Starts polling immediately and returns a watcher you can stop later.
|
|
161
84
|
|
|
162
|
-
```
|
|
163
|
-
|
|
85
|
+
```ts
|
|
86
|
+
const watcher = social.watchLikes(
|
|
87
|
+
({ post, seenAt }) => {
|
|
88
|
+
console.log(`[${seenAt}] ${post.url}`);
|
|
89
|
+
},
|
|
90
|
+
{ everyMs: 30_000 }
|
|
91
|
+
);
|
|
164
92
|
|
|
165
|
-
//
|
|
166
|
-
|
|
93
|
+
// later
|
|
94
|
+
watcher.stop();
|
|
167
95
|
```
|
|
168
96
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
For a more opinionated interface, use `createSocial`:
|
|
97
|
+
Options:
|
|
172
98
|
|
|
173
|
-
|
|
174
|
-
|
|
99
|
+
- `everyMs?: number`
|
|
100
|
+
- `onError?: (error: Error) => void`
|
|
175
101
|
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
const timeline = await social.timeline({ maxResults: 10 });
|
|
179
|
-
const liked = await social.likedPosts({ maxResults: 10 });
|
|
102
|
+
You can also use the object form if you prefer:
|
|
180
103
|
|
|
104
|
+
```ts
|
|
181
105
|
const watcher = social.watchLikes({
|
|
182
|
-
|
|
106
|
+
everyMs: 30_000,
|
|
183
107
|
onLike: ({ post }) => {
|
|
184
|
-
console.log(
|
|
108
|
+
console.log(post.text);
|
|
185
109
|
},
|
|
186
110
|
});
|
|
187
|
-
|
|
188
|
-
watcher.start();
|
|
189
111
|
```
|
|
190
112
|
|
|
191
|
-
|
|
113
|
+
## Watcher
|
|
192
114
|
|
|
193
|
-
|
|
115
|
+
`watchLikes()` returns a `SocialLikeWatcher`.
|
|
194
116
|
|
|
195
|
-
|
|
196
|
-
- Get a bearer token from the X Developer Portal: https://developer.x.com/en/docs/authentication/oauth-2-0/bearer-tokens
|
|
117
|
+
Methods:
|
|
197
118
|
|
|
198
|
-
|
|
199
|
-
|
|
119
|
+
- `start()` starts polling and returns the watcher
|
|
120
|
+
- `stop()` stops polling
|
|
121
|
+
- `poll()` runs one polling cycle manually
|
|
200
122
|
|
|
201
|
-
|
|
202
|
-
type: "x",
|
|
203
|
-
bearerToken: process.env.X_BEARER_TOKEN,
|
|
204
|
-
});
|
|
205
|
-
```
|
|
123
|
+
The first poll seeds known likes and does not emit notifications for existing liked posts.
|
|
206
124
|
|
|
207
|
-
##
|
|
125
|
+
## Types
|
|
208
126
|
|
|
209
|
-
|
|
127
|
+
Core types exported by the package:
|
|
210
128
|
|
|
211
|
-
-
|
|
212
|
-
-
|
|
213
|
-
-
|
|
129
|
+
- `SocialOptions`
|
|
130
|
+
- `SocialListOptions`
|
|
131
|
+
- `SocialPost`
|
|
132
|
+
- `SocialAuthor`
|
|
133
|
+
- `SocialPostMetrics`
|
|
134
|
+
- `LikeNotification`
|
|
135
|
+
- `WatchLikesOptions`
|
|
214
136
|
|
|
215
|
-
|
|
137
|
+
## Compatibility Aliases
|
|
216
138
|
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
139
|
+
These still exist, but they are no longer the preferred style:
|
|
140
|
+
|
|
141
|
+
- `createSocialClient()` delegates to `createSocial()`
|
|
142
|
+
- `client.getPost()` delegates to `client.post()`
|
|
143
|
+
- `client.likedPosts()` delegates to `client.likes()`
|
|
144
|
+
- `pollIntervalMs` is accepted as an alias for `everyMs`
|
|
220
145
|
|
|
221
|
-
##
|
|
146
|
+
## Scope
|
|
222
147
|
|
|
223
|
-
|
|
148
|
+
This package is read-only for now:
|
|
224
149
|
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
| Liked Posts | ✅ | ❌ (stub) |
|
|
229
|
-
| Like Watching | ✅ | ❌ (stub) |
|
|
150
|
+
- Read timeline content
|
|
151
|
+
- Read liked posts
|
|
152
|
+
- Watch for newly liked posts
|
|
230
153
|
|
|
231
|
-
|
|
154
|
+
Posting, liking, and reposting are intentionally out of scope.
|
package/dist/SocialClient.d.ts
CHANGED
|
@@ -1,19 +1,22 @@
|
|
|
1
1
|
import { SocialLikeWatcher, type SocialLikeWatcherOptions } from "./SocialLikeWatcher.js";
|
|
2
2
|
import type { SocialProviderClient } from "./SocialProviderClient.js";
|
|
3
|
-
import type { SocialPost } from "./types.js";
|
|
3
|
+
import type { LikeNotification, SocialListOptions, SocialPost } from "./types.js";
|
|
4
|
+
type SocialListInput = number | SocialListOptions | {
|
|
5
|
+
readonly maxResults?: number;
|
|
6
|
+
};
|
|
4
7
|
/**
|
|
5
8
|
*
|
|
6
9
|
*/
|
|
7
10
|
export declare class SocialClient {
|
|
8
11
|
private readonly provider;
|
|
9
12
|
constructor(provider: SocialProviderClient);
|
|
13
|
+
post(postId: string): Promise<SocialPost | null>;
|
|
10
14
|
getPost(postId: string): Promise<SocialPost | null>;
|
|
11
|
-
timeline(options?:
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
likedPosts(options?: {
|
|
15
|
-
maxResults?: number;
|
|
16
|
-
}): Promise<readonly SocialPost[]>;
|
|
15
|
+
timeline(options?: SocialListInput): Promise<readonly SocialPost[]>;
|
|
16
|
+
likes(options?: SocialListInput): Promise<readonly SocialPost[]>;
|
|
17
|
+
likedPosts(options?: SocialListInput): Promise<readonly SocialPost[]>;
|
|
17
18
|
watchLikes(options: SocialLikeWatcherOptions): SocialLikeWatcher;
|
|
19
|
+
watchLikes(onLike: (notification: LikeNotification) => void, options?: Omit<SocialLikeWatcherOptions, "onLike">): SocialLikeWatcher;
|
|
18
20
|
}
|
|
21
|
+
export {};
|
|
19
22
|
//# sourceMappingURL=SocialClient.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SocialClient.d.ts","sourceRoot":"","sources":["../src/SocialClient.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iBAAiB,EACjB,KAAK,wBAAwB,EAC9B,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACtE,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"SocialClient.d.ts","sourceRoot":"","sources":["../src/SocialClient.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iBAAiB,EACjB,KAAK,wBAAwB,EAC9B,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACtE,OAAO,KAAK,EACV,gBAAgB,EAChB,iBAAiB,EACjB,UAAU,EACX,MAAM,YAAY,CAAC;AAEpB,KAAK,eAAe,GAChB,MAAM,GACN,iBAAiB,GACjB;IACE,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;CAC9B,CAAC;AAwBN;;GAEG;AACH,qBAAa,YAAY;IACX,OAAO,CAAC,QAAQ,CAAC,QAAQ;gBAAR,QAAQ,EAAE,oBAAoB;IAE3D,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;IAIhD,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;IAInD,QAAQ,CAAC,OAAO,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,SAAS,UAAU,EAAE,CAAC;IAInE,KAAK,CAAC,OAAO,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,SAAS,UAAU,EAAE,CAAC;IAIhE,UAAU,CAAC,OAAO,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,SAAS,UAAU,EAAE,CAAC;IAIrE,UAAU,CAAC,OAAO,EAAE,wBAAwB,GAAG,iBAAiB;IAChE,UAAU,CACR,MAAM,EAAE,CAAC,YAAY,EAAE,gBAAgB,KAAK,IAAI,EAChD,OAAO,CAAC,EAAE,IAAI,CAAC,wBAAwB,EAAE,QAAQ,CAAC,GACjD,iBAAiB;CAerB"}
|
package/dist/SocialClient.js
CHANGED
|
@@ -2,6 +2,18 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.SocialClient = void 0;
|
|
4
4
|
const SocialLikeWatcher_js_1 = require("./SocialLikeWatcher.js");
|
|
5
|
+
function normalizeListOptions(options) {
|
|
6
|
+
if (typeof options === "number") {
|
|
7
|
+
return { limit: options };
|
|
8
|
+
}
|
|
9
|
+
if (!options) {
|
|
10
|
+
return undefined;
|
|
11
|
+
}
|
|
12
|
+
return {
|
|
13
|
+
limit: ("limit" in options ? options.limit : undefined) ??
|
|
14
|
+
("maxResults" in options ? options.maxResults : undefined),
|
|
15
|
+
};
|
|
16
|
+
}
|
|
5
17
|
/**
|
|
6
18
|
*
|
|
7
19
|
*/
|
|
@@ -10,17 +22,29 @@ class SocialClient {
|
|
|
10
22
|
constructor(provider) {
|
|
11
23
|
this.provider = provider;
|
|
12
24
|
}
|
|
25
|
+
post(postId) {
|
|
26
|
+
return this.provider.post(postId);
|
|
27
|
+
}
|
|
13
28
|
getPost(postId) {
|
|
14
|
-
return this.
|
|
29
|
+
return this.post(postId);
|
|
15
30
|
}
|
|
16
31
|
timeline(options) {
|
|
17
|
-
return this.provider.
|
|
32
|
+
return this.provider.timeline(normalizeListOptions(options));
|
|
33
|
+
}
|
|
34
|
+
likes(options) {
|
|
35
|
+
return this.provider.likes(normalizeListOptions(options));
|
|
18
36
|
}
|
|
19
37
|
likedPosts(options) {
|
|
20
|
-
return this.
|
|
38
|
+
return this.likes(options);
|
|
21
39
|
}
|
|
22
|
-
watchLikes(options) {
|
|
23
|
-
|
|
40
|
+
watchLikes(optionsOrHandler, options) {
|
|
41
|
+
const watcherOptions = typeof optionsOrHandler === "function"
|
|
42
|
+
? {
|
|
43
|
+
...options,
|
|
44
|
+
onLike: optionsOrHandler,
|
|
45
|
+
}
|
|
46
|
+
: optionsOrHandler;
|
|
47
|
+
return SocialLikeWatcher_js_1.SocialLikeWatcher.create(this.provider, watcherOptions).start();
|
|
24
48
|
}
|
|
25
49
|
}
|
|
26
50
|
exports.SocialClient = SocialClient;
|
package/dist/SocialClient.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SocialClient.js","sourceRoot":"","sources":["../src/SocialClient.ts"],"names":[],"mappings":";;;AAAA,iEAGgC;
|
|
1
|
+
{"version":3,"file":"SocialClient.js","sourceRoot":"","sources":["../src/SocialClient.ts"],"names":[],"mappings":";;;AAAA,iEAGgC;AAmBhC,SAAS,oBAAoB,CAC3B,OAAyB;IAEzB,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE,CAAC;QAChC,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;IAC5B,CAAC;IAED,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,OAAO;QACL,KAAK,EACH,CAAC,OAAO,IAAI,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;YAChD,CAAC,YAAY,IAAI,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS,CAAC;KAC7D,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAa,YAAY;IACM;IAA7B,YAA6B,QAA8B;QAA9B,aAAQ,GAAR,QAAQ,CAAsB;IAAG,CAAC;IAE/D,IAAI,CAAC,MAAc;QACjB,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACpC,CAAC;IAED,OAAO,CAAC,MAAc;QACpB,OAAO,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAC3B,CAAC;IAED,QAAQ,CAAC,OAAyB;QAChC,OAAO,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,oBAAoB,CAAC,OAAO,CAAC,CAAC,CAAC;IAC/D,CAAC;IAED,KAAK,CAAC,OAAyB;QAC7B,OAAO,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,oBAAoB,CAAC,OAAO,CAAC,CAAC,CAAC;IAC5D,CAAC;IAED,UAAU,CAAC,OAAyB;QAClC,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAC7B,CAAC;IAOD,UAAU,CACR,gBAAiC,EACjC,OAAkD;QAElD,MAAM,cAAc,GAClB,OAAO,gBAAgB,KAAK,UAAU;YACpC,CAAC,CAAC;gBACE,GAAG,OAAO;gBACV,MAAM,EAAE,gBAAgB;aACzB;YACH,CAAC,CAAC,gBAAgB,CAAC;QAEvB,OAAO,wCAAiB,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,cAAc,CAAC,CAAC,KAAK,EAAE,CAAC;IACzE,CAAC;CACF;AA1CD,oCA0CC"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { SocialProviderClient } from "./SocialProviderClient.js";
|
|
2
|
-
import type {
|
|
3
|
-
export type SocialLikeWatcherOptions =
|
|
2
|
+
import type { WatchLikesOptions } from "./types.js";
|
|
3
|
+
export type SocialLikeWatcherOptions = WatchLikesOptions;
|
|
4
4
|
/**
|
|
5
5
|
*
|
|
6
6
|
*/
|
|
@@ -11,9 +11,9 @@ export declare class SocialLikeWatcher {
|
|
|
11
11
|
private polling;
|
|
12
12
|
private seeded;
|
|
13
13
|
private readonly knownLikeIds;
|
|
14
|
-
constructor(provider: SocialProviderClient, options: Required<Pick<
|
|
15
|
-
static create(provider: SocialProviderClient, options:
|
|
16
|
-
start():
|
|
14
|
+
constructor(provider: SocialProviderClient, options: Required<Pick<WatchLikesOptions, "everyMs">> & Pick<WatchLikesOptions, "onLike" | "onError">);
|
|
15
|
+
static create(provider: SocialProviderClient, options: WatchLikesOptions): SocialLikeWatcher;
|
|
16
|
+
start(): this;
|
|
17
17
|
stop(): void;
|
|
18
18
|
poll(): Promise<void>;
|
|
19
19
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SocialLikeWatcher.d.ts","sourceRoot":"","sources":["../src/SocialLikeWatcher.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACtE,OAAO,KAAK,EAAoB,
|
|
1
|
+
{"version":3,"file":"SocialLikeWatcher.d.ts","sourceRoot":"","sources":["../src/SocialLikeWatcher.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACtE,OAAO,KAAK,EAAoB,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAEtE,MAAM,MAAM,wBAAwB,GAAG,iBAAiB,CAAC;AAEzD;;GAEG;AACH,qBAAa,iBAAiB;IAO1B,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAP1B,OAAO,CAAC,KAAK,CAA+C;IAC5D,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAqB;gBAG/B,QAAQ,EAAE,oBAAoB,EAC9B,OAAO,EAAE,QAAQ,CAAC,IAAI,CAAC,iBAAiB,EAAE,SAAS,CAAC,CAAC,GACpE,IAAI,CAAC,iBAAiB,EAAE,QAAQ,GAAG,SAAS,CAAC;IAGjD,MAAM,CAAC,MAAM,CACX,QAAQ,EAAE,oBAAoB,EAC9B,OAAO,EAAE,iBAAiB,GACzB,iBAAiB;IAQpB,KAAK,IAAI,IAAI;IAWb,IAAI,IAAI,IAAI;IAON,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;CA6C5B"}
|
|
@@ -19,16 +19,17 @@ class SocialLikeWatcher {
|
|
|
19
19
|
static create(provider, options) {
|
|
20
20
|
return new SocialLikeWatcher(provider, {
|
|
21
21
|
...options,
|
|
22
|
-
|
|
22
|
+
everyMs: options.everyMs ?? options.pollIntervalMs ?? date_time_1.MILLISECONDS_PER_MINUTE,
|
|
23
23
|
});
|
|
24
24
|
}
|
|
25
25
|
start() {
|
|
26
26
|
if (this.timer !== null) {
|
|
27
|
-
return;
|
|
27
|
+
return this;
|
|
28
28
|
}
|
|
29
29
|
void this.poll();
|
|
30
|
-
this.timer = setInterval(() => void this.poll(), this.options.
|
|
30
|
+
this.timer = setInterval(() => void this.poll(), this.options.everyMs);
|
|
31
31
|
this.timer.unref();
|
|
32
|
+
return this;
|
|
32
33
|
}
|
|
33
34
|
stop() {
|
|
34
35
|
if (this.timer !== null) {
|
|
@@ -42,7 +43,7 @@ class SocialLikeWatcher {
|
|
|
42
43
|
}
|
|
43
44
|
this.polling = true;
|
|
44
45
|
try {
|
|
45
|
-
const liked = await this.provider.
|
|
46
|
+
const liked = await this.provider.likes();
|
|
46
47
|
const now = new Date().toISOString();
|
|
47
48
|
if (!this.seeded) {
|
|
48
49
|
for (const post of liked) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SocialLikeWatcher.js","sourceRoot":"","sources":["../src/SocialLikeWatcher.ts"],"names":[],"mappings":";;;AAAA,0DAAqE;AAOrE;;GAEG;AACH,MAAa,iBAAiB;IAOT;IACA;IAPX,KAAK,GAA0C,IAAI,CAAC;IACpD,OAAO,GAAG,KAAK,CAAC;IAChB,MAAM,GAAG,KAAK,CAAC;IACN,YAAY,GAAG,IAAI,GAAG,EAAU,CAAC;IAElD,YACmB,QAA8B,EAC9B,
|
|
1
|
+
{"version":3,"file":"SocialLikeWatcher.js","sourceRoot":"","sources":["../src/SocialLikeWatcher.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,11 +1,7 @@
|
|
|
1
|
-
import type { SocialPost } from "./types.js";
|
|
1
|
+
import type { SocialListOptions, SocialPost } from "./types.js";
|
|
2
2
|
export interface SocialProviderClient {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
}): Promise<readonly SocialPost[]>;
|
|
7
|
-
getLikedPosts(options?: {
|
|
8
|
-
maxResults?: number;
|
|
9
|
-
}): Promise<readonly SocialPost[]>;
|
|
3
|
+
post(postId: string): Promise<SocialPost | null>;
|
|
4
|
+
timeline(options?: SocialListOptions): Promise<readonly SocialPost[]>;
|
|
5
|
+
likes(options?: SocialListOptions): Promise<readonly SocialPost[]>;
|
|
10
6
|
}
|
|
11
7
|
//# sourceMappingURL=SocialProviderClient.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SocialProviderClient.d.ts","sourceRoot":"","sources":["../src/SocialProviderClient.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"SocialProviderClient.d.ts","sourceRoot":"","sources":["../src/SocialProviderClient.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAEhE,MAAM,WAAW,oBAAoB;IACnC,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC;IACjD,QAAQ,CAAC,OAAO,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,SAAS,UAAU,EAAE,CAAC,CAAC;IACtE,KAAK,CAAC,OAAO,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,SAAS,UAAU,EAAE,CAAC,CAAC;CACpE"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,17 +1,16 @@
|
|
|
1
|
-
export type { Provider, XConfig, SocialConfig, SocialPost, SocialAuthor, SocialPostMetrics, LikeWatcherOptions, LikeNotification, } from "./types.js";
|
|
2
|
-
export type { SocialProviderClient } from "./SocialProviderClient.js";
|
|
1
|
+
export type { Provider, XConfig, SocialOptions, SocialConfig, SocialListOptions, SocialPost, SocialAuthor, SocialPostMetrics, WatchLikesOptions, LikeWatcherOptions, LikeNotification, } from "./types.js";
|
|
3
2
|
export { SocialClient } from "./SocialClient.js";
|
|
4
3
|
export { SocialLikeWatcher, type SocialLikeWatcherOptions, } from "./SocialLikeWatcher.js";
|
|
5
|
-
export { XSocialClient } from "./x";
|
|
6
|
-
export { MastodonSocialClient } from "./mastodon/MastodonSocialClient.js";
|
|
7
4
|
import { SocialClient } from "./SocialClient.js";
|
|
8
|
-
import type {
|
|
5
|
+
import type { SocialOptions } from "./types.js";
|
|
9
6
|
/**
|
|
10
|
-
* Create
|
|
7
|
+
* Create the opinionated social client. X is the only provider today,
|
|
8
|
+
* so the factory accepts X settings directly and will also read
|
|
9
|
+
* X_BEARER_TOKEN from the environment.
|
|
11
10
|
*/
|
|
12
|
-
export declare function
|
|
11
|
+
export declare function createSocial(config?: SocialOptions): SocialClient;
|
|
13
12
|
/**
|
|
14
|
-
*
|
|
13
|
+
* Backwards-compatible alias for older call sites.
|
|
15
14
|
*/
|
|
16
|
-
export declare function
|
|
15
|
+
export declare function createSocialClient(config?: SocialOptions): SocialClient;
|
|
17
16
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,QAAQ,EACR,OAAO,EACP,YAAY,EACZ,UAAU,EACV,YAAY,EACZ,iBAAiB,EACjB,kBAAkB,EAClB,gBAAgB,GACjB,MAAM,YAAY,CAAC;AAEpB,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EACV,QAAQ,EACR,OAAO,EACP,aAAa,EACb,YAAY,EACZ,iBAAiB,EACjB,UAAU,EACV,YAAY,EACZ,iBAAiB,EACjB,iBAAiB,EACjB,kBAAkB,EAClB,gBAAgB,GACjB,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,EACL,iBAAiB,EACjB,KAAK,wBAAwB,GAC9B,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAGhD;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,MAAM,GAAE,aAAkB,GAAG,YAAY,CAErE;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,GAAE,aAAkB,GAAG,YAAY,CAE3E"}
|
package/dist/index.js
CHANGED
|
@@ -1,28 +1,26 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
4
|
-
exports.createSocialClient = createSocialClient;
|
|
3
|
+
exports.SocialLikeWatcher = exports.SocialClient = void 0;
|
|
5
4
|
exports.createSocial = createSocial;
|
|
5
|
+
exports.createSocialClient = createSocialClient;
|
|
6
6
|
var SocialClient_js_1 = require("./SocialClient.js");
|
|
7
7
|
Object.defineProperty(exports, "SocialClient", { enumerable: true, get: function () { return SocialClient_js_1.SocialClient; } });
|
|
8
8
|
var SocialLikeWatcher_js_1 = require("./SocialLikeWatcher.js");
|
|
9
9
|
Object.defineProperty(exports, "SocialLikeWatcher", { enumerable: true, get: function () { return SocialLikeWatcher_js_1.SocialLikeWatcher; } });
|
|
10
|
-
var x_1 = require("./x");
|
|
11
|
-
Object.defineProperty(exports, "XSocialClient", { enumerable: true, get: function () { return x_1.XSocialClient; } });
|
|
12
|
-
var MastodonSocialClient_js_1 = require("./mastodon/MastodonSocialClient.js");
|
|
13
|
-
Object.defineProperty(exports, "MastodonSocialClient", { enumerable: true, get: function () { return MastodonSocialClient_js_1.MastodonSocialClient; } });
|
|
14
10
|
const SocialClient_js_2 = require("./SocialClient.js");
|
|
15
|
-
const
|
|
11
|
+
const x_1 = require("./x");
|
|
16
12
|
/**
|
|
17
|
-
* Create
|
|
13
|
+
* Create the opinionated social client. X is the only provider today,
|
|
14
|
+
* so the factory accepts X settings directly and will also read
|
|
15
|
+
* X_BEARER_TOKEN from the environment.
|
|
18
16
|
*/
|
|
19
|
-
function
|
|
20
|
-
return new SocialClient_js_2.SocialClient(new
|
|
17
|
+
function createSocial(config = {}) {
|
|
18
|
+
return new SocialClient_js_2.SocialClient(new x_1.XSocialClient(config));
|
|
21
19
|
}
|
|
22
20
|
/**
|
|
23
|
-
*
|
|
21
|
+
* Backwards-compatible alias for older call sites.
|
|
24
22
|
*/
|
|
25
|
-
function
|
|
26
|
-
return
|
|
23
|
+
function createSocialClient(config = {}) {
|
|
24
|
+
return createSocial(config);
|
|
27
25
|
}
|
|
28
26
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AA6BA,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AA6BA,oCAEC;AAKD,gDAEC;AAxBD,qDAAiD;AAAxC,+GAAA,YAAY,OAAA;AACrB,+DAGgC;AAF9B,yHAAA,iBAAiB,OAAA;AAInB,uDAAiD;AAEjD,2BAAoC;AAEpC;;;;GAIG;AACH,SAAgB,YAAY,CAAC,SAAwB,EAAE;IACrD,OAAO,IAAI,8BAAY,CAAC,IAAI,iBAAa,CAAC,MAAM,CAAC,CAAC,CAAC;AACrD,CAAC;AAED;;GAEG;AACH,SAAgB,kBAAkB,CAAC,SAAwB,EAAE;IAC3D,OAAO,YAAY,CAAC,MAAM,CAAC,CAAC;AAC9B,CAAC"}
|
|
@@ -1,16 +1,15 @@
|
|
|
1
1
|
import type { SocialProviderClient } from "../SocialProviderClient.js";
|
|
2
|
-
import type { SocialPost } from "../types.js";
|
|
2
|
+
import type { SocialListOptions, SocialPost } from "../types.js";
|
|
3
3
|
/**
|
|
4
4
|
*
|
|
5
5
|
*/
|
|
6
6
|
export declare class MastodonSocialClient implements SocialProviderClient {
|
|
7
7
|
private readonly message;
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
}): Promise<readonly SocialPost[]>;
|
|
8
|
+
post(_postId: string): Promise<SocialPost | null>;
|
|
9
|
+
getPost(postId: string): Promise<SocialPost | null>;
|
|
10
|
+
timeline(_options?: SocialListOptions): Promise<readonly SocialPost[]>;
|
|
11
|
+
getTimeline(options?: SocialListOptions): Promise<readonly SocialPost[]>;
|
|
12
|
+
likes(_options?: SocialListOptions): Promise<readonly SocialPost[]>;
|
|
13
|
+
getLikedPosts(options?: SocialListOptions): Promise<readonly SocialPost[]>;
|
|
15
14
|
}
|
|
16
15
|
//# sourceMappingURL=MastodonSocialClient.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MastodonSocialClient.d.ts","sourceRoot":"","sources":["../../src/mastodon/MastodonSocialClient.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AACvE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"MastodonSocialClient.d.ts","sourceRoot":"","sources":["../../src/mastodon/MastodonSocialClient.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AACvE,OAAO,KAAK,EAAE,iBAAiB,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEjE;;GAEG;AACH,qBAAa,oBAAqB,YAAW,oBAAoB;IAC/D,OAAO,CAAC,QAAQ,CAAC,OAAO,CACiF;IAEzG,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;IAIjD,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;IAInD,QAAQ,CAAC,QAAQ,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,SAAS,UAAU,EAAE,CAAC;IAItE,WAAW,CAAC,OAAO,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,SAAS,UAAU,EAAE,CAAC;IAIxE,KAAK,CAAC,QAAQ,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,SAAS,UAAU,EAAE,CAAC;IAInE,aAAa,CAAC,OAAO,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,SAAS,UAAU,EAAE,CAAC;CAG3E"}
|
|
@@ -6,15 +6,24 @@ exports.MastodonSocialClient = void 0;
|
|
|
6
6
|
*/
|
|
7
7
|
class MastodonSocialClient {
|
|
8
8
|
message = 'MastodonSocialClient is not yet supported in @hardlydifficult/social. Use provider type "x" for now.';
|
|
9
|
-
|
|
9
|
+
post(_postId) {
|
|
10
10
|
throw new Error(this.message);
|
|
11
11
|
}
|
|
12
|
-
|
|
12
|
+
getPost(postId) {
|
|
13
|
+
return this.post(postId);
|
|
14
|
+
}
|
|
15
|
+
timeline(_options) {
|
|
13
16
|
throw new Error(this.message);
|
|
14
17
|
}
|
|
15
|
-
|
|
18
|
+
getTimeline(options) {
|
|
19
|
+
return this.timeline(options);
|
|
20
|
+
}
|
|
21
|
+
likes(_options) {
|
|
16
22
|
throw new Error(this.message);
|
|
17
23
|
}
|
|
24
|
+
getLikedPosts(options) {
|
|
25
|
+
return this.likes(options);
|
|
26
|
+
}
|
|
18
27
|
}
|
|
19
28
|
exports.MastodonSocialClient = MastodonSocialClient;
|
|
20
29
|
//# sourceMappingURL=MastodonSocialClient.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MastodonSocialClient.js","sourceRoot":"","sources":["../../src/mastodon/MastodonSocialClient.ts"],"names":[],"mappings":";;;AAGA;;GAEG;AACH,MAAa,oBAAoB;IACd,OAAO,GACtB,sGAAsG,CAAC;IAEzG,
|
|
1
|
+
{"version":3,"file":"MastodonSocialClient.js","sourceRoot":"","sources":["../../src/mastodon/MastodonSocialClient.ts"],"names":[],"mappings":";;;AAGA;;GAEG;AACH,MAAa,oBAAoB;IACd,OAAO,GACtB,sGAAsG,CAAC;IAEzG,IAAI,CAAC,OAAe;QAClB,MAAM,IAAI,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAChC,CAAC;IAED,OAAO,CAAC,MAAc;QACpB,OAAO,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAC3B,CAAC;IAED,QAAQ,CAAC,QAA4B;QACnC,MAAM,IAAI,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAChC,CAAC;IAED,WAAW,CAAC,OAA2B;QACrC,OAAO,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;IAChC,CAAC;IAED,KAAK,CAAC,QAA4B;QAChC,MAAM,IAAI,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAChC,CAAC;IAED,aAAa,CAAC,OAA2B;QACvC,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAC7B,CAAC;CACF;AA3BD,oDA2BC"}
|
package/dist/types.d.ts
CHANGED
|
@@ -1,10 +1,15 @@
|
|
|
1
1
|
export type Provider = "x";
|
|
2
|
-
export interface
|
|
3
|
-
readonly type
|
|
2
|
+
export interface SocialOptions {
|
|
3
|
+
readonly type?: "x";
|
|
4
4
|
readonly bearerToken?: string;
|
|
5
|
+
readonly limit?: number;
|
|
5
6
|
readonly maxResults?: number;
|
|
6
7
|
}
|
|
7
|
-
export type
|
|
8
|
+
export type XConfig = SocialOptions;
|
|
9
|
+
export type SocialConfig = SocialOptions;
|
|
10
|
+
export interface SocialListOptions {
|
|
11
|
+
readonly limit?: number;
|
|
12
|
+
}
|
|
8
13
|
export interface SocialAuthor {
|
|
9
14
|
readonly id: string;
|
|
10
15
|
readonly username: string;
|
|
@@ -27,9 +32,11 @@ export interface LikeNotification {
|
|
|
27
32
|
readonly post: SocialPost;
|
|
28
33
|
readonly seenAt: string;
|
|
29
34
|
}
|
|
30
|
-
export interface
|
|
35
|
+
export interface WatchLikesOptions {
|
|
36
|
+
readonly everyMs?: number;
|
|
31
37
|
readonly pollIntervalMs?: number;
|
|
32
38
|
readonly onLike: (notification: LikeNotification) => void;
|
|
33
39
|
readonly onError?: (error: Error) => void;
|
|
34
40
|
}
|
|
41
|
+
export type LikeWatcherOptions = WatchLikesOptions;
|
|
35
42
|
//# sourceMappingURL=types.d.ts.map
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,QAAQ,GAAG,GAAG,CAAC;AAE3B,MAAM,WAAW,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,QAAQ,GAAG,GAAG,CAAC;AAE3B,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC;IACpB,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED,MAAM,MAAM,OAAO,GAAG,aAAa,CAAC;AAEpC,MAAM,MAAM,YAAY,GAAG,aAAa,CAAC;AAEzC,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;CAC9B;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC;IAC9B,QAAQ,CAAC,OAAO,EAAE,iBAAiB,CAAC;CACrC;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,MAAM,EAAE,CAAC,YAAY,EAAE,gBAAgB,KAAK,IAAI,CAAC;IAC1D,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;CAC3C;AAED,MAAM,MAAM,kBAAkB,GAAG,iBAAiB,CAAC"}
|
|
@@ -1,19 +1,18 @@
|
|
|
1
1
|
import type { SocialProviderClient } from "../SocialProviderClient.js";
|
|
2
|
-
import type { SocialPost, XConfig } from "../types.js";
|
|
2
|
+
import type { SocialListOptions, SocialPost, XConfig } from "../types.js";
|
|
3
3
|
/**
|
|
4
4
|
*
|
|
5
5
|
*/
|
|
6
6
|
export declare class XSocialClient implements SocialProviderClient {
|
|
7
7
|
private readonly bearerToken;
|
|
8
|
-
private readonly
|
|
8
|
+
private readonly limit;
|
|
9
9
|
constructor(config: XConfig);
|
|
10
|
+
post(postId: string): Promise<SocialPost | null>;
|
|
10
11
|
getPost(postId: string): Promise<SocialPost | null>;
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
getLikedPosts(options?:
|
|
15
|
-
maxResults?: number;
|
|
16
|
-
}): Promise<readonly SocialPost[]>;
|
|
12
|
+
timeline(options?: SocialListOptions): Promise<readonly SocialPost[]>;
|
|
13
|
+
getTimeline(options?: SocialListOptions): Promise<readonly SocialPost[]>;
|
|
14
|
+
likes(options?: SocialListOptions): Promise<readonly SocialPost[]>;
|
|
15
|
+
getLikedPosts(options?: SocialListOptions): Promise<readonly SocialPost[]>;
|
|
17
16
|
private buildQuery;
|
|
18
17
|
private request;
|
|
19
18
|
private readSingleTweet;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"XSocialClient.d.ts","sourceRoot":"","sources":["../../src/x/XSocialClient.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AACvE,OAAO,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"XSocialClient.d.ts","sourceRoot":"","sources":["../../src/x/XSocialClient.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,4BAA4B,CAAC;AACvE,OAAO,KAAK,EAAE,iBAAiB,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AA2B1E;;GAEG;AACH,qBAAa,aAAc,YAAW,oBAAoB;IACxD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAS;gBAEnB,MAAM,EAAE,OAAO;IASrB,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;IAYtD,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;IAI7C,QAAQ,CAAC,OAAO,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,SAAS,UAAU,EAAE,CAAC;IAU3E,WAAW,CAAC,OAAO,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,SAAS,UAAU,EAAE,CAAC;IAIlE,KAAK,CAAC,OAAO,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,SAAS,UAAU,EAAE,CAAC;IAUxE,aAAa,CAAC,OAAO,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,SAAS,UAAU,EAAE,CAAC;IAI1E,OAAO,CAAC,UAAU;YAWJ,OAAO;IAgBrB,OAAO,CAAC,eAAe;IAQvB,OAAO,CAAC,aAAa;IAQrB,OAAO,CAAC,OAAO;IAWf,OAAO,CAAC,cAAc;CAoBvB"}
|
package/dist/x/XSocialClient.js
CHANGED
|
@@ -6,15 +6,15 @@ exports.XSocialClient = void 0;
|
|
|
6
6
|
*/
|
|
7
7
|
class XSocialClient {
|
|
8
8
|
bearerToken;
|
|
9
|
-
|
|
9
|
+
limit;
|
|
10
10
|
constructor(config) {
|
|
11
11
|
this.bearerToken = config.bearerToken ?? process.env.X_BEARER_TOKEN ?? "";
|
|
12
|
-
this.
|
|
12
|
+
this.limit = config.limit ?? config.maxResults ?? 25;
|
|
13
13
|
if (this.bearerToken.length === 0) {
|
|
14
14
|
throw new Error("X bearer token is required. Set X_BEARER_TOKEN.");
|
|
15
15
|
}
|
|
16
16
|
}
|
|
17
|
-
async
|
|
17
|
+
async post(postId) {
|
|
18
18
|
const response = await this.request(`/tweets/${postId}${this.buildQuery()}`);
|
|
19
19
|
const tweet = this.readSingleTweet(response.data);
|
|
20
20
|
if (!tweet) {
|
|
@@ -22,20 +22,29 @@ class XSocialClient {
|
|
|
22
22
|
}
|
|
23
23
|
return this.normalizeTweet(tweet, response.includes?.users ?? []);
|
|
24
24
|
}
|
|
25
|
-
|
|
26
|
-
|
|
25
|
+
getPost(postId) {
|
|
26
|
+
return this.post(postId);
|
|
27
|
+
}
|
|
28
|
+
async timeline(options) {
|
|
29
|
+
const response = await this.request(`/users/me/timelines/reverse_chronological${this.buildQuery(options?.limit)}`);
|
|
27
30
|
return this.readTweetList(response.data).map((tweet) => this.normalizeTweet(tweet, response.includes?.users ?? []));
|
|
28
31
|
}
|
|
29
|
-
|
|
30
|
-
|
|
32
|
+
getTimeline(options) {
|
|
33
|
+
return this.timeline(options);
|
|
34
|
+
}
|
|
35
|
+
async likes(options) {
|
|
36
|
+
const response = await this.request(`/users/me/liked_tweets${this.buildQuery(options?.limit)}`);
|
|
31
37
|
return this.readTweetList(response.data).map((tweet) => this.normalizeTweet(tweet, response.includes?.users ?? []));
|
|
32
38
|
}
|
|
33
|
-
|
|
39
|
+
getLikedPosts(options) {
|
|
40
|
+
return this.likes(options);
|
|
41
|
+
}
|
|
42
|
+
buildQuery(limit) {
|
|
34
43
|
const params = new URLSearchParams({
|
|
35
44
|
expansions: "author_id",
|
|
36
45
|
"tweet.fields": "created_at,public_metrics",
|
|
37
46
|
"user.fields": "name,username",
|
|
38
|
-
max_results: String(
|
|
47
|
+
max_results: String(limit ?? this.limit),
|
|
39
48
|
});
|
|
40
49
|
return `?${params.toString()}`;
|
|
41
50
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"XSocialClient.js","sourceRoot":"","sources":["../../src/x/XSocialClient.ts"],"names":[],"mappings":";;;AA4BA;;GAEG;AACH,MAAa,aAAa;IACP,WAAW,CAAS;IACpB,
|
|
1
|
+
{"version":3,"file":"XSocialClient.js","sourceRoot":"","sources":["../../src/x/XSocialClient.ts"],"names":[],"mappings":"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"}
|