nodexh 1.1.0 → 2.1.0
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/README.md +5 -0
- package/bin/nodexh +27 -1
- package/lib/main.js +150 -57
- package/lib/main.js.map +2 -2
- package/package.json +9 -7
- package/pnpm-lock.yaml +76 -0
- package/src/main.coffee +119 -43
package/README.md
CHANGED
|
@@ -56,4 +56,9 @@ Use `nodexh path/to/file.js` instead of `node path/to/file.js`, and you're good
|
|
|
56
56
|
* [ ] fix async stacktraces (probably not yet handled correctly; might be issue with `stackman`?)
|
|
57
57
|
* [ ] consider [utf8ize-sourcemaps](https://github.com/twada/utf8ize-sourcemaps) in case there should be
|
|
58
58
|
problems w/ 32bit characters
|
|
59
|
+
* [ ] truncate long lines in context
|
|
60
|
+
* [ ] offer capabilities of NodeXH as API so applications (such as test libraries) can easily retrieve
|
|
61
|
+
source code, display source lines with contexts
|
|
62
|
+
|
|
63
|
+
|
|
59
64
|
|
package/bin/nodexh
CHANGED
|
@@ -1,3 +1,29 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
|
-
|
|
2
|
+
|
|
3
|
+
realpath() {
|
|
4
|
+
# thx to https://github.com/whatwg/html-build/issues/90
|
|
5
|
+
OURPWD=$PWD
|
|
6
|
+
cd "$(dirname "$1")"
|
|
7
|
+
LINK=$(readlink "$(basename "$1")")
|
|
8
|
+
while [ "$LINK" ]; do
|
|
9
|
+
cd "$(dirname "$LINK")"
|
|
10
|
+
LINK=$(readlink "$(basename "$1")")
|
|
11
|
+
done
|
|
12
|
+
REALPATH="$PWD/$(basename "$1")"
|
|
13
|
+
cd "$OURPWD"
|
|
14
|
+
echo "$REALPATH"
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
node \
|
|
18
|
+
--require "$(realpath "$0")"/../../lib/main.js \
|
|
19
|
+
--trace-warnings \
|
|
20
|
+
--enable-source-maps \
|
|
21
|
+
--stack-trace-limit=100 \
|
|
22
|
+
--expose-gc \
|
|
23
|
+
"$@"
|
|
24
|
+
# --nouse_idle_notification \
|
|
25
|
+
# --trace_gc \
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
|
|
3
29
|
|
package/lib/main.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
(function() {
|
|
2
2
|
'use strict';
|
|
3
|
-
var CND, FS, PATH, alert, badge, bold, cyan, debug, echo, exit_handler, fetch_mapped_location, get_context, get_error_callsites, gold, green, grey, help, info, load_source_map, log, red, reverse, rpr, show_error_with_source_context, steel, underline, urge, warn, whisper, white, write_to_stderr, yellow;
|
|
3
|
+
var CND, FS, PATH, _get_context, alert, badge, bold, cyan, debug, echo, exit_handler, fetch_mapped_location, get_context, get_error_callsites, get_stacktracey, gold, green, grey, help, info, load_source_map, log, red, reverse, rpr, show_error_with_source_context, show_stacktracey, steel, underline, urge, warn, whisper, white, write_to_stderr, yellow;
|
|
4
4
|
|
|
5
5
|
//###########################################################################################################
|
|
6
6
|
CND = require('cnd');
|
|
@@ -57,7 +57,8 @@
|
|
|
57
57
|
});
|
|
58
58
|
} catch (error1) {
|
|
59
59
|
error = error1;
|
|
60
|
-
warn
|
|
60
|
+
// warn '^7763-3^', "!!!!!!!!!!!!!!!!!", { path, }
|
|
61
|
+
// warn '^7763-3^', "!!!!!!!!!!!!!!!!!", error.message
|
|
61
62
|
return {path, linenr, colnr};
|
|
62
63
|
}
|
|
63
64
|
//.........................................................................................................
|
|
@@ -75,57 +76,62 @@
|
|
|
75
76
|
|
|
76
77
|
//-----------------------------------------------------------------------------------------------------------
|
|
77
78
|
get_context = function(path, linenr, colnr, width) {
|
|
78
|
-
var
|
|
79
|
+
var error;
|
|
79
80
|
try {
|
|
80
|
-
|
|
81
|
-
lines = (FS.readFileSync(path, {
|
|
82
|
-
encoding: 'utf-8'
|
|
83
|
-
})).split('\n');
|
|
84
|
-
delta = 1;
|
|
85
|
-
coldelta = 5;
|
|
86
|
-
/* TAINT use more meaningful limit like n times the terminal width, assuming default of 100 */
|
|
87
|
-
// effect = underline
|
|
88
|
-
// effect = bold
|
|
89
|
-
effect = reverse;
|
|
90
|
-
first_idx = Math.max(0, linenr - 1 - delta);
|
|
91
|
-
last_idx = Math.min(lines.length - 1, linenr - 1 + delta);
|
|
92
|
-
R = [];
|
|
93
|
-
ref = lines.slice(first_idx, +last_idx + 1 || 9e9);
|
|
94
|
-
for (idx = i = 0, len = ref.length; i < len; idx = ++i) {
|
|
95
|
-
line = ref[idx];
|
|
96
|
-
this_linenr = first_idx + idx + 1;
|
|
97
|
-
this_linenr_txt = (this_linenr.toString().padStart(4)) + '│ ';
|
|
98
|
-
if (this_linenr === linenr) {
|
|
99
|
-
c0 = colnr - 1;
|
|
100
|
-
c1 = colnr + coldelta;
|
|
101
|
-
hilite = effect(line.slice(c0, c1));
|
|
102
|
-
line = line.slice(0, c0) + hilite + line.slice(c1);
|
|
103
|
-
if (c1 > width) {
|
|
104
|
-
width2 = Math.floor(width / 2);
|
|
105
|
-
line = '... ' + line.slice(c1 - width2, +(c1 + hilite.length - (c1 - c0) + width2) + 1 || 9e9) + ' ...';
|
|
106
|
-
} else {
|
|
107
|
-
line = line.slice(0, +width + 1 || 9e9);
|
|
108
|
-
}
|
|
109
|
-
R.push(`${grey(this_linenr_txt)}${cyan(line)}`);
|
|
110
|
-
} else {
|
|
111
|
-
R.push(`${grey(this_linenr_txt)}${grey(line)}`);
|
|
112
|
-
}
|
|
113
|
-
}
|
|
81
|
+
return _get_context(path, linenr, colnr, width);
|
|
114
82
|
} catch (error1) {
|
|
115
|
-
// R = R.join '\n'
|
|
116
83
|
error = error1;
|
|
117
84
|
if (error.code !== 'ENOENT') {
|
|
118
85
|
throw error;
|
|
119
86
|
}
|
|
120
|
-
return [];
|
|
121
87
|
}
|
|
122
|
-
|
|
88
|
+
return [];
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
//-----------------------------------------------------------------------------------------------------------
|
|
92
|
+
// return [ ( red "!!! #{rpr error.message} !!!" ), ]
|
|
93
|
+
_get_context = function(path, linenr, colnr, width) {
|
|
94
|
+
/* TAINT perform line length adjustment, hiliting in dedicated method */
|
|
95
|
+
var R, c0, c1, coldelta, delta, effect, first_idx, hilite, i, idx, last_idx, len, line, lines, ref, this_linenr, this_linenr_txt, width2;
|
|
96
|
+
lines = (FS.readFileSync(path, {
|
|
97
|
+
encoding: 'utf-8'
|
|
98
|
+
})).split('\n');
|
|
99
|
+
delta = 1;
|
|
100
|
+
coldelta = 5;
|
|
101
|
+
effect = reverse;
|
|
102
|
+
first_idx = Math.max(0, linenr - 1 - delta);
|
|
103
|
+
last_idx = Math.min(lines.length - 1, linenr - 1 + delta);
|
|
104
|
+
R = [];
|
|
105
|
+
ref = lines.slice(first_idx, +last_idx + 1 || 9e9);
|
|
106
|
+
for (idx = i = 0, len = ref.length; i < len; idx = ++i) {
|
|
107
|
+
line = ref[idx];
|
|
108
|
+
this_linenr = first_idx + idx + 1;
|
|
109
|
+
this_linenr_txt = (this_linenr.toString().padStart(4)) + '│ ';
|
|
110
|
+
if (this_linenr !== linenr) {
|
|
111
|
+
/* TAINT should adjust overlong context lines as well */
|
|
112
|
+
R.push(`${grey(this_linenr_txt)}${grey(line)}`);
|
|
113
|
+
continue;
|
|
114
|
+
}
|
|
115
|
+
c0 = colnr - 1;
|
|
116
|
+
c1 = colnr + coldelta;
|
|
117
|
+
hilite = effect(line.slice(c0, c1));
|
|
118
|
+
line = line.slice(0, c0) + hilite + line.slice(c1);
|
|
119
|
+
if (c1 > width) {
|
|
120
|
+
width2 = Math.floor(width / 2);
|
|
121
|
+
line = '... ' + line.slice(c1 - width2, +(c1 + hilite.length - (c1 - c0) + width2) + 1 || 9e9) + ' ...';
|
|
122
|
+
} else {
|
|
123
|
+
line = line.slice(0, +width + 1 || 9e9);
|
|
124
|
+
}
|
|
125
|
+
R.push(`${grey(this_linenr_txt)}${cyan(line)}`);
|
|
126
|
+
}
|
|
127
|
+
// R = R.join '\n'
|
|
123
128
|
return R;
|
|
124
129
|
};
|
|
125
130
|
|
|
126
131
|
//-----------------------------------------------------------------------------------------------------------
|
|
127
132
|
show_error_with_source_context = async function(error, headline) {
|
|
128
|
-
|
|
133
|
+
/* TAINT use proper methods to format with multiple colors */
|
|
134
|
+
var arrowhead, arrowshaft, callsite, callsites, colnr, context_line, fname, fname_txt, i, j, len, len1, linenr, path, ref, ref1, ref2, relpath, width, width1;
|
|
129
135
|
/* From https://github.com/watson/stackman#gotchas: "This module works because V8 (the JavaScript engine
|
|
130
136
|
behind Node.js) allows us to hook into the stack trace generator function before that stack trace is
|
|
131
137
|
generated. It's triggered by accessing the .stack property on the Error object, so please don't do
|
|
@@ -137,7 +143,7 @@
|
|
|
137
143
|
callsites = get_error_callsites(error);
|
|
138
144
|
//.........................................................................................................
|
|
139
145
|
if ((callsites == null) || (callsites.length === 0)) {
|
|
140
|
-
write_to_stderr(CND.red(CND.reverse("error has no associated callsites:")));
|
|
146
|
+
write_to_stderr(CND.red(CND.reverse("^455756^ error has no associated callsites:")));
|
|
141
147
|
write_to_stderr(CND.red(CND.reverse(rpr(error))));
|
|
142
148
|
return null;
|
|
143
149
|
}
|
|
@@ -156,48 +162,135 @@
|
|
|
156
162
|
linenr = callsite.getLineNumber();
|
|
157
163
|
colnr = callsite.getColumnNumber();
|
|
158
164
|
//.......................................................................................................
|
|
159
|
-
if (path.startsWith('internal/')) {
|
|
160
|
-
write_to_stderr(arrowhead, grey(`${path}
|
|
165
|
+
if ((path.startsWith('node:internal/')) || (path.startsWith('internal/'))) {
|
|
166
|
+
write_to_stderr(arrowhead, grey(`${path} @ ${linenr},${colnr}`));
|
|
161
167
|
continue;
|
|
162
168
|
}
|
|
163
169
|
//.......................................................................................................
|
|
164
|
-
// debug '^344463^', { relpath, linenr, colnr, }
|
|
165
170
|
// write_to_stderr()
|
|
166
171
|
// write_to_stderr steel bold reverse ( "#{relpath} ##{linenr}:" ).padEnd 108
|
|
172
|
+
fname = (ref = (ref1 = callsite.getFunctionName()) != null ? ref1 : callsite.getMethodName()) != null ? ref : null;
|
|
167
173
|
({path, linenr, colnr} = (await fetch_mapped_location(path, linenr, colnr)));
|
|
168
174
|
relpath = PATH.relative(process.cwd(), path);
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
175
|
+
if (fname != null) {
|
|
176
|
+
fname_txt = steel(fname);
|
|
177
|
+
width1 = width + (fname_txt.length - fname.length);
|
|
178
|
+
write_to_stderr(arrowhead, gold(`${relpath} @ ${linenr},${colnr}: ${fname_txt}() \x1b[38;05;234m`.padEnd(width1, '—')));
|
|
179
|
+
} else {
|
|
180
|
+
write_to_stderr(arrowhead, gold(`${relpath} @ ${linenr},${colnr}: \x1b[38;05;234m`.padEnd(width, '—')));
|
|
181
|
+
}
|
|
182
|
+
ref2 = (await get_context(path, linenr, colnr, width));
|
|
183
|
+
for (j = 0, len1 = ref2.length; j < len1; j++) {
|
|
184
|
+
context_line = ref2[j];
|
|
173
185
|
write_to_stderr(arrowshaft, context_line);
|
|
174
186
|
}
|
|
175
187
|
}
|
|
176
188
|
alert('^77765-2^', reverse(bold(headline)));
|
|
177
|
-
//
|
|
189
|
+
// urge "^94843^ error.stack:", rpr error.stack
|
|
190
|
+
// urge "^94843^ error.message:", rpr error.message
|
|
191
|
+
// urge "^94843^ error.code:", rpr error.code
|
|
192
|
+
// urge "^94843^ error.name:", rpr error.name
|
|
193
|
+
// urge "^94843^ error.type:", rpr error.type
|
|
194
|
+
// urge "^94843^ error.toString():", rpr error.toString()
|
|
195
|
+
// urge "^94843^ error:", rpr error
|
|
196
|
+
// CATALOGUING = require '../../multimix/lib/cataloguing'
|
|
197
|
+
// urge "^94843^", ( CATALOGUING.all_keys_of error )
|
|
178
198
|
return null;
|
|
179
199
|
};
|
|
180
200
|
|
|
181
201
|
//-----------------------------------------------------------------------------------------------------------
|
|
182
|
-
exit_handler = async function(error) {
|
|
183
|
-
var message, ref;
|
|
184
|
-
|
|
202
|
+
exit_handler = async function(error, origin) {
|
|
203
|
+
var message, ref, ref1, ref2, type;
|
|
204
|
+
/* TAINT origin never used */
|
|
205
|
+
// show_stacktracey error
|
|
206
|
+
// debug '^4488^', error
|
|
207
|
+
// debug '^4488^', await origin
|
|
208
|
+
// return null
|
|
209
|
+
type = (ref = (ref1 = error.code) != null ? ref1 : error.name) != null ? ref : 'EXCEPTION';
|
|
210
|
+
message = ` ${type}: ` + ((ref2 = error != null ? error.message : void 0) != null ? ref2 : "an unrecoverable condition occurred");
|
|
185
211
|
await show_error_with_source_context(error, message);
|
|
186
212
|
setImmediate((function() {
|
|
187
213
|
return process.exit(111);
|
|
188
214
|
}));
|
|
189
|
-
// process.exit 111
|
|
190
215
|
return null;
|
|
191
216
|
};
|
|
192
217
|
|
|
218
|
+
//###########################################################################################################
|
|
219
|
+
//###########################################################################################################
|
|
220
|
+
//###########################################################################################################
|
|
221
|
+
get_stacktracey = function(error) {
|
|
222
|
+
var R, StackTracey, d, i, idx, ref, s, stack;
|
|
223
|
+
StackTracey = require('stacktracey');
|
|
224
|
+
stack = (new StackTracey(error)).withSources();
|
|
225
|
+
// stack = stack.clean()
|
|
226
|
+
R = [];
|
|
227
|
+
for (idx = i = ref = stack.items.length - 1; i >= 0; idx = i += -1) {
|
|
228
|
+
d = stack.items[idx];
|
|
229
|
+
// debug '^2798^', ( k for k of d )
|
|
230
|
+
s = {
|
|
231
|
+
// target_path: d.file
|
|
232
|
+
relpath: d.fileRelative, // fileShort
|
|
233
|
+
native: d.native,
|
|
234
|
+
// is_nodejs: d.native
|
|
235
|
+
is_other: d.thirdParty,
|
|
236
|
+
line: d.line,
|
|
237
|
+
column: d.column,
|
|
238
|
+
source: d.sourceLine,
|
|
239
|
+
error: d.error
|
|
240
|
+
};
|
|
241
|
+
// for k in [ 'sourceLine', 'native', 'file', 'line', 'column', 'calleeShort', 'fileRelative', 'fileShort', 'fileName', 'thirdParty', 'name',]
|
|
242
|
+
// debug k, rpr d[ k ]
|
|
243
|
+
R.push(s);
|
|
244
|
+
}
|
|
245
|
+
// info '\n' + stack.asTable()
|
|
246
|
+
return R;
|
|
247
|
+
};
|
|
248
|
+
|
|
249
|
+
show_stacktracey = function(error) {
|
|
250
|
+
var d, i, len, ref, ref1;
|
|
251
|
+
ref = get_stacktracey(error);
|
|
252
|
+
for (i = 0, len = ref.length; i < len; i++) {
|
|
253
|
+
d = ref[i];
|
|
254
|
+
echo(CND.steel('^44872^ ' + `${d.relpath} @ ${d.line}:${d.column}`));
|
|
255
|
+
/* NOTE errors:
|
|
256
|
+
ENOENT: no such file or directory
|
|
257
|
+
EISDIR: illegal operation on a directory, read
|
|
258
|
+
'Cannot read property 'originalPositionFor' of undefined'
|
|
259
|
+
*/
|
|
260
|
+
if (d.error != null) {
|
|
261
|
+
echo(CND.red('^44873^ ' + ((ref1 = d.error.message) != null ? ref1 : "an error occurred")));
|
|
262
|
+
} else {
|
|
263
|
+
echo(CND.yellow('^44874^ ' + `${rpr(d.source.slice(0, 101))}`));
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
return null;
|
|
267
|
+
};
|
|
268
|
+
|
|
269
|
+
//###########################################################################################################
|
|
270
|
+
//###########################################################################################################
|
|
271
|
+
//###########################################################################################################
|
|
272
|
+
|
|
193
273
|
//###########################################################################################################
|
|
194
274
|
if (global[Symbol.for('cnd-exception-handler')] == null) {
|
|
275
|
+
null;
|
|
195
276
|
global[Symbol.for('cnd-exception-handler')] = true;
|
|
196
|
-
process.
|
|
197
|
-
process.
|
|
277
|
+
process.once('uncaughtException', exit_handler);
|
|
278
|
+
process.once('unhandledRejection', exit_handler);
|
|
198
279
|
}
|
|
199
280
|
|
|
200
|
-
|
|
281
|
+
// do =>
|
|
282
|
+
// process.stderr.on 'data', ( data ) => debug "^6863-1^ (stderr.on 'data'):", rpr data
|
|
283
|
+
// process.stdout.on 'data', ( data ) => debug "^6863-2^ (stdout.on 'data'):", rpr data
|
|
284
|
+
// process.stderr.on 'end', => debug "^6863-1^ (stderr.on 'end')"
|
|
285
|
+
// process.stdout.on 'end', => debug "^6863-2^ (stdout.on 'end')"
|
|
286
|
+
// debug '^6456^'
|
|
287
|
+
// echo "^4564^ echo to stdout"
|
|
288
|
+
// warn "^4564^ warn to stderr"
|
|
289
|
+
// process.stderr.write "this goes to stderr\n"
|
|
290
|
+
// process.stdout.write "this goes to stdout\n"
|
|
291
|
+
// process.on 'message', ( message ) -> debug "^6863-3^' (process.on 'message'):", rpr message
|
|
292
|
+
// process.on 'warning', ( warning ) -> debug "^6863-3^' (process.on 'warning'):", rpr warning
|
|
293
|
+
/*
|
|
201
294
|
callsite.getThis() - returns the value of this
|
|
202
295
|
callsite.getTypeName() - returns the type of this as a string. This is the name of the function stored in the constructor field of this, if available, otherwise the object's [[Class]] internal property.
|
|
203
296
|
callsite.getFunction() - returns the current function
|
package/lib/main.js.map
CHANGED
|
@@ -6,8 +6,8 @@
|
|
|
6
6
|
"../src/main.coffee"
|
|
7
7
|
],
|
|
8
8
|
"names": [],
|
|
9
|
-
"mappings": "AAEA;EAAA;AAAA,MAAA,GAAA,EAAA,EAAA,EAAA,IAAA,EAAA,KAAA,EAAA,KAAA,EAAA,IAAA,EAAA,IAAA,EAAA,KAAA,EAAA,IAAA,EAAA,YAAA,EAAA,qBAAA,EAAA,WAAA,EAAA,mBAAA,EAAA,IAAA,EAAA,KAAA,EAAA,IAAA,EAAA,IAAA,EAAA,IAAA,EAAA,eAAA,EAAA,GAAA,EAAA,GAAA,EAAA,OAAA,EAAA,GAAA,EAAA,8BAAA,EAAA,KAAA,EAAA,SAAA,EAAA,IAAA,EAAA,IAAA,EAAA,OAAA,EAAA,KAAA,EAAA,eAAA,EAAA,MAAA;;;EAIA,GAAA,GAA4B,OAAA,CAAQ,KAAR;;EAC5B,GAAA,GAA4B,GAAG,CAAC;;EAChC,KAAA,GAA4B;;EAC5B,GAAA,GAA4B,GAAG,CAAC,UAAJ,CAAe,OAAf,EAA4B,KAA5B;;EAC5B,KAAA,GAA4B,GAAG,CAAC,UAAJ,CAAe,OAAf,EAA4B,KAA5B;;EAC5B,IAAA,GAA4B,GAAG,CAAC,UAAJ,CAAe,MAAf,EAA4B,KAA5B;;EAC5B,IAAA,GAA4B,GAAG,CAAC,UAAJ,CAAe,MAAf,EAA4B,KAA5B;;EAC5B,KAAA,GAA4B,GAAG,CAAC,UAAJ,CAAe,OAAf,EAA6B,KAA7B;;EAC5B,IAAA,GAA4B,GAAG,CAAC,UAAJ,CAAe,MAAf,EAA4B,KAA5B;;EAC5B,IAAA,GAA4B,GAAG,CAAC,UAAJ,CAAe,MAAf,EAA4B,KAA5B;;EAC5B,OAAA,GAA4B,GAAG,CAAC,UAAJ,CAAe,SAAf,EAA4B,KAA5B;;EAC5B,IAAA,GAA4B,GAAG,CAAC,IAAI,CAAC,IAAT,CAAc,GAAd,EAf5B;;;EAiBA,mBAAA,GAA4B,OAAA,CAAQ,iBAAR;;EAC5B,eAAA,GAA4B,CAAE,OAAA,CAAQ,MAAR,CAAF,CAAkB,CAAC,SAAnB,CAA+B,OAAA,CAAQ,iBAAR,CAA/B;;EAC5B,EAAA,GAA4B,OAAA,CAAQ,IAAR;;EAC5B,IAAA,GAA4B,OAAA,CAAQ,MAAR;;EAC5B,CAAA,CAAE,GAAF,EACE,KADF,EAEE,KAFF,EAGE,IAHF,EAIE,IAJF,EAKE,IALF,EAME,IANF,EAOE,KAPF,EAQE,MARF,EASE,OATF,EAUE,SAVF,EAWE,IAXF,CAAA,GAW4B,GAX5B,EArBA;;;;;;EAqCA,eAAA,GAAkB,QAAA,CAAA,GAAE,CAAF,CAAA;WAAY,OAAO,CAAC,MAAM,CAAC,KAAf,CAAqB,GAAA,GAAM,GAAG,CAAC,GAAJ,CAAQ,GAAA,CAAR,CAA3B;EAAZ,EArClB;;;EAwCA,qBAAA,GAAwB,MAAA,QAAA,CAAE,IAAF,EAAQ,MAAR,EAAgB,KAAhB,CAAA;AACxB,QAAA,KAAA,EAAA,WAAA,EAAA,GAAA,EAAA;AAAE;MACE,SAAA,GAAY,CAAA,MAAM,eAAA,CAAgB,IAAhB,CAAN;MACZ,GAAA,GAAY,SAAS,CAAC,mBAAV,CAA8B;QAAE,IAAA,EAAM,MAAR;QAAgB,MAAA,EAAQ;MAAxB,CAA9B,EAFd;KAGA,cAAA;MAAM
|
|
9
|
+
"mappings": "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",
|
|
10
10
|
"sourcesContent": [
|
|
11
|
-
"\n\n'use strict'\n\n\n############################################################################################################\nCND = require 'cnd'\nrpr = CND.rpr\nbadge = 'nodexh'\nlog = CND.get_logger 'plain', badge\ndebug = CND.get_logger 'debug', badge\ninfo = CND.get_logger 'info', badge\nwarn = CND.get_logger 'warn', badge\nalert = CND.get_logger 'alert', badge\nhelp = CND.get_logger 'help', badge\nurge = CND.get_logger 'urge', badge\nwhisper = CND.get_logger 'whisper', badge\necho = CND.echo.bind CND\n# stackman = ( require 'stackman' )()\nget_error_callsites = require 'error-callsites'\nload_source_map = ( require 'util' ).promisify ( require 'load-source-map' )\nFS = require 'fs'\nPATH = require 'path'\n{ red\n green\n steel\n grey\n cyan\n bold\n gold\n white\n yellow\n reverse\n underline\n bold } = CND\n# types = new ( require '../../intertype' ).Intertype()\n# { isa } = types.export()\n\n#-----------------------------------------------------------------------------------------------------------\nwrite_to_stderr = ( P... ) -> process.stderr.write ' ' + CND.pen P...\n\n#-----------------------------------------------------------------------------------------------------------\nfetch_mapped_location = ( path, linenr, colnr ) ->\n try\n sourcemap = await load_source_map path\n smp = sourcemap.originalPositionFor { line: linenr, column: colnr, }\n catch error\n warn '^7763-3^', \"!!!!!!!!!!!!!!!!!\", error.message\n return { path, linenr, colnr, }\n #.........................................................................................................\n if ( smp? ) and ( smp.source? ) and ( smp.source isnt '' ) and ( smp.line? ) and ( smp.column? )\n mapped_path = PATH.join ( PATH.dirname path ), smp.source\n return { path: mapped_path, linenr: smp.line, colnr: smp.column, }\n #.........................................................................................................\n return { path, linenr, colnr, }\n\n#-----------------------------------------------------------------------------------------------------------\nget_context = ( path, linenr, colnr, width ) ->\n #.........................................................................................................\n try\n lines = ( FS.readFileSync path, { encoding: 'utf-8' } ).split '\\n'\n delta = 1\n coldelta = 5\n ### TAINT use more meaningful limit like n times the terminal width, assuming default of 100 ###\n # effect = underline\n # effect = bold\n effect = reverse\n first_idx = Math.max 0, linenr - 1 - delta\n last_idx = Math.min lines.length - 1, linenr - 1 + delta\n R = []\n for line, idx in lines[ first_idx .. last_idx ]\n this_linenr = first_idx + idx + 1\n this_linenr_txt = ( this_linenr.toString().padStart 4 ) + '│ '\n if this_linenr is linenr\n c0 = colnr - 1\n c1 = colnr + coldelta\n hilite = effect line[ c0 ... c1 ]\n line = line[ ... c0 ] + hilite + line[ c1 .. ]\n if c1 > width\n width2 = Math.floor width / 2\n line = '... ' + line[ c1 - width2 .. c1 + hilite.length - ( c1 - c0 ) + width2 ] + ' ...'\n else\n line = line[ .. width ]\n R.push \"#{grey this_linenr_txt}#{cyan line}\"\n else\n R.push \"#{grey this_linenr_txt}#{grey line}\"\n # R = R.join '\\n'\n catch error\n throw error unless error.code is 'ENOENT'\n # return [ ( red \"!!! #{rpr error.message} !!!\" ), ]\n return []\n return R\n\n#-----------------------------------------------------------------------------------------------------------\nshow_error_with_source_context = ( error, headline ) ->\n ### From https://github.com/watson/stackman#gotchas: \"This module works because V8 (the JavaScript engine\n behind Node.js) allows us to hook into the stack trace generator function before that stack trace is\n generated. It's triggered by accessing the .stack property on the Error object, so please don't do\n that before parsing the error to stackman, else this will not work!\" ###\n alert '^77765-1^', reverse bold headline\n arrowhead = white '▲'\n arrowshaft = white '│'\n width = process.stdout.columns\n callsites = get_error_callsites error\n #.........................................................................................................\n if ( not callsites? ) or ( callsites.length is 0 )\n write_to_stderr CND.red CND.reverse \"error has no associated callsites:\"\n write_to_stderr CND.red CND.reverse rpr error\n return null\n #.........................................................................................................\n callsites.reverse()\n #.........................................................................................................\n for callsite in callsites\n path = callsite.getFileName()\n #.......................................................................................................\n unless path?\n write_to_stderr grey '—'.repeat 108\n continue\n #.......................................................................................................\n linenr = callsite.getLineNumber()\n colnr = callsite.getColumnNumber()\n #.......................................................................................................\n if path.startsWith 'internal/'\n write_to_stderr arrowhead, grey \"#{path} ##{linenr}\"\n continue\n #.......................................................................................................\n # debug '^344463^', { relpath, linenr, colnr, }\n # write_to_stderr()\n # write_to_stderr steel bold reverse ( \"#{relpath} ##{linenr}:\" ).padEnd 108\n { path\n linenr\n colnr } = await fetch_mapped_location path, linenr, colnr\n relpath = PATH.relative process.cwd(), path\n write_to_stderr arrowhead, gold ( \"#{relpath} @ #{linenr},#{colnr}: \\x1b[38;05;234m\".padEnd width, '—' )\n for context_line in await get_context path, linenr, colnr, width\n write_to_stderr arrowshaft, context_line\n alert '^77765-2^', reverse bold headline\n # if error?.message?\n return null\n\n#-----------------------------------------------------------------------------------------------------------\nexit_handler = ( error ) ->\n message = ' EXCEPTION: ' + ( error?.message ? \"an unrecoverable condition occurred\" )\n await show_error_with_source_context error, message\n setImmediate ( -> process.exit 111 )\n # process.exit 111\n return null\n\n\n\n############################################################################################################\nunless global[ Symbol.for 'cnd-exception-handler' ]?\n global[ Symbol.for 'cnd-exception-handler' ] = true\n process.on 'uncaughtException', exit_handler\n process.on 'unhandledRejection', exit_handler\n\n###\ncallsite.getThis() - returns the value of this\ncallsite.getTypeName() - returns the type of this as a string. This is the name of the function stored in the constructor field of this, if available, otherwise the object's [[Class]] internal property.\ncallsite.getFunction() - returns the current function\ncallsite.getFunctionName() - returns the name of the current function, typically its name property. If a name property is not available an attempt will be made to try to infer a name from the function's context.\ncallsite.getMethodName() - returns the name of the property of this or one of its prototypes that holds the current function\ncallsite.getFileName() - if this function was defined in a script returns the name of the script\ncallsite.getLineNumber() - if this function was defined in a script returns the current line number\ncallsite.getColumnNumber() - if this function was defined in a script returns the current column number\ncallsite.getEvalOrigin() - if this function was created using a call to eval returns a CallSite object representing the location where eval was called\ncallsite.isToplevel() - is this a toplevel invocation, that is, is this the global object?\ncallsite.isEval() - does this call take place in code defined by a call to eval?\ncallsite.isNative() - is this call in native V8 code?\ncallsite.isConstructor() - is this a constructor c\n###\n\n"
|
|
11
|
+
"\n\n'use strict'\n\n\n############################################################################################################\nCND = require 'cnd'\nrpr = CND.rpr\nbadge = 'nodexh'\nlog = CND.get_logger 'plain', badge\ndebug = CND.get_logger 'debug', badge\ninfo = CND.get_logger 'info', badge\nwarn = CND.get_logger 'warn', badge\nalert = CND.get_logger 'alert', badge\nhelp = CND.get_logger 'help', badge\nurge = CND.get_logger 'urge', badge\nwhisper = CND.get_logger 'whisper', badge\necho = CND.echo.bind CND\n# stackman = ( require 'stackman' )()\nget_error_callsites = require 'error-callsites'\nload_source_map = ( require 'util' ).promisify ( require 'load-source-map' )\nFS = require 'fs'\nPATH = require 'path'\n{ red\n green\n steel\n grey\n cyan\n bold\n gold\n white\n yellow\n reverse\n underline\n bold } = CND\n# types = new ( require '../../intertype' ).Intertype()\n# { isa } = types.export()\n\n#-----------------------------------------------------------------------------------------------------------\nwrite_to_stderr = ( P... ) -> process.stderr.write ' ' + CND.pen P...\n\n#-----------------------------------------------------------------------------------------------------------\nfetch_mapped_location = ( path, linenr, colnr ) ->\n try\n sourcemap = await load_source_map path\n smp = sourcemap.originalPositionFor { line: linenr, column: colnr, }\n catch error\n # warn '^7763-3^', \"!!!!!!!!!!!!!!!!!\", { path, }\n # warn '^7763-3^', \"!!!!!!!!!!!!!!!!!\", error.message\n return { path, linenr, colnr, }\n #.........................................................................................................\n if ( smp? ) and ( smp.source? ) and ( smp.source isnt '' ) and ( smp.line? ) and ( smp.column? )\n mapped_path = PATH.join ( PATH.dirname path ), smp.source\n return { path: mapped_path, linenr: smp.line, colnr: smp.column, }\n #.........................................................................................................\n return { path, linenr, colnr, }\n\n#-----------------------------------------------------------------------------------------------------------\nget_context = ( path, linenr, colnr, width ) ->\n try return ( _get_context path, linenr, colnr, width ) catch error\n throw error unless error.code is 'ENOENT'\n # return [ ( red \"!!! #{rpr error.message} !!!\" ), ]\n return []\n\n#-----------------------------------------------------------------------------------------------------------\n_get_context = ( path, linenr, colnr, width ) ->\n lines = ( FS.readFileSync path, { encoding: 'utf-8' } ).split '\\n'\n delta = 1\n coldelta = 5\n effect = reverse\n first_idx = Math.max 0, linenr - 1 - delta\n last_idx = Math.min lines.length - 1, linenr - 1 + delta\n R = []\n for line, idx in lines[ first_idx .. last_idx ]\n this_linenr = first_idx + idx + 1\n this_linenr_txt = ( this_linenr.toString().padStart 4 ) + '│ '\n if this_linenr isnt linenr\n ### TAINT should adjust overlong context lines as well ###\n R.push \"#{grey this_linenr_txt}#{grey line}\"\n continue\n ### TAINT perform line length adjustment, hiliting in dedicated method ###\n c0 = colnr - 1\n c1 = colnr + coldelta\n hilite = effect line[ c0 ... c1 ]\n line = line[ ... c0 ] + hilite + line[ c1 .. ]\n if c1 > width\n width2 = Math.floor width / 2\n line = '... ' + line[ c1 - width2 .. c1 + hilite.length - ( c1 - c0 ) + width2 ] + ' ...'\n else\n line = line[ .. width ]\n R.push \"#{grey this_linenr_txt}#{cyan line}\"\n # R = R.join '\\n'\n return R\n\n#-----------------------------------------------------------------------------------------------------------\nshow_error_with_source_context = ( error, headline ) ->\n ### From https://github.com/watson/stackman#gotchas: \"This module works because V8 (the JavaScript engine\n behind Node.js) allows us to hook into the stack trace generator function before that stack trace is\n generated. It's triggered by accessing the .stack property on the Error object, so please don't do\n that before parsing the error to stackman, else this will not work!\" ###\n alert '^77765-1^', reverse bold headline\n arrowhead = white '▲'\n arrowshaft = white '│'\n width = process.stdout.columns\n callsites = get_error_callsites error\n #.........................................................................................................\n if ( not callsites? ) or ( callsites.length is 0 )\n write_to_stderr CND.red CND.reverse \"^455756^ error has no associated callsites:\"\n write_to_stderr CND.red CND.reverse rpr error\n return null\n #.........................................................................................................\n callsites.reverse()\n #.........................................................................................................\n for callsite in callsites\n path = callsite.getFileName()\n #.......................................................................................................\n unless path?\n write_to_stderr grey '—'.repeat 108\n continue\n #.......................................................................................................\n linenr = callsite.getLineNumber()\n colnr = callsite.getColumnNumber()\n #.......................................................................................................\n if ( path.startsWith 'node:internal/' ) or ( path.startsWith 'internal/' )\n write_to_stderr arrowhead, grey \"#{path} @ #{linenr},#{colnr}\"\n continue\n #.......................................................................................................\n # write_to_stderr()\n # write_to_stderr steel bold reverse ( \"#{relpath} ##{linenr}:\" ).padEnd 108\n fname = callsite.getFunctionName() ? callsite.getMethodName() ? null\n { path\n linenr\n colnr } = await fetch_mapped_location path, linenr, colnr\n relpath = PATH.relative process.cwd(), path\n if fname?\n ### TAINT use proper methods to format with multiple colors ###\n fname_txt = steel fname\n width1 = width + ( fname_txt.length - fname.length )\n write_to_stderr arrowhead, gold ( \"#{relpath} @ #{linenr},#{colnr}: #{fname_txt}() \\x1b[38;05;234m\".padEnd width1, '—' )\n else\n write_to_stderr arrowhead, gold ( \"#{relpath} @ #{linenr},#{colnr}: \\x1b[38;05;234m\".padEnd width, '—' )\n for context_line in await get_context path, linenr, colnr, width\n write_to_stderr arrowshaft, context_line\n alert '^77765-2^', reverse bold headline\n # urge \"^94843^ error.stack:\", rpr error.stack\n # urge \"^94843^ error.message:\", rpr error.message\n # urge \"^94843^ error.code:\", rpr error.code\n # urge \"^94843^ error.name:\", rpr error.name\n # urge \"^94843^ error.type:\", rpr error.type\n # urge \"^94843^ error.toString():\", rpr error.toString()\n # urge \"^94843^ error:\", rpr error\n # CATALOGUING = require '../../multimix/lib/cataloguing'\n # urge \"^94843^\", ( CATALOGUING.all_keys_of error )\n return null\n\n#-----------------------------------------------------------------------------------------------------------\nexit_handler = ( error, origin ) ->\n ### TAINT origin never used ###\n # show_stacktracey error\n # debug '^4488^', error\n # debug '^4488^', await origin\n # return null\n type = error.code ? error.name ? 'EXCEPTION'\n message = \" #{type}: \" + ( error?.message ? \"an unrecoverable condition occurred\" )\n await show_error_with_source_context error, message\n setImmediate ( -> process.exit 111 )\n return null\n\n############################################################################################################\n############################################################################################################\n############################################################################################################\n\nget_stacktracey = ( error ) ->\n StackTracey = require 'stacktracey'\n stack = ( new StackTracey error ).withSources()\n # stack = stack.clean()\n R = []\n for idx in [ stack.items.length - 1 .. 0 ] by -1\n d = stack.items[ idx ]\n # debug '^2798^', ( k for k of d )\n s =\n # target_path: d.file\n relpath: d.fileRelative # fileShort\n native: d.native\n # is_nodejs: d.native\n is_other: d.thirdParty\n line: d.line\n column: d.column\n source: d.sourceLine\n error: d.error\n # for k in [ 'sourceLine', 'native', 'file', 'line', 'column', 'calleeShort', 'fileRelative', 'fileShort', 'fileName', 'thirdParty', 'name',]\n # debug k, rpr d[ k ]\n R.push s\n # info '\\n' + stack.asTable()\n return R\n\nshow_stacktracey = ( error ) ->\n for d in get_stacktracey error\n echo CND.steel '^44872^ ' + \"#{d.relpath} @ #{d.line}:#{d.column}\"\n ### NOTE errors:\n ENOENT: no such file or directory\n EISDIR: illegal operation on a directory, read\n 'Cannot read property 'originalPositionFor' of undefined'\n ###\n if d.error? then echo CND.red '^44873^ ' + ( d.error.message ? \"an error occurred\" )\n else echo CND.yellow '^44874^ ' + \"#{rpr d.source[ .. 100 ]}\"\n return null\n\n############################################################################################################\n############################################################################################################\n############################################################################################################\n\n\n############################################################################################################\nunless global[ Symbol.for 'cnd-exception-handler' ]?\n null\n global[ Symbol.for 'cnd-exception-handler' ] = true\n process.once 'uncaughtException', exit_handler\n process.once 'unhandledRejection', exit_handler\n\n # do =>\n # process.stderr.on 'data', ( data ) => debug \"^6863-1^ (stderr.on 'data'):\", rpr data\n # process.stdout.on 'data', ( data ) => debug \"^6863-2^ (stdout.on 'data'):\", rpr data\n # process.stderr.on 'end', => debug \"^6863-1^ (stderr.on 'end')\"\n # process.stdout.on 'end', => debug \"^6863-2^ (stdout.on 'end')\"\n # debug '^6456^'\n # echo \"^4564^ echo to stdout\"\n # warn \"^4564^ warn to stderr\"\n # process.stderr.write \"this goes to stderr\\n\"\n # process.stdout.write \"this goes to stdout\\n\"\n # process.on 'message', ( message ) -> debug \"^6863-3^' (process.on 'message'):\", rpr message\n # process.on 'warning', ( warning ) -> debug \"^6863-3^' (process.on 'warning'):\", rpr warning\n###\ncallsite.getThis() - returns the value of this\ncallsite.getTypeName() - returns the type of this as a string. This is the name of the function stored in the constructor field of this, if available, otherwise the object's [[Class]] internal property.\ncallsite.getFunction() - returns the current function\ncallsite.getFunctionName() - returns the name of the current function, typically its name property. If a name property is not available an attempt will be made to try to infer a name from the function's context.\ncallsite.getMethodName() - returns the name of the property of this or one of its prototypes that holds the current function\ncallsite.getFileName() - if this function was defined in a script returns the name of the script\ncallsite.getLineNumber() - if this function was defined in a script returns the current line number\ncallsite.getColumnNumber() - if this function was defined in a script returns the current column number\ncallsite.getEvalOrigin() - if this function was created using a call to eval returns a CallSite object representing the location where eval was called\ncallsite.isToplevel() - is this a toplevel invocation, that is, is this the global object?\ncallsite.isEval() - does this call take place in code defined by a call to eval?\ncallsite.isNative() - is this call in native V8 code?\ncallsite.isConstructor() - is this a constructor c\n###\n\n"
|
|
12
12
|
]
|
|
13
13
|
}
|
package/package.json
CHANGED
|
@@ -1,14 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nodexh",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.1.0",
|
|
4
4
|
"description": "a wrapper around the `node` executable for better stacktraces with sourcemaps, sourcecode excerpts",
|
|
5
5
|
"main": "lib/main.js",
|
|
6
6
|
"bin": {
|
|
7
7
|
"nodexh": "bin/nodexh"
|
|
8
8
|
},
|
|
9
|
-
"scripts": {
|
|
10
|
-
"build": "coffee --map -o lib -c src"
|
|
11
|
-
},
|
|
12
9
|
"repository": {
|
|
13
10
|
"type": "git",
|
|
14
11
|
"url": "https://github.com/loveencounterflow/nodexh.git"
|
|
@@ -28,6 +25,11 @@
|
|
|
28
25
|
"dependencies": {
|
|
29
26
|
"cnd": "^9.1.0",
|
|
30
27
|
"error-callsites": "^2.0.3",
|
|
31
|
-
"load-source-map": "^2.0.0"
|
|
32
|
-
|
|
33
|
-
}
|
|
28
|
+
"load-source-map": "^2.0.0",
|
|
29
|
+
"stacktracey": "^2.0.14"
|
|
30
|
+
},
|
|
31
|
+
"scripts": {
|
|
32
|
+
"build": "coffee --map -o lib -c src"
|
|
33
|
+
},
|
|
34
|
+
"readme": "\n\n# NodeXH: NodeJS With a Better Exception Handler\n\n<!-- START doctoc generated TOC please keep comment here to allow auto update -->\n<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->\n**Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)*\n\n- [What It Is](#what-it-is)\n- [How to Install](#how-to-install)\n- [How to Use](#how-to-use)\n- [What to Expect](#what-to-expect)\n- [Related](#related)\n- [To Do](#to-do)\n\n<!-- END doctoc generated TOC please keep comment here to allow auto update -->\n\n## What It Is\n\nNodeXH is a drop-in wrapper for the NodeJS executable hat provides better stacktraces.\n\n## How to Install\n\n`npm install -g nodexh`\n\n## How to Use\n\nUse `nodexh path/to/file.js` instead of `node path/to/file.js`, and you're good to go.\n\n## What to Expect\n\n* Stack trace items will be reversed, so most recent calls will be shown *last*, i.e. also closest to where\n the cursor of your terminal is.\n* Stack traces will show source contexts (3 lines by default) except where files can not be opened or are\n NodeJS internals.\n* Source code shown will honor sourcemaps, which is great when you're using the likes of CoffeeScript or\n TypeScript.\n* The error message will be repeated to avoid having to scroll up when stack traces get longer.\n* Colors!\n\n## Related\n\n* https://github.com/mozilla/source-map/\n* https://sokra.github.io/source-map-visualization/\n* https://medium.com/@nodejs/source-maps-in-node-js-482872b56116:\n * \"In v13.7.0 a public API was introduced for interacting with source\n maps.\"—[link](https://nodejs.org/dist/latest-v14.x/docs/api/all.html#modules_source_map_v3_support)\n * \"You can start using Node.js’ source map functionality today: make sure you have an up-to-date version\n of Node.js installed, and run your programs with the flag --enable-source-maps.\"\n\n## To Do\n\n* [ ] Add `error.name`, `error.code`; where `node` reports `TypeError: TEMPLATES.main_2 is not a function`,\n `nodexh` only reports `EXCEPTION: TEMPLATES.main_2 is not a function`\n* [ ] visually indicate spot of error (e.g. by reversing)\n* [ ] fix async stacktraces (probably not yet handled correctly; might be issue with `stackman`?)\n* [ ] consider [utf8ize-sourcemaps](https://github.com/twada/utf8ize-sourcemaps) in case there should be\n problems w/ 32bit characters\n* [ ] truncate long lines in context\n* [ ] offer capabilities of NodeXH as API so applications (such as test libraries) can easily retrieve\n source code, display source lines with contexts\n\n\n\n"
|
|
35
|
+
}
|
package/pnpm-lock.yaml
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
lockfileVersion: 5.3
|
|
2
|
+
|
|
3
|
+
specifiers:
|
|
4
|
+
cnd: ^9.1.0
|
|
5
|
+
error-callsites: ^2.0.3
|
|
6
|
+
load-source-map: ^2.0.0
|
|
7
|
+
stacktracey: ^2.0.14
|
|
8
|
+
|
|
9
|
+
dependencies:
|
|
10
|
+
cnd: 9.2.2
|
|
11
|
+
error-callsites: 2.0.4
|
|
12
|
+
load-source-map: 2.0.0
|
|
13
|
+
stacktracey: 2.1.8
|
|
14
|
+
|
|
15
|
+
packages:
|
|
16
|
+
|
|
17
|
+
/as-table/1.0.55:
|
|
18
|
+
resolution: {integrity: sha512-xvsWESUJn0JN421Xb9MQw6AsMHRCUknCe0Wjlxvjud80mU4E6hQf1A6NzQKcYNmYw62MfzEtXc+badstZP3JpQ==}
|
|
19
|
+
dependencies:
|
|
20
|
+
printable-characters: 1.0.42
|
|
21
|
+
dev: false
|
|
22
|
+
|
|
23
|
+
/cnd/9.2.2:
|
|
24
|
+
resolution: {integrity: sha512-F+/H+7luk4fZkvN0+MT0I2nwn80YM/EtfMttNUFxENR50XJH4g0KgQevzeyEJ8B6t6l8Tb4Xti6QAksa8DmePA==}
|
|
25
|
+
hasBin: true
|
|
26
|
+
dependencies:
|
|
27
|
+
jsx-number-format: 0.1.4
|
|
28
|
+
dev: false
|
|
29
|
+
|
|
30
|
+
/data-uri-to-buffer/2.0.2:
|
|
31
|
+
resolution: {integrity: sha512-ND9qDTLc6diwj+Xe5cdAgVTbLVdXbtxTJRXRhli8Mowuaan+0EJOtdqJ0QCHNSSPyoXGx9HX2/VMnKeC34AChA==}
|
|
32
|
+
dev: false
|
|
33
|
+
|
|
34
|
+
/error-callsites/2.0.4:
|
|
35
|
+
resolution: {integrity: sha512-V877Ch4FC4FN178fDK1fsrHN4I1YQIBdtjKrHh3BUHMnh3SMvwUVrqkaOgDpUuevgSNna0RBq6Ox9SGlxYrigA==}
|
|
36
|
+
engines: {node: '>=6.x'}
|
|
37
|
+
dev: false
|
|
38
|
+
|
|
39
|
+
/get-source/2.0.12:
|
|
40
|
+
resolution: {integrity: sha512-X5+4+iD+HoSeEED+uwrQ07BOQr0kEDFMVqqpBuI+RaZBpBpHCuXxo70bjar6f0b0u/DQJsJ7ssurpP0V60Az+w==}
|
|
41
|
+
dependencies:
|
|
42
|
+
data-uri-to-buffer: 2.0.2
|
|
43
|
+
source-map: 0.6.1
|
|
44
|
+
dev: false
|
|
45
|
+
|
|
46
|
+
/jsx-number-format/0.1.4:
|
|
47
|
+
resolution: {integrity: sha512-uPc/Q90XqZoRE7Cu1OLFQB2cSrA2Dy8+okzPOtML8vbagNFDSipbndIPme+q0odBjEhL+wf3WH3Wo52was4Tsg==}
|
|
48
|
+
dev: false
|
|
49
|
+
|
|
50
|
+
/load-source-map/2.0.0:
|
|
51
|
+
resolution: {integrity: sha512-QNZzJ2wMrTmCdeobMuMNEXHN1QGk8HG6louEkzD/zwQ7EU2RarrzlhQ4GnUYEFzLhK+Jq7IGyF/qy+XYBSO7AQ==}
|
|
52
|
+
engines: {node: '>= 8'}
|
|
53
|
+
dependencies:
|
|
54
|
+
source-map: 0.7.3
|
|
55
|
+
dev: false
|
|
56
|
+
|
|
57
|
+
/printable-characters/1.0.42:
|
|
58
|
+
resolution: {integrity: sha1-Pxjpd6m9jrN/zE/1ZZ176Qhos9g=}
|
|
59
|
+
dev: false
|
|
60
|
+
|
|
61
|
+
/source-map/0.6.1:
|
|
62
|
+
resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==}
|
|
63
|
+
engines: {node: '>=0.10.0'}
|
|
64
|
+
dev: false
|
|
65
|
+
|
|
66
|
+
/source-map/0.7.3:
|
|
67
|
+
resolution: {integrity: sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==}
|
|
68
|
+
engines: {node: '>= 8'}
|
|
69
|
+
dev: false
|
|
70
|
+
|
|
71
|
+
/stacktracey/2.1.8:
|
|
72
|
+
resolution: {integrity: sha512-Kpij9riA+UNg7TnphqjH7/CzctQ/owJGNbFkfEeve4Z4uxT5+JapVLFXcsurIfN34gnTWZNJ/f7NMG0E8JDzTw==}
|
|
73
|
+
dependencies:
|
|
74
|
+
as-table: 1.0.55
|
|
75
|
+
get-source: 2.0.12
|
|
76
|
+
dev: false
|
package/src/main.coffee
CHANGED
|
@@ -45,7 +45,8 @@ fetch_mapped_location = ( path, linenr, colnr ) ->
|
|
|
45
45
|
sourcemap = await load_source_map path
|
|
46
46
|
smp = sourcemap.originalPositionFor { line: linenr, column: colnr, }
|
|
47
47
|
catch error
|
|
48
|
-
warn '^7763-3^', "!!!!!!!!!!!!!!!!!",
|
|
48
|
+
# warn '^7763-3^', "!!!!!!!!!!!!!!!!!", { path, }
|
|
49
|
+
# warn '^7763-3^', "!!!!!!!!!!!!!!!!!", error.message
|
|
49
50
|
return { path, linenr, colnr, }
|
|
50
51
|
#.........................................................................................................
|
|
51
52
|
if ( smp? ) and ( smp.source? ) and ( smp.source isnt '' ) and ( smp.line? ) and ( smp.column? )
|
|
@@ -56,39 +57,39 @@ fetch_mapped_location = ( path, linenr, colnr ) ->
|
|
|
56
57
|
|
|
57
58
|
#-----------------------------------------------------------------------------------------------------------
|
|
58
59
|
get_context = ( path, linenr, colnr, width ) ->
|
|
59
|
-
|
|
60
|
-
try
|
|
61
|
-
lines = ( FS.readFileSync path, { encoding: 'utf-8' } ).split '\n'
|
|
62
|
-
delta = 1
|
|
63
|
-
coldelta = 5
|
|
64
|
-
### TAINT use more meaningful limit like n times the terminal width, assuming default of 100 ###
|
|
65
|
-
# effect = underline
|
|
66
|
-
# effect = bold
|
|
67
|
-
effect = reverse
|
|
68
|
-
first_idx = Math.max 0, linenr - 1 - delta
|
|
69
|
-
last_idx = Math.min lines.length - 1, linenr - 1 + delta
|
|
70
|
-
R = []
|
|
71
|
-
for line, idx in lines[ first_idx .. last_idx ]
|
|
72
|
-
this_linenr = first_idx + idx + 1
|
|
73
|
-
this_linenr_txt = ( this_linenr.toString().padStart 4 ) + '│ '
|
|
74
|
-
if this_linenr is linenr
|
|
75
|
-
c0 = colnr - 1
|
|
76
|
-
c1 = colnr + coldelta
|
|
77
|
-
hilite = effect line[ c0 ... c1 ]
|
|
78
|
-
line = line[ ... c0 ] + hilite + line[ c1 .. ]
|
|
79
|
-
if c1 > width
|
|
80
|
-
width2 = Math.floor width / 2
|
|
81
|
-
line = '... ' + line[ c1 - width2 .. c1 + hilite.length - ( c1 - c0 ) + width2 ] + ' ...'
|
|
82
|
-
else
|
|
83
|
-
line = line[ .. width ]
|
|
84
|
-
R.push "#{grey this_linenr_txt}#{cyan line}"
|
|
85
|
-
else
|
|
86
|
-
R.push "#{grey this_linenr_txt}#{grey line}"
|
|
87
|
-
# R = R.join '\n'
|
|
88
|
-
catch error
|
|
60
|
+
try return ( _get_context path, linenr, colnr, width ) catch error
|
|
89
61
|
throw error unless error.code is 'ENOENT'
|
|
90
62
|
# return [ ( red "!!! #{rpr error.message} !!!" ), ]
|
|
91
|
-
|
|
63
|
+
return []
|
|
64
|
+
|
|
65
|
+
#-----------------------------------------------------------------------------------------------------------
|
|
66
|
+
_get_context = ( path, linenr, colnr, width ) ->
|
|
67
|
+
lines = ( FS.readFileSync path, { encoding: 'utf-8' } ).split '\n'
|
|
68
|
+
delta = 1
|
|
69
|
+
coldelta = 5
|
|
70
|
+
effect = reverse
|
|
71
|
+
first_idx = Math.max 0, linenr - 1 - delta
|
|
72
|
+
last_idx = Math.min lines.length - 1, linenr - 1 + delta
|
|
73
|
+
R = []
|
|
74
|
+
for line, idx in lines[ first_idx .. last_idx ]
|
|
75
|
+
this_linenr = first_idx + idx + 1
|
|
76
|
+
this_linenr_txt = ( this_linenr.toString().padStart 4 ) + '│ '
|
|
77
|
+
if this_linenr isnt linenr
|
|
78
|
+
### TAINT should adjust overlong context lines as well ###
|
|
79
|
+
R.push "#{grey this_linenr_txt}#{grey line}"
|
|
80
|
+
continue
|
|
81
|
+
### TAINT perform line length adjustment, hiliting in dedicated method ###
|
|
82
|
+
c0 = colnr - 1
|
|
83
|
+
c1 = colnr + coldelta
|
|
84
|
+
hilite = effect line[ c0 ... c1 ]
|
|
85
|
+
line = line[ ... c0 ] + hilite + line[ c1 .. ]
|
|
86
|
+
if c1 > width
|
|
87
|
+
width2 = Math.floor width / 2
|
|
88
|
+
line = '... ' + line[ c1 - width2 .. c1 + hilite.length - ( c1 - c0 ) + width2 ] + ' ...'
|
|
89
|
+
else
|
|
90
|
+
line = line[ .. width ]
|
|
91
|
+
R.push "#{grey this_linenr_txt}#{cyan line}"
|
|
92
|
+
# R = R.join '\n'
|
|
92
93
|
return R
|
|
93
94
|
|
|
94
95
|
#-----------------------------------------------------------------------------------------------------------
|
|
@@ -104,7 +105,7 @@ show_error_with_source_context = ( error, headline ) ->
|
|
|
104
105
|
callsites = get_error_callsites error
|
|
105
106
|
#.........................................................................................................
|
|
106
107
|
if ( not callsites? ) or ( callsites.length is 0 )
|
|
107
|
-
write_to_stderr CND.red CND.reverse "error has no associated callsites:"
|
|
108
|
+
write_to_stderr CND.red CND.reverse "^455756^ error has no associated callsites:"
|
|
108
109
|
write_to_stderr CND.red CND.reverse rpr error
|
|
109
110
|
return null
|
|
110
111
|
#.........................................................................................................
|
|
@@ -120,40 +121,115 @@ show_error_with_source_context = ( error, headline ) ->
|
|
|
120
121
|
linenr = callsite.getLineNumber()
|
|
121
122
|
colnr = callsite.getColumnNumber()
|
|
122
123
|
#.......................................................................................................
|
|
123
|
-
if path.startsWith 'internal/'
|
|
124
|
-
write_to_stderr arrowhead, grey "#{path}
|
|
124
|
+
if ( path.startsWith 'node:internal/' ) or ( path.startsWith 'internal/' )
|
|
125
|
+
write_to_stderr arrowhead, grey "#{path} @ #{linenr},#{colnr}"
|
|
125
126
|
continue
|
|
126
127
|
#.......................................................................................................
|
|
127
|
-
# debug '^344463^', { relpath, linenr, colnr, }
|
|
128
128
|
# write_to_stderr()
|
|
129
129
|
# write_to_stderr steel bold reverse ( "#{relpath} ##{linenr}:" ).padEnd 108
|
|
130
|
+
fname = callsite.getFunctionName() ? callsite.getMethodName() ? null
|
|
130
131
|
{ path
|
|
131
132
|
linenr
|
|
132
133
|
colnr } = await fetch_mapped_location path, linenr, colnr
|
|
133
134
|
relpath = PATH.relative process.cwd(), path
|
|
134
|
-
|
|
135
|
+
if fname?
|
|
136
|
+
### TAINT use proper methods to format with multiple colors ###
|
|
137
|
+
fname_txt = steel fname
|
|
138
|
+
width1 = width + ( fname_txt.length - fname.length )
|
|
139
|
+
write_to_stderr arrowhead, gold ( "#{relpath} @ #{linenr},#{colnr}: #{fname_txt}() \x1b[38;05;234m".padEnd width1, '—' )
|
|
140
|
+
else
|
|
141
|
+
write_to_stderr arrowhead, gold ( "#{relpath} @ #{linenr},#{colnr}: \x1b[38;05;234m".padEnd width, '—' )
|
|
135
142
|
for context_line in await get_context path, linenr, colnr, width
|
|
136
143
|
write_to_stderr arrowshaft, context_line
|
|
137
144
|
alert '^77765-2^', reverse bold headline
|
|
138
|
-
#
|
|
145
|
+
# urge "^94843^ error.stack:", rpr error.stack
|
|
146
|
+
# urge "^94843^ error.message:", rpr error.message
|
|
147
|
+
# urge "^94843^ error.code:", rpr error.code
|
|
148
|
+
# urge "^94843^ error.name:", rpr error.name
|
|
149
|
+
# urge "^94843^ error.type:", rpr error.type
|
|
150
|
+
# urge "^94843^ error.toString():", rpr error.toString()
|
|
151
|
+
# urge "^94843^ error:", rpr error
|
|
152
|
+
# CATALOGUING = require '../../multimix/lib/cataloguing'
|
|
153
|
+
# urge "^94843^", ( CATALOGUING.all_keys_of error )
|
|
139
154
|
return null
|
|
140
155
|
|
|
141
156
|
#-----------------------------------------------------------------------------------------------------------
|
|
142
|
-
exit_handler = ( error ) ->
|
|
143
|
-
|
|
157
|
+
exit_handler = ( error, origin ) ->
|
|
158
|
+
### TAINT origin never used ###
|
|
159
|
+
# show_stacktracey error
|
|
160
|
+
# debug '^4488^', error
|
|
161
|
+
# debug '^4488^', await origin
|
|
162
|
+
# return null
|
|
163
|
+
type = error.code ? error.name ? 'EXCEPTION'
|
|
164
|
+
message = " #{type}: " + ( error?.message ? "an unrecoverable condition occurred" )
|
|
144
165
|
await show_error_with_source_context error, message
|
|
145
166
|
setImmediate ( -> process.exit 111 )
|
|
146
|
-
# process.exit 111
|
|
147
167
|
return null
|
|
148
168
|
|
|
169
|
+
############################################################################################################
|
|
170
|
+
############################################################################################################
|
|
171
|
+
############################################################################################################
|
|
172
|
+
|
|
173
|
+
get_stacktracey = ( error ) ->
|
|
174
|
+
StackTracey = require 'stacktracey'
|
|
175
|
+
stack = ( new StackTracey error ).withSources()
|
|
176
|
+
# stack = stack.clean()
|
|
177
|
+
R = []
|
|
178
|
+
for idx in [ stack.items.length - 1 .. 0 ] by -1
|
|
179
|
+
d = stack.items[ idx ]
|
|
180
|
+
# debug '^2798^', ( k for k of d )
|
|
181
|
+
s =
|
|
182
|
+
# target_path: d.file
|
|
183
|
+
relpath: d.fileRelative # fileShort
|
|
184
|
+
native: d.native
|
|
185
|
+
# is_nodejs: d.native
|
|
186
|
+
is_other: d.thirdParty
|
|
187
|
+
line: d.line
|
|
188
|
+
column: d.column
|
|
189
|
+
source: d.sourceLine
|
|
190
|
+
error: d.error
|
|
191
|
+
# for k in [ 'sourceLine', 'native', 'file', 'line', 'column', 'calleeShort', 'fileRelative', 'fileShort', 'fileName', 'thirdParty', 'name',]
|
|
192
|
+
# debug k, rpr d[ k ]
|
|
193
|
+
R.push s
|
|
194
|
+
# info '\n' + stack.asTable()
|
|
195
|
+
return R
|
|
196
|
+
|
|
197
|
+
show_stacktracey = ( error ) ->
|
|
198
|
+
for d in get_stacktracey error
|
|
199
|
+
echo CND.steel '^44872^ ' + "#{d.relpath} @ #{d.line}:#{d.column}"
|
|
200
|
+
### NOTE errors:
|
|
201
|
+
ENOENT: no such file or directory
|
|
202
|
+
EISDIR: illegal operation on a directory, read
|
|
203
|
+
'Cannot read property 'originalPositionFor' of undefined'
|
|
204
|
+
###
|
|
205
|
+
if d.error? then echo CND.red '^44873^ ' + ( d.error.message ? "an error occurred" )
|
|
206
|
+
else echo CND.yellow '^44874^ ' + "#{rpr d.source[ .. 100 ]}"
|
|
207
|
+
return null
|
|
208
|
+
|
|
209
|
+
############################################################################################################
|
|
210
|
+
############################################################################################################
|
|
211
|
+
############################################################################################################
|
|
149
212
|
|
|
150
213
|
|
|
151
214
|
############################################################################################################
|
|
152
215
|
unless global[ Symbol.for 'cnd-exception-handler' ]?
|
|
216
|
+
null
|
|
153
217
|
global[ Symbol.for 'cnd-exception-handler' ] = true
|
|
154
|
-
process.
|
|
155
|
-
process.
|
|
218
|
+
process.once 'uncaughtException', exit_handler
|
|
219
|
+
process.once 'unhandledRejection', exit_handler
|
|
156
220
|
|
|
221
|
+
# do =>
|
|
222
|
+
# process.stderr.on 'data', ( data ) => debug "^6863-1^ (stderr.on 'data'):", rpr data
|
|
223
|
+
# process.stdout.on 'data', ( data ) => debug "^6863-2^ (stdout.on 'data'):", rpr data
|
|
224
|
+
# process.stderr.on 'end', => debug "^6863-1^ (stderr.on 'end')"
|
|
225
|
+
# process.stdout.on 'end', => debug "^6863-2^ (stdout.on 'end')"
|
|
226
|
+
# debug '^6456^'
|
|
227
|
+
# echo "^4564^ echo to stdout"
|
|
228
|
+
# warn "^4564^ warn to stderr"
|
|
229
|
+
# process.stderr.write "this goes to stderr\n"
|
|
230
|
+
# process.stdout.write "this goes to stdout\n"
|
|
231
|
+
# process.on 'message', ( message ) -> debug "^6863-3^' (process.on 'message'):", rpr message
|
|
232
|
+
# process.on 'warning', ( warning ) -> debug "^6863-3^' (process.on 'warning'):", rpr warning
|
|
157
233
|
###
|
|
158
234
|
callsite.getThis() - returns the value of this
|
|
159
235
|
callsite.getTypeName() - returns the type of this as a string. This is the name of the function stored in the constructor field of this, if available, otherwise the object's [[Class]] internal property.
|