1 | const createHash = require('crypto').createHash;
|
2 | const denodeify = require('denodeify');
|
3 | const readFileNodeback = require('fs').readFile;
|
4 | const writeFileNodeback = require('fs').writeFile;
|
5 | const parse = require('url').parse;
|
6 | const resolve = require('path').resolve;
|
7 | const dirname = require('path').dirname;
|
8 | const mkdirpNodeback = require('mkdirp');
|
9 | const fetch = require('omni-fetch');
|
10 |
|
11 | const readFile = denodeify(readFileNodeback);
|
12 | const writeFile = denodeify(writeFileNodeback);
|
13 | const mkdirp = denodeify(mkdirpNodeback);
|
14 |
|
15 | function getSchemaCacheId(uri) {
|
16 | const sum = createHash('md5');
|
17 | sum.update(uri);
|
18 | return sum.digest('hex');
|
19 | }
|
20 |
|
21 | function readSchemaCache(uri) {
|
22 | const id = getSchemaCacheId(uri);
|
23 | const tmp = resolve(__dirname, '.tmp', `${id}.json`);
|
24 | return readFile(tmp)
|
25 | .catch(() => {});
|
26 | }
|
27 |
|
28 | function writeSchemaCache(uri, schema) {
|
29 | const id = getSchemaCacheId(uri);
|
30 | const tmp = resolve(__dirname, '..', '.tmp', `${id}.json`);
|
31 |
|
32 | mkdirp(dirname(tmp))
|
33 | .then(() => {
|
34 | return writeFile(tmp, schema);
|
35 | })
|
36 | .catch(err => {
|
37 | console.log(err);
|
38 | });
|
39 | }
|
40 |
|
41 | module.exports = schema => {
|
42 | const parsed = parse(schema);
|
43 |
|
44 | if (parsed.protocol && parsed.host) {
|
45 | return readSchemaCache(schema)
|
46 | .then(buffer => {
|
47 | return buffer ?
|
48 | buffer.toString('utf-8') :
|
49 | fetch(schema)
|
50 | .then(resp => resp.text())
|
51 | .then(data => {
|
52 | setTimeout(() => {
|
53 | writeSchemaCache(schema, data);
|
54 | }, 0);
|
55 | return data;
|
56 | });
|
57 | })
|
58 | .then(data => JSON.parse(data));
|
59 | }
|
60 |
|
61 | return require(schema);
|
62 | };
|