-
-
Notifications
You must be signed in to change notification settings - Fork 53
/
polar.ts
83 lines (75 loc) · 2.41 KB
/
polar.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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
import { ofetch } from 'ofetch'
import type { Provider, Sponsorship } from '../types'
export const PolarProvider: Provider = {
name: 'polar',
fetchSponsors(config) {
return fetchPolarSponsors(config.polar?.token || config.token!, config.polar?.organization)
},
}
export async function fetchPolarSponsors(token: string, organization?: string): Promise<Sponsorship[]> {
if (!token)
throw new Error('Polar token is required')
if (!organization)
throw new Error('Polar organization is required')
const apiFetch = ofetch.create({
baseURL: 'https://api.polar.sh/v1',
headers: { Authorization: `Bearer ${token}` },
})
/**
* Get the organization by config name. Fetching the ID for future API calls.
*
* For backward compatability with existing configs, improved readability & DX,
* we keep config.polar.organization vs. introducing config.polar.organization_id even
* though we only need the ID.
*/
const org = await apiFetch('/organizations', {
params: {
slug: organization,
},
})
const orgId = org.items?.[0]?.id
if (!orgId)
throw new Error(`Polar organization "${organization}" not found`)
/**
* Fetch the list of all subscriptions. This is a paginated
* endpoint so loop through all the pages
*/
let page = 1
let pages = 1
const subscriptions = []
do {
const params: Record<string, any> = {
organization_id: orgId,
page,
}
const subs = await apiFetch('/subscriptions', { params })
subscriptions.push(...subs.items)
pages = subs.pagination.max_page
page += 1
} while (page <= pages)
return subscriptions
/**
* - People can subscribe for free on Polar : the price is null in this case
*/
.filter(sub => !!sub.price)
.map((sub) => {
const isActive = sub.status === 'active'
return {
sponsor: {
name: sub.user.public_name,
avatarUrl: sub.user.avatar_url,
login: sub.user.github_username,
type: sub.product.type === 'individual' ? 'User' : 'Organization',
socialLogins: {
github: sub.user.github_username,
},
},
isOneTime: false,
provider: 'polar',
privacyLevel: 'PUBLIC',
createdAt: new Date(sub.created_at).toISOString(),
tierName: isActive ? sub.product.name : undefined,
monthlyDollars: isActive ? sub.price.price_amount / 100 : -1,
}
})
}