-
Notifications
You must be signed in to change notification settings - Fork 22
/
Copy pathindex.ts
109 lines (93 loc) · 2.64 KB
/
index.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
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
import type { RawPkg } from '../@types/pkg';
import { config } from '../config';
import { datadog } from '../utils/datadog';
import { log } from '../utils/log';
import { request } from '../utils/request';
type Hit = { type: 'npm'; name: string; hits: number };
export type File = { name: string; hash: string; time: string; size: number };
export const hits = new Map<string, number>();
/**
* Load downloads hits.
*/
export async function loadHits(): Promise<void> {
const start = Date.now();
log.info('📦 Loading hits from jsDelivr');
try {
const res = await request<Hit[]>(config.jsDelivrHitsEndpoint, {
responseType: 'json',
});
hits.clear();
res.body.forEach((pkg) => {
hits.set(pkg.name, pkg.hits);
});
} catch (e) {
log.error(e);
}
datadog.timing('jsdelivr.loadHits', Date.now() - start);
}
/**
* Get download hits.
*/
export function getHits(pkgs: Array<Pick<RawPkg, 'name'>>): Array<{
jsDelivrHits: number;
_searchInternal: { jsDelivrPopularity: number };
}> {
const start = Date.now();
const all = pkgs.map(({ name }) => {
const jsDelivrHits = hits.get(name) || 0;
return {
jsDelivrHits,
_searchInternal: {
// anything below 1000 hits/month is likely to mean that
// someone just made a few random requests so we count that as 0
jsDelivrPopularity: Math.max(jsDelivrHits.toString().length - 3, 0),
},
};
});
datadog.timing('jsdelivr.getHits', Date.now() - start);
return all;
}
/**
* Get packages files list.
*/
export async function getAllFilesList(
pkgs: Array<Pick<RawPkg, 'name' | 'version'>>
): Promise<File[][]> {
const start = Date.now();
const files = await Promise.all(pkgs.map(getFilesList));
datadog.timing('jsdelivr.getAllFilesList', Date.now() - start);
return files;
}
/**
* Get one package files list.
*/
export async function getFilesList(
pkg: Pick<RawPkg, 'name' | 'version'>
): Promise<File[]> {
const start = Date.now();
if (!pkg.name || !pkg.version) {
throw new Error(
`Package name should contain a version number: ${pkg.name}`
);
}
let files: File[] = [];
try {
const response = await request<{ default: string; files: File[] }>(
`${config.jsDelivrPackageEndpoint}/${pkg.name}@${pkg.version}/flat`,
{
responseType: 'json',
}
);
files = response.body.files;
} catch (e) {
log.warn(e);
}
datadog.timing('jsdelivr.getFilesList', Date.now() - start);
return files;
}
export function getFullURL(
pkg: Pick<RawPkg, 'name' | 'version'>,
file: File
): string {
return `https://cdn.jsdelivr.net/npm/${pkg.name}@${pkg.version}${file.name}`;
}