eyeling 1.28.0 → 1.28.1

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/eyeling.js CHANGED
@@ -4623,10 +4623,13 @@ module.exports = {
4623
4623
  'use strict';
4624
4624
 
4625
4625
  const fs = require('node:fs');
4626
- const os = require('node:os');
4627
4626
  const path = require('node:path');
4628
- const { pathToFileURL, fileURLToPath } = require('node:url');
4627
+ const { pathToFileURL, fileURLToPath, URL } = require('node:url');
4629
4628
  const { TextDecoder } = require('node:util');
4629
+ const http = require('node:http');
4630
+ const https = require('node:https');
4631
+ const readline = require('node:readline');
4632
+ const zlib = require('node:zlib');
4630
4633
 
4631
4634
  const engine = require('./engine');
4632
4635
  const deref = require('./deref');
@@ -4760,7 +4763,8 @@ function __httpFetchScriptBody({ prefixOnly = false } = {}) {
4760
4763
  if (finished) return;
4761
4764
  chunks.push(chunk);
4762
4765
  bytes += chunk.length;
4763
- if (bytes >= limit) finish();
4766
+ const text = Buffer.concat(chunks, bytes).toString('utf8');
4767
+ if (bytes >= limit || /^\\s*(?:@version|VERSION)\\s+(["'])(?:1\\.1|1\\.2|1\\.2-basic)-messages\\1\\s*\\.?\\s*(?:#.*)?$/im.test(text)) finish();
4764
4768
  });
4765
4769
  body.on('end', finish);
4766
4770
  body.on('error', (e) => { console.error(e && e.message ? e.message : String(e)); process.exit(5); });
@@ -4789,22 +4793,95 @@ function __readHttpPrefixSync(sourceLabel, byteLimit = 64 * 1024) {
4789
4793
  return r.stdout;
4790
4794
  }
4791
4795
 
4792
- function __downloadHttpSourceToTempFileSync(sourceLabel) {
4793
- const cp = require('node:child_process');
4794
- const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'eyeling-rdf-message-log-'));
4795
- const file = path.join(dir, 'source.txt');
4796
- const r = cp.spawnSync(process.execPath, ['-e', __httpFetchScriptBody({ prefixOnly: false }), sourceLabel, file], {
4797
- encoding: 'utf8',
4798
- maxBuffer: 1024 * 1024,
4799
- stdio: ['ignore', 'ignore', 'pipe'],
4796
+ function __openHttpTextStream(sourceLabel, redirects = 0) {
4797
+ const maxRedirects = 10;
4798
+ return new Promise((resolve, reject) => {
4799
+ if (redirects > maxRedirects) {
4800
+ reject(new Error('Too many redirects'));
4801
+ return;
4802
+ }
4803
+
4804
+ let parsed;
4805
+ try {
4806
+ parsed = new URL(sourceLabel);
4807
+ } catch (e) {
4808
+ reject(e);
4809
+ return;
4810
+ }
4811
+
4812
+ const mod = parsed.protocol === 'https:' ? https : parsed.protocol === 'http:' ? http : null;
4813
+ if (!mod) {
4814
+ reject(new Error(`Unsupported protocol ${parsed.protocol}`));
4815
+ return;
4816
+ }
4817
+
4818
+ const req = mod.request(
4819
+ {
4820
+ protocol: parsed.protocol,
4821
+ hostname: parsed.hostname,
4822
+ port: parsed.port || undefined,
4823
+ path: parsed.pathname + parsed.search,
4824
+ headers: {
4825
+ accept: 'text/n3, text/turtle, application/trig, application/n-triples, application/n-quads, text/plain;q=0.8, */*;q=0.01',
4826
+ 'accept-encoding': 'identity',
4827
+ 'user-agent': 'eyeling-rdf-message-stream',
4828
+ },
4829
+ },
4830
+ (res) => {
4831
+ const sc = res.statusCode || 0;
4832
+ if (sc >= 300 && sc < 400 && res.headers && res.headers.location) {
4833
+ const next = new URL(res.headers.location, sourceLabel).toString();
4834
+ res.resume();
4835
+ resolve(__openHttpTextStream(next, redirects + 1));
4836
+ return;
4837
+ }
4838
+ if (sc < 200 || sc >= 300) {
4839
+ res.resume();
4840
+ reject(new Error(`HTTP status ${sc}`));
4841
+ return;
4842
+ }
4843
+
4844
+ const enc = String((res.headers && res.headers['content-encoding']) || '').toLowerCase();
4845
+ let body = res;
4846
+ if (enc.includes('gzip')) body = res.pipe(zlib.createGunzip());
4847
+ else if (enc.includes('deflate')) body = res.pipe(zlib.createInflate());
4848
+ else if (enc.includes('br')) body = res.pipe(zlib.createBrotliDecompress());
4849
+ resolve(body);
4850
+ },
4851
+ );
4852
+ req.on('error', reject);
4853
+ req.end();
4800
4854
  });
4801
- if (r.status !== 0) {
4802
- try { fs.rmSync(dir, { recursive: true, force: true }); } catch {}
4803
- throw new Error(`Failed to dereference ${sourceLabel}${r.stderr ? ': ' + String(r.stderr).trim() : ''}`);
4804
- }
4805
- return { file, cleanup: () => { try { fs.rmSync(dir, { recursive: true, force: true }); } catch {} } };
4806
4855
  }
4807
4856
 
4857
+ async function forEachLineInHttpSource(sourceLabel, onLine) {
4858
+ const body = await __openHttpTextStream(sourceLabel);
4859
+ await new Promise((resolve, reject) => {
4860
+ let settled = false;
4861
+ function done(err) {
4862
+ if (settled) return;
4863
+ settled = true;
4864
+ if (err) reject(err);
4865
+ else resolve();
4866
+ }
4867
+
4868
+ const rl = readline.createInterface({ input: body, crlfDelay: Infinity });
4869
+ rl.on('line', (line) => {
4870
+ try {
4871
+ onLine(line + '\n');
4872
+ } catch (e) {
4873
+ try { rl.close(); } catch {}
4874
+ if (body && typeof body.destroy === 'function') {
4875
+ try { body.destroy(); } catch {}
4876
+ }
4877
+ done(e);
4878
+ }
4879
+ });
4880
+ rl.on('close', () => done());
4881
+ rl.on('error', done);
4882
+ body.on('error', done);
4883
+ });
4884
+ }
4808
4885
 
4809
4886
  const RDF_MESSAGE_VERSION_RE = /^\s*(?:@version|VERSION)\s+(["'])(?:1\.1|1\.2|1\.2-basic)-messages\1\s*\.?\s*(?:#.*)?$/im;
4810
4887
  const RDF_MESSAGE_VERSION_LINE_RE = /^\s*(?:@version|VERSION)\s+(["'])(?:1\.1|1\.2|1\.2-basic)-messages\1\s*\.?\s*(?:#.*)?$/i;
@@ -5022,15 +5099,50 @@ function __forEachRdfMessageChunkSync(sourceLabel, onMessage) {
5022
5099
  return;
5023
5100
  }
5024
5101
  if (__isHttpSource(sourceLabel)) {
5025
- const tmp = __downloadHttpSourceToTempFileSync(sourceLabel);
5026
- try {
5027
- forEachRdfMessageChunkInFileSync(tmp.file, onMessage);
5028
- } finally {
5029
- tmp.cleanup();
5102
+ throw new Error('internal error: HTTP RDF Message Logs must be streamed asynchronously');
5103
+ }
5104
+ forEachRdfMessageChunkInText(__readInputSourceSync(sourceLabel), onMessage);
5105
+ }
5106
+
5107
+
5108
+ async function forEachRdfMessageChunkInHttpSource(sourceLabel, onMessage) {
5109
+ const directives = [];
5110
+ const seenDirectives = new Set();
5111
+ let chunk = '';
5112
+ let messageIndex = 1;
5113
+ let sawVersion = false;
5114
+ let sawDelimiter = false;
5115
+
5116
+ function emit() {
5117
+ onMessage({ messageIndex, chunk, directives: directives.slice() });
5118
+ messageIndex += 1;
5119
+ chunk = '';
5120
+ }
5121
+
5122
+ await forEachLineInHttpSource(sourceLabel, (line) => {
5123
+ if (RDF_MESSAGE_VERSION_LINE_RE.test(line)) {
5124
+ sawVersion = true;
5125
+ return;
5126
+ }
5127
+ if (RDF_MESSAGE_DELIMITER_LINE_RE.test(line)) {
5128
+ emit();
5129
+ sawDelimiter = true;
5130
+ return;
5030
5131
  }
5132
+ addRdfDirective(directives, seenDirectives, line);
5133
+ chunk += line;
5134
+ });
5135
+
5136
+ if (!sawVersion) throw new Error('not an RDF Message Log: missing VERSION "*-messages" directive');
5137
+ if (sawDelimiter || hasRdfPayload(chunk)) emit();
5138
+ }
5139
+
5140
+ async function __forEachRdfMessageChunk(sourceLabel, onMessage) {
5141
+ if (__isHttpSource(sourceLabel)) {
5142
+ await forEachRdfMessageChunkInHttpSource(sourceLabel, onMessage);
5031
5143
  return;
5032
5144
  }
5033
- forEachRdfMessageChunkInText(__readInputSourceSync(sourceLabel), onMessage);
5145
+ __forEachRdfMessageChunkSync(sourceLabel, onMessage);
5034
5146
  }
5035
5147
 
5036
5148
  function factsContainOutputStrings(triplesForOutput) {
@@ -5096,7 +5208,7 @@ function runParsedDocumentOnce(mergedDocument, { rdfMode = false, outputPrefixes
5096
5208
  }
5097
5209
  }
5098
5210
 
5099
- function runStreamMessagesMode(sourceLabels, { rdfMode }) {
5211
+ async function runStreamMessagesMode(sourceLabels, { rdfMode }) {
5100
5212
  const ordinarySourceLabels = [];
5101
5213
  const messageSourceLabels = [];
5102
5214
 
@@ -5148,7 +5260,7 @@ function runStreamMessagesMode(sourceLabels, { rdfMode }) {
5148
5260
  const fullIriPrefixes = new PrefixEnv({});
5149
5261
  for (const messageSourceLabel of messageSourceLabels) {
5150
5262
  try {
5151
- __forEachRdfMessageChunkSync(messageSourceLabel, ({ messageIndex, chunk, directives }) => {
5263
+ await __forEachRdfMessageChunk(messageSourceLabel, ({ messageIndex, chunk, directives }) => {
5152
5264
  const messageText = buildSingleMessageReplayDocument({
5153
5265
  sourceLabel: messageSourceLabel,
5154
5266
  messageIndex,
@@ -5182,7 +5294,7 @@ function runStreamMessagesMode(sourceLabels, { rdfMode }) {
5182
5294
  }
5183
5295
  }
5184
5296
 
5185
- function main() {
5297
+ async function main() {
5186
5298
  // Drop "node" and script name; keep only user-provided args
5187
5299
  // Expand combined short options: -pt == -p -t
5188
5300
  const argvRaw = process.argv.slice(2);
@@ -5321,7 +5433,7 @@ function main() {
5321
5433
  }
5322
5434
 
5323
5435
  if (streamMessagesMode) {
5324
- runStreamMessagesMode(sourceLabels, { rdfMode });
5436
+ await runStreamMessagesMode(sourceLabels, { rdfMode });
5325
5437
  return;
5326
5438
  }
5327
5439
 
@@ -5405,7 +5517,8 @@ function main() {
5405
5517
  return false;
5406
5518
  }
5407
5519
 
5408
- function factsContainOutputStrings(triplesForOutput) {
5520
+
5521
+ function factsContainOutputStrings(triplesForOutput) {
5409
5522
  return (
5410
5523
  Array.isArray(triplesForOutput) &&
5411
5524
  triplesForOutput.some(
@@ -9843,7 +9956,15 @@ function reasonRdfJs(input, opts = {}) {
9843
9956
  // Minimal export surface for Node + browser/worker
9844
9957
  function main() {
9845
9958
  // Lazily require to avoid hard cycles in the module graph.
9846
- return require('./cli').main();
9959
+ const result = require('./cli').main();
9960
+ if (result && typeof result.then === 'function') {
9961
+ result.catch((e) => {
9962
+ const msg = e && e.stack ? e.stack : e && e.message ? e.message : String(e);
9963
+ console.error(msg);
9964
+ process.exit(1);
9965
+ });
9966
+ }
9967
+ return result;
9847
9968
  }
9848
9969
 
9849
9970
  // ---------------------------------------------------------------------------
@@ -16061,7 +16182,13 @@ module.exports = {
16061
16182
 
16062
16183
  try {
16063
16184
  if (__outerModule && __outerRequire && __outerRequire.main === __outerModule && typeof __entry.main === "function") {
16064
- __entry.main();
16185
+ const __mainResult = __entry.main();
16186
+ if (__mainResult && typeof __mainResult.then === "function") {
16187
+ __mainResult.catch((e) => {
16188
+ try { if (typeof console !== "undefined" && console.error) console.error(e && e.stack ? e.stack : e && e.message ? e.message : String(e)); } catch (ignoredError) {}
16189
+ try { if (typeof process !== "undefined" && process.exit) process.exit(1); } catch (ignoredError) {}
16190
+ });
16191
+ }
16065
16192
  }
16066
16193
  } catch (ignoredError) {}
16067
16194
  })();
package/lib/cli.js CHANGED
@@ -8,10 +8,13 @@
8
8
  'use strict';
9
9
 
10
10
  const fs = require('node:fs');
11
- const os = require('node:os');
12
11
  const path = require('node:path');
13
- const { pathToFileURL, fileURLToPath } = require('node:url');
12
+ const { pathToFileURL, fileURLToPath, URL } = require('node:url');
14
13
  const { TextDecoder } = require('node:util');
14
+ const http = require('node:http');
15
+ const https = require('node:https');
16
+ const readline = require('node:readline');
17
+ const zlib = require('node:zlib');
15
18
 
16
19
  const engine = require('./engine');
17
20
  const deref = require('./deref');
@@ -145,7 +148,8 @@ function __httpFetchScriptBody({ prefixOnly = false } = {}) {
145
148
  if (finished) return;
146
149
  chunks.push(chunk);
147
150
  bytes += chunk.length;
148
- if (bytes >= limit) finish();
151
+ const text = Buffer.concat(chunks, bytes).toString('utf8');
152
+ if (bytes >= limit || /^\\s*(?:@version|VERSION)\\s+(["'])(?:1\\.1|1\\.2|1\\.2-basic)-messages\\1\\s*\\.?\\s*(?:#.*)?$/im.test(text)) finish();
149
153
  });
150
154
  body.on('end', finish);
151
155
  body.on('error', (e) => { console.error(e && e.message ? e.message : String(e)); process.exit(5); });
@@ -174,22 +178,95 @@ function __readHttpPrefixSync(sourceLabel, byteLimit = 64 * 1024) {
174
178
  return r.stdout;
175
179
  }
176
180
 
177
- function __downloadHttpSourceToTempFileSync(sourceLabel) {
178
- const cp = require('node:child_process');
179
- const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'eyeling-rdf-message-log-'));
180
- const file = path.join(dir, 'source.txt');
181
- const r = cp.spawnSync(process.execPath, ['-e', __httpFetchScriptBody({ prefixOnly: false }), sourceLabel, file], {
182
- encoding: 'utf8',
183
- maxBuffer: 1024 * 1024,
184
- stdio: ['ignore', 'ignore', 'pipe'],
181
+ function __openHttpTextStream(sourceLabel, redirects = 0) {
182
+ const maxRedirects = 10;
183
+ return new Promise((resolve, reject) => {
184
+ if (redirects > maxRedirects) {
185
+ reject(new Error('Too many redirects'));
186
+ return;
187
+ }
188
+
189
+ let parsed;
190
+ try {
191
+ parsed = new URL(sourceLabel);
192
+ } catch (e) {
193
+ reject(e);
194
+ return;
195
+ }
196
+
197
+ const mod = parsed.protocol === 'https:' ? https : parsed.protocol === 'http:' ? http : null;
198
+ if (!mod) {
199
+ reject(new Error(`Unsupported protocol ${parsed.protocol}`));
200
+ return;
201
+ }
202
+
203
+ const req = mod.request(
204
+ {
205
+ protocol: parsed.protocol,
206
+ hostname: parsed.hostname,
207
+ port: parsed.port || undefined,
208
+ path: parsed.pathname + parsed.search,
209
+ headers: {
210
+ accept: 'text/n3, text/turtle, application/trig, application/n-triples, application/n-quads, text/plain;q=0.8, */*;q=0.01',
211
+ 'accept-encoding': 'identity',
212
+ 'user-agent': 'eyeling-rdf-message-stream',
213
+ },
214
+ },
215
+ (res) => {
216
+ const sc = res.statusCode || 0;
217
+ if (sc >= 300 && sc < 400 && res.headers && res.headers.location) {
218
+ const next = new URL(res.headers.location, sourceLabel).toString();
219
+ res.resume();
220
+ resolve(__openHttpTextStream(next, redirects + 1));
221
+ return;
222
+ }
223
+ if (sc < 200 || sc >= 300) {
224
+ res.resume();
225
+ reject(new Error(`HTTP status ${sc}`));
226
+ return;
227
+ }
228
+
229
+ const enc = String((res.headers && res.headers['content-encoding']) || '').toLowerCase();
230
+ let body = res;
231
+ if (enc.includes('gzip')) body = res.pipe(zlib.createGunzip());
232
+ else if (enc.includes('deflate')) body = res.pipe(zlib.createInflate());
233
+ else if (enc.includes('br')) body = res.pipe(zlib.createBrotliDecompress());
234
+ resolve(body);
235
+ },
236
+ );
237
+ req.on('error', reject);
238
+ req.end();
185
239
  });
186
- if (r.status !== 0) {
187
- try { fs.rmSync(dir, { recursive: true, force: true }); } catch {}
188
- throw new Error(`Failed to dereference ${sourceLabel}${r.stderr ? ': ' + String(r.stderr).trim() : ''}`);
189
- }
190
- return { file, cleanup: () => { try { fs.rmSync(dir, { recursive: true, force: true }); } catch {} } };
191
240
  }
192
241
 
242
+ async function forEachLineInHttpSource(sourceLabel, onLine) {
243
+ const body = await __openHttpTextStream(sourceLabel);
244
+ await new Promise((resolve, reject) => {
245
+ let settled = false;
246
+ function done(err) {
247
+ if (settled) return;
248
+ settled = true;
249
+ if (err) reject(err);
250
+ else resolve();
251
+ }
252
+
253
+ const rl = readline.createInterface({ input: body, crlfDelay: Infinity });
254
+ rl.on('line', (line) => {
255
+ try {
256
+ onLine(line + '\n');
257
+ } catch (e) {
258
+ try { rl.close(); } catch {}
259
+ if (body && typeof body.destroy === 'function') {
260
+ try { body.destroy(); } catch {}
261
+ }
262
+ done(e);
263
+ }
264
+ });
265
+ rl.on('close', () => done());
266
+ rl.on('error', done);
267
+ body.on('error', done);
268
+ });
269
+ }
193
270
 
194
271
  const RDF_MESSAGE_VERSION_RE = /^\s*(?:@version|VERSION)\s+(["'])(?:1\.1|1\.2|1\.2-basic)-messages\1\s*\.?\s*(?:#.*)?$/im;
195
272
  const RDF_MESSAGE_VERSION_LINE_RE = /^\s*(?:@version|VERSION)\s+(["'])(?:1\.1|1\.2|1\.2-basic)-messages\1\s*\.?\s*(?:#.*)?$/i;
@@ -407,15 +484,50 @@ function __forEachRdfMessageChunkSync(sourceLabel, onMessage) {
407
484
  return;
408
485
  }
409
486
  if (__isHttpSource(sourceLabel)) {
410
- const tmp = __downloadHttpSourceToTempFileSync(sourceLabel);
411
- try {
412
- forEachRdfMessageChunkInFileSync(tmp.file, onMessage);
413
- } finally {
414
- tmp.cleanup();
487
+ throw new Error('internal error: HTTP RDF Message Logs must be streamed asynchronously');
488
+ }
489
+ forEachRdfMessageChunkInText(__readInputSourceSync(sourceLabel), onMessage);
490
+ }
491
+
492
+
493
+ async function forEachRdfMessageChunkInHttpSource(sourceLabel, onMessage) {
494
+ const directives = [];
495
+ const seenDirectives = new Set();
496
+ let chunk = '';
497
+ let messageIndex = 1;
498
+ let sawVersion = false;
499
+ let sawDelimiter = false;
500
+
501
+ function emit() {
502
+ onMessage({ messageIndex, chunk, directives: directives.slice() });
503
+ messageIndex += 1;
504
+ chunk = '';
505
+ }
506
+
507
+ await forEachLineInHttpSource(sourceLabel, (line) => {
508
+ if (RDF_MESSAGE_VERSION_LINE_RE.test(line)) {
509
+ sawVersion = true;
510
+ return;
511
+ }
512
+ if (RDF_MESSAGE_DELIMITER_LINE_RE.test(line)) {
513
+ emit();
514
+ sawDelimiter = true;
515
+ return;
415
516
  }
517
+ addRdfDirective(directives, seenDirectives, line);
518
+ chunk += line;
519
+ });
520
+
521
+ if (!sawVersion) throw new Error('not an RDF Message Log: missing VERSION "*-messages" directive');
522
+ if (sawDelimiter || hasRdfPayload(chunk)) emit();
523
+ }
524
+
525
+ async function __forEachRdfMessageChunk(sourceLabel, onMessage) {
526
+ if (__isHttpSource(sourceLabel)) {
527
+ await forEachRdfMessageChunkInHttpSource(sourceLabel, onMessage);
416
528
  return;
417
529
  }
418
- forEachRdfMessageChunkInText(__readInputSourceSync(sourceLabel), onMessage);
530
+ __forEachRdfMessageChunkSync(sourceLabel, onMessage);
419
531
  }
420
532
 
421
533
  function factsContainOutputStrings(triplesForOutput) {
@@ -481,7 +593,7 @@ function runParsedDocumentOnce(mergedDocument, { rdfMode = false, outputPrefixes
481
593
  }
482
594
  }
483
595
 
484
- function runStreamMessagesMode(sourceLabels, { rdfMode }) {
596
+ async function runStreamMessagesMode(sourceLabels, { rdfMode }) {
485
597
  const ordinarySourceLabels = [];
486
598
  const messageSourceLabels = [];
487
599
 
@@ -533,7 +645,7 @@ function runStreamMessagesMode(sourceLabels, { rdfMode }) {
533
645
  const fullIriPrefixes = new PrefixEnv({});
534
646
  for (const messageSourceLabel of messageSourceLabels) {
535
647
  try {
536
- __forEachRdfMessageChunkSync(messageSourceLabel, ({ messageIndex, chunk, directives }) => {
648
+ await __forEachRdfMessageChunk(messageSourceLabel, ({ messageIndex, chunk, directives }) => {
537
649
  const messageText = buildSingleMessageReplayDocument({
538
650
  sourceLabel: messageSourceLabel,
539
651
  messageIndex,
@@ -567,7 +679,7 @@ function runStreamMessagesMode(sourceLabels, { rdfMode }) {
567
679
  }
568
680
  }
569
681
 
570
- function main() {
682
+ async function main() {
571
683
  // Drop "node" and script name; keep only user-provided args
572
684
  // Expand combined short options: -pt == -p -t
573
685
  const argvRaw = process.argv.slice(2);
@@ -706,7 +818,7 @@ function main() {
706
818
  }
707
819
 
708
820
  if (streamMessagesMode) {
709
- runStreamMessagesMode(sourceLabels, { rdfMode });
821
+ await runStreamMessagesMode(sourceLabels, { rdfMode });
710
822
  return;
711
823
  }
712
824
 
@@ -790,7 +902,8 @@ function main() {
790
902
  return false;
791
903
  }
792
904
 
793
- function factsContainOutputStrings(triplesForOutput) {
905
+
906
+ function factsContainOutputStrings(triplesForOutput) {
794
907
  return (
795
908
  Array.isArray(triplesForOutput) &&
796
909
  triplesForOutput.some(
package/lib/engine.js CHANGED
@@ -3832,7 +3832,15 @@ function reasonRdfJs(input, opts = {}) {
3832
3832
  // Minimal export surface for Node + browser/worker
3833
3833
  function main() {
3834
3834
  // Lazily require to avoid hard cycles in the module graph.
3835
- return require('./cli').main();
3835
+ const result = require('./cli').main();
3836
+ if (result && typeof result.then === 'function') {
3837
+ result.catch((e) => {
3838
+ const msg = e && e.stack ? e.stack : e && e.message ? e.message : String(e);
3839
+ console.error(msg);
3840
+ process.exit(1);
3841
+ });
3842
+ }
3843
+ return result;
3836
3844
  }
3837
3845
 
3838
3846
  // ---------------------------------------------------------------------------