Skip to content

Commit fdd92b5

Browse files
refactor: sonar fixes (#78)
1 parent 7741231 commit fdd92b5

13 files changed

Lines changed: 164 additions & 157 deletions

File tree

src/cache.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ export function stringifyCache(cache: Sponsorship[]): string {
55
return JSON.stringify(
66
cache,
77
(_key, value) => {
8-
if (value && value.type === 'Buffer' && Array.isArray(value.data)) {
8+
if (value?.type === 'Buffer' && Array.isArray(value.data)) {
99
return Buffer.from(value.data).toString('base64')
1010
}
1111
return value

src/cli.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import cac from 'cac'
33
import { version } from '../package.json'
44
import { run } from './run'
55

6-
const RE_FILTER = /([<>=]+)(\d+)/
6+
const RE_FILTER = /^(<=?|>=?)(\d+)$/
77
const cli = cac('contributors-svg')
88
.version(version)
99
.help()
@@ -37,7 +37,11 @@ cli.parse()
3737
* @param template
3838
*/
3939
function createFilterFromString(template: string): ContribkitConfig['filter'] {
40-
const [_, op, value] = template.split(RE_FILTER)
40+
const match = RE_FILTER.exec(template)
41+
if (!match)
42+
throw new Error(`Unable to parse filter template ${template}`)
43+
44+
const [, op, value] = match
4145
const num = Number.parseInt(value)
4246
if (op === '<')
4347
return s => s.monthlyDollars < num

src/configs/index.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,13 +69,13 @@ export async function loadConfig(inlineConfig: ContribkitConfig = {}): Promise<R
6969
if (!['sponsors', 'sponsees'].includes(resolved.mode))
7070
throw new Error(`Invalid mode: ${resolved.mode}. Expected "sponsors" or "sponsees".`)
7171

72-
resolved.name = inlineConfig.name || config.name || envConfig.name || resolved.mode
72+
resolved.name = inlineConfig.name ?? config.name ?? envConfig.name ?? resolved.mode
7373

7474
return resolved
7575
}
7676

7777
export function partitionTiers(sponsors: Sponsorship[], tiers: Tier[], includePastSponsors?: boolean): TierPartition[] {
78-
const tierMappings = tiers!.map<TierPartition>(tier => ({
78+
const tierMappings = tiers.map<TierPartition>(tier => ({
7979
monthlyDollars: tier.monthlyDollars ?? 0,
8080
tier,
8181
sponsors: [],
@@ -88,8 +88,9 @@ export function partitionTiers(sponsors: Sponsorship[], tiers: Tier[], includePa
8888
if (finalSponsors.length !== 1)
8989
throw new Error(`There should be exactly one tier with no \`monthlyDollars\`, but got ${finalSponsors.length}`)
9090

91+
sponsors.sort((a, b) => Date.parse(a.createdAt!) - Date.parse(b.createdAt!))
92+
9193
sponsors
92-
.sort((a, b) => Date.parse(a.createdAt!) - Date.parse(b.createdAt!))
9394
.filter(s => s.monthlyDollars > 0 || includePastSponsors) // Past sponsors monthlyDollars is -1
9495
.forEach((sponsor) => {
9596
const tier = tierMappings.find(t => sponsor.monthlyDollars >= t.monthlyDollars) ?? tierMappings[0]

src/processing/image.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,16 +51,16 @@ export async function resolveAvatars(
5151
if (pngBuffer) {
5252
// Store the highest resolution version we use of the original image
5353
// Stored in webp to save space
54-
ship.sponsor.avatarBuffer = await resizeImage(pngBuffer, 120, 'webp')
54+
ship.sponsor.avatarBuffer = await resizeImage(pngBuffer, 'webp', 120)
5555
}
5656
})))
5757
}
5858

5959
const cache = new Map<Buffer, Map<string, Buffer>>()
6060
export async function resizeImage(
6161
image: Buffer,
62-
size = 100,
6362
format: ImageFormat,
63+
size = 100,
6464
) {
6565
const cacheKey = `${size}:${format}`
6666
if (cache.has(image)) {

src/processing/svg.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,13 +42,13 @@ export async function generateBadge(
4242
const { size } = preset.avatar
4343
let avatar = sponsor.avatarBuffer!
4444
if (size < 50) {
45-
avatar = await resizeImage(avatar, 50, imageFormat)
45+
avatar = await resizeImage(avatar, imageFormat, 50)
4646
}
4747
else if (size < 80) {
48-
avatar = await resizeImage(avatar, 80, imageFormat)
48+
avatar = await resizeImage(avatar, imageFormat, 80)
4949
}
5050
else if (imageFormat === 'png') {
51-
avatar = await resizeImage(avatar, 120, imageFormat)
51+
avatar = await resizeImage(avatar, imageFormat, 120)
5252
}
5353

5454
const avatarBase64 = avatar.toString('base64')
@@ -122,5 +122,5 @@ ${this.body}
122122
}
123123

124124
function encodeHtmlEntities(str: string) {
125-
return String(str).replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/"/g, '&quot;')
125+
return String(str).replaceAll('&', '&amp;').replaceAll('<', '&lt;').replaceAll('>', '&gt;').replaceAll('"', '&quot;')
126126
}

src/providers/afdian.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,5 +109,7 @@ export async function fetchAfdianSponsors(options: ContribkitConfig['afdian'] =
109109
}
110110

111111
function md5(token: string, params: string, ts: number, userId: string) {
112-
return createHash('md5').update(`${token}params${params}ts${ts}user_id${userId}`).digest('hex')
112+
return createHash('md5') // NOSONAR(typescript:S4790): Afdian requires MD5 request signatures.
113+
.update(`${token}params${params}ts${ts}user_id${userId}`)
114+
.digest('hex')
113115
}

src/providers/githubContributors.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ export async function fetchGitHubContributors(
5858
},
5959
)
6060

61-
if (!response || !response.length)
61+
if (!response?.length)
6262
break
6363

6464
allContributors.push(...response)

src/providers/gitlabContributors.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ export async function fetchGitlabContributors(
6161
},
6262
)
6363

64-
if (!response || !response.length)
64+
if (!response?.length)
6565
break
6666

6767
allContributors.push(...response)

src/providers/index.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ export const ProvidersMap = {
2929
export function guessProviders(config: ContribkitConfig) {
3030
const items: ProviderName[] = []
3131
const credentials = getCredentials(config)
32-
if (config.github && config.github.login)
32+
if (config.github?.login)
3333
items.push('github')
3434

3535
if (credentials.patreon?.token)
@@ -44,7 +44,7 @@ export function guessProviders(config: ContribkitConfig) {
4444
if (credentials.polar?.token)
4545
items.push('polar')
4646

47-
if (config.liberapay && config.liberapay.login)
47+
if (config.liberapay?.login)
4848
items.push('liberapay')
4949

5050
if (config.githubContributors?.login && credentials.githubContributors?.token)

src/providers/opencollective.ts

Lines changed: 31 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -70,13 +70,12 @@ export async function fetchOpenCollectiveSponsors(
7070

7171
sponsors.push(...(nodes || []))
7272

73-
if ((nodes.length) !== 0) {
74-
if (totalCount > offset + nodes.length)
75-
offset += nodes.length
76-
else
77-
offset = undefined
78-
}
79-
else { offset = undefined }
73+
if (nodes.length === 0)
74+
offset = undefined
75+
else if (totalCount > offset + nodes.length)
76+
offset += nodes.length
77+
else
78+
offset = undefined
8079
} while (offset)
8180
}
8281

@@ -99,13 +98,12 @@ export async function fetchOpenCollectiveSponsors(
9998
const totalCount = data.data.account.transactions.totalCount
10099

101100
monthlyTransactions.push(...(nodes || []))
102-
if ((nodes.length) !== 0) {
103-
if (totalCount > offset + nodes.length)
104-
offset += nodes.length
105-
else
106-
offset = undefined
107-
}
108-
else { offset = undefined }
101+
if (nodes.length === 0)
102+
offset = undefined
103+
else if (totalCount > offset + nodes.length)
104+
offset += nodes.length
105+
else
106+
offset = undefined
109107
} while (offset)
110108

111109
const sponsorships: [string, Sponsorship][] = sponsors
@@ -139,12 +137,12 @@ export async function fetchOpenCollectiveSponsors(
139137
const transactionsBySponsorId: Map<string, Sponsorship> = monthlySponsorships.reduce((map, [id, sponsor]) => {
140138
const existingSponsor = map.get(id)
141139
if (existingSponsor) {
142-
const createdAt = new Date(sponsor.createdAt!)
143-
const existingSponsorCreatedAt = new Date(existingSponsor.createdAt!)
140+
const createdAt = toDate(sponsor.createdAt)
141+
const existingSponsorCreatedAt = toDate(existingSponsor.createdAt)
144142
if (createdAt >= existingSponsorCreatedAt)
145143
map.set(id, sponsor)
146144

147-
else if (new Date(existingSponsorCreatedAt.getFullYear(), existingSponsorCreatedAt.getMonth(), 1) === new Date(createdAt.getFullYear(), createdAt.getMonth(), 1))
145+
else if (isSameMonth(existingSponsorCreatedAt, createdAt))
148146
existingSponsor.monthlyDollars += sponsor.monthlyDollars
149147
}
150148
else { map.set(id, sponsor) }
@@ -156,8 +154,8 @@ export async function fetchOpenCollectiveSponsors(
156154
.reduce((map, [id, sponsor]) => {
157155
const existingSponsor = map.get(id)
158156
if (existingSponsor) {
159-
const createdAt = new Date(sponsor.createdAt!)
160-
const existingSponsorCreatedAt = new Date(existingSponsor.createdAt!)
157+
const createdAt = toDate(sponsor.createdAt)
158+
const existingSponsorCreatedAt = toDate(existingSponsor.createdAt)
161159
if (createdAt >= existingSponsorCreatedAt)
162160
map.set(id, sponsor)
163161
}
@@ -195,7 +193,7 @@ function createSponsorFromOrder(order: any): [string, Sponsorship] | undefined {
195193
avatarUrl: order.fromAccount.imageUrl,
196194
websiteUrl: normalizeUrl(getBestUrl(order.fromAccount.socialLinks)),
197195
linkUrl: `https://opencollective.com/${slug}`,
198-
socialLogins: getSocialLogins(order.fromAccount.socialLinks, slug),
196+
socialLogins: getSocialLogins(slug, order.fromAccount.socialLinks),
199197
},
200198
isOneTime: order.frequency === 'ONETIME',
201199
monthlyDollars,
@@ -242,14 +240,14 @@ function createSponsorFromTransaction(transaction: any, excludeOrders: string[],
242240
type: getAccountType(account.type),
243241
login: slug,
244242
avatarUrl: account.imageUrl,
245-
websiteUrl: normalizeUrl(getBestUrl(account.socialLinks || [])),
243+
websiteUrl: normalizeUrl(getBestUrl(account.socialLinks ?? [])),
246244
linkUrl: `https://opencollective.com/${slug}`,
247-
socialLogins: getSocialLogins(account.socialLinks || [], slug),
245+
socialLogins: getSocialLogins(slug, account.socialLinks),
248246
},
249247
isOneTime: transaction.order?.frequency === 'ONETIME',
250248
monthlyDollars,
251249
privacyLevel: sponseesMode ? 'PUBLIC' : (account.isIncognito ? 'PRIVATE' : 'PUBLIC'),
252-
tierName: transaction.order?.tier?.name || transaction.tier?.name,
250+
tierName: transaction.order?.tier?.name ?? transaction.tier?.name,
253251
createdAt: sponseesMode
254252
? transaction.createdAt
255253
: transaction.order?.frequency === 'ONETIME'
@@ -432,13 +430,21 @@ function getBestUrl(socialLinks: SocialLink[]): string | undefined {
432430
return urls[0]
433431
}
434432

433+
function isSameMonth(a: Date, b: Date) {
434+
return a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth()
435+
}
436+
437+
function toDate(value: string | undefined) {
438+
return new Date(value ?? Number.NaN)
439+
}
440+
435441
const RE_GITHUB_URL = /github\.com\/([^/]*)/
436442

437-
function getSocialLogins(socialLinks: SocialLink[] = [], opencollectiveLogin: string): Record<string, string> {
443+
function getSocialLogins(opencollectiveLogin: string, socialLinks: SocialLink[] = []): Record<string, string> {
438444
const socialLogins: Record<string, string> = {}
439445
for (const link of socialLinks) {
440446
if (link.type === 'GITHUB') {
441-
const login = link.url.match(RE_GITHUB_URL)?.[1]
447+
const login = RE_GITHUB_URL.exec(link.url)?.[1]
442448
if (login)
443449
socialLogins.github = login
444450
}

0 commit comments

Comments
 (0)