@coderich/sandman 0.0.1 → 0.0.3
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/package.json +1 -1
- package/src/FetchService.js +5 -3
- package/src/Sandman.js +47 -13
- package/src/app.js +2 -2
package/package.json
CHANGED
package/src/FetchService.js
CHANGED
|
@@ -13,7 +13,9 @@ exports.fetch = (req) => {
|
|
|
13
13
|
};
|
|
14
14
|
|
|
15
15
|
exports.normalizeRequest = (req) => {
|
|
16
|
+
req.path ??= '';
|
|
16
17
|
req.method ??= 'get'; req.headers ??= {}; req.params ??= {};
|
|
18
|
+
req.url += req.path;
|
|
17
19
|
req.url = Object.entries(req.params).reduce((url, [key, value]) => { url.searchParams.append(key, value); return url; }, new URL(req.url)).toString();
|
|
18
20
|
req.headers = Object.entries(req.headers).reduce((prev, [key, value]) => Object.assign(prev, { [key.toLowerCase()]: value }), {});
|
|
19
21
|
const [contentType] = req.headers['content-type']?.split(';') || [];
|
|
@@ -50,8 +52,8 @@ exports.normalizeRequest = (req) => {
|
|
|
50
52
|
exports.decorateRequest = (mergeData, key, request) => {
|
|
51
53
|
const toMerge = key.split('.').reduce((prev, k, i, arr) => {
|
|
52
54
|
const $key = arr.slice(0, i).join('.');
|
|
53
|
-
return Merge(prev, mergeData[$key]?.request);
|
|
54
|
-
}, {
|
|
55
|
+
return Merge({}, prev, mergeData[$key]?.request);
|
|
56
|
+
}, Merge({}, mergeData.request));
|
|
55
57
|
|
|
56
|
-
return Merge(toMerge, request);
|
|
58
|
+
return Merge({}, toMerge, request);
|
|
57
59
|
};
|
package/src/Sandman.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
const Path = require('path');
|
|
2
|
+
const Merge = require('lodash.merge');
|
|
2
3
|
const Readline = require('readline');
|
|
3
4
|
const Chokidar = require('chokidar');
|
|
4
5
|
const EventEmitter = require('events');
|
|
@@ -6,8 +7,11 @@ const { get, flatten } = require('@coderich/util');
|
|
|
6
7
|
const FetchService = require('./FetchService');
|
|
7
8
|
const ConfigClient = require('./ConfigClient');
|
|
8
9
|
|
|
10
|
+
const resolveSymbol = Symbol('resolve');
|
|
11
|
+
|
|
9
12
|
module.exports = class Sandman extends EventEmitter {
|
|
10
13
|
#configClient; #configDir; #options; #watcher; #readline; #mergeData = {}; #cli;
|
|
14
|
+
#captureCandidates = false; #candidates = []; #tabCounter = 0; #candidateIndex = 0; #line; #lastToken;
|
|
11
15
|
|
|
12
16
|
constructor(configDir, options) {
|
|
13
17
|
super();
|
|
@@ -29,7 +33,16 @@ module.exports = class Sandman extends EventEmitter {
|
|
|
29
33
|
}
|
|
30
34
|
|
|
31
35
|
cli() {
|
|
32
|
-
return this.#cli
|
|
36
|
+
return Object.defineProperties(this.#cli, {
|
|
37
|
+
resolve: {
|
|
38
|
+
value: (...args) => {
|
|
39
|
+
this.#configClient.resolve(...args);
|
|
40
|
+
this.#prompt();
|
|
41
|
+
return this.#cli;
|
|
42
|
+
},
|
|
43
|
+
configurable: true,
|
|
44
|
+
},
|
|
45
|
+
});
|
|
33
46
|
}
|
|
34
47
|
|
|
35
48
|
#run(key) {
|
|
@@ -59,8 +72,10 @@ module.exports = class Sandman extends EventEmitter {
|
|
|
59
72
|
const value = get(config, key);
|
|
60
73
|
|
|
61
74
|
if (value?.request) {
|
|
62
|
-
const request = FetchService.decorateRequest(this.#mergeData, key, value.request);
|
|
63
|
-
this.#configClient.
|
|
75
|
+
const $request = FetchService.decorateRequest(this.#mergeData, key, value.request);
|
|
76
|
+
const request = this.#configClient.set(resolveSymbol, $request).get(resolveSymbol);
|
|
77
|
+
this.#configClient.del(resolveSymbol);
|
|
78
|
+
return Merge({}, value, { request });
|
|
64
79
|
}
|
|
65
80
|
|
|
66
81
|
return this.#configClient.get(key, ...rest);
|
|
@@ -106,7 +121,7 @@ module.exports = class Sandman extends EventEmitter {
|
|
|
106
121
|
const paths = lastToken.split('.');
|
|
107
122
|
const path = paths.at(-1);
|
|
108
123
|
|
|
109
|
-
// Specific request
|
|
124
|
+
// Specific request.data selector
|
|
110
125
|
if (lastToken.startsWith('.')) {
|
|
111
126
|
const api = this.#get(tokens.at(-2));
|
|
112
127
|
if (!api?.request) return [[], path];
|
|
@@ -120,34 +135,51 @@ module.exports = class Sandman extends EventEmitter {
|
|
|
120
135
|
|
|
121
136
|
// These keys follow the typing of the user
|
|
122
137
|
const startsWithCandidates = Array.from(new Set(flatKeys.map((flatKey) => {
|
|
123
|
-
return flatKey.split('.').slice(0, paths.length).join('.');
|
|
138
|
+
return flatKey.split('.').slice(0, paths.length).join('.');
|
|
124
139
|
}))).filter((c) => {
|
|
125
140
|
return c.toLowerCase().startsWith(lastToken.toLowerCase());
|
|
126
|
-
}).map(p => p.split('.').at(-1)); // Here!
|
|
141
|
+
}); // .map(p => p.split('.').at(-1)); // Here!
|
|
127
142
|
|
|
128
143
|
// These are shortcut keys to requests
|
|
129
144
|
const requestKeyCandidates = Array.from(new Set(flatKeys.map((flatKey) => {
|
|
130
145
|
const keys = flatKey.split('.');
|
|
131
146
|
const index = keys.indexOf('request');
|
|
132
|
-
|
|
133
|
-
const
|
|
134
|
-
|
|
147
|
+
return index && flatKey.split('.').slice(0, index).join('.');
|
|
148
|
+
// const typedPath = keys.slice(0, paths.length - 1).join('.');
|
|
149
|
+
// const autocompletePath = keys.slice(paths.length - 1, index).join('.');
|
|
150
|
+
// return index > 0 && lastToken.toLowerCase().startsWith(typedPath.toLowerCase()) && autocompletePath;
|
|
135
151
|
}).filter(Boolean))).filter((c) => {
|
|
136
|
-
return c.toLowerCase().includes(
|
|
152
|
+
return c.toLowerCase().includes(lastToken.toLowerCase());
|
|
153
|
+
// return c.toLowerCase().includes(path.toLowerCase());
|
|
137
154
|
});
|
|
138
155
|
|
|
139
156
|
const candidates = Array.from(new Set(startsWithCandidates.concat(requestKeyCandidates)));
|
|
140
|
-
|
|
141
|
-
return [candidates,
|
|
157
|
+
if (this.#captureCandidates) { this.#candidates = candidates; this.#line = line; this.#lastToken = lastToken; }
|
|
158
|
+
return [candidates, lastToken];
|
|
142
159
|
},
|
|
143
160
|
});
|
|
144
161
|
|
|
145
162
|
process.stdin.on('keypress', (ch, key) => {
|
|
163
|
+
if (key && key.name === 'tab') this.#tabCounter++; else this.#tabCounter = 0;
|
|
164
|
+
this.#captureCandidates = this.#tabCounter === 2;
|
|
165
|
+
|
|
146
166
|
if (key && key.name === 'escape') {
|
|
147
167
|
this.#readline.line = '';
|
|
148
168
|
Readline.cursorTo(process.stdout, 0);
|
|
149
169
|
Readline.clearLine(process.stdout, 0);
|
|
150
170
|
this.#readline.prompt();
|
|
171
|
+
} else if (this.#tabCounter > 2 && this.#candidates.length) {
|
|
172
|
+
let value = this.#candidates.at(this.#candidateIndex++);
|
|
173
|
+
|
|
174
|
+
if (!value) {
|
|
175
|
+
this.#candidateIndex = 0;
|
|
176
|
+
value = this.#candidates.at(this.#candidateIndex++);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
value = this.#line.replace(this.#lastToken, value);
|
|
180
|
+
this.#readline.line = value;
|
|
181
|
+
this.#readline.cursor = value.length;
|
|
182
|
+
this.#readline.prompt(true);
|
|
151
183
|
}
|
|
152
184
|
});
|
|
153
185
|
}
|
|
@@ -165,10 +197,12 @@ module.exports = class Sandman extends EventEmitter {
|
|
|
165
197
|
if (['add', 'change'].includes(event)) {
|
|
166
198
|
const api = ConfigClient.parseFile(path);
|
|
167
199
|
if (key) this.#configClient.set(key, api);
|
|
168
|
-
else this.#configClient.merge(api);
|
|
200
|
+
else this.#configClient.merge(api); // index.yaml
|
|
169
201
|
if (api.request) this.emit('save', { key, api });
|
|
202
|
+
this.#prompt();
|
|
170
203
|
} else if (['unlink', 'unlinkDir'].includes(event)) {
|
|
171
204
|
this.#configClient.del(key);
|
|
205
|
+
this.#prompt();
|
|
172
206
|
}
|
|
173
207
|
});
|
|
174
208
|
}
|
package/src/app.js
CHANGED