Skip to content

Commit 825552f

Browse files
committed
Add simple fetch API implementation
PR-URL: #88
1 parent 6dc4136 commit 825552f

6 files changed

Lines changed: 68 additions & 10 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
## [Unreleased][unreleased]
44

55
- Fixed Pool infinite loop case
6+
- Add simple `fetch` API implementation
67

78
## [3.5.14][] - 2021-09-21
89

README.md

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,6 @@
1616

1717
- `random(min: number, max?: number): number`
1818
- `sample(arr: Array<any>): any`
19-
- `ipToInt(ip?: string): number`
20-
- `parseHost(host?: string): string`
2119
- `parseParams(params: string): object`
2220
- `replace(str: string, substr: string, newstr: string): string`
2321
- `split(s: string, separator: string): [string, string]`
@@ -35,11 +33,17 @@
3533
- `namespaceByPath(namespace: object, path: string): object | null`
3634
- `makePrivate(instance: object): object`
3735
- `protect(allowMixins: Array<string>, ...namespaces: Array<object>): void`
38-
- `parseCookies(cookie: string): object`
3936
- `createAbortController(): AbortController`
4037
- `timeout(msec: number, signal?: EventEmitter): Promise<void>`
4138
- `delay(msec: number, signal?: EventEmitter): Promise<void>`
4239

40+
## Network utilities
41+
42+
- `ipToInt(ip?: string): number`
43+
- `parseHost(host?: string): string`
44+
- `parseCookies(cookie: string): object`
45+
- `fetch(url: string): Promise<string>`
46+
4347
## Crypto utilities
4448

4549
- `cryptoRandom(): number`

lib/fetch.js

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
'use strict';
2+
3+
const http = require('http');
4+
const https = require('https');
5+
6+
const fetch = async (url) => {
7+
const transport = url.startsWith('https') ? https : http;
8+
return new Promise((resolve, reject) => {
9+
transport.get(url, async (res) => {
10+
const code = res.statusCode;
11+
if (code !== 200) return reject(new Error(`HTTP status code ${code}`));
12+
res.on('error', reject);
13+
const chunks = [];
14+
try {
15+
for await (const chunk of res) chunks.push(chunk);
16+
const json = Buffer.concat(chunks).toString();
17+
const object = JSON.parse(json);
18+
resolve(object);
19+
} catch (error) {
20+
return reject(error);
21+
}
22+
});
23+
});
24+
};
25+
26+
module.exports = { fetch };

metautil.d.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,3 +101,5 @@ export class Pool {
101101
capture(): Promise<object | null>;
102102
release(item: object): void;
103103
}
104+
105+
export function fetch(url: string): Promise<string>;

metautil.js

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
'use strict';
22

3-
const utilities = require('./lib/utilities.js');
4-
const crypto = require('./lib/crypto.js');
5-
const async = require('./lib/async.js');
6-
const semaphore = require('./lib/semaphore.js');
7-
const pool = require('./lib/pool.js');
8-
9-
module.exports = { ...utilities, ...crypto, ...semaphore, ...pool, ...async };
3+
module.exports = {
4+
...require('./lib/utilities.js'),
5+
...require('./lib/crypto.js'),
6+
...require('./lib/semaphore.js'),
7+
...require('./lib/pool.js'),
8+
...require('./lib/async.js'),
9+
...require('./lib/fetch.js'),
10+
};

test/fetch.js

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
'use strict';
2+
3+
const metatests = require('metatests');
4+
const metautil = require('..');
5+
6+
const API_EXCHANGE = {
7+
host: 'openexchangerates.org',
8+
path: '/api/latest.json?app_id=',
9+
key: '1f43ea96b1e343fe94333dd2b97a109d',
10+
};
11+
12+
const getRate = async (currency) => {
13+
const { host, path, key } = API_EXCHANGE;
14+
const url = `https://${host}/${path}${key}`;
15+
const data = await metautil.fetch(url);
16+
const rate = data.rates[currency];
17+
return rate;
18+
};
19+
20+
metatests.test('Fetch', async (test) => {
21+
const rate = await getRate('USD');
22+
test.strictSame(rate, 1);
23+
test.end();
24+
});

0 commit comments

Comments
 (0)