snowbase 6.0.2 → 6.0.5

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/bin/snowbase.js CHANGED
@@ -1,315 +1,286 @@
1
- #!/usr/bin/env node
2
- import Snowbase from "../src/Snowbase.js";
3
- import fs from "fs";
4
- import path from "path";
5
- import chalk from "chalk";
6
-
7
- const args = process.argv.slice(2);
8
- const cmd = args[0];
9
- function levenshtein(a, b) {
10
- const matrix = Array.from({ length: b.length + 1 }, (_, i) => [i]);
11
-
12
- for (let j = 0; j <= a.length; j++) matrix[0][j] = j;
13
-
14
- for (let i = 1; i <= b.length; i++) {
15
- for (let j = 1; j <= a.length; j++) {
16
- matrix[i][j] =
17
- b[i - 1] === a[j - 1]
18
- ? matrix[i - 1][j - 1]
19
- : Math.min(
20
- matrix[i - 1][j] + 1,
21
- matrix[i][j - 1] + 1,
22
- matrix[i - 1][j - 1] + 1,
23
- );
24
- }
25
- }
26
-
27
- return matrix[b.length][a.length];
28
- }
29
-
30
- function suggestCommand(input, commands) {
31
- let best = null;
32
- let distance = Infinity;
33
-
34
- for (const command of commands) {
35
- const d = levenshtein(input, command);
36
-
37
- if (d < distance) {
38
- distance = d;
39
- best = command;
40
- }
41
- }
42
-
43
- return distance <= 3 ? best : null;
44
- }
45
-
46
- let helpMessage = `
47
- ${chalk.bold("SNOWBASE COMMANDS")}
48
- ${chalk.blue("init")} Load the directory and create the database file
49
-
50
- ${chalk.blue("inspect")} Inspect the database file
51
-
52
- ${chalk.blue("backup")} Creates a backup of the database file
53
-
54
- ${chalk.blue("restore")} Restore the database file
55
-
56
- ${chalk.blue("clear")} Clear the database file
57
-
58
- ${chalk.blue("get")} Get the value of a key
59
-
60
- ${chalk.blue("set")} Set the value of a key
61
-
62
- ${chalk.blue("remove")} Remove a key from the database
63
-
64
- ${chalk.blue("has")} Check if a key exists in the database
65
-
66
- ============================================================
67
- ${chalk.bold("COMPILER OPTION")}
68
-
69
- ${chalk.blue("--baseDir")} The directory where the database is located. Default: ./snowbase
70
-
71
- ${chalk.blue("--encryption")} Enables encryption. Default: false
72
-
73
- ${chalk.blue("--secret")} The secret key for encryption. Default: ""
74
-
75
- ${chalk.blue("--logging")} Enables logging. Default: false
76
-
77
- ${chalk.blue("--backup")} Enables backup. Default: false
78
-
79
- ${chalk.blue("--restoreFile")} The backup file to restore. Default: ""
80
-
81
- ${chalk.bold("EXAMPLE")}
82
- ${chalk.yellow('snowbase init --baseDir "./snowbase" --encryption --secret "mysecret" --logging --backup')}
83
- `;
84
- if (!cmd) {
85
- console.log(helpMessage);
86
- }
87
-
88
- const commands = [
89
- "init",
90
- "inspect",
91
- "backup",
92
- "restore",
93
- "clear",
94
- "get",
95
- "set",
96
- "remove",
97
- "has",
98
- ];
99
- if (cmd) {
100
- let config = {
101
- baseDir: "./snowbase",
102
- encryption: false,
103
- secret: "",
104
- logging: false,
105
- backup: false,
106
- };
107
- for (let i = 1; i < args.length; i++) {
108
- const arg = args[i];
109
-
110
- if (!arg.startsWith("--")) continue;
111
-
112
- const key = arg.slice(2);
113
-
114
- if (i + 1 < args.length && !args[i + 1].startsWith("--")) {
115
- config[key] = args[++i];
116
- } else {
117
- config[key] = true;
118
- }
119
- }
120
- const db = new Snowbase(config);
121
-
122
- switch (cmd) {
123
- default: {
124
- console.log(helpMessage);
125
- const suggestion = suggestCommand(cmd, commands);
126
- if (suggestion) {
127
- console.log(`Did you mean ${chalk.blue(suggestion)}?`);
128
- }
129
- break;
130
- }
131
-
132
- case "init": {
133
- console.log(`Snowbase initialized at ${db.baseDir}`);
134
- console.log(db.backupDir);
135
- break;
136
- }
137
- case "inspect": {
138
- const all = db.get();
139
- let keys = Object.keys(all || {});
140
- let d = 0;
141
- if (
142
- keys.length === 4 &&
143
- keys.sort().every((v, i) => v === ["data", "iv", "salt", "tag"][i])
144
- ) {
145
- d = 1;
146
- console.log(chalk.blue("Database is encrypted, wait..."));
147
- try {
148
- keys = Object.keys(db._decrypt(JSON.stringify(all), config.secret));
149
- } catch (error) {
150
- d = -1;
151
- }
152
- }
153
- if (d === 1)
154
- console.log(chalk.greenBright("Database decrypted successfully"));
155
- if (d > -1) {
156
- console.log(`Number of keys: ${keys.length}`);
157
- console.log("Keys:", keys);
158
- console.log("Size of database:", JSON.stringify(all).length, " bytes");
159
- } else
160
- console.log(
161
- chalk.red("Decryption failed, please provide a valid secret"),
162
- );
163
- break;
164
- }
165
-
166
- case "backup": {
167
- const backupFile = db.storage.createBackup();
168
- if (!backupFile)
169
- console.log(
170
- chalk.red(
171
- "You need to use --backup flag and must have a backup directory",
172
- ),
173
- );
174
- else console.log(`Backup created at ${backupFile}`);
175
- break;
176
- }
177
-
178
- case "restore": {
179
- if (!config.restoreFile) {
180
- console.log(
181
- "Usage: snowbase restore --secret <secret, only if needed> --restoreFile <backup-ID>",
182
- );
183
- console.log(
184
- "Example: snowbase restore --secret mysecret123 --restoreFile 2026-06-27T14-30-45-123Z-asf3k",
185
- );
186
- break;
187
- }
188
- const backupFile = path.join(
189
- db.storage.backupDir || "./snowbase/backups",
190
- `backup_${config.restoreFile}.json`,
191
- );
192
- if (fs.existsSync(backupFile)) {
193
- let fileData = fs.readFileSync(backupFile, "utf8");
194
- fileData = JSON.parse(fileData);
195
- let keys = Object.keys(fileData || {});
196
- let d = 0;
197
- if (
198
- keys.length === 4 &&
199
- keys.sort().every((v, i) => v === ["data", "iv", "salt", "tag"][i])
200
- ) {
201
- d++;
202
- console.log(chalk.blue("Database is encrypted, wait..."));
203
- try {
204
- fileData = db._decrypt(JSON.stringify(fileData), config.secret);
205
- } catch (error) {
206
- d = -1;
207
- }
208
- }
209
- if (d === 1)
210
- console.log(chalk.greenBright("Database decrypted successfully"));
211
- if (d > -1) {
212
- const backupDataRestore = JSON.parse(
213
- fs.readFileSync(backupFile, "utf8"),
214
- );
215
-
216
- fs.mkdirSync(db.storage.baseDir, { recursive: true });
217
- fs.writeFileSync(
218
- path.join(db.storage.baseDir, "snowbase.json"),
219
- JSON.stringify(backupDataRestore),
220
- );
221
- db.storage._cache = backupDataRestore;
222
- db.storage._cacheMtime = fs.statSync(backupFile).mtimeMs;
223
- db.storage._cacheSize = fs.statSync(backupFile).size;
224
- console.log(`Database restored from ${backupFile}`);
225
- } else
226
- console.log(
227
- chalk.red("Decryption failed, please provide a valid secret"),
228
- "Example: snowbase restore --secret <secret> --restoreFile <backup-ID>",
229
- );
230
- } else {
231
- console.log(
232
- chalk.red(
233
- `Backup file ${backupFile} does not exist. Check the backup ID or if the dir exists`,
234
- ),
235
- );
236
- }
237
- break;
238
- }
239
-
240
- case "clear": {
241
- let all = db.get();
242
- let keys = Object.keys(all || {});
243
- let d = 0;
244
- if (
245
- keys.length === 4 &&
246
- keys.sort().every((v, i) => v === ["data", "iv", "salt", "tag"][i])
247
- ) {
248
- d = 1;
249
- console.log(chalk.blue("Database is encrypted, wait..."));
250
- try {
251
- all = db._decrypt(JSON.stringify(all), config.secret);
252
- } catch (error) {
253
- d = -1;
254
- }
255
- }
256
- if (d === 1)
257
- console.log(chalk.greenBright("Database decrypted successfully"));
258
- if (d > -1) {
259
- db.clear();
260
- console.log("Database cleared.");
261
- } else
262
- console.log(
263
- chalk.red("Decryption failed, please provide a valid secret"),
264
- );
265
- break;
266
- }
267
-
268
- case "get": {
269
- let all = db.get();
270
- let keys = Object.keys(all || {});
271
- let d = 0;
272
- if (
273
- keys.length === 4 &&
274
- keys.sort().every((v, i) => v === ["data", "iv", "salt", "tag"][i])
275
- ) {
276
- d = 1;
277
- console.log(chalk.blue("Database is encrypted, wait..."));
278
- try {
279
- all = db._decrypt(JSON.stringify(all), config.secret);
280
- } catch (error) {
281
- d = -1;
282
- }
283
- }
284
- if (d === 1)
285
- console.log(chalk.greenBright("Database decrypted successfully"));
286
- if (d > -1) {
287
- if (!config.key) console.log(all);
288
- else console.log(db._getTargetFromData(all, config.key));
289
- } else
290
- console.log(
291
- chalk.red("Decryption failed, please provide a valid secret"),
292
- );
293
- break;
294
- }
295
-
296
- case "set": {
297
- if (!config.key) console.log(db.get());
298
- else console.log(db.get(config.key));
299
- break;
300
- }
301
-
302
- case "remove": {
303
- let run = db.remove(config.key);
304
- if (run) console.log(chalk.green("Value removed successfully"));
305
- else console.log(chalk.red("Value not removed"));
306
- break;
307
- }
308
-
309
- case "has": {
310
- let run = db.has(config.key);
311
- console.log(run);
312
- break;
313
- }
314
- }
315
- }
1
+ #!/usr/bin/env node
2
+ import Snowbase from "../src/Snowbase.js";
3
+ import fs from "fs";
4
+ import path from "path";
5
+ import chalk from "chalk";
6
+
7
+ const args = process.argv.slice(2);
8
+ const cmd = args[0];
9
+ function levenshtein(a, b) {
10
+ const matrix = Array.from({ length: b.length + 1 }, (_, i) => [i]);
11
+
12
+ for (let j = 0; j <= a.length; j++) matrix[0][j] = j;
13
+
14
+ for (let i = 1; i <= b.length; i++) {
15
+ for (let j = 1; j <= a.length; j++) {
16
+ matrix[i][j] =
17
+ b[i - 1] === a[j - 1]
18
+ ? matrix[i - 1][j - 1]
19
+ : Math.min(
20
+ matrix[i - 1][j] + 1,
21
+ matrix[i][j - 1] + 1,
22
+ matrix[i - 1][j - 1] + 1,
23
+ );
24
+ }
25
+ }
26
+
27
+ return matrix[b.length][a.length];
28
+ }
29
+
30
+ function suggestCommand(input, commands) {
31
+ let best = null;
32
+ let distance = Infinity;
33
+
34
+ for (const command of commands) {
35
+ const d = levenshtein(input, command);
36
+
37
+ if (d < distance) {
38
+ distance = d;
39
+ best = command;
40
+ }
41
+ }
42
+
43
+ return distance <= 3 ? best : null;
44
+ }
45
+
46
+ let helpMessage = `
47
+ ${chalk.bold("SNOWBASE COMMANDS")}
48
+ ${chalk.blue("init")} Load the directory and create the database file
49
+
50
+ ${chalk.blue("inspect")} Inspect the database file
51
+
52
+ ${chalk.blue("backup")} Creates a backup of the database file
53
+
54
+ ${chalk.blue("restore")} Restore the database file
55
+
56
+ ${chalk.blue("clear")} Clear the database file
57
+
58
+ ${chalk.blue("get")} Get the value of a key
59
+
60
+ ${chalk.blue("set")} Set the value of a key
61
+
62
+ ${chalk.blue("remove")} Remove a key from the database
63
+
64
+ ${chalk.blue("has")} Check if a key exists in the database
65
+
66
+ ============================================================
67
+ ${chalk.bold("COMPILER OPTIONS")}
68
+
69
+ ${chalk.blue("--baseDir")} The directory where the database is located. Default: ./snowbase
70
+
71
+ ${chalk.blue("--encryption")} Enables encryption. Default: false
72
+
73
+ ${chalk.blue("--secret")} The secret key for encryption. Default: ""
74
+
75
+ ${chalk.blue("--logging")} Enables logging. Default: false
76
+
77
+ ${chalk.blue("--backup")} Enables backup. Default: false
78
+
79
+ ${chalk.blue("--restoreFile")} The backup file to restore. Default: ""
80
+
81
+ ${chalk.blue("--path")} The path to get value. Default: undefined
82
+
83
+ ${chalk.blue("--value")} The value to set. Default: undefined
84
+
85
+ ${chalk.bold("EXAMPLE")}
86
+ ${chalk.yellow('snowbase init --baseDir "./snowbase" --encryption --secret "mysecret" --logging --backup')}
87
+ `;
88
+ if (!cmd) {
89
+ console.log(helpMessage);
90
+ }
91
+
92
+ const commands = [
93
+ "init",
94
+ "inspect",
95
+ "backup",
96
+ "restore",
97
+ "clear",
98
+ "get",
99
+ "set",
100
+ "remove",
101
+ "has",
102
+ ];
103
+ if (cmd && commands.includes((cmd || "").toLocaleLowerCase())) {
104
+ let config = {
105
+ baseDir: "./snowbase",
106
+ encryption: false,
107
+ secret: "",
108
+ logging: false,
109
+ backup: false,
110
+ };
111
+ for (let i = 1; i < args.length; i++) {
112
+ const arg = args[i];
113
+
114
+ if (!arg.startsWith("--")) continue;
115
+
116
+ const key = arg.slice(2);
117
+
118
+ if (i + 1 < args.length && !args[i + 1].startsWith("--")) {
119
+ config[key] = args[++i];
120
+ } else {
121
+ config[key] = true;
122
+ }
123
+ }
124
+ let db = new Snowbase(config);
125
+
126
+ let all = db.get();
127
+ let keys = Object.keys(all || {});
128
+ let d = 0; //default
129
+ if (
130
+ keys.length === 4 &&
131
+ keys.sort().every((v, i) => v === ["data", "iv", "salt", "tag"][i])
132
+ ) {
133
+ d = 1; //encrypted/decrypted
134
+ console.log(chalk.blue("Database is encrypted, wait..."));
135
+ try {
136
+ all = db._decrypt(JSON.stringify(all), config.secret);
137
+ } catch (error) {
138
+ d = -1; //decryption failed
139
+ }
140
+ }
141
+ if (d === 1)
142
+ console.log(chalk.greenBright("Database decrypted successfully"));
143
+ if (d === 1) db = new Snowbase({ ...config, encryption: true }); //recreate db to avoid decryption issues
144
+ if (d === -1)
145
+ console.log(chalk.red("Decryption failed, please provide a valid secret"));
146
+
147
+ switch (cmd) {
148
+ case "init": {
149
+ console.log(`Snowbase initialized at ${db.baseDir}`);
150
+ console.log(db.backupDir);
151
+ break;
152
+ }
153
+ case "inspect": {
154
+ if (d > -1) {
155
+ console.log(`Number of keys: ${keys.length}`);
156
+ console.log("Keys:", keys);
157
+ console.log("Size of database:", JSON.stringify(all).length, " bytes");
158
+ }
159
+ break;
160
+ }
161
+
162
+ case "backup": {
163
+ const backupFile = db.storage.createBackup();
164
+ if (!backupFile)
165
+ console.log(
166
+ chalk.red(
167
+ "You need to use --backup flag and must have a backup directory",
168
+ ),
169
+ );
170
+ else console.log(`Backup created at ${backupFile}`);
171
+ break;
172
+ }
173
+
174
+ case "restore": {
175
+ if (!config.restoreFile) {
176
+ console.log(
177
+ "Usage: snowbase restore --secret <secret, only if needed> --restoreFile <backup-ID>",
178
+ );
179
+ console.log(
180
+ "Example: snowbase restore --secret mysecret123 --restoreFile 2026-06-27T14-30-45-123Z-asf3k",
181
+ );
182
+ break;
183
+ }
184
+ const backupFile = path.join(
185
+ db.storage.backupDir || "./snowbase/backups",
186
+ `backup_${config.restoreFile}.json`,
187
+ );
188
+ if (fs.existsSync(backupFile)) {
189
+ let fileData = fs.readFileSync(backupFile, "utf8");
190
+ fileData = JSON.parse(fileData);
191
+ keys = Object.keys(fileData || {});
192
+ let d = 0;
193
+ if (
194
+ keys.length === 4 &&
195
+ keys.sort().every((v, i) => v === ["data", "iv", "salt", "tag"][i])
196
+ ) {
197
+ d++;
198
+ console.log(chalk.blue("Database is encrypted, wait..."));
199
+ try {
200
+ fileData = db._decrypt(JSON.stringify(fileData), config.secret);
201
+ } catch (error) {
202
+ d = -1;
203
+ }
204
+ }
205
+ if (d === 1)
206
+ console.log(chalk.greenBright("Database decrypted successfully"));
207
+ if (d > -1) {
208
+ const backupDataRestore = JSON.parse(
209
+ fs.readFileSync(backupFile, "utf8"),
210
+ );
211
+
212
+ fs.mkdirSync(db.storage.baseDir, { recursive: true });
213
+ fs.writeFileSync(
214
+ path.join(db.storage.baseDir, "snowbase.json"),
215
+ JSON.stringify(backupDataRestore),
216
+ );
217
+ db.storage._cache = backupDataRestore;
218
+ db.storage._cacheMtime = fs.statSync(backupFile).mtimeMs;
219
+ db.storage._cacheSize = fs.statSync(backupFile).size;
220
+ console.log(`Database restored from ${backupFile}`);
221
+ } else
222
+ console.log(
223
+ chalk.red("Decryption failed, please provide a valid secret"),
224
+ "Example: snowbase restore --secret <secret> --restoreFile <backup-ID>",
225
+ );
226
+ } else {
227
+ console.log(
228
+ chalk.red(
229
+ `Backup file ${backupFile} does not exist. Check the backup ID or if the dir exists`,
230
+ ),
231
+ );
232
+ }
233
+ break;
234
+ }
235
+
236
+ case "clear": {
237
+ if (d > -1) {
238
+ db.clear();
239
+ console.log("Database cleared.");
240
+ }
241
+ break;
242
+ }
243
+
244
+ case "get": {
245
+ if (d > -1) {
246
+ if (!config.path) console.log(all);
247
+ else console.log(db._getTargetFromData(all, config.path));
248
+ }
249
+ break;
250
+ }
251
+
252
+ case "set": {
253
+ if (d > -1) {
254
+ console.log(db.set(config.path, config.value));
255
+ }
256
+ break;
257
+ }
258
+
259
+ case "remove": {
260
+ if (d > -1) {
261
+ let run = db.remove(config.path);
262
+ if (run) console.log(chalk.green("Value removed successfully"));
263
+ else
264
+ console.log(
265
+ chalk.red("Value not removed"),
266
+ "Check if the path exists",
267
+ );
268
+ }
269
+ break;
270
+ }
271
+
272
+ case "has": {
273
+ if (d > -1) {
274
+ let run = db._getTargetFromData(all, config.path) !== undefined;
275
+ console.log(run);
276
+ }
277
+ break;
278
+ }
279
+ }
280
+ } else if (cmd && !commands.includes((cmd || "").toLocaleLowerCase())) {
281
+ console.log(helpMessage);
282
+ const suggestion = suggestCommand(cmd, commands);
283
+ if (suggestion) {
284
+ console.log(`Did you mean ${chalk.blue(suggestion)}?`);
285
+ }
286
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "snowbase",
3
- "version": "6.0.2",
3
+ "version": "6.0.5",
4
4
  "description": "A lightweight local JSON database for modern JavaScript projects.",
5
5
  "keywords": [
6
6
  "file-database",
@@ -40,7 +40,7 @@
40
40
  "scripts": {
41
41
  "build": "tsc",
42
42
  "dev": "tsc --watch",
43
- "typecheck": "tsc --noEmit",
43
+ "typecheck": "tsc --noEmit -p jsconfig.json && echo Typecheck OK",
44
44
  "test": "node test/index.js",
45
45
  "test:comprehensive": "node test/comprehensive.js",
46
46
  "test:async": "node test/indexAsync.js"