jsir 2.2.9 → 2.3.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/cmd/oaa.js CHANGED
@@ -4,14 +4,14 @@ const {
4
4
  getLibDataDir, trim, regEach, getConfig, mkdir, reget,
5
5
  getCbText, e, sleep, objDataFile, vl, md5, BigNumber,
6
6
  arrayDataFile, infoStr, warnStr,
7
- getInfo, ei, pad, msgStr, getType,
7
+ getInfo, pad, msgStr, getType,
8
8
  isMatch, draftQuery, setConfig,
9
9
  getTextComments, importG, requireG,
10
10
  clearConsole, trimText, getFnArgsStr,
11
11
  createConsole, setTips, delTips,
12
12
  getEditor, errorStr, getConfigDir,
13
13
  getFullPath, parseUniqueName, toUniqueName, isJsirFileName, toJsirFileName,
14
- getOr, getAlias, wrapperJsirText
14
+ getOr, getAlias, wrapperJsirText, eia
15
15
  } = $lib;
16
16
  const _args = process.argv.slice(2).map(trim);
17
17
  const evalCode = require('../deps/evalCode')
@@ -26,11 +26,7 @@ const example = require("../deps/example");
26
26
  const _workspaceConfigFile = 'workspace.json';
27
27
  const _libDataDir = getLibDataDir()
28
28
  const _fileWatcherMap = {}
29
- const _types = {
30
- 'e': "exe",
31
- 'i': "init",
32
- 'f': "file"
33
- }
29
+ const _types = setting.fileType
34
30
  const console = createConsole();
35
31
 
36
32
  let lastFilterArg = '';
@@ -41,6 +37,7 @@ let _rlHistory = []
41
37
  let _haveWrapperInput = true
42
38
  let _noAppendNextLine = true
43
39
  let _onLazyTempCode = null
40
+ let _isTipsDoneShowKey = false
44
41
 
45
42
  const _onLazyGetMap = Object.create(null)
46
43
  const _data = Object.create(null)
@@ -291,7 +288,9 @@ async function nextLine(callback, promptStr, hidden) {
291
288
  }
292
289
 
293
290
  function defaultPromptStr(showKey = false) {
294
- return [getTipStr(showKey), $defaultSpace].filter(i => i).join(':') + `> `;
291
+ let tips = [getTipStr(showKey), $defaultSpace].filter(i => i).join(':') + `> `;
292
+ _isTipsDoneShowKey = showKey;
293
+ return tips;
295
294
  }
296
295
 
297
296
  function initRl(callback, promptStr, hidden) {
@@ -367,7 +366,11 @@ function getTipStr(showKey = false) {
367
366
  items.push(item)
368
367
  }
369
368
  }
370
- return items.join(',');
369
+ let tips = items.join(',')
370
+ if (!showKey && !_isTipsDoneShowKey && tips.length > 81) {
371
+ return '...'
372
+ }
373
+ return tips;
371
374
  }
372
375
 
373
376
  function closeRl() {
@@ -450,9 +453,9 @@ async function save(args) {
450
453
  return
451
454
  }
452
455
  let resp;
453
- if (args[0] === 'e') {
456
+ if (args[0].startsWith(setting.exeKey)) {
454
457
  resp = example.exeFile;
455
- } else if (args[0] === 'i') {
458
+ } else if (args[0].startsWith(setting.initKey)) {
456
459
  resp = example.initFile;
457
460
  } else {
458
461
  resp = await getCbText();
@@ -534,7 +537,7 @@ function listCmd(tmpMap) {
534
537
  let item = {
535
538
  key: ' ' + i,
536
539
  name: pair[0] + '/' + name,
537
- type: [_types[name.split(/\s+/)[0]] || 'note', suffix].map(trim).join(".")
540
+ type: [_types[name.substring(0, 1)] || setting.defaultType, suffix].map(trim).join(".")
538
541
  }
539
542
  items.push(item)
540
543
 
@@ -552,9 +555,9 @@ function listCmd(tmpMap) {
552
555
  }
553
556
  if (item.type) {
554
557
  let pair = parseUniqueName(item.name);
555
- if (item.type.startsWith('exe.')) {
558
+ if (item.type.startsWith(_types[setting.exeKey] + '.')) {
556
559
  item.name = infoStr(pair[1])
557
- } else if (item.type.startsWith('init.')) {
560
+ } else if (item.type.startsWith(_types[setting.initKey] + '.')) {
558
561
  item.name = msgStr(pair[1])
559
562
  } else {
560
563
  item.name = pair[1]
@@ -574,6 +577,33 @@ async function wrapperInput(str) {
574
577
  }
575
578
  }
576
579
 
580
+ function wrapperAlias(str) {
581
+ let aliasMap = null;
582
+ try {
583
+ aliasMap = getConfig("alias");
584
+ } catch (e) {
585
+ console.$error(e);
586
+ }
587
+ if (!aliasMap) {
588
+ return str;
589
+ }
590
+ let args = enrichArgs(str);
591
+ for (let i = 0; i < args.length; i++) {
592
+ let arg = args[i];
593
+ if (arg.endsWith(" ")) {
594
+ arg = `\`${arg}\``
595
+ } else if (arg.endsWith(" ")) {
596
+ arg = `"${arg}"`
597
+ } else if (arg.endsWith(" ")) {
598
+ arg = `'${arg}'`
599
+ } else {
600
+ arg = getAlias(aliasMap, arg)
601
+ }
602
+ args[i] = arg;
603
+ }
604
+ return args.join(' ')
605
+ }
606
+
577
607
  async function _wrapperInput(str) {
578
608
  _haveWrapperInput = true;
579
609
  global.$newInput = true;
@@ -582,6 +612,8 @@ async function _wrapperInput(str) {
582
612
  if (!str) {
583
613
  return;
584
614
  }
615
+ str = wrapperAlias(str);
616
+
585
617
  if (/^[`'"]/.test(str)) {
586
618
  let fstr = str.substr(0, 1);
587
619
  if (fstr === '`') {
@@ -616,10 +648,10 @@ async function _wrapperInput(str) {
616
648
  let path = getFullPath(_cmdMap[strs[0]])
617
649
  let uniqueName = trim(_cmdMap[strs[0]]);
618
650
  let fileName = parseUniqueName(uniqueName)[1]
619
- let firstName = fileName.split(/\s+/)[0]
620
- if (firstName === 'f') {
651
+ let firstName = fileName.substring(0, 1)
652
+ if (firstName === setting.fileKey) {
621
653
  await workFile(uniqueName)
622
- } else if (firstName !== 'e') {
654
+ } else if (firstName !== setting.exeKey) {
623
655
  console.log(String(fs.readFileSync(path)));
624
656
  } else {
625
657
  await runCmd(str)
@@ -1073,7 +1105,7 @@ const keywordDef = {
1073
1105
  console.warn("no items")
1074
1106
  } else {
1075
1107
  let path = getFullPath(uniqueName)
1076
- ei(getEditor(), [path])
1108
+ await eia(getEditor(), [path])
1077
1109
  }
1078
1110
  },
1079
1111
  args: {
@@ -1088,9 +1120,9 @@ const keywordDef = {
1088
1120
  if (uniqueName) {
1089
1121
  let configDir = `${getLibDataDir()}/config`;
1090
1122
  mkdir(configDir)
1091
- ei(getEditor(), [`${configDir}/${md5(uniqueName)}.json`])
1123
+ await eia(getEditor(), [`${configDir}/${md5(uniqueName)}.json`])
1092
1124
  } else {
1093
- ei(getEditor(), [`${getLibDataDir()}/config.json`])
1125
+ await eia(getEditor(), [`${getLibDataDir()}/config.json`])
1094
1126
  }
1095
1127
  },
1096
1128
  short: 's'
@@ -1283,7 +1315,7 @@ const keywordDef = {
1283
1315
  let keyword = args[0]
1284
1316
  let justList = false;
1285
1317
  if (keyword.endsWith('.')) {
1286
- let _tmp = getAlias(keyword.substring(0, keyword.length - 1));
1318
+ let _tmp = trim(keyword.substring(0, keyword.length - 1));
1287
1319
  if (_tmp) {
1288
1320
  if (keywordDef[_tmp] || Object.values(keywordDef).map(item => item.short).indexOf(_tmp) !== -1) {
1289
1321
  help(i => i === _tmp || keywordDef[i].short === _tmp);
@@ -1295,8 +1327,6 @@ const keywordDef = {
1295
1327
  console.warn('invalid keyword')
1296
1328
  return
1297
1329
  }
1298
- } else {
1299
- keyword = getAlias(keyword)
1300
1330
  }
1301
1331
  let pair = parseUniqueName(keyword)
1302
1332
  let cmds;
@@ -1343,7 +1373,7 @@ const keywordDef = {
1343
1373
  },
1344
1374
  exe: {
1345
1375
  comment: 'System execute',
1346
- exeFn: (args) => {
1376
+ exeFn: async (args) => {
1347
1377
  let cmd = ''
1348
1378
  let _args = []
1349
1379
  if (args.length > 0) {
@@ -1352,13 +1382,13 @@ const keywordDef = {
1352
1382
  if (args.length > 1) {
1353
1383
  _args = args.slice(1)
1354
1384
  }
1355
- ei(`cd "${$workspaceMap[global.$defaultSpace]}";${cmd}`, _args, true)
1385
+ await eia(`cd "${$workspaceMap[global.$defaultSpace]}";${cmd}`, _args, true)
1356
1386
  },
1357
1387
  short: 'E'
1358
1388
  },
1359
1389
  log: {
1360
1390
  comment: 'View log (type[[lt][le]], index)',
1361
- exeFn: (args) => {
1391
+ exeFn: async (args) => {
1362
1392
  let path = `${getLibDataDir()}/log/jsir`
1363
1393
  let type = '';
1364
1394
  for (let arg of args) {
@@ -1383,7 +1413,7 @@ const keywordDef = {
1383
1413
  console.warn('log file not found')
1384
1414
  return;
1385
1415
  }
1386
- ei(cmdStr, [`"${path}"`], true)
1416
+ await eia(cmdStr, [`"${path}"`], true)
1387
1417
  },
1388
1418
  short: 'l'
1389
1419
  },
@@ -1408,7 +1438,7 @@ function getQuickRunCmds(input, matchStr) {
1408
1438
  } else if (input.startsWith("/")) {
1409
1439
  matchStr = '/' + matchStr;
1410
1440
  }
1411
- return filterCmd(matchStr).filter(i => parseUniqueName(i)[1].startsWith("e "))
1441
+ return filterCmd(matchStr).filter(i => parseUniqueName(i)[1].startsWith(setting.exeKey))
1412
1442
  }
1413
1443
 
1414
1444
  async function preLoad(text, fnNameMatch, fn, packages = [], space) {
@@ -1918,7 +1948,7 @@ function parseArgDef(inputString) {
1918
1948
  }
1919
1949
 
1920
1950
  function getArgDef(text, uniqueName) {
1921
- if (uniqueName && !parseUniqueName(uniqueName)[1].startsWith("e ")) {
1951
+ if (uniqueName && !parseUniqueName(uniqueName)[1].startsWith(setting.exeKey)) {
1922
1952
  return {}
1923
1953
  }
1924
1954
  if (text.indexOf("$defArgs") === -1) {
@@ -1970,12 +2000,7 @@ function filterRequire(currSpace, cmdMatchStr) {
1970
2000
 
1971
2001
  let cmds;
1972
2002
  let uName = toUniqueName(cmdMatchStr, currSpace)
1973
- let pr = parseUniqueName(uName)
1974
- let fullPath;
1975
- if (!/^[ef]\s+/.test(pr[1])) {
1976
- uName = pr[0] + "/i " + pr[1].replace(/^f\s+/, '')
1977
- fullPath = getFullPath(uName)
1978
- }
2003
+ let fullPath = getFullPath(uName)
1979
2004
  if (fullPath && fs.existsSync(fullPath)) {
1980
2005
  cmds = [uName]
1981
2006
  } else {
@@ -1984,6 +2009,9 @@ function filterRequire(currSpace, cmdMatchStr) {
1984
2009
  if (cmds.length > 0) {
1985
2010
  cmds = cmds.filter(cmd => parseUniqueName(cmd)[0] === (appointSpace || currSpace))
1986
2011
  }
2012
+ if (cmds.length > 0) {
2013
+ cmds = cmds.filter(cmd => parseUniqueName(cmd)[1].startsWith(setting.initKey))
2014
+ }
1987
2015
  }
1988
2016
  if (cmds.length > 1) {
1989
2017
  throw `multiple match: ${cmdMatchStr}`
@@ -1999,9 +2027,9 @@ async function _requireSource(currSpace, cmdMatchStr) {
1999
2027
  let path = getFullPath(uniqueName)
2000
2028
  let text = String(await fp.readFile(path))
2001
2029
  let pair = parseUniqueName(uniqueName)
2002
- if (pair[1].startsWith('i ')) {
2030
+ if (pair[1].startsWith(setting.initKey)) {
2003
2031
  result = await evalText(text, uniqueName)
2004
- } else if (pair[1].startsWith('e ')) {
2032
+ } else if (pair[1].startsWith(setting.exeKey)) {
2005
2033
  result = async (argsStr) => {
2006
2034
  return await runCmd(trim(argsStr), uniqueName, text)
2007
2035
  }
@@ -2084,15 +2112,15 @@ function sigExit() {
2084
2112
  }
2085
2113
 
2086
2114
  process.on('uncaughtException',function(err){
2087
- console.error('uncaughtException', err)
2115
+ console.$error('uncaughtException', err)
2088
2116
  _noAppendNextLine || nextLine()
2089
2117
  })
2090
2118
  process.on('unhandledRejection',function(err){
2091
- console.error('unhandledRejection', err)
2119
+ console.$error('unhandledRejection', err)
2092
2120
  _noAppendNextLine || nextLine()
2093
2121
  })
2094
2122
  process.on('rejectionHandled',function(err){
2095
- console.error('rejectionHandled', err)
2123
+ console.$error('rejectionHandled', err)
2096
2124
  _noAppendNextLine || nextLine()
2097
2125
  })
2098
2126
  process.on('SIGINT', sigExit);
package/deps/setting.js CHANGED
@@ -1,4 +1,21 @@
1
+
2
+ const exeKey = 'e';
3
+ const initKey = 'i';
4
+ const fileKey = 'f';
5
+
6
+ const fileType = {};
7
+ fileType[exeKey] = "exe";
8
+ fileType[initKey] = "init";
9
+ fileType[fileKey] = "file";
10
+
11
+ const defaultType = 'note';
12
+
1
13
  module.exports = {
2
14
  name: 'jsir',
3
- libDataDir: '.jsirData'
4
- }
15
+ libDataDir: '.jsirData',
16
+ fileType,
17
+ exeKey,
18
+ initKey,
19
+ fileKey,
20
+ defaultType
21
+ }
package/deps/util.js CHANGED
@@ -1,7 +1,7 @@
1
1
  const setting = require('./setting')
2
2
  const os = require('os')
3
3
  const home = os.homedir()
4
- const {exec, spawnSync} = require('child_process');
4
+ const {exec, spawnSync, spawn} = require('child_process');
5
5
  const readline = require('readline')
6
6
  const fs = require('fs')
7
7
  const fp = require('fs').promises
@@ -12,6 +12,8 @@ const dayJs = require('dayjs')
12
12
  const table = require('console.table')
13
13
  const initModulePaths = Object.assign([], module.paths)
14
14
  const path = require('path')
15
+ const _types = setting.fileType
16
+ const _typeKeys = Object.keys(_types)
15
17
 
16
18
  global.$newInput = false
17
19
  global.$workspaceMap = {}
@@ -23,6 +25,7 @@ global.$packages = {}
23
25
  let libDataDir;
24
26
  let lockDir;
25
27
  let logDir;
28
+ let tempDir;
26
29
  let configDir;
27
30
 
28
31
  class SyncQueue {
@@ -300,7 +303,10 @@ function toJsirFileName(name) {
300
303
  }
301
304
 
302
305
  function isJsirFileName(name) {
303
- return /^[^./]*[^./\s]\.[^./\s]+$/.test(name) && name.indexOf(".") > 1
306
+ if (name.indexOf(".") === 1) {
307
+ return _typeKeys.indexOf(name.substring(0, 1)) === -1
308
+ }
309
+ return /^[^./]*[^./\s]\.[^./\s]+$/.test(name)
304
310
  }
305
311
 
306
312
  function isMatch(text,
@@ -607,6 +613,15 @@ function getLogDir() {
607
613
  return logDir;
608
614
  }
609
615
 
616
+ function getTempDir() {
617
+ if (tempDir) {
618
+ return tempDir;
619
+ }
620
+ tempDir = getLibDataDir() + "/temp"
621
+ mkdir(tempDir)
622
+ return tempDir;
623
+ }
624
+
610
625
  /**
611
626
  * 根据文件完整路径,检查并创建其父级目录
612
627
  * 示例:/a/b/c/d.txt -> 检查并创建 /a/b/c
@@ -679,7 +694,7 @@ function getInitName(fileName) {
679
694
  fileName = trim(fileName)
680
695
  let homeDir = global.$workspaceMap[$defaultSpace]
681
696
  if (!fileName.startsWith("/")) {
682
- fileName = 'i ' + fileName.replace(/i\s+/, '')
697
+ fileName = setting.initKey + ' ' + fileName.replace(new RegExp(`^${setting.initKey}\\s+`), '')
683
698
  if (!/\..+/.test(fileName)) {
684
699
  fileName = fileName + '.js'
685
700
  }
@@ -687,6 +702,7 @@ function getInitName(fileName) {
687
702
  }
688
703
  return fileName;
689
704
  }
705
+
690
706
  function dataFile(fileName, fn, fmt, defaultObj = {}, returnStr = false) {
691
707
  let dataDir = getLibDataDir() + "/data"
692
708
  fileName = trim(fileName)
@@ -746,7 +762,7 @@ async function fileJson(key, fn, fmt = true) {
746
762
  let fileName = trim(key)
747
763
  let path = dataDir + "/" + fileName;
748
764
  let homeDir = global.$workspaceMap[$defaultSpace]
749
- let isInit = fileName.startsWith("i ");
765
+ let isInit = fileName.startsWith(setting.initKey);
750
766
  if (isInit) {
751
767
  path = homeDir + '/' + toJsirFileName(fileName);
752
768
  }
@@ -881,12 +897,11 @@ function getConfigDir() {
881
897
  return configDir;
882
898
  }
883
899
 
884
- function getAlias(key) {
900
+ function getAlias(aliasMap, key) {
885
901
  key = trim(key)
886
902
  if (!key) {
887
903
  return key;
888
904
  }
889
- let aliasMap = getConfig('alias', {});
890
905
  if (aliasMap.hasOwnProperty(key) && vl(aliasMap[key])) {
891
906
  return aliasMap[key].trim();
892
907
  }
@@ -1090,6 +1105,9 @@ function setTips(key, value, onRm) {
1090
1105
  `
1091
1106
  可以设置相同的key, value值,会在左侧提示符体现出来
1092
1107
  `
1108
+ if (!vl(key) || key.indexOf(",") !== -1) {
1109
+ throw "invalid tip key";
1110
+ }
1093
1111
  getOr(global.$tips, key, []).push(value);
1094
1112
  if (onRm) {
1095
1113
  getOr(_tipsOnRm, key, []).push(onRm)
@@ -1336,7 +1354,7 @@ function mkdir(dir) {
1336
1354
 
1337
1355
  function e(cmd, mbNum = 3, doTrim = true){
1338
1356
  `
1339
- return Promise(result)
1357
+ return Promise(resolve, reject)
1340
1358
  `
1341
1359
  return new Promise((resolve, reject) => {
1342
1360
  exec(`${cmd}`, {
@@ -1353,7 +1371,7 @@ function e(cmd, mbNum = 3, doTrim = true){
1353
1371
 
1354
1372
  function ee(cmd, mbNum = 3, doTrim = true){
1355
1373
  `
1356
- return Promise([stdout, stderr])
1374
+ return Promise(resolve([stdout, stderr]))
1357
1375
  `
1358
1376
  return new Promise((resolve, reject) => {
1359
1377
  exec(`${cmd}`, {
@@ -1372,6 +1390,23 @@ function ei(cmd, args = [], shell = false) {
1372
1390
  spawnSync(cmd, args, {stdio:"inherit", shell});
1373
1391
  }
1374
1392
 
1393
+ async function eia(cmd, args = [], shell = false) {
1394
+ `
1395
+ 当前进程不会卡住,输入输出由cmd进程持有
1396
+ `
1397
+ let child = spawn(cmd, args, {stdio:"inherit", shell});
1398
+ return new Promise((resolve, reject) => {
1399
+ // 监听子进程的关闭事件
1400
+ child.on('close', (code) => {
1401
+ resolve(code);
1402
+ });
1403
+ // 可选:监听子进程的错误事件
1404
+ child.on('error', (err) => {
1405
+ reject(err)
1406
+ });
1407
+ })
1408
+ }
1409
+
1375
1410
  async function getCbText(mbNum) {
1376
1411
  return await e(`pbpaste`, mbNum, false)
1377
1412
  }
@@ -1806,6 +1841,24 @@ function wrapperJsirText(text) {
1806
1841
  ;
1807
1842
  }
1808
1843
 
1844
+ async function terminalRun(cmd) {
1845
+ `
1846
+ 打开新的苹果终端并执行命令
1847
+ `
1848
+ const scriptText = `tell application "Terminal"
1849
+ activate
1850
+ do script "${cmd}"
1851
+ end tell
1852
+ `;
1853
+ let tempScriptPath = getTempDir() + `/terminalRun_${Date.now()}.scpt`
1854
+ fs.writeFileSync(tempScriptPath, scriptText);
1855
+ try {
1856
+ console.log(await e(`osascript ${tempScriptPath}`))
1857
+ } finally {
1858
+ fs.unlinkSync(tempScriptPath)
1859
+ }
1860
+ }
1861
+
1809
1862
  module.exports = {
1810
1863
  wrapperJsirText,
1811
1864
  run,
@@ -1903,5 +1956,8 @@ module.exports = {
1903
1956
  fileJson,
1904
1957
  debugStr,
1905
1958
  getAlias,
1906
- createDirs
1959
+ createDirs,
1960
+ getTempDir,
1961
+ terminalRun,
1962
+ eia
1907
1963
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jsir",
3
- "version": "2.2.9",
3
+ "version": "2.3.0",
4
4
  "description": "JavaScript Script Management Tool",
5
5
  "main": "index.js",
6
6
  "scripts": {