better code: simpler api for httpString
Massimo Melina committed
Sep 24, 2023 at 17:20 UTC
fc69b9592a5e2db05288a7cf6ded109988796f6f
3 files changed
+18
-25
src/api.net.ts
+1
-1
@@ -61,7 +61,7 @@ async function getPublicIp() {
61
for (const urls of _.chunk(_.shuffle(prjInfo.publicIpServices), 2)) // small parallelization
62
try {
63
return await Promise.any(urls.map(url => httpString(url).then(res => {
64
- const ip = res.body?.trim()
64
+ const ip = res.trim()
65
if (!/[.:0-9a-fA-F]/.test(ip))
66
throw Error("bad result: " + ip)
67
return ip
src/github.ts
+9
-19
@@ -39,8 +39,7 @@ function downloadProgress(id: string, status: DownloadStatus) {
39
40
// determine default branch, possibly without consuming api quota
41
async function getGithubDefaultBranch(repo: string) {
42
- const res = await httpString(`https://github.com/${repo}/archive/refs/heads/main.zip`, { method: 'HEAD' })
43
- return res.ok ? 'main'
42
+ return await httpString(`https://github.com/${repo}/archive/refs/heads/main.zip`, { method: 'HEAD' }) ? 'main'
43
: (await getRepoInfo(repo))?.default_branch as string
44
}
45
@@ -110,7 +109,6 @@ export function getRepoInfo(id: string) {
109
110
export function readGithubFile(uri: string) {
111
return httpString('https://raw.githubusercontent.com/' + uri)
113
- .then(res => res.body)
112
}
113
114
export async function readOnlinePlugin(repo: Repo, branch='') {
@@ -122,9 +120,7 @@ export async function readOnlinePlugin(repo: Repo, branch='') {
120
if (!main) throw Error("missing repo.main")
121
if (!main.includes('//'))
122
main = pl.repo.web + main
125
- const res = await httpString(main)
126
- if (!res.ok) throw Error("bad repo.main")
127
- return parsePluginSource(main, res.body) // use 'repo' as 'id' client-side
123
+ return parsePluginSource(main, await httpString(main)) // use 'repo' as 'id' client-side
124
}
125
branch ||= await getGithubDefaultBranch(repo)
126
const res = await readGithubFile(`${repo}/${branch}/${DIST_ROOT}/plugin.js`)
@@ -141,22 +137,16 @@ export function getFolder2repo() {
137
}
138
139
async function apiGithub(uri: string) {
144
- try {
145
- const res = await httpString('https://api.github.com/'+uri, {
146
- headers: {
147
- 'User-Agent': 'HFS',
148
- Accept: 'application/vnd.github.v3+json',
149
- }
150
- })
151
- if (!res.ok)
152
- throw res.statusCode
153
- return JSON.parse(res.body)
154
- }
155
- catch(e: any) {
140
+ return httpString('https://api.github.com/' + uri, {
141
+ headers: {
142
+ 'User-Agent': 'HFS',
143
+ Accept: 'application/vnd.github.v3+json',
144
+ }
145
+ }).then(JSON.parse, e => {
146
// https://docs.github.com/en/rest/overview/resources-in-the-rest-api?apiVersion=2022-11-28#rate-limiting
147
throw e.message === '403' ? Error('github_quota')
148
: e
159
- }
149
+ })
150
}
151
152
export async function searchPlugins(text='') {
src/util-http.ts
+8
-5
@@ -4,16 +4,19 @@ import { RequestOptions } from 'https'
4
import http, { IncomingMessage } from 'node:http'
5
import https from 'node:https'
6
import { HTTP_TEMPORARY_REDIRECT } from './const'
7
+import _ from 'lodash'
8
8
-export function httpString(url: string, options?: XRequestOptions): Promise<IncomingMessage & { ok: boolean, body: string }> {
9
+// in case the response is not 2xx, it will throw and the error object is the Response object
10
+export function httpString(url: string, options?: XRequestOptions): Promise<string> {
11
return httpStream(url, options).then(res =>
12
new Promise(resolve => {
13
let buf = ''
14
res.on('data', chunk => buf += chunk.toString())
13
- res.on('end', () => resolve(Object.assign(res, {
14
- ok: (res.statusCode || 400) < 400,
15
- body: buf
16
- })))
15
+ res.on('end', () => {
16
+ if (!_.inRange(res.statusCode!, 200, 299))
17
+ throw res
18
+ resolve(buf)
19
+ })
20
})
21
)
22
}