UNPKG

7.16 kBJavaScriptView Raw
1const
2 fs = require('fs'),
3 path = require('path'),
4 colors = require('ansi-colors'),
5 fancyLog = require('fancy-log'),
6 marked = require('marked'),
7 ConfigManager = require('./ConfigManager'),
8
9 capitalizeString = (str) => {
10 return str.toLowerCase()
11 .replace(/\b\w/g, (matches) => matches.toUpperCase());
12 },
13
14 getTitleFromName = (str) => {
15 const [basename] = str.split('.');
16 return capitalizeString(basename)
17 .replace(/\d{2,}-|-|_/g, ' ')
18 .trim();
19 },
20
21 getTitleFromFilename = (filePath) => {
22 return getTitleFromName(path.basename(filePath, path.extname(filePath)));
23 },
24
25 getTitleFromFoldername = (filePath) => {
26 return getTitleFromName(path.basename(path.dirname(filePath)));
27 },
28
29 getFileExtension = (filePath) => {
30 return path.extname(filePath)
31 .substr(1);
32 },
33
34 removeFileExtension = (filePath, onlyLastExt = true) => {
35 const i = onlyLastExt ? filePath.lastIndexOf('.') : filePath.indexOf('.');
36 return (i < 0) ? filePath : filePath.substr(0, i);
37 },
38
39 replaceFileExtension = (filePath, extension, allExt = false) => {
40 const basePath = removeFileExtension(filePath, !allExt);
41 return basePath === filePath ? filePath : `${basePath}.${extension}`;
42 },
43
44 getRelatedDataPath = (_filePath, warn) => {
45 let
46 dataExt = ConfigManager.get('dataExt'),
47 defaultDataFileName = ConfigManager.get('defaultDataFileName'),
48 filePath = replaceFileExtension(_filePath, dataExt, true);
49
50 if (!path.isAbsolute(filePath)) {
51 filePath = path.join(ConfigManager.get('rootPath'), filePath);
52 }
53
54 if (fs.existsSync(filePath)) {
55 return filePath;
56 }
57
58 filePath = path.join(path.dirname(removeFileExtension(filePath, false)), `${defaultDataFileName}.${dataExt}`);
59
60 if (fs.existsSync(filePath)) {
61 return filePath;
62 }
63
64 if (typeof warn === 'undefined' || warn) {
65 log(`Notice: unable to load resolved data file '${path.relative(path.resolve('./'), filePath)}' `, 'notice');
66 log(`(origin '${path.relative(path.resolve('./'), _filePath)}')`, 'notice');
67 }
68
69 return false;
70 },
71
72 readRelatedData = (_filePath, warn) => {
73 let filePath = getRelatedDataPath(_filePath, warn);
74 return filePath ? readJson5File(filePath) : {};
75 },
76
77 readRelatedMarkdown = (_filePath, isRequired = false) => {
78
79 filePath = replaceFileExtension(_filePath, ConfigManager.get('markdownExt'));
80
81 if (!path.isAbsolute(filePath)) {
82 filePath = path.join(ConfigManager.get('rootPath'), filePath);
83 }
84
85 if (!fs.existsSync(filePath)) {
86 if (isRequired) {
87 log(`sgUtil.readRelatedMarkdown: resolved '${_filePath}' to '${filePath}' but unable to load`, 'notice');
88 }
89 return '';
90 }
91
92 return readMarkdownFile(filePath);
93 },
94
95 readFileContents = (absPath, encoding = 'utf8') => {
96
97 if (!fs.existsSync(absPath)) {
98 log(`sgUtil.readFileContents: ${absPath} not found`, 'warn');
99 log(new Error().stack, 'warn');
100 return '';
101 }
102
103 if (!fs.lstatSync(absPath)
104 .isFile()) {
105 log(`sgUtil.readFileContents: ${absPath} is no file`, 'warn');
106 return '';
107 }
108
109 return fs.readFileSync(absPath, encoding);
110 },
111
112 flatten = (data) => {
113 if (typeof data !== 'object') return data;
114 return Array.from(data.values())
115 .map((item) => flatten(item))
116 .join('\n');
117 },
118
119 isObject = (val) => {
120 return val &&
121 (typeof val === 'object') &&
122 !Array.isArray(val) &&
123 !(val instanceof RegExp) &&
124 !(val instanceof Date);
125 },
126
127 createPath = (filePath) => {
128 const targetPath = path.dirname(filePath);
129
130 targetPath.split(path.sep)
131 .reduce((parentDir, childDir) => {
132 const curDir = path.resolve(parentDir, childDir);
133 if (!fs.existsSync(curDir)) {
134 fs.mkdirSync(curDir);
135 }
136 return curDir;
137 }, path.isAbsolute(targetPath) ? path.sep : '');
138 },
139
140 copyFile = (sourceFile, targetFile, callback) => {
141 writeFile(targetFile, readFileContents(sourceFile), callback);
142 },
143
144 writeFile = (absPath, content, callback) => {
145 let contentString;
146
147 if (!content.hasOwnProperty('values') && typeof content.values === 'function') {
148 contentString = flatten(content);
149 }
150 else {
151 contentString = content.toString();
152 }
153
154 createPath(absPath);
155
156 if (typeof callback === 'function') {
157 fs.writeFile(absPath, contentString, callback);
158 }
159 else {
160 fs.writeFileSync(absPath, contentString);
161 }
162 },
163
164 writeJsonFile = (absPath, content = {}) => {
165 writeFile(absPath, JSON.stringify(content, null, 2));
166 },
167
168 readJson5File = (filePath) => {
169
170 if (!path.isAbsolute(filePath)) {
171 filePath = path.join(ConfigManager.get('rootPath'), filePath);
172 }
173
174 return ConfigManager.util.parseFile(filePath);
175 },
176
177 readMarkdownFile = (filePath) => {
178 return marked(readFileContents(filePath));
179 },
180
181 filterFilenameSibling = (filename, otherFilenames) => {
182 const dirname = path.dirname(filename);
183
184 return otherFilenames.filter((filename) => path.dirname(filename) === dirname);
185 },
186
187 hashCode = (str) => {
188 let
189 hash = 0,
190 i,
191 chr,
192 len;
193
194 if (typeof str !== 'string') {
195 str = JSON.stringify(str);
196 }
197
198 if (str.length === 0) return hash;
199
200 for (i = 0, len = str.length; i < len; i++) {
201 chr = str.charCodeAt(i);
202 hash = ((hash << 5) - hash) + chr;
203 hash |= 0; // Convert to 32bit integer
204 }
205 return Math.abs(hash);
206 },
207
208 log = (message, type) => {
209 switch (type) {
210 case 'info':
211 fancyLog(colors.green(message));
212 break;
213
214 case 'notice':
215 fancyLog(colors.gray(message));
216 break;
217
218 case 'warn':
219 fancyLog(colors.yellow(message));
220 break;
221
222 case 'error':
223 fancyLog(colors.red(message));
224 break;
225
226 default:
227 fancyLog(message);
228 }
229 },
230
231 dumpData = (filename, data) => {
232 if (ConfigManager.get('dumpData', false) === true) {
233 writeJsonFile(`.tmp/${this.constructor.name}-${this.hash}.json`, data);
234 }
235 }
236;
237
238module.exports.capitalizeString = capitalizeString;
239module.exports.getTitleFromName = getTitleFromName;
240module.exports.getTitleFromFilename = getTitleFromFilename;
241module.exports.getTitleFromFoldername = getTitleFromFoldername;
242module.exports.getFileExtension = getFileExtension;
243module.exports.removeFileExtension = removeFileExtension;
244module.exports.replaceFileExtension = replaceFileExtension;
245module.exports.readFileContents = readFileContents;
246module.exports.getRelatedDataPath = getRelatedDataPath;
247module.exports.readRelatedData = readRelatedData;
248module.exports.readMarkdownFile = readMarkdownFile;
249module.exports.readRelatedMarkdown = readRelatedMarkdown;
250module.exports.isObject = isObject;
251module.exports.createPath = createPath;
252module.exports.writeFile = writeFile;
253module.exports.copyFile = copyFile;
254module.exports.writeJsonFile = writeJsonFile;
255module.exports.readJson5File = readJson5File;
256module.exports.filterFilenameSibling = filterFilenameSibling;
257module.exports.hashCode = hashCode;
258module.exports.log = log;
259module.exports.dumpData = dumpData;