whet 0.0.30 → 0.0.32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/Reflect.d.ts +13 -0
- package/bin/Reflect.js +19 -0
- package/bin/whet/SourceHash.d.ts +14 -0
- package/bin/whet/SourceHash.js +49 -2
- package/bin/whet/Whet.js +1 -1
- package/bin/whet/cache/FileCache.js +1 -1
- package/bin/whet/cache/MemoryCache.js +1 -1
- package/bin/whet/route/Router.d.ts +1 -0
- package/bin/whet/route/Router.js +13 -1
- package/bin/whet/stones/Files.js +1 -1
- package/bin/whet/stones/Server.js +115 -23
- package/package.json +4 -2
- package/bin/List.d.ts +0 -3
package/bin/Reflect.d.ts
CHANGED
|
@@ -7,6 +7,19 @@ abstract interface in an untyped manner. Use with care.
|
|
|
7
7
|
*/
|
|
8
8
|
export declare class Reflect {
|
|
9
9
|
|
|
10
|
+
/**
|
|
11
|
+
Returns the value of the field named `field` on object `o`.
|
|
12
|
+
|
|
13
|
+
If `o` is not an object or has no field named `field`, the result is
|
|
14
|
+
null.
|
|
15
|
+
|
|
16
|
+
If the field is defined as a property, its accessors are ignored. Refer
|
|
17
|
+
to `Reflect.getProperty` for a function supporting property accessors.
|
|
18
|
+
|
|
19
|
+
If `field` is null, the result is unspecified.
|
|
20
|
+
*/
|
|
21
|
+
static field(o: any, field: string): any
|
|
22
|
+
|
|
10
23
|
/**
|
|
11
24
|
Returns the fields of structure `o`.
|
|
12
25
|
|
package/bin/Reflect.js
CHANGED
|
@@ -11,6 +11,25 @@ abstract interface in an untyped manner. Use with care.
|
|
|
11
11
|
export const Reflect = Register.global("$hxClasses")["Reflect"] =
|
|
12
12
|
class Reflect {
|
|
13
13
|
|
|
14
|
+
/**
|
|
15
|
+
Returns the value of the field named `field` on object `o`.
|
|
16
|
+
|
|
17
|
+
If `o` is not an object or has no field named `field`, the result is
|
|
18
|
+
null.
|
|
19
|
+
|
|
20
|
+
If the field is defined as a property, its accessors are ignored. Refer
|
|
21
|
+
to `Reflect.getProperty` for a function supporting property accessors.
|
|
22
|
+
|
|
23
|
+
If `field` is null, the result is unspecified.
|
|
24
|
+
*/
|
|
25
|
+
static field(o, field) {
|
|
26
|
+
try {
|
|
27
|
+
return o[field];
|
|
28
|
+
}catch (_g) {
|
|
29
|
+
return null;
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
|
|
14
33
|
/**
|
|
15
34
|
Returns the fields of structure `o`.
|
|
16
35
|
|
package/bin/whet/SourceHash.d.ts
CHANGED
|
@@ -15,6 +15,20 @@ export declare class SourceHash {
|
|
|
15
15
|
static fromFiles(paths: MaybeArray<string>, filter?: null | ((arg0: string) => boolean), recursive?: boolean): Promise<SourceHash>
|
|
16
16
|
static fromBytes(data: Buffer): SourceHash
|
|
17
17
|
static fromString(data: string): SourceHash
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Converts `obj` to string via JSON.stringify, defaults to 'null' if undefined to prevent
|
|
21
|
+
* errors. The string is then converted to hash. See also `fromConfig`.
|
|
22
|
+
*/
|
|
23
|
+
static fromStringify(obj: any): SourceHash
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Convert a Stone config into hash by ignoring the base `StoneConfig` fields
|
|
27
|
+
* and anything inside `ignoreList`, getting hash of `Stone` and `Router` instances,
|
|
28
|
+
* and applying `fromStringify` on the rest.
|
|
29
|
+
* Only checks keys at root level, no deep inspection is done.
|
|
30
|
+
*/
|
|
31
|
+
static fromConfig(obj: {[key: string]: any}, ignoreList?: null | string[]): Promise<SourceHash>
|
|
18
32
|
static equals(a: SourceHash, b: SourceHash): boolean
|
|
19
33
|
static toHex(hash: SourceHash): string
|
|
20
34
|
static fromHex(hex: string): SourceHash
|
package/bin/whet/SourceHash.js
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
|
+
import {Router} from "./route/Router.js"
|
|
1
2
|
import {MaybeArray_Fields_} from "./magic/MaybeArray.js"
|
|
2
3
|
import {Utils} from "./Utils.js"
|
|
4
|
+
import {Stone} from "./Stone.js"
|
|
3
5
|
import {Register} from "../genes/Register.js"
|
|
4
6
|
import * as Fs from "fs"
|
|
5
7
|
import * as Crypto from "crypto"
|
|
6
8
|
import {Buffer} from "buffer"
|
|
9
|
+
import {Reflect as Reflect__1} from "../Reflect.js"
|
|
7
10
|
|
|
8
11
|
const $global = Register.$global
|
|
9
12
|
|
|
@@ -115,6 +118,50 @@ class SourceHash extends Register.inherits() {
|
|
|
115
118
|
static fromString(data) {
|
|
116
119
|
return SourceHash.fromBytes(Buffer.from(data));
|
|
117
120
|
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Converts `obj` to string via JSON.stringify, defaults to 'null' if undefined to prevent
|
|
124
|
+
* errors. The string is then converted to hash. See also `fromConfig`.
|
|
125
|
+
*/
|
|
126
|
+
static fromStringify(obj) {
|
|
127
|
+
let tmp = JSON.stringify(obj);
|
|
128
|
+
return SourceHash.fromBytes(Buffer.from((tmp != null) ? tmp : "null"));
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Convert a Stone config into hash by ignoring the base `StoneConfig` fields
|
|
133
|
+
* and anything inside `ignoreList`, getting hash of `Stone` and `Router` instances,
|
|
134
|
+
* and applying `fromStringify` on the rest.
|
|
135
|
+
* Only checks keys at root level, no deep inspection is done.
|
|
136
|
+
*/
|
|
137
|
+
static fromConfig(obj, ignoreList) {
|
|
138
|
+
let keys = [];
|
|
139
|
+
let _g = [];
|
|
140
|
+
let _g_keys = Reflect__1.fields(obj);
|
|
141
|
+
let _g_index = 0;
|
|
142
|
+
while (_g_index < _g_keys.length) {
|
|
143
|
+
let key = _g_keys[_g_index++];
|
|
144
|
+
let _g_value = obj[key];
|
|
145
|
+
let tmp;
|
|
146
|
+
switch (key) {
|
|
147
|
+
case "cacheStrategy":case "dependencies":case "id":case "project":
|
|
148
|
+
continue;
|
|
149
|
+
break
|
|
150
|
+
default:
|
|
151
|
+
if (ignoreList != null && ignoreList.includes(key)) {
|
|
152
|
+
continue;
|
|
153
|
+
} else {
|
|
154
|
+
keys.push(key);
|
|
155
|
+
tmp = (((_g_value) instanceof Stone)) ? _g_value.getHash() : (((_g_value) instanceof Router)) ? _g_value.getHash() : SourceHash.fromStringify(_g_value);
|
|
156
|
+
};
|
|
157
|
+
|
|
158
|
+
};
|
|
159
|
+
_g.push(tmp);
|
|
160
|
+
};
|
|
161
|
+
return Promise.all(_g).then(function (hashes) {
|
|
162
|
+
return SourceHash.merge(...hashes);
|
|
163
|
+
});
|
|
164
|
+
}
|
|
118
165
|
static equals(a, b) {
|
|
119
166
|
if (a != null && b != null) {
|
|
120
167
|
return a.bytes.compare(b.bytes) == 0;
|
|
@@ -156,8 +203,8 @@ class SourceHash extends Register.inherits() {
|
|
|
156
203
|
}
|
|
157
204
|
|
|
158
205
|
|
|
159
|
-
SourceHash
|
|
206
|
+
Register.createStatic(SourceHash, "EMPTY", function () { return (function($this) {var $r0
|
|
160
207
|
let bytes = Buffer.alloc(32);
|
|
161
208
|
|
|
162
209
|
$r0 = new SourceHash(bytes)
|
|
163
|
-
return $r0})(this)
|
|
210
|
+
return $r0})(this) })
|
package/bin/whet/Whet.js
CHANGED
|
@@ -12,7 +12,7 @@ const $global = Register.$global
|
|
|
12
12
|
export const Whet_Fields_ = Register.global("$hxClasses")["whet._Whet.Whet_Fields_"] =
|
|
13
13
|
class Whet_Fields_ {
|
|
14
14
|
static main() {
|
|
15
|
-
Whet_Fields_.program.enablePositionalOptions().passThroughOptions().description("Project tooling.").usage("[options] [command] [+ [command]...]").version("0.0.
|
|
15
|
+
Whet_Fields_.program.enablePositionalOptions().passThroughOptions().description("Project tooling.").usage("[options] [command] [+ [command]...]").version("0.0.32", "-v, --version").allowUnknownOption(true).showSuggestionAfterError(true).option("-p, --project <file>", "project to run", "Project.mjs").option("-l, --log-level <level>", "log level, a string/number", "info").option("--no-pretty", "disable pretty logging").exitOverride();
|
|
16
16
|
try {
|
|
17
17
|
Whet_Fields_.program.parse();
|
|
18
18
|
}catch (_g) {
|
|
@@ -14,7 +14,7 @@ import {HxOverrides} from "../../HxOverrides.js"
|
|
|
14
14
|
const $global = Register.$global
|
|
15
15
|
|
|
16
16
|
export const FileCache = Register.global("$hxClasses")["whet.cache.FileCache"] =
|
|
17
|
-
class FileCache extends Register.inherits(BaseCache) {
|
|
17
|
+
class FileCache extends Register.inherits(() => BaseCache, true) {
|
|
18
18
|
new(rootDir) {
|
|
19
19
|
this.flushQueued = false;
|
|
20
20
|
super.new(rootDir, new StringMap());
|
|
@@ -5,7 +5,7 @@ import {Register} from "../../genes/Register.js"
|
|
|
5
5
|
const $global = Register.$global
|
|
6
6
|
|
|
7
7
|
export const MemoryCache = Register.global("$hxClasses")["whet.cache.MemoryCache"] =
|
|
8
|
-
class MemoryCache extends Register.inherits(BaseCache) {
|
|
8
|
+
class MemoryCache extends Register.inherits(() => BaseCache, true) {
|
|
9
9
|
new(rootDir) {
|
|
10
10
|
super.new(rootDir, new ObjectMap());
|
|
11
11
|
}
|
package/bin/whet/route/Router.js
CHANGED
|
@@ -190,10 +190,12 @@ class Router extends Register.inherits() {
|
|
|
190
190
|
|
|
191
191
|
/**
|
|
192
192
|
* Get combined hash of all sources that fit the `pattern`.
|
|
193
|
+
* Includes matched serveIds in hash to capture filter effects.
|
|
193
194
|
*/
|
|
194
195
|
getHash(pattern) {
|
|
195
196
|
return this.get(pattern).then(function (items) {
|
|
196
197
|
let uniqueStones = [];
|
|
198
|
+
let serveIds = [];
|
|
197
199
|
let _g = 0;
|
|
198
200
|
while (_g < items.length) {
|
|
199
201
|
let item = items[_g];
|
|
@@ -201,7 +203,17 @@ class Router extends Register.inherits() {
|
|
|
201
203
|
if (uniqueStones.indexOf(item.source) == -1) {
|
|
202
204
|
uniqueStones.push(item.source);
|
|
203
205
|
};
|
|
206
|
+
serveIds.push(item.serveId);
|
|
204
207
|
};
|
|
208
|
+
serveIds.sort(function (a, b) {
|
|
209
|
+
if (a < b) {
|
|
210
|
+
return -1;
|
|
211
|
+
} else if (a > b) {
|
|
212
|
+
return 1;
|
|
213
|
+
} else {
|
|
214
|
+
return 0;
|
|
215
|
+
};
|
|
216
|
+
});
|
|
205
217
|
let result = new Array(uniqueStones.length);
|
|
206
218
|
let _g1 = 0;
|
|
207
219
|
let _g2 = uniqueStones.length;
|
|
@@ -210,7 +222,7 @@ class Router extends Register.inherits() {
|
|
|
210
222
|
result[i] = uniqueStones[i].getHash();
|
|
211
223
|
};
|
|
212
224
|
return Promise.all(result).then(function (hashes) {
|
|
213
|
-
return SourceHash.merge(...hashes);
|
|
225
|
+
return SourceHash.merge(...hashes).add(SourceHash.fromString(serveIds.join("\n")));
|
|
214
226
|
});
|
|
215
227
|
});
|
|
216
228
|
}
|
package/bin/whet/stones/Files.js
CHANGED
|
@@ -8,7 +8,7 @@ import {Register} from "../../genes/Register.js"
|
|
|
8
8
|
const $global = Register.$global
|
|
9
9
|
|
|
10
10
|
export const Files = Register.global("$hxClasses")["whet.stones.Files"] =
|
|
11
|
-
class Files extends Register.inherits(Stone) {
|
|
11
|
+
class Files extends Register.inherits(() => Stone, true) {
|
|
12
12
|
new(config) {
|
|
13
13
|
super.new(config);
|
|
14
14
|
}
|
|
@@ -7,6 +7,7 @@ import * as Http from "http"
|
|
|
7
7
|
import {Register} from "../../genes/Register.js"
|
|
8
8
|
import {Std} from "../../Std.js"
|
|
9
9
|
import {Reflect as Reflect__1} from "../../Reflect.js"
|
|
10
|
+
import {Lambda} from "../../Lambda.js"
|
|
10
11
|
|
|
11
12
|
const $global = Register.$global
|
|
12
13
|
|
|
@@ -71,34 +72,63 @@ class Server extends Register.inherits(Stone) {
|
|
|
71
72
|
let _gthis = this;
|
|
72
73
|
switch (req.method) {
|
|
73
74
|
case "GET":
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
75
|
+
let isDirOrNoExt = id.length == 0 || id.charCodeAt(id.length - 1) == 47 || Path.posix.extname(id) == "";
|
|
76
|
+
let queryPromise;
|
|
77
|
+
if (isDirOrNoExt) {
|
|
78
|
+
let searchPattern = id.length == 0 || id.charCodeAt(id.length - 1) == 47;
|
|
79
|
+
queryPromise = this.config.router.get((searchPattern) ? id + "**" : id + "/**");
|
|
80
|
+
} else {
|
|
81
|
+
queryPromise = Promise.resolve([]);
|
|
80
82
|
};
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
83
|
+
queryPromise.then(function (dirResults) {
|
|
84
|
+
if (isDirOrNoExt && dirResults.length == 1) {
|
|
85
|
+
id = dirResults[0].serveId;
|
|
86
|
+
} else if (isDirOrNoExt) {
|
|
87
|
+
if (!req.url.substring(0, (searchIndex > 0) ? searchIndex : req.url.length).endsWith("/")) {
|
|
88
|
+
let redirectUrl = (searchIndex > 0) ? req.url.substring(0, searchIndex) + "/" + req.url.substring(searchIndex) : req.url + "/";
|
|
89
|
+
res.writeHead(301, "Moved Permanently", {"Location": redirectUrl});
|
|
86
90
|
res.end();
|
|
87
91
|
return;
|
|
88
92
|
};
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
let
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
let key = _g_keys[_g_index++];
|
|
96
|
-
headers[key] = access[key];
|
|
97
|
-
};
|
|
93
|
+
if (id.length == 0 || id.charCodeAt(id.length - 1) == 47) {
|
|
94
|
+
let id1 = id;
|
|
95
|
+
let dir = id1.substring(0, id1.lastIndexOf("/") + 1);
|
|
96
|
+
id = Path.posix.join((dir.length == 0) ? "./" : dir, "index.html");
|
|
97
|
+
} else if (Path.posix.extname(id) == "") {
|
|
98
|
+
id = "" + id + "/index.html";
|
|
98
99
|
};
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
100
|
+
};
|
|
101
|
+
_gthis.config.router.get(id).then(function (routeResult) {
|
|
102
|
+
let sourcePromise = (routeResult.length > 0) ? routeResult[0].get() : (_gthis.routeDynamic != null) ? _gthis.routeDynamic(id) : Promise.resolve(null);
|
|
103
|
+
return sourcePromise.then(function (source) {
|
|
104
|
+
if (source == null) {
|
|
105
|
+
res.writeHead(404, "File not found.");
|
|
106
|
+
res.end();
|
|
107
|
+
return;
|
|
108
|
+
};
|
|
109
|
+
let headers = {"Content-Type": Mime.getType(Path.posix.extname(id).toLowerCase()), "Last-Modified": new Date(source.source.ctime * 1000).toUTCString(), "Content-Length": Std.string(source.data.length), "Cache-Control": "no-store, no-cache"};
|
|
110
|
+
if (_gthis.config.headers != null) {
|
|
111
|
+
let access = _gthis.config.headers;
|
|
112
|
+
let _g_keys = Reflect__1.fields(access);
|
|
113
|
+
let _g_index = 0;
|
|
114
|
+
while (_g_index < _g_keys.length) {
|
|
115
|
+
let key = _g_keys[_g_index++];
|
|
116
|
+
headers[key] = access[key];
|
|
117
|
+
};
|
|
118
|
+
};
|
|
119
|
+
res.writeHead(200, headers);
|
|
120
|
+
res.write(source.data, "binary");
|
|
121
|
+
res.end();
|
|
122
|
+
})["catch"](function (e) {
|
|
123
|
+
Log.log(40, ...["Server error.", {"error": e}]);
|
|
124
|
+
res.writeHead(500, "Error happened.", _gthis.config.headers);
|
|
125
|
+
if (((e) instanceof Error)) {
|
|
126
|
+
res.write(e.stack, "utf-8");
|
|
127
|
+
} else {
|
|
128
|
+
res.write(Std.string(e), "utf-8");
|
|
129
|
+
};
|
|
130
|
+
res.end();
|
|
131
|
+
});
|
|
102
132
|
})["catch"](function (e) {
|
|
103
133
|
Log.log(40, ...["Server error.", {"error": e}]);
|
|
104
134
|
res.writeHead(500, "Error happened.", _gthis.config.headers);
|
|
@@ -124,6 +154,68 @@ class Server extends Register.inherits(Stone) {
|
|
|
124
154
|
res.writeHead(200, this.config.headers);
|
|
125
155
|
res.end();
|
|
126
156
|
break
|
|
157
|
+
case "POST":
|
|
158
|
+
let stoneId = Path.posix.join(".", "./", ".", id);
|
|
159
|
+
let stone = Lambda.find(this.project.stones, function (s) {
|
|
160
|
+
return s.id == stoneId;
|
|
161
|
+
});
|
|
162
|
+
if (stone == null) {
|
|
163
|
+
let e = "Could not find stone with such id.";
|
|
164
|
+
Log.log(40, ...["Server error.", {"error": e}]);
|
|
165
|
+
res.writeHead(500, "Error happened.", _gthis.config.headers);
|
|
166
|
+
if (((e) instanceof Error)) {
|
|
167
|
+
res.write(e.stack, "utf-8");
|
|
168
|
+
} else {
|
|
169
|
+
res.write(Std.string(e), "utf-8");
|
|
170
|
+
};
|
|
171
|
+
res.end();
|
|
172
|
+
} else {
|
|
173
|
+
let body = "";
|
|
174
|
+
req.on("data", function (chunk) {
|
|
175
|
+
body += chunk;
|
|
176
|
+
return body;
|
|
177
|
+
});
|
|
178
|
+
req.on("end", function () {
|
|
179
|
+
let request = JSON.parse(body);
|
|
180
|
+
if (request.config != null) {
|
|
181
|
+
let _g = 0;
|
|
182
|
+
let _g1 = Reflect__1.fields(stone.config);
|
|
183
|
+
while (_g < _g1.length) {
|
|
184
|
+
let field = _g1[_g];
|
|
185
|
+
++_g;
|
|
186
|
+
stone.config[field] = Reflect__1.field(request.config, field);
|
|
187
|
+
};
|
|
188
|
+
};
|
|
189
|
+
if (request.getSource) {
|
|
190
|
+
stone.getSource().then(function (src) {
|
|
191
|
+
let resJson = {};
|
|
192
|
+
let _g = 0;
|
|
193
|
+
let _g1 = src.data;
|
|
194
|
+
while (_g < _g1.length) {
|
|
195
|
+
let data = _g1[_g];
|
|
196
|
+
++_g;
|
|
197
|
+
resJson[data.id] = data.data.toString("base64");
|
|
198
|
+
};
|
|
199
|
+
res.writeHead(200, _gthis.config.headers);
|
|
200
|
+
res.write(JSON.stringify(resJson), "utf-8");
|
|
201
|
+
res.end();
|
|
202
|
+
})["catch"](function (e) {
|
|
203
|
+
Log.log(40, ...["Server error.", {"error": e}]);
|
|
204
|
+
res.writeHead(500, "Error happened.", _gthis.config.headers);
|
|
205
|
+
if (((e) instanceof Error)) {
|
|
206
|
+
res.write(e.stack, "utf-8");
|
|
207
|
+
} else {
|
|
208
|
+
res.write(Std.string(e), "utf-8");
|
|
209
|
+
};
|
|
210
|
+
res.end();
|
|
211
|
+
});
|
|
212
|
+
} else {
|
|
213
|
+
res.writeHead(200, _gthis.config.headers);
|
|
214
|
+
res.end();
|
|
215
|
+
};
|
|
216
|
+
});
|
|
217
|
+
};
|
|
218
|
+
break
|
|
127
219
|
case "PUT":
|
|
128
220
|
let cmd = [Path.posix.join(".", "./", ".", id)];
|
|
129
221
|
let body = "";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "whet",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.32",
|
|
4
4
|
"description": "NodeJS based assets management and project tooling library.",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"devinit": "npx dts2hx commander pino-pretty --modular --noLibWrap",
|
|
@@ -13,7 +13,9 @@
|
|
|
13
13
|
"files": [
|
|
14
14
|
"bin"
|
|
15
15
|
],
|
|
16
|
-
"bin":
|
|
16
|
+
"bin": {
|
|
17
|
+
"whet": "bin/whet.js"
|
|
18
|
+
},
|
|
17
19
|
"main": "bin/whet.js",
|
|
18
20
|
"type": "module",
|
|
19
21
|
"author": "Peter Achberger",
|
package/bin/List.d.ts
DELETED