@anitrack/patreon-wrapper 1.5.3 → 1.6.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/.prettierrc +6 -0
- package/LICENSE +21 -21
- package/README.md +185 -157
- package/package.json +35 -36
- package/{lib → src}/index.d.ts +19 -3
- package/src/index.d.ts.map +1 -0
- package/src/index.js +179 -0
- package/src/index.js.map +1 -0
- package/src/index.ts +309 -265
- package/tsconfig.json +14 -102
- package/lib/index.d.ts.map +0 -1
- package/lib/index.js +0 -157
- package/lib/index.js.map +0 -1
package/src/index.ts
CHANGED
|
@@ -1,265 +1,309 @@
|
|
|
1
|
-
import axios from 'axios';
|
|
2
|
-
|
|
3
|
-
export type PatronStatus =
|
|
4
|
-
| 'active_patron'
|
|
5
|
-
| 'declined_patron'
|
|
6
|
-
| 'former_patron';
|
|
7
|
-
|
|
8
|
-
export type PatronAPIAuth = {
|
|
9
|
-
AccessToken: string;
|
|
10
|
-
CampaignID: string;
|
|
11
|
-
};
|
|
12
|
-
|
|
13
|
-
export type PatronType = {
|
|
14
|
-
displayId: string;
|
|
15
|
-
displayName: string;
|
|
16
|
-
emailAddress: string;
|
|
17
|
-
isFollower: boolean;
|
|
18
|
-
subscription: {
|
|
19
|
-
note: string;
|
|
20
|
-
currentEntitled: {
|
|
21
|
-
status: PatronStatus;
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
};
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
const
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
:
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
return
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
}
|
|
265
|
-
|
|
1
|
+
import axios from 'axios';
|
|
2
|
+
|
|
3
|
+
export type PatronStatus =
|
|
4
|
+
| 'active_patron'
|
|
5
|
+
| 'declined_patron'
|
|
6
|
+
| 'former_patron';
|
|
7
|
+
|
|
8
|
+
export type PatronAPIAuth = {
|
|
9
|
+
AccessToken: string;
|
|
10
|
+
CampaignID: string;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export type PatronType = {
|
|
14
|
+
displayId: string;
|
|
15
|
+
displayName: string | null; // [2026-05-26] Identity Masking
|
|
16
|
+
emailAddress: string | null; // [2026-05-26] Identity Masking
|
|
17
|
+
isFollower: boolean;
|
|
18
|
+
subscription: {
|
|
19
|
+
note: string;
|
|
20
|
+
currentEntitled: {
|
|
21
|
+
status: PatronStatus;
|
|
22
|
+
lastChargeStatus: string | null;
|
|
23
|
+
tier: {
|
|
24
|
+
id: string;
|
|
25
|
+
title: string;
|
|
26
|
+
};
|
|
27
|
+
cents: number;
|
|
28
|
+
willPayCents: number;
|
|
29
|
+
lifetimeCents: number;
|
|
30
|
+
firstCharge: string;
|
|
31
|
+
nextCharge: string;
|
|
32
|
+
lastCharge: string;
|
|
33
|
+
};
|
|
34
|
+
};
|
|
35
|
+
mediaConnection: {
|
|
36
|
+
patreon: {
|
|
37
|
+
id: string;
|
|
38
|
+
url: string;
|
|
39
|
+
};
|
|
40
|
+
discord: {
|
|
41
|
+
id: string | null;
|
|
42
|
+
url: string | null;
|
|
43
|
+
};
|
|
44
|
+
};
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
export type CampaignType = {
|
|
48
|
+
id: string;
|
|
49
|
+
name: string;
|
|
50
|
+
patronCount: number;
|
|
51
|
+
currency: string;
|
|
52
|
+
isMonthly: boolean;
|
|
53
|
+
isNsfw: boolean;
|
|
54
|
+
summary: string | null;
|
|
55
|
+
createdAt: string;
|
|
56
|
+
publishedAt: string | null;
|
|
57
|
+
imageUrl: string | null;
|
|
58
|
+
imageSmallUrl: string | null;
|
|
59
|
+
discordServerId: string | null;
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
export type SandboxOptions = {
|
|
63
|
+
displayId: string;
|
|
64
|
+
displayName: string;
|
|
65
|
+
emailAddress: string;
|
|
66
|
+
tier: {
|
|
67
|
+
id: string;
|
|
68
|
+
title: string;
|
|
69
|
+
};
|
|
70
|
+
cents: number;
|
|
71
|
+
willPayCents: number;
|
|
72
|
+
lifetimeCents: number;
|
|
73
|
+
patronStatus: PatronStatus;
|
|
74
|
+
firstCharge: string;
|
|
75
|
+
nextCharge: string;
|
|
76
|
+
lastCharge: string;
|
|
77
|
+
mediaConnection: {
|
|
78
|
+
patreon: {
|
|
79
|
+
id: string;
|
|
80
|
+
url: string;
|
|
81
|
+
};
|
|
82
|
+
discord: {
|
|
83
|
+
id: string | null;
|
|
84
|
+
url: string | null;
|
|
85
|
+
};
|
|
86
|
+
};
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
export class Patreon {
|
|
90
|
+
private static _URL: string = 'https://www.patreon.com/api/oauth2/v2/';
|
|
91
|
+
|
|
92
|
+
private static _AccessToken: string;
|
|
93
|
+
private static _CampaignID: string;
|
|
94
|
+
private static _SandboxPatrons: Array<SandboxOptions> = [];
|
|
95
|
+
|
|
96
|
+
public static Authorization(AuthCredentials: PatronAPIAuth) {
|
|
97
|
+
if (!AuthCredentials.AccessToken || !AuthCredentials.CampaignID) {
|
|
98
|
+
throw new Error(
|
|
99
|
+
'AccessToken and CampaignID are required on Authorization'
|
|
100
|
+
);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
this._AccessToken = AuthCredentials.AccessToken;
|
|
104
|
+
this._CampaignID = AuthCredentials.CampaignID;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
private static async FetchAPI(url: string) {
|
|
108
|
+
if (!this._AccessToken || !this._CampaignID) {
|
|
109
|
+
throw new Error(
|
|
110
|
+
'AccessToken and CampaignID are required on Authorization'
|
|
111
|
+
);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
const resolvedUrl = url.startsWith('http') ? url : this._URL + url;
|
|
115
|
+
|
|
116
|
+
return await axios(resolvedUrl, {
|
|
117
|
+
method: 'GET',
|
|
118
|
+
headers: { Authorization: 'Bearer ' + this._AccessToken },
|
|
119
|
+
}).catch((err: Error) => {
|
|
120
|
+
throw new Error('Fetch API Failed...' + err);
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
private static BuildMembersURL(pageSize: number): string {
|
|
125
|
+
const params = new URLSearchParams({
|
|
126
|
+
include: 'user,currently_entitled_tiers',
|
|
127
|
+
'page[count]': String(pageSize),
|
|
128
|
+
'fields[member]':
|
|
129
|
+
'currently_entitled_amount_cents,campaign_lifetime_support_cents,email,full_name,is_follower,last_charge_date,last_charge_status,next_charge_date,note,patron_status,pledge_relationship_start,will_pay_amount_cents',
|
|
130
|
+
'fields[user]': 'social_connections',
|
|
131
|
+
'fields[tier]': 'title',
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
return `${this._URL}campaigns/${this._CampaignID}/members?${params.toString()}`;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
public static async FetchPatrons(
|
|
138
|
+
filters: Array<PatronStatus> = ['active_patron'],
|
|
139
|
+
pageSize: number = 450,
|
|
140
|
+
showSandboxPatrons: boolean = false
|
|
141
|
+
) {
|
|
142
|
+
const Patrons: Array<PatronType> = [];
|
|
143
|
+
let nextUrl: string | null = this.BuildMembersURL(pageSize);
|
|
144
|
+
|
|
145
|
+
while (nextUrl) {
|
|
146
|
+
const { data } = await this.FetchAPI(nextUrl);
|
|
147
|
+
const PagePatrons = data?.data || [];
|
|
148
|
+
|
|
149
|
+
for (let x = 0; x < PagePatrons.length; x++) {
|
|
150
|
+
const Relationships = PagePatrons[x].relationships;
|
|
151
|
+
const Attributes = PagePatrons[x].attributes;
|
|
152
|
+
|
|
153
|
+
if (!filters.includes(Attributes.patron_status)) continue;
|
|
154
|
+
|
|
155
|
+
const socialInfo = data.included?.find(
|
|
156
|
+
(item: any) =>
|
|
157
|
+
item.id === Relationships.user.data.id &&
|
|
158
|
+
item.type === 'user'
|
|
159
|
+
);
|
|
160
|
+
|
|
161
|
+
const tierInfo = data.included?.find(
|
|
162
|
+
(item: any) =>
|
|
163
|
+
item.id ===
|
|
164
|
+
Relationships.currently_entitled_tiers?.data[0]
|
|
165
|
+
?.id && item.type === 'tier'
|
|
166
|
+
);
|
|
167
|
+
|
|
168
|
+
const discordId =
|
|
169
|
+
socialInfo?.attributes?.social_connections?.discord
|
|
170
|
+
?.user_id ?? null;
|
|
171
|
+
|
|
172
|
+
Patrons.push({
|
|
173
|
+
displayId: Relationships.user.data.id,
|
|
174
|
+
displayName: Attributes.full_name ?? null,
|
|
175
|
+
emailAddress: Attributes.email ?? null,
|
|
176
|
+
isFollower: Attributes.is_follower,
|
|
177
|
+
subscription: {
|
|
178
|
+
note: Attributes.note,
|
|
179
|
+
currentEntitled: {
|
|
180
|
+
status: Attributes.patron_status,
|
|
181
|
+
lastChargeStatus:
|
|
182
|
+
Attributes.last_charge_status ?? null,
|
|
183
|
+
tier: {
|
|
184
|
+
id: tierInfo ? tierInfo.id : null,
|
|
185
|
+
title: tierInfo
|
|
186
|
+
? tierInfo.attributes.title
|
|
187
|
+
: null,
|
|
188
|
+
},
|
|
189
|
+
cents:
|
|
190
|
+
Attributes.currently_entitled_amount_cents !== 0
|
|
191
|
+
? Attributes.currently_entitled_amount_cents
|
|
192
|
+
: null,
|
|
193
|
+
willPayCents: Attributes.will_pay_amount_cents,
|
|
194
|
+
lifetimeCents:
|
|
195
|
+
Attributes.campaign_lifetime_support_cents,
|
|
196
|
+
firstCharge: Attributes.pledge_relationship_start,
|
|
197
|
+
nextCharge: Attributes.next_charge_date,
|
|
198
|
+
lastCharge: Attributes.last_charge_date,
|
|
199
|
+
},
|
|
200
|
+
},
|
|
201
|
+
mediaConnection: {
|
|
202
|
+
patreon: {
|
|
203
|
+
id: Relationships.user.data.id,
|
|
204
|
+
url: Relationships.user.links.related,
|
|
205
|
+
},
|
|
206
|
+
discord: {
|
|
207
|
+
id: discordId,
|
|
208
|
+
url: discordId
|
|
209
|
+
? `https://discord.com/users/${discordId}`
|
|
210
|
+
: null,
|
|
211
|
+
},
|
|
212
|
+
},
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
nextUrl = data?.links?.next ?? null;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
if (showSandboxPatrons) {
|
|
220
|
+
for (let x = 0; x < this._SandboxPatrons.length; x++) {
|
|
221
|
+
const Patron = this._SandboxPatrons[x];
|
|
222
|
+
|
|
223
|
+
Patrons.push({
|
|
224
|
+
displayId: Patron.displayId,
|
|
225
|
+
displayName: Patron.displayName,
|
|
226
|
+
emailAddress: Patron.emailAddress,
|
|
227
|
+
isFollower: false,
|
|
228
|
+
subscription: {
|
|
229
|
+
note: 'Sandbox',
|
|
230
|
+
currentEntitled: {
|
|
231
|
+
status: Patron.patronStatus,
|
|
232
|
+
lastChargeStatus: null,
|
|
233
|
+
tier: {
|
|
234
|
+
id: Patron.tier.id,
|
|
235
|
+
title: Patron.tier.title,
|
|
236
|
+
},
|
|
237
|
+
cents: Patron.cents,
|
|
238
|
+
willPayCents: Patron.willPayCents,
|
|
239
|
+
lifetimeCents: Patron.lifetimeCents,
|
|
240
|
+
firstCharge: Patron.firstCharge,
|
|
241
|
+
nextCharge: Patron.nextCharge,
|
|
242
|
+
lastCharge: Patron.lastCharge,
|
|
243
|
+
},
|
|
244
|
+
},
|
|
245
|
+
mediaConnection: {
|
|
246
|
+
patreon: {
|
|
247
|
+
id: Patron.mediaConnection.patreon.id,
|
|
248
|
+
url: Patron.mediaConnection.patreon.url,
|
|
249
|
+
},
|
|
250
|
+
discord: {
|
|
251
|
+
id: Patron.mediaConnection.discord?.id ?? null,
|
|
252
|
+
url: Patron.mediaConnection.discord?.url ?? null,
|
|
253
|
+
},
|
|
254
|
+
},
|
|
255
|
+
});
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
return Patrons;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
protected static _SandboxAddPatron(Patron: SandboxOptions) {
|
|
263
|
+
this._SandboxPatrons.push(Patron);
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
protected static _SandboxGetPatron() {
|
|
267
|
+
return this._SandboxPatrons;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
// public static FetchPatron() {}
|
|
271
|
+
|
|
272
|
+
public static async FetchCampaign(): Promise<CampaignType> {
|
|
273
|
+
const params = new URLSearchParams({
|
|
274
|
+
'fields[campaign]':
|
|
275
|
+
'name,currency,patron_count,is_monthly,is_nsfw,summary,created_at,published_at,image_url,image_small_url,discord_server_id',
|
|
276
|
+
});
|
|
277
|
+
|
|
278
|
+
const { data } = await this.FetchAPI(
|
|
279
|
+
`campaigns/${this._CampaignID}?${params.toString()}`
|
|
280
|
+
);
|
|
281
|
+
|
|
282
|
+
const Attributes = data?.data?.attributes;
|
|
283
|
+
|
|
284
|
+
return {
|
|
285
|
+
id: data?.data?.id,
|
|
286
|
+
name: Attributes.name,
|
|
287
|
+
patronCount: Attributes.patron_count,
|
|
288
|
+
currency: Attributes.currency,
|
|
289
|
+
isMonthly: Attributes.is_monthly,
|
|
290
|
+
isNsfw: Attributes.is_nsfw,
|
|
291
|
+
summary: Attributes.summary ?? null,
|
|
292
|
+
createdAt: Attributes.created_at,
|
|
293
|
+
publishedAt: Attributes.published_at ?? null,
|
|
294
|
+
imageUrl: Attributes.image_url ?? null,
|
|
295
|
+
imageSmallUrl: Attributes.image_small_url ?? null,
|
|
296
|
+
discordServerId: Attributes.discord_server_id ?? null,
|
|
297
|
+
};
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
export class Sandbox extends Patreon {
|
|
302
|
+
public static GetPatrons() {
|
|
303
|
+
return super._SandboxGetPatron();
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
public static AddPatron(Patron: SandboxOptions) {
|
|
307
|
+
super._SandboxAddPatron(Patron);
|
|
308
|
+
}
|
|
309
|
+
}
|