@makano/rew 1.4.6 → 1.5.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -302,6 +302,10 @@ yargs(hideBin(process.argv))
302
302
  alias: 'u',
303
303
  describe: 'Update the app',
304
304
  type: 'boolean',
305
+ }).option('clean', {
306
+ alias: 'c',
307
+ describe: 'Clean intall the app',
308
+ type: 'boolean',
305
309
  }).option('yes', {
306
310
  alias: 'y',
307
311
  describe: 'Auto yes',
@@ -9,6 +9,9 @@ const logspath = path.join(conf({}).create('').root, '.logs');
9
9
  const cachepath = path.join(conf({}).create('').root, '.cache');
10
10
  const localBinPath = path.join(binpath, '../../../', 'bin');
11
11
 
12
+ const FILE_DL_EXTRACT_REGEX = /^file\+sha\(([^)]+)\)\+([a-zA-Z0-9_-]+)(\([^\)]*\))?:(.*)$|^file\+([a-zA-Z0-9_-]+)(\([^\)]*\))?:(.*)$/;
13
+
14
+
12
15
  if (!fs.existsSync(CONFIG_PATH) || !fs.existsSync(CONFIG_PATH + '/repos.yaml')) {
13
16
  fs.mkdirSync(CONFIG_PATH, { recursive: true });
14
17
  log('First time init');
@@ -66,5 +69,6 @@ module.exports = {
66
69
  localBinPath,
67
70
  npm_package_name,
68
71
  getAllPipeInput,
69
- hashTags
72
+ hashTags,
73
+ FILE_DL_EXTRACT_REGEX
70
74
  }
@@ -21,10 +21,13 @@ const {
21
21
  logspath,
22
22
  cachepath,
23
23
  localBinPath,
24
- hashTags
24
+ hashTags,
25
+ FILE_DL_EXTRACT_REGEX
25
26
  } = require('./helpers');
26
27
  const { input } = require('../functions/stdout');
27
28
 
29
+
30
+
28
31
  module.exports = {
29
32
  conf(command, fullPath, key, value) {
30
33
  const con = conf({});
@@ -399,8 +402,8 @@ module.exports = {
399
402
  if(command == 'list'){
400
403
  console.log(fs.readdirSync(cachepath).join('\n').trim());
401
404
  } else if(command == 'clear'){
402
- if(file) fs.rmSync(path.join(cachepath, file), { recursive: true });
403
- else if(file == 'all') fs.readdirSync(cachepath).forEach(file => fs.rmSync(path.join(cachepath, file), { recursive: true }));
405
+ if(file && file !== 'all') fs.rmSync(path.join(cachepath, file), { recursive: true });
406
+ else if(file == 'all' || !file) fs.readdirSync(cachepath).forEach(file => fs.rmSync(path.join(cachepath, file), { recursive: true }));
404
407
  } else if(command == 'install'){
405
408
  if(!file) return process.exit(1);
406
409
  this.installApp(path.join(cachepath, file, 'clone'), {
@@ -496,8 +499,146 @@ module.exports = {
496
499
  const repos = conf({}).create('').optionCenter('repos');
497
500
  return repos.get(repo);
498
501
  },
502
+ isCommandAvailable(command) {
503
+ try {
504
+ execSync(`command -v ${command}`, { stdio: 'ignore' });
505
+ return true;
506
+ } catch (e) {
507
+ return false;
508
+ }
509
+ },
510
+ downloadFileFromUrl(url, dest, sha, opts) {
511
+ const isCurlAvailable = this.isCommandAvailable('curl');
512
+ const isWgetAvailable = this.isCommandAvailable('wget');
513
+
514
+ if (!isCurlAvailable && !isWgetAvailable) {
515
+ log(` Failed to download: Nither curl nor wget command were found.`.red.bold, ':end');
516
+ return false;
517
+ }
518
+
519
+ if(opts.c || opts.clean){
520
+ if(fs.existsSync(dest)) fs.rmSync(dest);
521
+ }
522
+ let tries = 0;
523
+
524
+ const checkSha = (throwErr) => {
525
+ if(sha){
526
+ const thisSha = execSync(`sha256sum "${dest}"`).toString().split(' ')[0];
527
+ if(thisSha === sha){
528
+ return true;
529
+ } else {
530
+ if(throwErr) {
531
+ log(` Failed to verify file checksum, ${tries == 0 ? 'trying again...' : 'try again.'}`.red.bold, ':end');
532
+ fs.rmSync(dest);
533
+ tries++;
534
+ if(tries < 2) return tryDl();
535
+ }
536
+ return false;
537
+ }
538
+ } else return true;
539
+ }
540
+
541
+ const downloadCommand = isCurlAvailable
542
+ ? `curl -L -o "${dest}" "${url}"`
543
+ : `wget -O "${dest}" "${url}"`;
544
+
545
+ const tryDl = () => {
546
+ try {
547
+ if(fs.existsSync(dest)){
548
+ return checkSha(true);
549
+ } else {
550
+ execSync(downloadCommand, { stdio: opts.verbose ? 'inherit' : 'ignore' });
551
+ return checkSha(true);
552
+ }
553
+ } catch(e){
554
+ log(` Failed to download ${url}: ${e.name}: ${e.message}.`.red.bold, ':end');
555
+ return false;
556
+ }
557
+ }
558
+
559
+ return tryDl();
560
+ },
561
+ downloadFile(fullPath, opts){
562
+ const pathToDownloadInto = path.join(cachepath, 'rew-file-download-'+gen_key(fullPath).substring(0, 12));
563
+
564
+ const commandMatch = fullPath.match(FILE_DL_EXTRACT_REGEX);
565
+
566
+ let shaHash = null;
567
+ let command = null;
568
+ let args = [];
569
+ let url = null;
570
+
571
+ if (commandMatch) {
572
+ // If sha() is present in the format file+sha(SHA-AAAA)+command(args):URL
573
+ if (commandMatch[1]) {
574
+ shaHash = commandMatch[1];
575
+ command = commandMatch[2];
576
+ args = commandMatch[3] ? commandMatch[3].slice(1, -1).split(' ') : [];
577
+ url = commandMatch[4];
578
+ } else {
579
+ command = commandMatch[5];
580
+ args = commandMatch[6] ? commandMatch[6].slice(1, -1).split(' ') : [];
581
+ url = commandMatch[7];
582
+ }
583
+
584
+ fs.mkdirSync(pathToDownloadInto, { recursive: true });
585
+ } else {
586
+ log(` Format not correct`.red.bold, ':end');
587
+ process.exit(1);
588
+ }
589
+
590
+ const fileName = path.basename(url);
591
+ const filePath = path.join(pathToDownloadInto, fileName);
592
+
593
+ const extractPath = path.join(pathToDownloadInto, 'extract');
594
+ if(opts.c || opts.clean || opts.u){
595
+ if(fs.existsSync(extractPath)) execSync(`rm -rf ${extractPath}`);
596
+ }
597
+
598
+ const fixedArgs = args.join(' ')
599
+ .replaceAll('$path', extractPath)
600
+ .replaceAll('$file', filePath) || (
601
+ command == 'unzip' ?
602
+ `${filePath} -d ${extractPath}` :
603
+ `${filePath} ${extractPath}`
604
+ );
605
+
606
+ if(opts.verbose){
607
+ log('Download started for'.cyan, url.yellow, 'at'.cyan, filePath.yellow, shaHash ? 'with sha'.cyan : '', shaHash ? shaHash.yellow : '');
608
+ } else {
609
+ log(`Downloading`.cyan, fileName.yellow);
610
+ }
611
+ const downloaded = fs.existsSync(extractPath) ? true : this.downloadFileFromUrl(url, filePath, shaHash, opts);
612
+ if(downloaded){
613
+ log(`Download Complete for`.cyan, fileName.yellow);
614
+ log('Extracting'.cyan, fileName.yellow);
615
+ if(opts.verbose){
616
+ log('Running command:'.cyan, command.green.bold, 'for'.cyan, filePath.yellow, 'at'.cyan, extractPath.yellow);
617
+ }
618
+ if(this.isCommandAvailable(command)){
619
+ try{
620
+ if(fs.existsSync(extractPath)) {
621
+ log('Found Extracted Directory'.cyan);
622
+ } else execSync(`${command} ${fixedArgs}`, {
623
+ stdio: opts.verbose ? 'inherit' : 'ignore'
624
+ });
625
+ } catch(e){
626
+ log(` Failed to extract`.red.bold, ':end');
627
+ return null;
628
+ }
629
+ } else {
630
+ log(` Command "${command}" not found.`.red.bold, ':end');
631
+ return null;
632
+ }
633
+
634
+ return extractPath;
635
+ } else {
636
+ return null;
637
+ }
638
+ },
499
639
  async installAppFrom(path, opts) {
500
640
  if (path.startsWith('github:')) this.installApp(await this.cloneGit(path, opts), opts, true);
641
+ if (path.match(FILE_DL_EXTRACT_REGEX)) this.installApp(this.downloadFile(path, opts), opts, true);
501
642
  else if (path.startsWith('@')) this.fromRepo(path, opts);
502
643
  else this.installApp(path, opts, null, null);
503
644
  },
@@ -20,7 +20,7 @@ module.exports = (currentFile) => {
20
20
  ...options,
21
21
  },
22
22
  callback,
23
- );
23
+ )
24
24
  };
25
25
 
26
26
  function spawn(command, ...args) {
@@ -1,10 +1,86 @@
1
1
  const { spawnSync } = require('child_process');
2
+ const r = require('colors')
3
+
4
+ const baseAnsii = '\x1b';
5
+ const fg = {
6
+ o: ["30", '39'],
7
+ r: ["31", '39'],
8
+ g: ["32", '39'],
9
+ y: ["33", '39'],
10
+ b: ["34", '39'],
11
+ m: ["35", '39'],
12
+ c: ["36", '39'],
13
+ w: ["37", '39'],
14
+ a: ["90", '39']
15
+ }
16
+ const bg = {
17
+ O: ["40", '49'],
18
+ R: ["41", '49'],
19
+ G: ["42", '49'],
20
+ Y: ["43", '49'],
21
+ B: ["44", '49'],
22
+ M: ["45", '49'],
23
+ C: ["46", '49'],
24
+ W: ["47", '49'],
25
+ A: ["48", '49']
26
+ }
27
+ const styles = {
28
+ "!": ["1", '22'], // bold
29
+ "'": ["2", '22'], // dim
30
+ "/": ["3", '23'], // italic
31
+ "_": ["4", '24'], // underline
32
+ "i": ["7", '27'],
33
+ "h": ["8", '28'],
34
+ "-": ["9", '29'],
35
+ }
36
+
37
+ const findStyle = (name) => {
38
+ return styles[name] || bg[name] || fg[name];
39
+ }
40
+
41
+ const addColorize = (applied) => {
42
+ return `${baseAnsii}[${applied.fg}m${applied.bg ? `${baseAnsii}[${applied.bg}m` : ''}${applied.style ? `${baseAnsii}[${applied.style}m` : ''}`
43
+ }
44
+
45
+ const colorize = (baseString = '') => {
46
+ const applied = {
47
+ style: '',
48
+ fg: "39",
49
+ bg: "49",
50
+ };
51
+ const stringParts = baseString.replace(/%([orgybmcwaORGYBMCWA!'\/_ih-])/gmi, (_, col) => {
52
+ const val = findStyle(col);
53
+ if(!val) return _;
54
+ const tag = col in styles ? 'style' :
55
+ col in fg ? 'fg' : 'bg';
56
+ if(applied[tag] == val[0]){
57
+ applied[tag] = val[1];
58
+ } else {
59
+ applied[tag] = val[0];
60
+ }
61
+ return addColorize(applied);
62
+ });
63
+ return stringParts + addColorize({
64
+ style: '',
65
+ fg: "39",
66
+ bg: "49",
67
+ });
68
+ }
2
69
 
3
70
  (module.exports.print = function print(...args) {
71
+ if(!args.some(i => typeof i !== "string")){
72
+ args = [args.join(' ')]
73
+ }
74
+ if(typeof args[0] === "string" && args[0].startsWith('%c')){
75
+ args[0] = colorize(args[0]);
76
+ }
4
77
  return console.log(...args);
5
78
  });
6
79
 
7
80
  module.exports.printf = function printf(buffer, cb) {
81
+ if(typeof buffer === "string" && buffer.startsWith('%c')){
82
+ buffer = colorize(buffer);
83
+ }
8
84
  return process.stdout.write(buffer, cb);
9
85
  };
10
86
 
@@ -41,7 +41,7 @@ function typedef(value, strict = false) {
41
41
  });
42
42
  }
43
43
 
44
- function typef(fn, returnType) {
44
+ function typef(fn, returnType, argumentsTypes) {
45
45
  if(typeof returnType == "function"){
46
46
  const ref = fn;
47
47
  fn = returnType;
@@ -51,7 +51,17 @@ function typef(fn, returnType) {
51
51
  throw new Error('First argument must be a function');
52
52
  }
53
53
  if (typeof returnType == 'function' && returnType.type instanceof Type) returnType = returnType.type;
54
+ const requiredArguments = Array.isArray(argumentsTypes) ? argumentsTypes.filter(i => Array.isArray(i) ? !i.includes(null) : true) : [];
54
55
  const wrappedFn = function(...args){
56
+ if(argumentsTypes && Array.isArray(argumentsTypes)){
57
+ if(args.length !== requiredArguments.length && args.length !== argumentsTypes.length){
58
+ throw new TypeError(`Function ${fn.name || '<anonymous>'} takes exactly ${requiredArguments.length} parameters`)
59
+ }
60
+ const argumentsTyped = typeAre(args, argumentsTypes);
61
+ if(argumentsTyped !== false){
62
+ throw new TypeError(`Function ${fn.name || '<anonymous>'} call error: Parameter at index ${argumentsTyped} is of the wrong type`);
63
+ }
64
+ }
55
65
  const result = fn.call(this, ...args);
56
66
  if(!typeis(result, wrappedFn.returnType)){
57
67
  throw new TypeError(`Function ${fn.name || '<anonymous>'} does not return it's own return type.`);
@@ -60,13 +70,32 @@ function typef(fn, returnType) {
60
70
  }
61
71
  wrappedFn.returnType = returnType;
62
72
  wrappedFn.type = returnType;
73
+ wrappedFn.argumentsTypes = argumentsTypes;
63
74
  return wrappedFn;
64
75
  }
65
- typef.is = function(func, returnType){
76
+ typef.is = function(func, returnType, argumentsTypes){
66
77
  return typeis(func.returnType.defaultValue, returnType);
67
78
  }
68
79
 
80
+ const typeAre = (values, types) => {
81
+ const verified = values.map((t, i) => Array.isArray(types[i]) ? (types[i].map((t2) => typeis(t, t2)).includes(true)) : typeis(t, types[i]));
82
+ const hasWrong = verified.indexOf(false);
83
+ return hasWrong > -1 ? hasWrong : false;
84
+ }
85
+
69
86
  function typeis(obj, typeDef, missingObjects = false) {
87
+
88
+ if(obj == null && typeDef === null) return true;
89
+ else if(obj == null) return false;
90
+ if(obj == undefined && typeDef === undefined) return true;
91
+ else if(obj == undefined) return false;
92
+
93
+ if(typeDef == null && obj === null) return true;
94
+ else if(typeDef == null) return false;
95
+
96
+ if(typeDef == undefined && obj === undefined) return true;
97
+ else if(typeDef == undefined) return false;
98
+
70
99
  // Resolve Type
71
100
  if (typeof typeDef == 'function' && typeDef.type instanceof Type) typeDef = typeDef.type;
72
101
 
@@ -123,6 +152,7 @@ function typeis(obj, typeDef, missingObjects = false) {
123
152
 
124
153
  return missingObjects ? [true] : true;
125
154
  }
155
+ typeis.multi = (values, types) => typeAre(values, types);
126
156
 
127
157
  function typex(child, parent) {
128
158
  return child.prototype instanceof parent || child === parent;
@@ -81,7 +81,7 @@ module.exports.prepareContext = function (
81
81
  this['@cb'] = cb;
82
82
  }
83
83
  });
84
- }, out: {...process.stdout, put: (...logs) => context.print(...logs), strace: (...logs) => straceLog('==> STRACE_OUT():', ...logs ), write: (logs) => context.printf(logs+'\n') }, in: {...process.stdin, read: (...args) => context.input(...args)}, define: (name, object) => {
84
+ }, out: {...process.stdout, cols: process.stdout.columns, rows: process.stdout.rows, put: (...logs) => context.print(...logs), strace: (...logs) => straceLog('==> STRACE_OUT():', ...logs ), write: (logs) => context.printf(logs+'\n') }, in: {...process.stdin, read: (...args) => context.input(...args)}, define: (name, object) => {
85
85
  if(Array.isArray(name) && name.length == 2 && typeof name[0] == 'string'){
86
86
  object = name[1];
87
87
  name = name[0];
@@ -62,6 +62,9 @@ module.exports = (context) => ({
62
62
  },
63
63
  fileRoot,
64
64
  exists,
65
+ create(ifExists){
66
+ return this.write('');
67
+ }
65
68
  };
66
69
  };
67
70
 
@@ -38,7 +38,7 @@ parentPort.on('message', (data) => {
38
38
  },
39
39
  },
40
40
  context: workerData.context,
41
- });
41
+ }, '', 'thread');
42
42
  } catch (e) {
43
43
  parentPort.postMessage({ type: 'error', error: e.message });
44
44
  }
@@ -33,7 +33,7 @@ module.exports = (context) => ({
33
33
  dataResult.resolve(data.result);
34
34
  stop();
35
35
  } else if (data.type === 'error') {
36
- reject(new Error(data.error));
36
+ listener.emit('error', new Error(data.error));
37
37
  stop();
38
38
  } else if (data.type === 'event') {
39
39
  listener.emit(data.event, data.data);
@@ -41,7 +41,7 @@ module.exports = (context) => ({
41
41
  });
42
42
 
43
43
  worker.on('error', (error) => {
44
- console.log(error);
44
+ listener.emit('error', error);
45
45
  stop();
46
46
  });
47
47
 
@@ -51,7 +51,7 @@ module.exports = (context) => ({
51
51
  if (exiting) return;
52
52
  stop();
53
53
  if (code !== 0) {
54
- throw new Error(`Worker stopped with exit code ${code}`);
54
+ listener.emit('error', new Error(`Worker stopped with exit code ${code}`));
55
55
  }
56
56
  });
57
57
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@makano/rew",
3
- "version": "1.4.6",
3
+ "version": "1.5.0",
4
4
  "description": "A simple coffescript runtime and app manager",
5
5
  "main": "main.js",
6
6
  "directories": {
@@ -23,7 +23,9 @@
23
23
  "url": "git+https://github.com/kevinj045/rew.git"
24
24
  },
25
25
  "keywords": [
26
- "coffescript",
26
+ "coffeescript",
27
+ "coffee",
28
+ "compiler",
27
29
  "rew",
28
30
  "runtime"
29
31
  ],