snowbase 5.1.0 → 6.0.1

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/CHANGELOG.md ADDED
@@ -0,0 +1,34 @@
1
+ # Changelog
2
+
3
+ ## [6.0.0] - 2026-07-XX
4
+
5
+ ### Added
6
+
7
+ - Added a cache layer to avoid repeated reads from disk and improve response times.
8
+ - Added cache validation based on file modification time and file size.
9
+ - Added support for a custom backup directory.
10
+ - Added an async version of the database for non-blocking operations.
11
+ - Added optional encryption support for stored data.
12
+ - Added backup versioning with filenames following the pattern backup_YYYY-MM-DD_HH-MM-SS-XXXXX.json.
13
+ - Added a CLI with commands for init, inspect, backup, restore, clear, get, set, remove, and has.
14
+ - Added richer database operations such as set, save, get, remove, clear, all, has, count, and find.
15
+ - Added event-based lifecycle support with ready and error events.
16
+ - Added operation events for get, set, remove, clear, writes, and backup creation.
17
+
18
+ ### Changed
19
+
20
+ - Reworked the storage layer to support persistence, backup, logging, and encryption in a more structured way.
21
+ - Improved initialization so the base directory, backup directory, log directory, and database file are created automatically when missing.
22
+ - Standardized backup and logging behavior to be configurable through constructor options.
23
+ - The keys are now saved in alphabetic order.
24
+
25
+ ### Fixed
26
+
27
+ - Fixed issues that caused repeated file reads when the database directory changed or the file state was updated.
28
+ - Fixed backup handling to keep the backup folder organized and avoid excessive backup accumulation.
29
+ - Improved validation to reject invalid database root structures.
30
+
31
+ ### Performance Improvements
32
+
33
+ - Reduced unnecessary disk I/O by reusing cached data until the underlying file changes.
34
+ - Improved write and backup flow for faster and more predictable persistence operations.
package/LICENSE ADDED
@@ -0,0 +1,7 @@
1
+ Copyright © 2026 Pedro Henrique Brandão (p3droob)
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4
+
5
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6
+
7
+ THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
package/README.md CHANGED
@@ -1,31 +1,229 @@
1
- # Snowbase ❄️
2
-
3
- ## Overview
4
- - #### [Alpha Discord](https://www.npmjs.com/package/alpha-discord) - A library for interact with discord [API](https://discord.com/api) on js
5
- - ## Server
6
- ```js
7
- const snowbase = require('snowbase');
8
-
9
- const db = new snowbase.Server({
10
- login: 'Your account login of snowbase',
11
- password: 'Your password'
12
- });
13
- db.save('value1', 150)//emits valueUpdate event: key, {old: old_value, new: new_value}
14
-
15
- db.get('value1')//150
16
-
17
- db.remove('value1')//emits valueDelete event: key, deleted_value
18
- ```
19
-
20
- - ## Local
21
- ```js
22
- const db = new snowbase.Local('./database.json')//or other file
23
-
24
- db.save('value2', 100)
25
-
26
- db.get('value2')//100
27
-
28
- db.all(a => a == 100)//filter
29
-
30
- db.remove('value2')
31
- ```
1
+ <div align="center">
2
+ <h1>Snowbase ❄️</h1>
3
+ <br>
4
+ <img src="./img/snowbase-logo.png" alt="Snowbase logo" width="200" height="200" style="border-radius:35%;border: 4px solid #e7e9ebff;"/>
5
+ <p>A lightweight file-based database for Node.js</p>
6
+ <a href="https://www.npmjs.com/package/snowbase">
7
+ <img src="https://img.shields.io/npm/v/snowbase?color=blue" alt="Current version"/>
8
+ </a>
9
+ <a href="https://www.npmjs.com/package/snowbase">
10
+ <img
11
+ src="https://packagephobia.com/badge?p=snowbase@6.0.0"
12
+ alt="install size">
13
+ </a>
14
+ <a href="https://www.npmjs.com/package/snowbase">
15
+ <img src="https://img.shields.io/npm/dt/snowbase?color=darkcyan" alt="npm downloads"/>
16
+ </a>
17
+ <img src="https://img.shields.io/npm/l/snowbase" alt="license"/>
18
+ <br>
19
+ <b>Simple.</b> <b>Fast.</b> <b>Persistent.</b>
20
+ </div>
21
+
22
+ ---
23
+
24
+ - [Overview](#overview)
25
+ - [Features](#features)
26
+ - [Installation](#installation)
27
+ - [Usage](#usage)
28
+ - [Configuration](#configuration)
29
+ - [Events](#events)
30
+ - [Async API](#async-api)
31
+ - [CLI](#cli)
32
+ - [License](#license)
33
+
34
+ ## Overview
35
+
36
+ Snowbase is a simple, fast, and persistent file-based database for Node.js.
37
+ It creates and manages a local JSON file to store your data safely, making it perfect for lightweight applications, prototypes, scripts, and small tools.
38
+
39
+ No servers. No complex setup. Just storage.
40
+
41
+ ## ✨ Features
42
+
43
+ - ⚡ Lightweight and easy to use
44
+ - 📦 File-based persistence with no external database required
45
+ - 🔐 Optional encryption for stored data
46
+ - 🧾 Optional logging for operations
47
+ - 💾 Automatic backups with versioned files
48
+ - ⚙️ Supports both sync and async APIs
49
+ - 🧩 Works well for prototypes, local apps, and small projects
50
+
51
+ ## 📥 Installation
52
+
53
+ ```bash
54
+ npm install snowbase
55
+ ```
56
+
57
+ ## Usage
58
+
59
+ ### CommonJS
60
+
61
+ ```js
62
+ const Snowbase = require("snowbase");
63
+
64
+ const db = new Snowbase();
65
+
66
+ db.on("ready", () => {
67
+ console.log("Database is ready");
68
+ });
69
+ ```
70
+
71
+ ### ES Modules
72
+
73
+ ```js
74
+ import Snowbase from "snowbase";
75
+
76
+ const db = new Snowbase();
77
+
78
+ db.on("ready", () => {
79
+ console.log("Database is ready");
80
+ });
81
+
82
+ //Multiples database
83
+ const db1 = new Snowbase({ baseDir: "storage" });
84
+ const db2 = new Snowbase({ baseDir: "database" }); // creates an isolated new Snowbase storage
85
+ // You need to specify the baseDir if use the CLI
86
+ ```
87
+
88
+ ### Basic operations
89
+
90
+ ```js
91
+ // Set a value
92
+ db.set("user/name", "Pedro");
93
+
94
+ // Get a value
95
+ console.log(db.get("user/name")); // Pedro
96
+
97
+ // Remove a value
98
+ db.remove("user/name");
99
+
100
+ // Clear the whole database
101
+ db.clear();
102
+ ```
103
+
104
+ ## Configuration
105
+
106
+ You can configure Snowbase during initialization:
107
+
108
+ ```js
109
+ const db = new Snowbase({
110
+ baseDir: "./my-database",
111
+ encryption: true,
112
+ secret: "my-secret",
113
+ logging: true,
114
+ backup: true,
115
+ });
116
+ ```
117
+
118
+ ### Options
119
+
120
+ - baseDir: directory where the database file will be stored
121
+ - encryption: enables encrypted persistence
122
+ - secret: secret key used when encryption is enabled
123
+ - logging: enables operation logging
124
+ - backup: enables automatic backups
125
+
126
+ ## Advanced examples
127
+
128
+ ### Set and save nested data
129
+
130
+ ```js
131
+ db.set("patients", {
132
+ john: {
133
+ age: 20,
134
+ name: "John",
135
+ city: "New York",
136
+ },
137
+ albert: {
138
+ age: 31,
139
+ name: "Albert",
140
+ city: "Chicago",
141
+ },
142
+ });
143
+ ```
144
+
145
+ ### Read and query data
146
+
147
+ ```js
148
+ console.log(db.get("patients/john/city")); // New York
149
+ console.log(db.has("patients/albert")); // true
150
+ console.log(db.count("patients")); // 2
151
+ ```
152
+
153
+ ### Find and remove
154
+
155
+ ```js
156
+ const result = db.find("patients", ({ key }) => key.includes("a"));
157
+ console.log(result);
158
+
159
+ db.remove("patients/albert"); // true
160
+ db.remove("patients/susy"); // false
161
+ ```
162
+
163
+ ## Events
164
+
165
+ Snowbase can emit events for lifecycle and database operations. You can listen to them with the standard EventEmitter API.
166
+
167
+ ```js
168
+ const db = new Snowbase();
169
+
170
+ db.on("ready", () => {
171
+ console.log("Database is ready");
172
+ });
173
+
174
+ db.on("error", (err) => {
175
+ console.error(err.message);
176
+ });
177
+
178
+ db.on("get", (details, timestamp) => {
179
+ console.log("Get event", details, timestamp);
180
+ });
181
+ ```
182
+
183
+ ### Available events
184
+
185
+ - ready: emitted when the database instance is initialized
186
+ - error: emitted when an error occurs; receives an Error object
187
+ - get: emitted after a read operation; payload includes the path and the resolved value
188
+ - set: emitted after a write operation; payload includes the path, key, and value
189
+ - remove: emitted after a remove operation; payload includes the path, removed value, and whether it was removed
190
+ - clear: emitted after clearing the database; payload includes the previous data
191
+ - \_write: emitted after data is written to disk
192
+ - create backup: emitted when a backup file is created
193
+
194
+ ## Async API
195
+
196
+ For non-blocking operations, use the async version:
197
+
198
+ ```js
199
+ import Snowbase from "snowbase/async";
200
+
201
+ const db = new Snowbase({
202
+ encryption: true,
203
+ secret: "my-secret",
204
+ backup: true,
205
+ });
206
+
207
+ await db.set("user/name", "Pedro");
208
+ console.log(await db.get("user/name"));
209
+ ```
210
+
211
+ ## CLI
212
+
213
+ Snowbase also includes a CLI for common tasks:
214
+
215
+ ```bash
216
+ snowbase init
217
+ snowbase inspect
218
+ snowbase backup
219
+ snowbase restore
220
+ snowbase get user/name
221
+ snowbase set user/name Pedro
222
+ snowbase remove user/name
223
+ snowbase clear
224
+ snowbase has
225
+ ```
226
+
227
+ ## License
228
+
229
+ MIT
@@ -0,0 +1,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 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
+ }
package/package.json CHANGED
@@ -1,24 +1,58 @@
1
1
  {
2
2
  "name": "snowbase",
3
- "version": "5.1.0",
4
- "description": "Local and Global Server database using json",
5
- "main": "index.js",
6
- "dependencies": {
7
- "node-fetch": "^2.6.1"
8
- },
9
- "devDependencies": {},
10
- "scripts": {
11
- "test": "echo \"Error: no test specified\" && exit 1"
12
- },
13
- "keywords": [],
14
- "author": "mr.frozenfire",
15
- "license": "ISC",
3
+ "version": "6.0.1",
4
+ "description": "A lightweight local JSON database for modern JavaScript projects.",
5
+ "keywords": [
6
+ "file-database",
7
+ "local storage",
8
+ "database",
9
+ "json",
10
+ "crypto",
11
+ "lightweight",
12
+ "db"
13
+ ],
14
+ "homepage": "https://github.com/p3droob/snowbase#readme",
16
15
  "repository": {
17
16
  "type": "git",
18
- "url": "git+https://github.com/FrozenFireBR/snowbase.git"
17
+ "url": "https://github.com/p3droob/snowbase"
19
18
  },
20
19
  "bugs": {
21
- "url": "https://github.com/FrozenFireBR/snowbase/issues"
20
+ "url": "https://github.com/p3droob/snowbase/issues"
21
+ },
22
+ "license": "MIT",
23
+ "author": "p3droob",
24
+ "main": "./src/Snowbase.js",
25
+ "type": "module",
26
+ "exports": {
27
+ ".": "./src/Snowbase.js",
28
+ "./async": "./src/SnowbaseAsync.js"
29
+ },
30
+ "bin": {
31
+ "snowbase": "./bin/snowbase.js"
22
32
  },
23
- "homepage": "https://github.com/FrozenFireBR/snowbase#readme"
33
+ "files": [
34
+ "src",
35
+ "bin",
36
+ "README.md",
37
+ "LICENSE",
38
+ "CHANGELOG.md"
39
+ ],
40
+ "scripts": {
41
+ "build": "tsc",
42
+ "dev": "tsc --watch",
43
+ "typecheck": "tsc --noEmit",
44
+ "test": "node test/index.js",
45
+ "test:comprehensive": "node test/comprehensive.js",
46
+ "test:async": "node test/indexAsync.js"
47
+ },
48
+ "engines": {
49
+ "node": ">=16"
50
+ },
51
+ "devDependencies": {
52
+ "@types/node": "^26.0.1",
53
+ "typescript": "^6.0.3"
54
+ },
55
+ "dependencies": {
56
+ "chalk": "^5.6.2"
57
+ }
24
58
  }