1 | 'use strict'
|
2 |
|
3 | const fs = require('fs')
|
4 | const path = require('path')
|
5 | const mkdirp = require('mkdirp')
|
6 | const assert = require('assert')
|
7 | const yaml = require('js-yaml')
|
8 | const dirname = require('path').dirname
|
9 |
|
10 | exports.exists = exists
|
11 | exports.existsSync = existsSync
|
12 | exports.mkdir = mkdir
|
13 | exports.readFile = readFile
|
14 | exports.writeFile = writeFile
|
15 | exports.writeFileSync = writeFileSync
|
16 | exports.renameFile = renameFile
|
17 | exports.readDir = readDir
|
18 | exports.parseFileContents = parseFileContents
|
19 | exports.resolveSchemaRefs = resolveSchemaRefs
|
20 | exports.isFunc = isFunc
|
21 | exports.isObj = isObj
|
22 |
|
23 | function exists(filePath) {
|
24 | return new Promise((res, rej) =>
|
25 | fs.lstat(filePath, (err, stats) =>
|
26 | err ? rej(err) : res(stats)))
|
27 | }
|
28 |
|
29 | function existsSync(filePath) {
|
30 | try {
|
31 | return fs.lstatSync(filePath)
|
32 | } catch (e) {
|
33 | return false
|
34 | }
|
35 | }
|
36 |
|
37 | function mkdir(dirPath) {
|
38 | return new Promise((res, rej) =>
|
39 | mkdirp(dirPath, err =>
|
40 | err && err.code !== 'EEXIST' ? rej(err) : res()))
|
41 | }
|
42 |
|
43 | function readFile(filePath) {
|
44 | return new Promise((res, rej) =>
|
45 | fs.readFile(filePath, 'utf8', (err, contents) =>
|
46 | err ? rej(err) : res(contents)))
|
47 | }
|
48 |
|
49 | function writeFile(filePath, contents) {
|
50 | return new Promise((res, rej) =>
|
51 | mkdir(dirname(filePath)).then(() =>
|
52 | fs.writeFile(filePath, contents, err =>
|
53 | err ? rej(err) : res())))
|
54 | }
|
55 |
|
56 | function writeFileSync(filePath, contents) {
|
57 | mkdirp.sync(dirname(filePath))
|
58 | fs.writeFileSync(filePath, contents)
|
59 | }
|
60 |
|
61 | function renameFile(oldPath, newPath) {
|
62 | return new Promise((res, rej) =>
|
63 | fs.rename(oldPath, newPath, err =>
|
64 | err ? rej(err) : res()))
|
65 | }
|
66 |
|
67 | function readDir(dirPath) {
|
68 | return new Promise((res, rej) =>
|
69 | fs.readdir(dirPath, (err, files) =>
|
70 | err ? rej(err) : res(files)))
|
71 | }
|
72 |
|
73 | function parseFileContents(contents, path) {
|
74 | return isYamlFile(path) ?
|
75 | yaml.safeLoad(contents) :
|
76 | JSON.parse(contents)
|
77 | }
|
78 |
|
79 | function isYamlFile(filePath) {
|
80 | return path.extname(filePath).match(/^\.ya?ml$/)
|
81 | }
|
82 |
|
83 | const dataCache = new Set()
|
84 |
|
85 |
|
86 |
|
87 |
|
88 |
|
89 |
|
90 |
|
91 |
|
92 | function resolveSchemaRefs(data, lookup) {
|
93 | if (!data || dataCache.has(data)) return data
|
94 |
|
95 | if (Array.isArray(data)) {
|
96 | return data.map(item => resolveSchemaRefs(item, lookup))
|
97 | } else if (typeof data === 'object') {
|
98 | if (data.$ref) {
|
99 | const resolved = resolveSchemaRef(data.$ref, lookup)
|
100 | delete data.$ref
|
101 | data = Object.assign({}, resolved, data)
|
102 | }
|
103 | dataCache.add(data)
|
104 |
|
105 | for (let name in data) {
|
106 | data[name] = resolveSchemaRefs(data[name], lookup)
|
107 | }
|
108 | }
|
109 | return data
|
110 | }
|
111 |
|
112 | function resolveSchemaRef(ref, lookup) {
|
113 | const parts = ref.split('/')
|
114 |
|
115 | assert.ok(parts.shift() === '#', `Only support JSON Schema $refs in format '#/path/to/ref'`)
|
116 |
|
117 | let value = lookup
|
118 | while (parts.length) {
|
119 | value = value[parts.shift()]
|
120 | assert.ok(value, `Invalid schema reference: ${ref}`)
|
121 | }
|
122 | return value
|
123 | }
|
124 |
|
125 | function isFunc(f) {
|
126 | return !!f && typeof f === 'function'
|
127 | }
|
128 |
|
129 | function isObj(o) {
|
130 | return !!o && typeof o === 'object'
|
131 | }
|