NS-DOS
From Hobby'dev
Overview[edit | edit source]
That's a Nodejs command line repl that smells like MS-DOS.
Every "folder" is a global namespace where you can store variables and functions. Subfolders appears as objects. The whole thing is persistent.
Type ".help" for help.
For example:
db> test = { one: "ok", two: "fine" } { one: 'ok', two: 'fine' } db> .cv test db/test> one 'ok'
Source[edit | edit source]
1 const repl = require('repl');
2 const fs = require('fs');
3 const serialize = require('serialize-javascript');
4 const vm = require('vm');
5 const util = require('util');
6 const fmt = require('fmt');
7 const prettyjson = require('prettyjson');
8 const asTable = require('as-table');
9
10 eval("db="+fs.readFileSync('./db.js','utf8'));
11
12 var today = new Date();
13 var now = today.toLocaleTimeString().replace(/:/g,'-');
14 today = today.toLocaleDateString();
15 fs.writeFileSync('./past/db-'+today+'-'+now+'.js',serialize(db));
16
17
18 eval('db.today='+serialize(db.planner[today]));
19
20
21 global.isArray = function(a) {
22 return (!!a) && (a.constructor === Array);
23 };
24
25 /*
26 global.isObject = function(a) {
27 return (!!a) && (a.constructor === Object);
28 };
29 */
30
31 function isObject(obj) {
32 return obj === Object(obj);
33 }
34
35 pretty = function(x,opt) { if (x !== undefined) console.log(prettyjson.render(x,opt)); }
36
37
38 db.zero.fmt = fmt;
39 db.zero.strfy = function(x) { console.log(serialize(x,2)); };
40 db.zero.pretty = pretty
41 db.zero.asTable = function(x,conf) { console.log(asTable.configure(conf)(x)); };
42 db.zero.isArray = isArray;
43 db.zero.isObject = isObject;
44
45
46 global.folderStack = ['db'];
47 global.folder = global;
48
49 global.evalTimeout = 1000;
50
51 jsonColor = { noColor:true };
52
53 inspectOptions = {
54 depth: null,
55 colors: true
56 };
57
58 function setFolder() {
59
60 folder = global;
61 for (var f=0; f<folderStack.length; f++) folder=folder[folderStack[f]];
62 }
63
64 function setPrompt() {
65
66 replServer._initialPrompt = '\n'+folderStack.join('/')+'> ';
67 replServer.displayPrompt();
68 }
69
70 function showPage() {
71
72 if (db.auto[folderStack[folderStack.length-1]]) {
73
74 Object.defineProperty(folder,'z',{value:db.zero,enumerable:false,configurable:true});
75
76 var replContext = vm.createContext(folder);
77 var cmd = '('+serialize(db.auto[folderStack[folderStack.length-1]])+')()';
78
79 try {
80
81 result = vm.runInContext(cmd,replContext,{timeout: evalTimeout});
82
83 } catch(e) { console.log(util.inspect(e,inspectOptions)); }
84 }
85 }
86
87 function myEval(cmd, context, filename, callback) {
88
89 setFolder();
90
91 var replContext = vm.createContext(folder);
92
93 var result;
94
95 try {
96
97 result = vm.runInContext(cmd,replContext,{timeout: evalTimeout});
98
99 } catch(e) { console.log(util.inspect(e,inspectOptions)); }
100
101 if (result !== undefined) console.log(util.inspect(result,inspectOptions));
102
103 var sdb = serialize(db);
104
105 fs.writeFileSync('./db.js',sdb);
106
107 setFolder();
108 setPrompt();
109 }
110
111
112 function completer(line) {
113 const completions = '.help .error .exit .quit .q'.split(' ');
114 const hits = completions.filter((c) => c.startsWith(line));
115
116 // show all completions if none found
117 return [hits.length ? hits : completions, line];
118 }
119
120
121
122
123 var replServer = repl.start({ prompt: '', eval: myEval, context: db, completer: completer });
124
125 setFolder();
126 showPage();
127 setPrompt();
128
129
130 function changeView(name) {
131
132 setFolder();
133 delete folder.z;
134
135 if (name==='..') {
136
137 if (folderStack.length>1) folderStack.pop();
138
139 } else if (isObject(folder[name]) && !isArray(folder[name])) {
140
141 folderStack.push(name);
142
143 }
144
145 setFolder();
146 Object.defineProperty(folder,'z',{value:db.zero,enumerable:false,configurable:true});
147 }
148
149
150 replServer.defineCommand('cv', {
151 help: 'Change view',
152 action(name) {
153
154 name.split('/').map(changeView);
155 showPage();
156 setPrompt();
157 }
158 });
159
160
161 replServer.defineCommand('keys', {
162 help: 'Show keys of current view',
163 action(name) {
164
165 setFolder();
166 console.log(pretty(Object.keys(folder)));
167 setPrompt();
168 }
169 });
170
171
172 replServer.defineCommand('show', {
173 help: 'Show serialized object',
174 action(name) {
175
176 setFolder();
177
178 if (typeof folder[name]==='function')
179 console.log(serialize(folder[name],2));
180 else
181 console.log(pretty(folder[name]));
182
183 setPrompt();
184 }
185 });
186
187
188 replServer.defineCommand('del', {
189 help: 'Delete an object',
190 action(name) {
191
192 setFolder();
193 delete folder[name];
194 setPrompt();
195 }
196 });
197
198
199 replServer.defineCommand('look', {
200 help: 'Pretty print current view',
201 action(name) {
202
203 setFolder();
204 delete folder.z;
205 pretty(folder);
206 Object.defineProperty(folder,'z',{value:db.zero,enumerable:false,configurable:true});
207 setPrompt();
208 }
209 });