secrez 2.1.13 → 2.1.15
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/README.md +63 -54
- package/bin/secrez.js +42 -43
- package/package.json +1 -1
- package/src/commands/Find.js +250 -8
- package/src/commands/Git.js +56 -3
package/README.md
CHANGED
|
@@ -368,6 +368,15 @@ Secrez is not intended to compete with password managers, so do not expect it to
|
|
|
368
368
|
|
|
369
369
|
## History
|
|
370
370
|
|
|
371
|
+
**2.1.15**
|
|
372
|
+
|
|
373
|
+
- add `find -R` to look for recent entries only. With `-l` to set a limit (default 10)
|
|
374
|
+
|
|
375
|
+
**2.1.14**
|
|
376
|
+
|
|
377
|
+
- reverse changes done in version 2.1.12
|
|
378
|
+
- add a push option to Git that checks if there are changes in the repo and, if so, pushes them remotely, updating the system
|
|
379
|
+
|
|
371
380
|
**2.1.12**
|
|
372
381
|
|
|
373
382
|
- enforce the usage of pnpm during global install. When that is not possible, for example with yarn, it blocks the execution asking the user to uninstall and install it again properly
|
|
@@ -892,60 +901,60 @@ Thank you for any contributions! 😉
|
|
|
892
901
|
## Test coverage
|
|
893
902
|
|
|
894
903
|
```
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
|
|
899
|
-
|
|
900
|
-
All files |
|
|
901
|
-
src |
|
|
902
|
-
Command.js |
|
|
903
|
-
PreCommand.js | 8.82 | 0 | 0 | 8.82 | 6-97
|
|
904
|
-
cliConfig.js | 100 | 100 | 100 | 100 |
|
|
905
|
-
src/commands |
|
|
906
|
-
Alias.js |
|
|
907
|
-
Bash.js |
|
|
908
|
-
Cat.js |
|
|
909
|
-
Cd.js |
|
|
910
|
-
Conf.js |
|
|
911
|
-
Contacts.js |
|
|
912
|
-
Copy.js |
|
|
913
|
-
Ds.js |
|
|
914
|
-
Edit.js |
|
|
915
|
-
Export.js |
|
|
916
|
-
Find.js |
|
|
917
|
-
Git.js |
|
|
918
|
-
Help.js |
|
|
919
|
-
Import.js |
|
|
920
|
-
Lcat.js |
|
|
921
|
-
Lcd.js |
|
|
922
|
-
Lls.js |
|
|
923
|
-
Lpwd.js |
|
|
924
|
-
Ls.js |
|
|
925
|
-
Mkdir.js |
|
|
926
|
-
Mv.js |
|
|
927
|
-
Paste.js |
|
|
928
|
-
Pwd.js |
|
|
929
|
-
Quit.js |
|
|
930
|
-
Rm.js |
|
|
931
|
-
Shell.js |
|
|
932
|
-
Show.js |
|
|
933
|
-
Ssh.js |
|
|
934
|
-
Tag.js |
|
|
935
|
-
Totp.js |
|
|
936
|
-
Touch.js |
|
|
937
|
-
Use.js |
|
|
938
|
-
Ver.js |
|
|
939
|
-
Whoami.js |
|
|
940
|
-
index.js | 87.5 | 50 | 100 | 86.95 | 15,22,31
|
|
941
|
-
src/prompts |
|
|
942
|
-
MainPromptMock.js |
|
|
943
|
-
src/utils |
|
|
944
|
-
AliasManager.js |
|
|
945
|
-
ContactManager.js |
|
|
946
|
-
HelpProto.js |
|
|
947
|
-
Logger.js |
|
|
948
|
-
|
|
904
|
+
1 passing (15s)
|
|
905
|
+
|
|
906
|
+
--------------------|---------|----------|---------|---------|----------------------------------
|
|
907
|
+
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
|
|
908
|
+
--------------------|---------|----------|---------|---------|----------------------------------
|
|
909
|
+
All files | 14.72 | 2.34 | 17.88 | 14.78 |
|
|
910
|
+
src | 25.42 | 6.25 | 15 | 25.64 |
|
|
911
|
+
Command.js | 24 | 8.62 | 21.42 | 24.32 | 22-35,40-110,116,127,130-182
|
|
912
|
+
PreCommand.js | 8.82 | 0 | 0 | 8.82 | 6-97
|
|
913
|
+
cliConfig.js | 100 | 100 | 100 | 100 |
|
|
914
|
+
src/commands | 13.44 | 1.7 | 19.32 | 13.52 |
|
|
915
|
+
Alias.js | 7.59 | 0 | 25 | 7.69 | 62-228
|
|
916
|
+
Bash.js | 62.5 | 0 | 33.33 | 62.5 | 11-19
|
|
917
|
+
Cat.js | 11.95 | 0 | 14.28 | 11.95 | 61-222
|
|
918
|
+
Cd.js | 17.85 | 0 | 25 | 17.85 | 28-73
|
|
919
|
+
Conf.js | 7.4 | 0 | 10 | 7.4 | 34-216
|
|
920
|
+
Contacts.js | 5.73 | 0 | 7.69 | 5.78 | 53-284
|
|
921
|
+
Copy.js | 10.98 | 0 | 12.5 | 11.11 | 71-268
|
|
922
|
+
Ds.js | 5.55 | 0 | 16.66 | 5.63 | 39-170
|
|
923
|
+
Edit.js | 11.76 | 0 | 20 | 11.76 | 61-222
|
|
924
|
+
Export.js | 9.82 | 0 | 16.66 | 9.82 | 82-325
|
|
925
|
+
Find.js | 7.69 | 0 | 8.33 | 7.89 | 63-211
|
|
926
|
+
Git.js | 48.88 | 35.71 | 75 | 48.88 | 31,49-54,61,70-97,103,108,114
|
|
927
|
+
Help.js | 33.33 | 0 | 50 | 33.33 | 26-43
|
|
928
|
+
Import.js | 6.16 | 0 | 9.09 | 6.22 | 87-506
|
|
929
|
+
Lcat.js | 30 | 0 | 25 | 30 | 35-65
|
|
930
|
+
Lcd.js | 17.39 | 0 | 25 | 17.39 | 30-72
|
|
931
|
+
Lls.js | 22.72 | 0 | 25 | 22.72 | 49-99
|
|
932
|
+
Lpwd.js | 30.76 | 0 | 25 | 30.76 | 15-38
|
|
933
|
+
Ls.js | 5.63 | 0 | 10 | 5.97 | 46-187
|
|
934
|
+
Mkdir.js | 18.51 | 0 | 25 | 18.51 | 27-71
|
|
935
|
+
Mv.js | 6.18 | 0 | 16.66 | 6.31 | 46-250
|
|
936
|
+
Paste.js | 13.46 | 0 | 25 | 13.46 | 40-141
|
|
937
|
+
Pwd.js | 30.76 | 0 | 25 | 30.76 | 15-35
|
|
938
|
+
Quit.js | 50 | 0 | 33.33 | 50 | 19-40
|
|
939
|
+
Rm.js | 14.54 | 0 | 16.66 | 14.81 | 36-147
|
|
940
|
+
Shell.js | 29.41 | 0 | 25 | 29.41 | 25-57
|
|
941
|
+
Show.js | 15.68 | 0 | 14.28 | 16 | 45-147
|
|
942
|
+
Ssh.js | 22.22 | 0 | 20 | 22.22 | 49-120
|
|
943
|
+
Tag.js | 8.41 | 0 | 9.09 | 8.49 | 66-246
|
|
944
|
+
Totp.js | 13.59 | 0 | 9.09 | 13.59 | 76-327
|
|
945
|
+
Touch.js | 14.54 | 0 | 25 | 14.81 | 75-245
|
|
946
|
+
Use.js | 11.11 | 0 | 25 | 11.11 | 30-95
|
|
947
|
+
Ver.js | 50 | 0 | 33.33 | 50 | 17-28
|
|
948
|
+
Whoami.js | 27.77 | 0 | 20 | 27.77 | 20-50
|
|
949
|
+
index.js | 87.5 | 50 | 100 | 86.95 | 15,22,31
|
|
950
|
+
src/prompts | 58.33 | 0 | 25 | 58.33 |
|
|
951
|
+
MainPromptMock.js | 58.33 | 0 | 25 | 58.33 | 22-44
|
|
952
|
+
src/utils | 15.89 | 6.86 | 10.25 | 15.62 |
|
|
953
|
+
AliasManager.js | 5.88 | 0 | 0 | 5.88 | 3-48
|
|
954
|
+
ContactManager.js | 6.66 | 0 | 0 | 6.66 | 3-44
|
|
955
|
+
HelpProto.js | 4.2 | 0 | 16.66 | 4.27 | 11-200
|
|
956
|
+
Logger.js | 54.54 | 43.75 | 15.78 | 53.48 | 8,12,16-57,65-69,74,84,88,93,105
|
|
957
|
+
--------------------|---------|----------|---------|---------|----------------------------------
|
|
949
958
|
```
|
|
950
959
|
|
|
951
960
|
## Copyright
|
package/bin/secrez.js
CHANGED
|
@@ -9,50 +9,49 @@ const pkg = require("../package");
|
|
|
9
9
|
|
|
10
10
|
const MainPrompt = require("../src/prompts/MainPrompt");
|
|
11
11
|
const Logger = require("../src/utils/Logger");
|
|
12
|
-
|
|
13
12
|
// Check if the package was installed with pnpm (skip check in development)
|
|
14
|
-
const installPath = __dirname;
|
|
15
|
-
if (process.env.NODE_ENV !== "dev" && installPath.indexOf("pnpm") === -1) {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
}
|
|
13
|
+
// const installPath = __dirname;
|
|
14
|
+
// if (process.env.NODE_ENV !== "dev" && installPath.indexOf("pnpm") === -1) {
|
|
15
|
+
// console.error(chalk.red.bold("\n⚠️ Installation Error\n"));
|
|
16
|
+
// console.error(
|
|
17
|
+
// chalk.yellow(
|
|
18
|
+
// "Secrez must be installed globally using pnpm.\n" +
|
|
19
|
+
// "It appears this package was installed with a different package manager.\n"
|
|
20
|
+
// )
|
|
21
|
+
// );
|
|
22
|
+
// console.error(chalk.white("\nPlease follow these steps:\n"));
|
|
23
|
+
// console.error(
|
|
24
|
+
// chalk.cyan(
|
|
25
|
+
// "1. Uninstall secrez using the package manager you previously used:\n" +
|
|
26
|
+
// " - If you used npm: " +
|
|
27
|
+
// chalk.bold("npm uninstall -g secrez") +
|
|
28
|
+
// "\n" +
|
|
29
|
+
// " - If you used yarn: " +
|
|
30
|
+
// chalk.bold("yarn global remove secrez") +
|
|
31
|
+
// "\n"
|
|
32
|
+
// )
|
|
33
|
+
// );
|
|
34
|
+
// console.error(
|
|
35
|
+
// chalk.cyan(
|
|
36
|
+
// "2. Install pnpm globally if you haven't already:\n" +
|
|
37
|
+
// " " +
|
|
38
|
+
// chalk.bold("npm install -g pnpm") +
|
|
39
|
+
// "\n"
|
|
40
|
+
// )
|
|
41
|
+
// );
|
|
42
|
+
// console.error(
|
|
43
|
+
// chalk.cyan("3. Setup pnpm:\n" + " " + chalk.bold("pnpm setup") + "\n")
|
|
44
|
+
// );
|
|
45
|
+
// console.error(
|
|
46
|
+
// chalk.cyan(
|
|
47
|
+
// "4. Install secrez globally using pnpm:\n" +
|
|
48
|
+
// " " +
|
|
49
|
+
// chalk.bold("pnpm install -g secrez") +
|
|
50
|
+
// "\n"
|
|
51
|
+
// )
|
|
52
|
+
// );
|
|
53
|
+
// process.exit(1);
|
|
54
|
+
// }
|
|
56
55
|
|
|
57
56
|
const optionDefinitions = [
|
|
58
57
|
{
|
package/package.json
CHANGED
package/src/commands/Find.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
const chalk = require("chalk");
|
|
2
2
|
const { Node } = require("@secrez/fs");
|
|
3
|
+
const { config } = require("@secrez/core");
|
|
4
|
+
const Crypto = require("@secrez/crypto");
|
|
3
5
|
|
|
4
6
|
class Find extends require("../Command") {
|
|
5
7
|
setHelpAndCompletion() {
|
|
@@ -56,6 +58,18 @@ class Find extends require("../Command") {
|
|
|
56
58
|
type: Boolean,
|
|
57
59
|
hint: "If global, search also in trash",
|
|
58
60
|
},
|
|
61
|
+
{
|
|
62
|
+
name: "recent",
|
|
63
|
+
alias: "R",
|
|
64
|
+
type: Boolean,
|
|
65
|
+
hint: "Search for recent changes",
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
name: "limit",
|
|
69
|
+
alias: "l",
|
|
70
|
+
type: Number,
|
|
71
|
+
hint: "Limit the number of results (default: 10 when recent is enabled)",
|
|
72
|
+
},
|
|
59
73
|
];
|
|
60
74
|
}
|
|
61
75
|
|
|
@@ -83,11 +97,69 @@ class Find extends require("../Command") {
|
|
|
83
97
|
"Search scanning all the versions in all the datasets",
|
|
84
98
|
],
|
|
85
99
|
["find archive:allet", "Search allet in the archive dataset"],
|
|
100
|
+
["find -R", "Show the 10 most recent changes"],
|
|
101
|
+
["find -R -l 20", "Show the 20 most recent changes"],
|
|
86
102
|
],
|
|
87
103
|
};
|
|
88
104
|
}
|
|
89
105
|
|
|
90
106
|
async find(options) {
|
|
107
|
+
// Handle recent mode
|
|
108
|
+
if (options.recent) {
|
|
109
|
+
// Set default limit if not specified by user
|
|
110
|
+
if (options.limit === undefined) {
|
|
111
|
+
options.limit = 10;
|
|
112
|
+
}
|
|
113
|
+
// In recent mode, ignore keywords completely - just show the N most recent entries
|
|
114
|
+
options.name = undefined;
|
|
115
|
+
options.keywords = undefined;
|
|
116
|
+
|
|
117
|
+
if (options.global) {
|
|
118
|
+
let datasetInfo = await this.internalFs.getDatasetsInfo();
|
|
119
|
+
let allResults = [];
|
|
120
|
+
for (let dataset of datasetInfo) {
|
|
121
|
+
if (options.global && !options.trashToo && dataset.index === 1) {
|
|
122
|
+
continue;
|
|
123
|
+
}
|
|
124
|
+
await this.internalFs.mountTree(dataset.index);
|
|
125
|
+
options.tree = this.internalFs.trees[dataset.index];
|
|
126
|
+
options.dataset = dataset.name;
|
|
127
|
+
// Collect raw results (with ts property) for sorting across datasets
|
|
128
|
+
let rawResults = await this._findRecentRaw(options);
|
|
129
|
+
allResults = allResults.concat(rawResults);
|
|
130
|
+
}
|
|
131
|
+
// Sort all results together by timestamp and limit
|
|
132
|
+
allResults.sort((a, b) => {
|
|
133
|
+
return Node.sortEntry(a.ts, b.ts);
|
|
134
|
+
});
|
|
135
|
+
if (allResults.length > options.limit) {
|
|
136
|
+
allResults = allResults.slice(0, options.limit);
|
|
137
|
+
}
|
|
138
|
+
// Format results
|
|
139
|
+
return allResults.map((e) => {
|
|
140
|
+
let result = [
|
|
141
|
+
Node.hashVersion(e.ts),
|
|
142
|
+
e.path + (e.isDir ? "/" : ""),
|
|
143
|
+
e.name,
|
|
144
|
+
undefined,
|
|
145
|
+
];
|
|
146
|
+
// Store timestamp for date formatting in recent mode
|
|
147
|
+
result.ts = e.ts;
|
|
148
|
+
if (e.dataset) {
|
|
149
|
+
result[1] = e.dataset + ":" + result[1];
|
|
150
|
+
}
|
|
151
|
+
return result;
|
|
152
|
+
});
|
|
153
|
+
} else {
|
|
154
|
+
let data = await this.internalFs.getTreeIndexAndPath(".");
|
|
155
|
+
// Don't set dataset for non-global search (matches regular find behavior)
|
|
156
|
+
// Dataset prefix is only shown when searching globally
|
|
157
|
+
options.tree = data.tree;
|
|
158
|
+
return await this._findRecent(options);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// Regular find mode
|
|
91
163
|
if (!options.name && options.keywords) {
|
|
92
164
|
options.name = options.keywords;
|
|
93
165
|
}
|
|
@@ -133,20 +205,155 @@ class Find extends require("../Command") {
|
|
|
133
205
|
});
|
|
134
206
|
}
|
|
135
207
|
|
|
208
|
+
async _findRecent(options) {
|
|
209
|
+
let rawResults = await this._findRecentRaw(options);
|
|
210
|
+
|
|
211
|
+
// Sort by timestamp (most recent first) and limit
|
|
212
|
+
rawResults.sort((a, b) => {
|
|
213
|
+
return Node.sortEntry(a.ts, b.ts);
|
|
214
|
+
});
|
|
215
|
+
|
|
216
|
+
// Limit results
|
|
217
|
+
if (rawResults.length > options.limit) {
|
|
218
|
+
rawResults = rawResults.slice(0, options.limit);
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
// Format results to match regular find output
|
|
222
|
+
return rawResults.map((e) => {
|
|
223
|
+
let result = [
|
|
224
|
+
Node.hashVersion(e.ts),
|
|
225
|
+
e.path + (e.isDir ? "/" : ""),
|
|
226
|
+
e.name,
|
|
227
|
+
undefined,
|
|
228
|
+
];
|
|
229
|
+
// Store timestamp for date formatting in recent mode
|
|
230
|
+
result.ts = e.ts;
|
|
231
|
+
// Only add dataset prefix if dataset is set (which happens in global mode)
|
|
232
|
+
if (options.dataset) {
|
|
233
|
+
result[1] = options.dataset + ":" + result[1];
|
|
234
|
+
}
|
|
235
|
+
return result;
|
|
236
|
+
});
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
async _findRecentRaw(options) {
|
|
240
|
+
let start = options.tree[options.root ? "root" : "workingNode"];
|
|
241
|
+
let results = [];
|
|
242
|
+
|
|
243
|
+
// Recursively collect all entries with their timestamps (no keyword filtering in recent mode)
|
|
244
|
+
await this._collectRecentEntries(start, results, options, null);
|
|
245
|
+
|
|
246
|
+
// Add dataset info to results for global mode
|
|
247
|
+
if (options.dataset) {
|
|
248
|
+
results = results.map((e) => {
|
|
249
|
+
e.dataset = options.dataset;
|
|
250
|
+
return e;
|
|
251
|
+
});
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
return results;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
async _collectRecentEntries(node, results, options, re) {
|
|
258
|
+
// Skip root node
|
|
259
|
+
if (Node.isRoot(node)) {
|
|
260
|
+
// Process children
|
|
261
|
+
if (node.children) {
|
|
262
|
+
for (let id in node.children) {
|
|
263
|
+
await this._collectRecentEntries(
|
|
264
|
+
node.children[id],
|
|
265
|
+
results,
|
|
266
|
+
options,
|
|
267
|
+
re
|
|
268
|
+
);
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
return;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
// Process current node if it has versions
|
|
275
|
+
if (node.versions && node.lastTs) {
|
|
276
|
+
let name = node.getName();
|
|
277
|
+
let path = node.getPath();
|
|
278
|
+
let isDir = Node.isDir(node);
|
|
279
|
+
|
|
280
|
+
// Filter by keywords if provided
|
|
281
|
+
if (re) {
|
|
282
|
+
if (re.test(name)) {
|
|
283
|
+
results.push({
|
|
284
|
+
ts: node.lastTs,
|
|
285
|
+
name: name,
|
|
286
|
+
path: path,
|
|
287
|
+
isDir: isDir,
|
|
288
|
+
});
|
|
289
|
+
} else if (
|
|
290
|
+
options.content &&
|
|
291
|
+
Node.isFile(node) &&
|
|
292
|
+
node.type === config.types.TEXT &&
|
|
293
|
+
options.tree
|
|
294
|
+
) {
|
|
295
|
+
// Check content if content option is enabled
|
|
296
|
+
try {
|
|
297
|
+
let { content } = await options.tree.getEntryDetails(
|
|
298
|
+
node,
|
|
299
|
+
node.lastTs
|
|
300
|
+
);
|
|
301
|
+
if (re.test(content || "")) {
|
|
302
|
+
results.push({
|
|
303
|
+
ts: node.lastTs,
|
|
304
|
+
name: name,
|
|
305
|
+
path: path,
|
|
306
|
+
isDir: isDir,
|
|
307
|
+
});
|
|
308
|
+
}
|
|
309
|
+
} catch (e) {
|
|
310
|
+
// Ignore errors when reading content
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
} else {
|
|
314
|
+
// No keyword filter, include all entries
|
|
315
|
+
results.push({
|
|
316
|
+
ts: node.lastTs,
|
|
317
|
+
name: name,
|
|
318
|
+
path: path,
|
|
319
|
+
isDir: isDir,
|
|
320
|
+
});
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
// Process children
|
|
325
|
+
if (node.children) {
|
|
326
|
+
for (let id in node.children) {
|
|
327
|
+
await this._collectRecentEntries(
|
|
328
|
+
node.children[id],
|
|
329
|
+
results,
|
|
330
|
+
options,
|
|
331
|
+
re
|
|
332
|
+
);
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
|
|
136
337
|
formatResult(result, re) {
|
|
137
|
-
if (re.test(result)) {
|
|
338
|
+
if (re && re.test(result)) {
|
|
138
339
|
return result.replace(re, (a) => chalk.bold(a));
|
|
139
340
|
} else {
|
|
140
341
|
return result;
|
|
141
342
|
}
|
|
142
343
|
}
|
|
143
344
|
|
|
345
|
+
formatDate(ts) {
|
|
346
|
+
let dateArray = Crypto.fromTsToDate(ts);
|
|
347
|
+
let date = dateArray[0].split("Z")[0].split("T")[0]; // Get YYYY-MM-DD format
|
|
348
|
+
return chalk.cyan(date);
|
|
349
|
+
}
|
|
350
|
+
|
|
144
351
|
formatIndex(len, i) {
|
|
145
352
|
return " ".repeat(len.toString().length - i.toString().length) + i;
|
|
146
353
|
}
|
|
147
354
|
|
|
148
355
|
formatList(list, options) {
|
|
149
|
-
let re = Node.getFindRe(options);
|
|
356
|
+
let re = options.name ? Node.getFindRe(options) : null;
|
|
150
357
|
let i = 0;
|
|
151
358
|
const setCache = (i, e) => {
|
|
152
359
|
this.prompt.setCache("findResult", i, e);
|
|
@@ -159,7 +366,7 @@ class Find extends require("../Command") {
|
|
|
159
366
|
let l = p.length;
|
|
160
367
|
let c = p[l - 1] ? p[l - 1] : p[l - 2];
|
|
161
368
|
if (e[2] && e[2] !== c) {
|
|
162
|
-
e[2] = this.formatResult(e[2], re, options.name);
|
|
369
|
+
e[2] = re ? this.formatResult(e[2], re, options.name) : e[2];
|
|
163
370
|
} else {
|
|
164
371
|
e[2] = undefined;
|
|
165
372
|
}
|
|
@@ -169,13 +376,29 @@ class Find extends require("../Command") {
|
|
|
169
376
|
" ",
|
|
170
377
|
chalk.yellow(e[0]),
|
|
171
378
|
" ",
|
|
172
|
-
this.formatResult(e[1], re, options.name),
|
|
379
|
+
re ? this.formatResult(e[1], re, options.name) : e[1],
|
|
173
380
|
" ",
|
|
174
381
|
e[2],
|
|
175
382
|
].join("");
|
|
176
383
|
} else {
|
|
177
384
|
setCache(i, e);
|
|
178
|
-
|
|
385
|
+
// In recent mode, show date before the path
|
|
386
|
+
if (options.recent && e.ts) {
|
|
387
|
+
let dateStr = this.formatDate(e.ts);
|
|
388
|
+
return [
|
|
389
|
+
k,
|
|
390
|
+
" ",
|
|
391
|
+
dateStr,
|
|
392
|
+
" ",
|
|
393
|
+
re ? this.formatResult(e[1], re, options.name) : e[1],
|
|
394
|
+
].join("");
|
|
395
|
+
} else {
|
|
396
|
+
return [
|
|
397
|
+
k,
|
|
398
|
+
" ",
|
|
399
|
+
re ? this.formatResult(e[1], re, options.name) : e[1],
|
|
400
|
+
].join("");
|
|
401
|
+
}
|
|
179
402
|
}
|
|
180
403
|
});
|
|
181
404
|
}
|
|
@@ -186,8 +409,8 @@ class Find extends require("../Command") {
|
|
|
186
409
|
}
|
|
187
410
|
try {
|
|
188
411
|
this.validate(options);
|
|
189
|
-
|
|
190
|
-
if (options.
|
|
412
|
+
// In recent mode, keywords are ignored - just show recent entries
|
|
413
|
+
if (options.recent) {
|
|
191
414
|
try {
|
|
192
415
|
this.lastResult = await this.find(options);
|
|
193
416
|
let list = this.formatList(this.lastResult, options);
|
|
@@ -203,7 +426,26 @@ class Find extends require("../Command") {
|
|
|
203
426
|
this.Logger.red(e.message);
|
|
204
427
|
}
|
|
205
428
|
} else {
|
|
206
|
-
|
|
429
|
+
// Regular find mode requires keywords
|
|
430
|
+
options.name = options.keywords;
|
|
431
|
+
if (options.name) {
|
|
432
|
+
try {
|
|
433
|
+
this.lastResult = await this.find(options);
|
|
434
|
+
let list = this.formatList(this.lastResult, options);
|
|
435
|
+
if (list && list.length) {
|
|
436
|
+
this.Logger.grey(
|
|
437
|
+
`${list.length} result${list.length > 1 ? "s" : ""} found:`
|
|
438
|
+
);
|
|
439
|
+
for (let l of list) this.Logger.reset(l);
|
|
440
|
+
} else {
|
|
441
|
+
this.Logger.grey("No results.");
|
|
442
|
+
}
|
|
443
|
+
} catch (e) {
|
|
444
|
+
this.Logger.red(e.message);
|
|
445
|
+
}
|
|
446
|
+
} else {
|
|
447
|
+
this.Logger.grey("Missing parameters");
|
|
448
|
+
}
|
|
207
449
|
}
|
|
208
450
|
} catch (e) {
|
|
209
451
|
this.Logger.red(e.message);
|
package/src/commands/Git.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
const chalk = require("chalk");
|
|
2
|
-
const { yamlStringify } = require("@secrez/utils");
|
|
2
|
+
const { yamlStringify, execAsync } = require("@secrez/utils");
|
|
3
3
|
|
|
4
4
|
class Git extends require("../Command") {
|
|
5
5
|
setHelpAndCompletion() {
|
|
@@ -19,13 +19,26 @@ class Git extends require("../Command") {
|
|
|
19
19
|
alias: "s",
|
|
20
20
|
type: Boolean,
|
|
21
21
|
},
|
|
22
|
+
{
|
|
23
|
+
name: "push",
|
|
24
|
+
alias: "p",
|
|
25
|
+
type: Boolean,
|
|
26
|
+
},
|
|
22
27
|
];
|
|
23
28
|
}
|
|
24
29
|
|
|
25
30
|
help() {
|
|
26
31
|
return {
|
|
27
|
-
description: [
|
|
28
|
-
|
|
32
|
+
description: [
|
|
33
|
+
"Check a git repository status or push current changes and update the fingerprint.",
|
|
34
|
+
],
|
|
35
|
+
examples: [
|
|
36
|
+
["git -s", "Check the git repository status"],
|
|
37
|
+
[
|
|
38
|
+
"git -p",
|
|
39
|
+
"Stage, commit (if needed), push changes, and update the fingerprint",
|
|
40
|
+
],
|
|
41
|
+
],
|
|
29
42
|
};
|
|
30
43
|
}
|
|
31
44
|
|
|
@@ -40,6 +53,46 @@ class Git extends require("../Command") {
|
|
|
40
53
|
return chalk.yellow(warning);
|
|
41
54
|
} else return "No remote changes found.";
|
|
42
55
|
}
|
|
56
|
+
if (options.push) {
|
|
57
|
+
const containerPath = this.secrez.config.container;
|
|
58
|
+
// Get current status to know what to do
|
|
59
|
+
const status = await this.internalFs.gitConflictChecker.getGitStatus();
|
|
60
|
+
if (status && status.error) {
|
|
61
|
+
return chalk.red(`Git status error: ${status.error}`);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// No changes and not ahead: nothing to push
|
|
65
|
+
if ((status?.uncommitted || 0) === 0 && (status?.ahead || 0) === 0) {
|
|
66
|
+
return "No changes in the repository";
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// If there are uncommitted changes, stage and commit
|
|
70
|
+
if (status && status.uncommitted > 0) {
|
|
71
|
+
const addRes = await execAsync("git", containerPath, ["add", "-A"]);
|
|
72
|
+
if (addRes && addRes.error) {
|
|
73
|
+
return chalk.red(`git add failed: ${addRes.error}`);
|
|
74
|
+
}
|
|
75
|
+
const commitRes = await execAsync("git", containerPath, [
|
|
76
|
+
"commit",
|
|
77
|
+
"-m",
|
|
78
|
+
"Secrez: save changes",
|
|
79
|
+
]);
|
|
80
|
+
if (commitRes && commitRes.error) {
|
|
81
|
+
return chalk.red(`git commit failed: ${commitRes.error}`);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// Try to push (even if there were no new commits but local might be ahead)
|
|
86
|
+
const pushRes = await execAsync("git", containerPath, ["push"]);
|
|
87
|
+
if (pushRes && pushRes.error) {
|
|
88
|
+
return chalk.red(`git push failed: ${pushRes.error}`);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// Update the initial fingerprint so Secrez won't block further operations in this session
|
|
92
|
+
await this.internalFs.gitConflictChecker.captureInitialState();
|
|
93
|
+
|
|
94
|
+
return "Pushed successfully. Fingerprint updated.";
|
|
95
|
+
}
|
|
43
96
|
} else {
|
|
44
97
|
return "Not a git repository";
|
|
45
98
|
}
|