-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathutils.ts
126 lines (111 loc) · 3.91 KB
/
utils.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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
import { window } from 'vscode';
import { DirectoryEntry, PackageData } from './types';
export const BASE_API_URL = 'https://reactnative.directory/api/libraries';
export const KEYWORD_REGEX = /:\w+/g;
export const numberFormatter = new Intl.NumberFormat('en-EN', { notation: 'compact' });
export enum ENTRY_OPTION {
INSTALL = 'Install package in the current workspace',
VISIT_HOMEPAGE = 'Visit homepage',
VISIT_REPO = 'Visit GitHub repository',
VISIT_NPM = 'Visit npm registry entry',
VIEW_BUNDLEPHOBIA = 'View BundlePhobia analysis',
VIEW_LICENSE = 'View license details',
COPY_NAME = 'Copy package name',
COPY_REPO_URL = 'Copy GitHub repository URL',
COPY_NPM_URL = 'Copy npm registry URL',
GO_BACK = '$(newline) Go back to search'
}
export enum STRINGS {
DEFAULT_TITLE = 'Search in React Native Directory',
PLACEHOLDER_BUSY = 'Loading directory data...',
PLACEHOLDER = 'Search for a package'
}
/**
* A subset of API query params mapped with normalized (lowercased) keyword values.
* @see https://github.com/react-native-community/directory/blob/main/types/index.ts#L14
*/
export const VALID_KEYWORDS_MAP = {
android: 'android',
expogo: 'expoGo',
ios: 'ios',
macos: 'macos',
fireos: 'fireos',
tvos: 'tvos',
visionos: 'visionos',
web: 'web',
windows: 'windows',
hasexample: 'hasExample',
hasimage: 'hasImage',
hastypes: 'hasTypes',
ismaintained: 'isMaintained',
ispopular: 'isPopular',
wasrecentlyupdated: 'wasRecentlyUpdated',
newarchitecture: 'newArchitecture'
};
export type ValidKeyword = keyof typeof VALID_KEYWORDS_MAP;
function getDetailLabel(item: PackageData) {
const platforms = [
item.android ? 'Android' : null,
item.ios ? 'iOS' : null,
item.macos ? 'macOS' : null,
item.tvos ? 'tvOS' : null,
item.visionos ? 'visionOS' : null,
item.web ? 'Web' : null,
item.windows ? 'Windows' : null
].filter(Boolean);
return [
`$(star) ${numberFormatter.format(item.github.stats.stars)}`,
`$(gist-fork) ${numberFormatter.format(item.github.stats.forks)}`,
item.npm?.downloads && `$(arrow-circle-down) ${numberFormatter.format(item.npm.downloads)}`,
'•',
platforms.join(', '),
(item.newArchitecture || item.expoGo || item.github.hasTypes) && '•',
(item.newArchitecture || item.expoGo) && `$(verified) New Architecture`,
item.github.hasTypes && `$(symbol-type-parameter) Types`
]
.filter(Boolean)
.join(' ');
}
export function getCommandToRun({ dev, npmPkg }: DirectoryEntry, preferredManager: string): string {
switch (preferredManager) {
case 'bun':
case 'pnpm':
case 'yarn':
return `${preferredManager} add${dev ? ' -D' : ''} ${npmPkg}`;
default:
return `${preferredManager} install${dev ? ' -D' : ''} ${npmPkg}`;
}
}
export async function fetchData(query?: string, keywords?: ValidKeyword[]): Promise<DirectoryEntry[]> {
try {
const apiUrl = new URL(BASE_API_URL);
if (query) {
apiUrl.searchParams.append('search', query);
apiUrl.searchParams.append('order', 'downloads');
}
if (keywords) {
keywords.forEach((keyword) => apiUrl.searchParams.append(keyword, 'true'));
}
const response = await fetch(apiUrl.href);
if (response.ok) {
const data = (await response.json()) as object;
if ('libraries' in data && Array.isArray(data.libraries)) {
return data.libraries.map((item: PackageData) => ({
label: item.npmPkg,
description: item.github.description,
detail: getDetailLabel(item),
alwaysShow: true,
...item
}));
}
window.showErrorMessage(`Invalid React Native Directory API response content`);
return [];
}
window.showErrorMessage(`Invalid React Native Directory API response: ${response.status}`);
return [];
} catch (error) {
console.error(error);
window.showErrorMessage('Failed to fetch data from React Native Directory API');
return [];
}
}