1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 | "use strict";
|
9 |
|
10 | const fs = require("fs");
|
11 | const hash = require("string-hash");
|
12 | const path = require("path");
|
13 | const untildify = require("untildify");
|
14 |
|
15 | var modificationCache = {};
|
16 | var jsonLoaded = {};
|
17 |
|
18 |
|
19 | const obj = {
|
20 |
|
21 | keyCount: function (obj) {
|
22 | if (obj.constructor === Object) {
|
23 | return Object.keys(obj).length;
|
24 | } else return 0;
|
25 | },
|
26 |
|
27 | isArray: function (obj) {
|
28 | return obj && obj.constructor === Array;
|
29 | },
|
30 |
|
31 |
|
32 | merge: function (objA, objB) {
|
33 | for (var key in objB) objA[key] = objB[key];
|
34 | return objA;
|
35 | },
|
36 |
|
37 |
|
38 | mergeTo: function (objA, objB) {
|
39 | var result = {};
|
40 | for (var keyA in objA) result[keyA] = objA[keyA];
|
41 | for (var keyB in objB) result[keyB] = objB[keyB];
|
42 | return result;
|
43 | },
|
44 |
|
45 |
|
46 | arrayify: function (obj) {
|
47 | if (Array.isArray(obj)) {
|
48 | return obj;
|
49 | } else {
|
50 | return [obj];
|
51 | }
|
52 | }
|
53 | };
|
54 |
|
55 |
|
56 | const parsePaths = function(paths) {
|
57 | paths = obj.arrayify(paths);
|
58 | paths.forEach((segment, index, pathsArray) => {
|
59 | if(segment) {
|
60 | pathsArray[index] = untildify(segment);
|
61 | } else {
|
62 | pathsArray[index] = "";
|
63 | }
|
64 | });
|
65 | return path.resolve.apply({}, paths);
|
66 | };
|
67 |
|
68 |
|
69 | const dir = {
|
70 | list: function (Path) {
|
71 | if (fs.existsSync(Path)) {
|
72 | return fs.readdirSync(Path);
|
73 | } else return false;
|
74 | },
|
75 |
|
76 | getDirectories: function(srcPath){
|
77 | return fs.readdirSync(srcPath).filter(function(file) {
|
78 | return fs.statSync(parsePaths([srcPath, file])).isDirectory();
|
79 | });
|
80 | }
|
81 | };
|
82 |
|
83 |
|
84 | const dombo = function(){
|
85 | var innerHead = [""];
|
86 |
|
87 | var tag = (type, content, attr) => {
|
88 | var chunks = [`<${type}`];
|
89 |
|
90 | for(var key in attr) {
|
91 | if(attr[key]) {
|
92 | chunks.push(` ${key}="${attr[key]}"`);
|
93 | } else {
|
94 | chunks.push(` ${key}`);
|
95 | }
|
96 | }
|
97 |
|
98 | if(content === false) {
|
99 | chunks.push("/>");
|
100 | } else {
|
101 | chunks.push(`>${content}</${type}>`);
|
102 | }
|
103 |
|
104 | return chunks.join("");
|
105 | };
|
106 |
|
107 | this.head = function (type, content, attr) {
|
108 | innerHead.push(tag(type, content, attr));
|
109 | };
|
110 |
|
111 | this.comment = function(content) {
|
112 | innerHead.push("<!-- " + content + " -->");
|
113 | };
|
114 |
|
115 | this.style = function (content) {
|
116 | innerHead.push(tag("style", content, {"type": "text/css"}));
|
117 | };
|
118 |
|
119 | const untildify = require('untildify');this.script = function (content) {
|
120 | innerHead.push(tag("script", content + "\n", {"type": "text/javascript"}));
|
121 | };
|
122 |
|
123 | this.parse = function(){
|
124 | innerHead.push("");
|
125 | var docType = "<!DOCTYPE html>\n";
|
126 | var head = `${tag("head", innerHead.join("\n"))}`;
|
127 | var body = "<body></body>";
|
128 | var innerHtml = `${head}${body}`;
|
129 | return `${docType}${tag("html", innerHtml, {lang:"en"})}\n`;
|
130 | };
|
131 | };
|
132 |
|
133 |
|
134 | const que = function (context) {
|
135 | var self = this;
|
136 | var row = [];
|
137 |
|
138 | var next = () => {
|
139 | if (row.length) {
|
140 | new Promise((resolve, reject) => {
|
141 | row.shift().call(context || self, resolve, reject);
|
142 | }).then(next);
|
143 | }
|
144 | };
|
145 |
|
146 | this.add = (step) => {
|
147 | if (step && step.call) {
|
148 | row.push(step);
|
149 | } else {
|
150 | console.error("util.que: not a function");
|
151 | }
|
152 |
|
153 | return self;
|
154 | };
|
155 |
|
156 | this.then = (action) => {
|
157 | self.add(action);
|
158 | next();
|
159 |
|
160 | return self;
|
161 | };
|
162 |
|
163 | return self;
|
164 | };
|
165 |
|
166 |
|
167 | const all = function (context) {
|
168 | var self = this;
|
169 | var list = [];
|
170 |
|
171 | this.add = (action) => {
|
172 | if (action && action.call) {
|
173 | list.push(action);
|
174 | } else {
|
175 | console.error("util.all, add: not a function");
|
176 | }
|
177 |
|
178 | return self;
|
179 | };
|
180 |
|
181 | this.then = (finalAction) => {
|
182 | new Promise((resolve) => {
|
183 | var count = list.length;
|
184 | if(count) {
|
185 | list.forEach((action) => {
|
186 | action.call(context || self, () => {
|
187 |
|
188 | count--;
|
189 |
|
190 | if (count === 0) {
|
191 | resolve();
|
192 | }
|
193 | });
|
194 | });
|
195 | } else resolve();
|
196 | }).then(() => {
|
197 | if(finalAction && finalAction.call) {
|
198 | finalAction.call(context || self);
|
199 | }
|
200 | });
|
201 |
|
202 | return self;
|
203 | };
|
204 |
|
205 | return self;
|
206 | };
|
207 |
|
208 |
|
209 | const modified = function (path, name) {
|
210 | return new Promise((resolve, reject) => {
|
211 | fs.stat(path, (err, stats) => {
|
212 | if(err){
|
213 | reject(err);
|
214 | } else {
|
215 | var modified = new Date(stats.mtime).getTime();
|
216 | if (modificationCache.hasOwnProperty(name) && modified <= modificationCache[name]) {
|
217 | modified = false;
|
218 | } else {
|
219 | modificationCache[name] = modified;
|
220 | }
|
221 | resolve(modified);
|
222 | }
|
223 | });
|
224 | });
|
225 | };
|
226 |
|
227 | const clearModificationCache = function() {
|
228 | modificationCache = {};
|
229 | };
|
230 |
|
231 |
|
232 | const localJson = function(path){
|
233 | return new Promise((resolve, reject) => {
|
234 | var name = hash(path);
|
235 | modified(path, name).then((isModified) => {
|
236 | if(isModified){
|
237 | fs.readFile(path, 'utf8', function (err, data) {
|
238 | if (err) {
|
239 | console.error(err);
|
240 | reject(err);
|
241 | } else {
|
242 | try {
|
243 | resolve(jsonLoaded[name] = JSON.parse(data));
|
244 | } catch (parseError) {
|
245 | console.error(parseError);
|
246 | reject(parseError);
|
247 | }
|
248 | }
|
249 | });
|
250 | } else {
|
251 | resolve(jsonLoaded[name]);
|
252 | }
|
253 | }, (err) => {
|
254 | reject(err);
|
255 | });
|
256 | });
|
257 | };
|
258 |
|
259 |
|
260 | module.exports = {
|
261 | obj: obj,
|
262 | dir: dir,
|
263 | parsePaths: parsePaths,
|
264 | dombo: dombo,
|
265 | que: que,
|
266 | all: all,
|
267 | modified: modified,
|
268 | clearModificationCache: clearModificationCache,
|
269 | localJson: localJson
|
270 | };
|
271 |
|