@jdeighan/coffee-utils 7.0.31 → 7.0.34

Sign up to get free protection for your applications and to get access to all the features.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@jdeighan/coffee-utils",
3
3
  "type": "module",
4
- "version": "7.0.31",
4
+ "version": "7.0.34",
5
5
  "description": "A set of utility functions for CoffeeScript",
6
6
  "main": "coffee_utils.js",
7
7
  "exports": {
@@ -5,6 +5,14 @@ export sep_eq = '='.repeat(42)
5
5
  `export const undef = undefined`
6
6
  LOG = (lArgs...) -> console.log lArgs... # synonym for console.log()
7
7
 
8
+ export doHaltOnError = false
9
+
10
+ # ---------------------------------------------------------------------------
11
+
12
+ export haltOnError = () ->
13
+
14
+ doHaltOnError = true
15
+
8
16
  # ---------------------------------------------------------------------------
9
17
  # pass - do nothing
10
18
 
@@ -15,16 +23,62 @@ export pass = () ->
15
23
 
16
24
  export error = (message) ->
17
25
 
26
+ if doHaltOnError
27
+ console.trace("ERROR: #{message}")
28
+ process.exit()
18
29
  throw new Error(message)
19
30
 
31
+ # ---------------------------------------------------------------------------
32
+
33
+ getCallers = (stackTrace, lExclude=[]) ->
34
+
35
+ iter = stackTrace.matchAll(///
36
+ at
37
+ \s+
38
+ (?:
39
+ async
40
+ \s+
41
+ )?
42
+ ([^\s(]+)
43
+ ///g)
44
+ if !iter
45
+ return ["<unknown>"]
46
+
47
+ lCallers = []
48
+ for lMatches from iter
49
+ [_, caller] = lMatches
50
+ if (caller.indexOf('file://') == 0)
51
+ break
52
+ if caller not in lExclude
53
+ lCallers.push caller
54
+
55
+ return lCallers
56
+
20
57
  # ---------------------------------------------------------------------------
21
58
  # assert - mimic nodejs's assert
59
+ # return true so we can use it in boolean expressions
22
60
 
23
61
  export assert = (cond, msg) ->
24
62
 
25
63
  if ! cond
26
- error(msg)
27
- return
64
+ try
65
+ throw new Error()
66
+ catch e
67
+ stackTrace = e.stack
68
+ lCallers = getCallers(stackTrace, ['assert'])
69
+
70
+ # console.log 'STACK'
71
+ # console.log stackTrace
72
+ console.log '--------------------'
73
+ console.log 'CALL STACK:'
74
+ for caller in lCallers
75
+ console.log " #{caller}"
76
+ console.log '--------------------'
77
+ console.log "ERROR: #{msg} (in #{lCallers[0]}())"
78
+ if doHaltOnError
79
+ process.exit()
80
+ error msg
81
+ return true
28
82
 
29
83
  # ---------------------------------------------------------------------------
30
84
  # croak - throws an error after possibly printing useful info
@@ -85,9 +139,16 @@ export isArray = (x) ->
85
139
 
86
140
  # ---------------------------------------------------------------------------
87
141
 
88
- export isHash = (x) ->
142
+ export isHash = (x, lKeys) ->
89
143
 
90
- return (getClassName(x) == 'Object')
144
+ if ! x || (getClassName(x) != 'Object')
145
+ return false
146
+ if defined(lKeys)
147
+ assert isArray(lKeys), "isHash(): lKeys not an array"
148
+ for key in lKeys
149
+ if ! x.hasOwnProperty(key)
150
+ return false
151
+ return true
91
152
 
92
153
  # ---------------------------------------------------------------------------
93
154
 
@@ -383,15 +444,16 @@ export replaceVars = (line, hVars={}, rx=/__(env\.)?([A-Za-z_]\w*)__/g) ->
383
444
 
384
445
  replacerFunc = (match, prefix, name) =>
385
446
  if prefix
386
- result = process.env[name]
387
- else if ! hVars[name]?
388
- result = 'undef'
447
+ return process.env[name]
389
448
  else
390
- result = hVars[name]
391
- if ! isString(result)
392
- result = JSON.stringify(result)
393
- return result
394
-
449
+ value = hVars[name]
450
+ if defined(value)
451
+ if isString(value)
452
+ return value
453
+ else
454
+ return JSON.stringify(value)
455
+ else
456
+ return "__#{name}__"
395
457
  return line.replace(rx, replacerFunc)
396
458
 
397
459
  # ---------------------------------------------------------------------------
@@ -1,6 +1,7 @@
1
1
  // Generated by CoffeeScript 2.6.1
2
- // coffee_utils.coffee
3
- var LOG;
2
+ // coffee_utils.coffee
3
+ var LOG, getCallers,
4
+ indexOf = [].indexOf;
4
5
 
5
6
  export var sep_dash = '-'.repeat(42);
6
7
 
@@ -12,6 +13,12 @@ LOG = function(...lArgs) {
12
13
  return console.log(...lArgs); // synonym for console.log()
13
14
  };
14
15
 
16
+ export var doHaltOnError = false;
17
+
18
+ // ---------------------------------------------------------------------------
19
+ export var haltOnError = function() {
20
+ return doHaltOnError = true;
21
+ };
15
22
 
16
23
  // ---------------------------------------------------------------------------
17
24
  // pass - do nothing
@@ -20,15 +27,62 @@ export var pass = function() {};
20
27
  // ---------------------------------------------------------------------------
21
28
  // error - throw an error
22
29
  export var error = function(message) {
30
+ if (doHaltOnError) {
31
+ console.trace(`ERROR: ${message}`);
32
+ process.exit();
33
+ }
23
34
  throw new Error(message);
24
35
  };
25
36
 
37
+ // ---------------------------------------------------------------------------
38
+ getCallers = function(stackTrace, lExclude = []) {
39
+ var _, caller, iter, lCallers, lMatches;
40
+ iter = stackTrace.matchAll(/at\s+(?:async\s+)?([^\s(]+)/g);
41
+ if (!iter) {
42
+ return ["<unknown>"];
43
+ }
44
+ lCallers = [];
45
+ for (lMatches of iter) {
46
+ [_, caller] = lMatches;
47
+ if (caller.indexOf('file://') === 0) {
48
+ break;
49
+ }
50
+ if (indexOf.call(lExclude, caller) < 0) {
51
+ lCallers.push(caller);
52
+ }
53
+ }
54
+ return lCallers;
55
+ };
56
+
26
57
  // ---------------------------------------------------------------------------
27
58
  // assert - mimic nodejs's assert
59
+ // return true so we can use it in boolean expressions
28
60
  export var assert = function(cond, msg) {
61
+ var caller, e, i, lCallers, len, stackTrace;
29
62
  if (!cond) {
63
+ try {
64
+ throw new Error();
65
+ } catch (error1) {
66
+ e = error1;
67
+ stackTrace = e.stack;
68
+ }
69
+ lCallers = getCallers(stackTrace, ['assert']);
70
+ // console.log 'STACK'
71
+ // console.log stackTrace
72
+ console.log('--------------------');
73
+ console.log('CALL STACK:');
74
+ for (i = 0, len = lCallers.length; i < len; i++) {
75
+ caller = lCallers[i];
76
+ console.log(` ${caller}`);
77
+ }
78
+ console.log('--------------------');
79
+ console.log(`ERROR: ${msg} (in ${lCallers[0]}())`);
80
+ if (doHaltOnError) {
81
+ process.exit();
82
+ }
30
83
  error(msg);
31
84
  }
85
+ return true;
32
86
  };
33
87
 
34
88
  // ---------------------------------------------------------------------------
@@ -77,8 +131,21 @@ export var isArray = function(x) {
77
131
  };
78
132
 
79
133
  // ---------------------------------------------------------------------------
80
- export var isHash = function(x) {
81
- return getClassName(x) === 'Object';
134
+ export var isHash = function(x, lKeys) {
135
+ var i, key, len;
136
+ if (!x || (getClassName(x) !== 'Object')) {
137
+ return false;
138
+ }
139
+ if (defined(lKeys)) {
140
+ assert(isArray(lKeys), "isHash(): lKeys not an array");
141
+ for (i = 0, len = lKeys.length; i < len; i++) {
142
+ key = lKeys[i];
143
+ if (!x.hasOwnProperty(key)) {
144
+ return false;
145
+ }
146
+ }
147
+ }
148
+ return true;
82
149
  };
83
150
 
84
151
  // ---------------------------------------------------------------------------
@@ -413,18 +480,21 @@ export var replaceVars = function(line, hVars = {}, rx = /__(env\.)?([A-Za-z_]\w
413
480
  var replacerFunc;
414
481
  assert(isHash(hVars), "replaceVars() hVars is not a hash");
415
482
  replacerFunc = (match, prefix, name) => {
416
- var result;
483
+ var value;
417
484
  if (prefix) {
418
- result = process.env[name];
419
- } else if (hVars[name] == null) {
420
- result = 'undef';
485
+ return process.env[name];
421
486
  } else {
422
- result = hVars[name];
423
- if (!isString(result)) {
424
- result = JSON.stringify(result);
487
+ value = hVars[name];
488
+ if (defined(value)) {
489
+ if (isString(value)) {
490
+ return value;
491
+ } else {
492
+ return JSON.stringify(value);
493
+ }
494
+ } else {
495
+ return `__${name}__`;
425
496
  }
426
497
  }
427
- return result;
428
498
  };
429
499
  return line.replace(rx, replacerFunc);
430
500
  };
@@ -361,6 +361,7 @@ export parseSource = (source) ->
361
361
  # fullpath
362
362
  # stub
363
363
  # ext
364
+ # purpose
364
365
  # }
365
366
  # --- NOTE: source may be a file URL, e.g. import.meta.url
366
367
 
@@ -394,6 +395,13 @@ export parseSource = (source) ->
394
395
  stub: hInfo.name
395
396
  ext: hInfo.ext
396
397
  }
398
+
399
+ # --- check for a 'purpose'
400
+ if lMatches = hSourceInfo.stub.match(///
401
+ \.
402
+ ([A-Za-z_]+)
403
+ $///)
404
+ hSourceInfo.purpose = lMatches[1]
397
405
  debug "return from parseSource()", hSourceInfo
398
406
  return hSourceInfo
399
407
 
package/src/fs_utils.js CHANGED
@@ -422,13 +422,14 @@ export var shortenPath = function(path) {
422
422
 
423
423
  // ---------------------------------------------------------------------------
424
424
  export var parseSource = function(source) {
425
- var dir, hInfo, hSourceInfo;
425
+ var dir, hInfo, hSourceInfo, lMatches;
426
426
  // --- returns {
427
427
  // dir
428
428
  // filename
429
429
  // fullpath
430
430
  // stub
431
431
  // ext
432
+ // purpose
432
433
  // }
433
434
  // --- NOTE: source may be a file URL, e.g. import.meta.url
434
435
  debug("enter parseSource()");
@@ -462,6 +463,10 @@ export var parseSource = function(source) {
462
463
  ext: hInfo.ext
463
464
  };
464
465
  }
466
+ // --- check for a 'purpose'
467
+ if (lMatches = hSourceInfo.stub.match(/\.([A-Za-z_]+)$/)) {
468
+ hSourceInfo.purpose = lMatches[1];
469
+ }
465
470
  }
466
471
  debug("return from parseSource()", hSourceInfo);
467
472
  return hSourceInfo;
@@ -1,7 +1,7 @@
1
1
  # indent_utils.coffee
2
2
 
3
3
  import {
4
- assert, undef, error, escapeStr,
4
+ assert, undef, error, escapeStr, defined,
5
5
  OL, isInteger, isString, isArray, isEmpty, rtrim,
6
6
  } from '@jdeighan/coffee-utils'
7
7
  import {arrayToBlock, blockToArray} from '@jdeighan/coffee-utils/block'
@@ -68,7 +68,7 @@ export indented = (input, level=1) ->
68
68
 
69
69
  export undented = (text, level=undef) ->
70
70
 
71
- if level? && (level==0)
71
+ if defined(level) && (level==0)
72
72
  return text
73
73
 
74
74
  if isString(text)
@@ -85,7 +85,7 @@ export undented = (text, level=undef) ->
85
85
  error "undented(): Not an array or string: #{OL(text)}"
86
86
 
87
87
  # --- determine what to remove from beginning of each line
88
- if level?
88
+ if defined(level)
89
89
  assert isInteger(level), "undented(): level must be an integer"
90
90
  toRemove = indentation(level)
91
91
  else
@@ -5,6 +5,7 @@ import {
5
5
  undef,
6
6
  error,
7
7
  escapeStr,
8
+ defined,
8
9
  OL,
9
10
  isInteger,
10
11
  isString,
@@ -86,7 +87,7 @@ export var indented = function(input, level = 1) {
86
87
  // - returns same type as text, i.e. either string or array
87
88
  export var undented = function(text, level = undef) {
88
89
  var i, j, lLines, lMatches, lNewLines, len, len1, line, nToRemove, toRemove;
89
- if ((level != null) && (level === 0)) {
90
+ if (defined(level) && (level === 0)) {
90
91
  return text;
91
92
  }
92
93
  if (isString(text)) {
@@ -107,7 +108,7 @@ export var undented = function(text, level = undef) {
107
108
  error(`undented(): Not an array or string: ${OL(text)}`);
108
109
  }
109
110
  // --- determine what to remove from beginning of each line
110
- if (level != null) {
111
+ if (defined(level)) {
111
112
  assert(isInteger(level), "undented(): level must be an integer");
112
113
  toRemove = indentation(level);
113
114
  } else {