keyv-dir-store 0.0.8 → 0.1.0
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 +191 -21
- package/dist/index.js +32 -9
- package/index.ts +35 -12
- package/package.json +27 -11
package/README.md
CHANGED
|
@@ -1,41 +1,211 @@
|
|
|
1
1
|
# Keyv Directory Store
|
|
2
2
|
|
|
3
|
-
High performance Filesystem Keyv Store, caches each key-value pair into a $key.json. and more!
|
|
3
|
+
High performance Filesystem Keyv Store, caches each key-value pair into a $key.json. and more! _.JSON, _.YAML, \*.CSV is also avaliable.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
[](https://www.npmjs.com/package/keyv-dir-store)
|
|
6
|
+
[](https://opensource.org/licenses/MIT)
|
|
7
|
+
|
|
8
|
+
This package provides a filesystem-based storage adapter for [Keyv](https://github.com/jaredwray/keyv), storing each key-value pair in individual files with support for various formats.
|
|
9
|
+
|
|
10
|
+
## Features
|
|
11
|
+
|
|
12
|
+
- ✅ Persistent storage using the filesystem
|
|
13
|
+
- ✅ Individual files per key-value pair
|
|
14
|
+
- ✅ Support customize serialize/deserialize, you can store your data into JSON, YAML, CSV, and TSV formats
|
|
15
|
+
- ✅ TTL (Time-To-Live) support using file modification times
|
|
16
|
+
- ✅ In-memory caching for improved performance
|
|
17
|
+
- ✅ Full compatibility with Keyv API
|
|
18
|
+
- ✅ Customizable file naming and extensions
|
|
19
|
+
|
|
20
|
+
## Installation
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
# Using npm
|
|
24
|
+
npm install keyv keyv-dir-store
|
|
25
|
+
|
|
26
|
+
# Using yarn
|
|
27
|
+
yarn add keyv keyv-dir-store
|
|
28
|
+
|
|
29
|
+
# Using pnpm
|
|
30
|
+
pnpm add keyv keyv-dir-store
|
|
31
|
+
|
|
32
|
+
# Using bun
|
|
33
|
+
bun add keyv keyv-dir-store
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Usage Examples
|
|
37
|
+
|
|
38
|
+
### Basic Usage
|
|
39
|
+
|
|
40
|
+
```ts
|
|
41
|
+
import Keyv from "keyv";
|
|
42
|
+
import { KeyvDirStore } from "keyv-dir-store";
|
|
43
|
+
|
|
44
|
+
// Default: Store each value with JSON
|
|
45
|
+
const keyv = new Keyv({
|
|
46
|
+
store: new KeyvDirStore(".cache/kv"),
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
// Set a value (never expires)
|
|
50
|
+
await keyv.set("key1", "value1");
|
|
51
|
+
|
|
52
|
+
// Set a value with TTL (expires after 1 day)
|
|
53
|
+
await keyv.set("key2", "value2", 86400000);
|
|
54
|
+
|
|
55
|
+
// Get a value
|
|
56
|
+
const value = await keyv.get("key1");
|
|
57
|
+
|
|
58
|
+
// Check if a key exists
|
|
59
|
+
const exists = await keyv.has("key1");
|
|
60
|
+
|
|
61
|
+
// Delete a key
|
|
62
|
+
await keyv.delete("key1");
|
|
63
|
+
|
|
64
|
+
// Clear all keys
|
|
65
|
+
await keyv.clear();
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### Format-Specific Examples
|
|
69
|
+
|
|
70
|
+
#### Store with JSON (using provided helper)
|
|
71
|
+
|
|
72
|
+
```ts
|
|
73
|
+
import Keyv from "keyv";
|
|
74
|
+
import { KeyvDirStore } from "keyv-dir-store";
|
|
75
|
+
import { KeyvDirStoreAsJSON } from "keyv-dir-store/KeyvDirStoreAsJSON";
|
|
76
|
+
|
|
77
|
+
const keyv = new Keyv({
|
|
78
|
+
store: new KeyvDirStore(".cache/kv", { ext: ".json" }),
|
|
79
|
+
...KeyvDirStoreAsJSON,
|
|
80
|
+
});
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
#### Store with YAML (using provided helper)
|
|
6
84
|
|
|
7
85
|
```ts
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
86
|
+
import Keyv from "keyv";
|
|
87
|
+
import { KeyvDirStore } from "keyv-dir-store";
|
|
88
|
+
import { KeyvDirStoreAsYaml } from "keyv-dir-store/KeyvDirStoreAsYaml";
|
|
89
|
+
|
|
90
|
+
const keyv = new Keyv({
|
|
91
|
+
store: new KeyvDirStore(".cache/kv", { ext: ".yaml" }),
|
|
92
|
+
...KeyvDirStoreAsYaml,
|
|
11
93
|
});
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
#### Store Object Lists with CSV
|
|
97
|
+
|
|
98
|
+
```ts
|
|
99
|
+
import Keyv from "keyv";
|
|
100
|
+
import { KeyvDirStore } from "keyv-dir-store";
|
|
101
|
+
import * as d3 from "d3";
|
|
12
102
|
|
|
13
|
-
|
|
14
|
-
new Keyv({
|
|
103
|
+
const keyv = new Keyv({
|
|
15
104
|
store: new KeyvDirStore(".cache/kv", { ext: ".csv" }),
|
|
16
105
|
serialize: ({ value }) => d3.csvFormat(value),
|
|
17
106
|
deserialize: (str) => ({ value: d3.csvParse(str), expires: undefined }),
|
|
18
107
|
});
|
|
108
|
+
```
|
|
19
109
|
|
|
20
|
-
|
|
21
|
-
|
|
110
|
+
#### Store Object Lists with TSV
|
|
111
|
+
|
|
112
|
+
```ts
|
|
113
|
+
import Keyv from "keyv";
|
|
114
|
+
import { KeyvDirStore } from "keyv-dir-store";
|
|
115
|
+
import * as d3 from "d3";
|
|
116
|
+
|
|
117
|
+
const keyv = new Keyv({
|
|
22
118
|
store: new KeyvDirStore(".cache/kv", { ext: ".tsv" }),
|
|
23
119
|
serialize: ({ value }) => d3.tsvFormat(value),
|
|
24
120
|
deserialize: (str) => ({ value: d3.tsvParse(str), expires: undefined }),
|
|
25
121
|
});
|
|
122
|
+
```
|
|
26
123
|
|
|
27
|
-
|
|
28
|
-
new Keyv({
|
|
29
|
-
store: new KeyvDirStore(".cache/kv", { ext: ".json" }),
|
|
30
|
-
serialize: ({ value }) => yaml.stringify(value),
|
|
31
|
-
deserialize: (str) => ({ value: yaml.parse(str), expires: undefined }),
|
|
32
|
-
});
|
|
124
|
+
## API Reference
|
|
33
125
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
126
|
+
### `new KeyvDirStore(directory, options?)`
|
|
127
|
+
|
|
128
|
+
Creates a new KeyvDirStore instance.
|
|
129
|
+
|
|
130
|
+
#### Parameters
|
|
131
|
+
|
|
132
|
+
- `directory` (string): The directory path where files will be stored
|
|
133
|
+
- `options` (object, optional):
|
|
134
|
+
- `cache` (Map, optional): Custom cache Map to use
|
|
135
|
+
- `filename` (function, optional): Custom filename generator function
|
|
136
|
+
- `ext` (string, optional): File extension to use (default: `.json`)
|
|
137
|
+
- `prefix` (string, optional): Path prefix prepended to every key (e.g. `'data/'`)
|
|
138
|
+
- `suffix` (string, optional): Path suffix appended to every key (overrides `ext` when set)
|
|
139
|
+
|
|
140
|
+
#### Example with Custom Options
|
|
141
|
+
|
|
142
|
+
```ts
|
|
143
|
+
import Keyv from "keyv";
|
|
144
|
+
import { KeyvDirStore } from "keyv-dir-store";
|
|
145
|
+
|
|
146
|
+
const keyv = new Keyv({
|
|
147
|
+
store: new KeyvDirStore(".cache/kv", {
|
|
148
|
+
// Custom file extension
|
|
149
|
+
ext: ".data",
|
|
150
|
+
|
|
151
|
+
// Custom filename generator
|
|
152
|
+
filename: (key) => `custom-prefix-${key}`,
|
|
153
|
+
}),
|
|
39
154
|
});
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
#### Mirror KeyvGithub paths (for use with keyv-nest)
|
|
158
|
+
|
|
159
|
+
Use the same prefix/suffix as KeyvGithub with `filename: (k) => k` for raw paths:
|
|
160
|
+
|
|
161
|
+
```ts
|
|
162
|
+
import KeyvNest from "keyv-nest";
|
|
163
|
+
import { KeyvDirStore } from "keyv-dir-store";
|
|
164
|
+
import KeyvGithub from "keyv-github";
|
|
165
|
+
|
|
166
|
+
const prefix = "data/";
|
|
167
|
+
const suffix = ".json";
|
|
168
|
+
|
|
169
|
+
const store = KeyvNest(
|
|
170
|
+
new KeyvDirStore("./cache", {
|
|
171
|
+
prefix,
|
|
172
|
+
suffix,
|
|
173
|
+
filename: (k) => k, // use key as-is, no hashing
|
|
174
|
+
}),
|
|
175
|
+
new KeyvGithub("owner/repo", { client, prefix, suffix })
|
|
176
|
+
);
|
|
177
|
+
|
|
178
|
+
// key "foo" -> ./cache/data/foo.json (local) and data/foo.json (GitHub)
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
## How It Works
|
|
182
|
+
|
|
183
|
+
1. Each key-value pair is stored in a separate file on disk
|
|
184
|
+
2. The key is used to generate a filename (with sanitization)
|
|
185
|
+
3. The value is serialized using the specified format
|
|
186
|
+
4. TTL information is stored in the file's modification time
|
|
187
|
+
5. An in-memory cache is used to improve performance
|
|
188
|
+
|
|
189
|
+
## See Also
|
|
190
|
+
|
|
191
|
+
Other Keyv storage adapters by the same author:
|
|
192
|
+
|
|
193
|
+
- [keyv-github](https://github.com/snomiao/keyv-github) — GitHub repository adapter; each key is a file, commits are writes
|
|
194
|
+
- [keyv-sqlite](https://github.com/snomiao/keyv-sqlite) — SQLite storage adapter
|
|
195
|
+
- [keyv-mongodb-store](https://github.com/snomiao/keyv-mongodb-store) — MongoDB storage adapter
|
|
196
|
+
- [keyv-nedb-store](https://github.com/snomiao/keyv-nedb-store) — NeDB embedded file-based adapter
|
|
197
|
+
- [keyv-cache-proxy](https://github.com/snomiao/keyv-cache-proxy) — transparent caching proxy that wraps any object
|
|
198
|
+
- [keyv-nest](https://github.com/snomiao/keyv-nest) — hierarchical multi-layer caching adapter
|
|
199
|
+
|
|
200
|
+
## License
|
|
201
|
+
|
|
202
|
+
MIT © [snomiao](https://github.com/snomiao)
|
|
203
|
+
|
|
204
|
+
## Contributing
|
|
205
|
+
|
|
206
|
+
Contributions, issues, and feature requests are welcome!
|
|
207
|
+
Feel free to check [issues page](https://github.com/snomiao/keyv-dir-store/issues).
|
|
208
|
+
|
|
209
|
+
## Acknowledgements
|
|
40
210
|
|
|
41
|
-
|
|
211
|
+
This package is built on top of the excellent [Keyv](https://github.com/jaredwray/keyv) library.
|
package/dist/index.js
CHANGED
|
@@ -4,15 +4,29 @@ var __getProtoOf = Object.getPrototypeOf;
|
|
|
4
4
|
var __defProp = Object.defineProperty;
|
|
5
5
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
6
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
function __accessProp(key) {
|
|
8
|
+
return this[key];
|
|
9
|
+
}
|
|
10
|
+
var __toESMCache_node;
|
|
11
|
+
var __toESMCache_esm;
|
|
7
12
|
var __toESM = (mod, isNodeMode, target) => {
|
|
13
|
+
var canCache = mod != null && typeof mod === "object";
|
|
14
|
+
if (canCache) {
|
|
15
|
+
var cache = isNodeMode ? __toESMCache_node ??= new WeakMap : __toESMCache_esm ??= new WeakMap;
|
|
16
|
+
var cached = cache.get(mod);
|
|
17
|
+
if (cached)
|
|
18
|
+
return cached;
|
|
19
|
+
}
|
|
8
20
|
target = mod != null ? __create(__getProtoOf(mod)) : {};
|
|
9
21
|
const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
|
|
10
22
|
for (let key of __getOwnPropNames(mod))
|
|
11
23
|
if (!__hasOwnProp.call(to, key))
|
|
12
24
|
__defProp(to, key, {
|
|
13
|
-
get: (
|
|
25
|
+
get: __accessProp.bind(mod, key),
|
|
14
26
|
enumerable: true
|
|
15
27
|
});
|
|
28
|
+
if (canCache)
|
|
29
|
+
cache.set(mod, to);
|
|
16
30
|
return to;
|
|
17
31
|
};
|
|
18
32
|
var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
|
|
@@ -331,17 +345,22 @@ class KeyvDirStore {
|
|
|
331
345
|
#ready;
|
|
332
346
|
#filename;
|
|
333
347
|
ext = ".json";
|
|
348
|
+
prefix;
|
|
349
|
+
suffix;
|
|
334
350
|
constructor(dir, {
|
|
335
351
|
cache = new Map,
|
|
336
352
|
filename,
|
|
337
|
-
ext
|
|
353
|
+
ext,
|
|
354
|
+
prefix,
|
|
355
|
+
suffix
|
|
338
356
|
} = {}) {
|
|
339
|
-
this.#ready = mkdir(dir, { recursive: true }).catch(() => {
|
|
340
|
-
});
|
|
357
|
+
this.#ready = mkdir(dir, { recursive: true }).catch(() => {});
|
|
341
358
|
this.#cache = cache;
|
|
342
359
|
this.#dir = dir;
|
|
343
360
|
this.#filename = filename ?? this.#defaultFilename;
|
|
344
361
|
this.ext = ext ?? this.ext;
|
|
362
|
+
this.prefix = prefix ?? "";
|
|
363
|
+
this.suffix = suffix ?? "";
|
|
345
364
|
}
|
|
346
365
|
#defaultFilename(key) {
|
|
347
366
|
const readableName = import_sanitize_filename.default(key).slice(0, 16);
|
|
@@ -350,7 +369,11 @@ class KeyvDirStore {
|
|
|
350
369
|
return name;
|
|
351
370
|
}
|
|
352
371
|
#path(key) {
|
|
353
|
-
|
|
372
|
+
const filename = this.#filename(key);
|
|
373
|
+
const ext = this.suffix || this.ext;
|
|
374
|
+
const safeFilename = import_sanitize_filename.default(filename + ext);
|
|
375
|
+
const relativePath = this.prefix + safeFilename;
|
|
376
|
+
return path.join(this.#dir, relativePath);
|
|
354
377
|
}
|
|
355
378
|
async get(key) {
|
|
356
379
|
const memCached = this.#cache.get(key);
|
|
@@ -383,10 +406,10 @@ class KeyvDirStore {
|
|
|
383
406
|
const expires = ttl ? Date.now() + ttl : 0;
|
|
384
407
|
this.#cache.set(key, { value, expires });
|
|
385
408
|
await this.#ready;
|
|
386
|
-
|
|
387
|
-
});
|
|
388
|
-
await writeFile(
|
|
389
|
-
await utimes(
|
|
409
|
+
const filePath = this.#path(key);
|
|
410
|
+
await mkdir(path.dirname(filePath), { recursive: true }).catch(() => {});
|
|
411
|
+
await writeFile(filePath, value);
|
|
412
|
+
await utimes(filePath, new Date, new Date(expires ?? 0));
|
|
390
413
|
return true;
|
|
391
414
|
}
|
|
392
415
|
async delete(key) {
|
package/index.ts
CHANGED
|
@@ -10,7 +10,7 @@ type CacheMap<Value> = Map<string, DeserializedData<Value>>;
|
|
|
10
10
|
*
|
|
11
11
|
* learn more [README](./README.md)
|
|
12
12
|
*
|
|
13
|
-
* @example
|
|
13
|
+
* @example Basic usage
|
|
14
14
|
* const kv = new Keyv<number | string | { obj: boolean }>({
|
|
15
15
|
* store: new KeyvDirStore("cache/test"),
|
|
16
16
|
* deserialize: KeyvDirStore.deserialize,
|
|
@@ -21,6 +21,16 @@ type CacheMap<Value> = Map<string, DeserializedData<Value>>;
|
|
|
21
21
|
* await kv.set("b", 1234); // never expired
|
|
22
22
|
* expect(await kv.get("b")).toEqual(1234);
|
|
23
23
|
*
|
|
24
|
+
* @example Mirror KeyvGithub paths (for use with keyv-nest)
|
|
25
|
+
* // Use same prefix/suffix as KeyvGithub, with filename: (k) => k for raw paths
|
|
26
|
+
* const dirStore = new KeyvDirStore("./cache", {
|
|
27
|
+
* prefix: "data/",
|
|
28
|
+
* suffix: ".json",
|
|
29
|
+
* filename: (k) => k, // use key as-is, no hashing
|
|
30
|
+
* });
|
|
31
|
+
* // Now dirStore uses same paths as KeyvGithub:
|
|
32
|
+
* // key "foo" -> ./cache/data/foo.json (local) and data/foo.json (GitHub)
|
|
33
|
+
*
|
|
24
34
|
*/
|
|
25
35
|
export class KeyvDirStore<Value extends string> implements Keyv.Store<string> {
|
|
26
36
|
#dir: string;
|
|
@@ -28,6 +38,10 @@ export class KeyvDirStore<Value extends string> implements Keyv.Store<string> {
|
|
|
28
38
|
#ready: Promise<unknown>;
|
|
29
39
|
#filename: (key: string) => string;
|
|
30
40
|
ext = ".json";
|
|
41
|
+
/** Path prefix prepended to every key (e.g. 'data/'). Defaults to ''. */
|
|
42
|
+
readonly prefix: string;
|
|
43
|
+
/** Path suffix appended to every key (e.g. '.json'). Defaults to ''. Overrides ext when set. */
|
|
44
|
+
readonly suffix: string;
|
|
31
45
|
constructor(
|
|
32
46
|
/** dir to cache store
|
|
33
47
|
* WARN: dont share this dir with other purpose
|
|
@@ -38,18 +52,25 @@ export class KeyvDirStore<Value extends string> implements Keyv.Store<string> {
|
|
|
38
52
|
cache = new Map(),
|
|
39
53
|
filename,
|
|
40
54
|
ext,
|
|
55
|
+
prefix,
|
|
56
|
+
suffix,
|
|
41
57
|
}: {
|
|
42
58
|
cache?: CacheMap<Value>;
|
|
43
59
|
filename?: (key: string) => string;
|
|
44
60
|
ext?: string;
|
|
45
|
-
|
|
61
|
+
/** Path prefix prepended to every key (e.g. 'data/'). Use with filename: (k) => k for raw paths. */
|
|
62
|
+
prefix?: string;
|
|
63
|
+
/** Path suffix appended to every key (e.g. '.json'). Overrides ext when set. Use with filename: (k) => k for raw paths. */
|
|
64
|
+
suffix?: string;
|
|
65
|
+
} = {},
|
|
46
66
|
) {
|
|
47
67
|
this.#ready = mkdir(dir, { recursive: true }).catch(() => {});
|
|
48
68
|
this.#cache = cache;
|
|
49
|
-
|
|
50
69
|
this.#dir = dir;
|
|
51
70
|
this.#filename = filename ?? this.#defaultFilename;
|
|
52
71
|
this.ext = ext ?? this.ext;
|
|
72
|
+
this.prefix = prefix ?? "";
|
|
73
|
+
this.suffix = suffix ?? "";
|
|
53
74
|
}
|
|
54
75
|
#defaultFilename(key: string) {
|
|
55
76
|
// use dir as hash salt to avoid collisions
|
|
@@ -59,10 +80,12 @@ export class KeyvDirStore<Value extends string> implements Keyv.Store<string> {
|
|
|
59
80
|
return name;
|
|
60
81
|
}
|
|
61
82
|
#path(key: string) {
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
);
|
|
83
|
+
const filename = this.#filename(key);
|
|
84
|
+
const ext = this.suffix || this.ext; // suffix overrides ext when set
|
|
85
|
+
// Sanitize filename+ext for safety; prefix can have slashes for nested paths
|
|
86
|
+
const safeFilename = sanitizeFilename(filename + ext);
|
|
87
|
+
const relativePath = this.prefix + safeFilename;
|
|
88
|
+
return path.join(this.#dir, relativePath);
|
|
66
89
|
}
|
|
67
90
|
async get(key: string) {
|
|
68
91
|
// read memory
|
|
@@ -98,10 +121,11 @@ export class KeyvDirStore<Value extends string> implements Keyv.Store<string> {
|
|
|
98
121
|
this.#cache.set(key, { value, expires });
|
|
99
122
|
// save to file
|
|
100
123
|
await this.#ready;
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
await
|
|
104
|
-
await
|
|
124
|
+
const filePath = this.#path(key);
|
|
125
|
+
// create parent directories for nested paths (e.g. data/sub/key.json)
|
|
126
|
+
await mkdir(path.dirname(filePath), { recursive: true }).catch(() => {});
|
|
127
|
+
await writeFile(filePath, value); // create a expired file
|
|
128
|
+
await utimes(filePath, new Date(), new Date(expires ?? 0)); // set expires time as mtime (0 as never expired)
|
|
105
129
|
return true;
|
|
106
130
|
}
|
|
107
131
|
async delete(key: string) {
|
|
@@ -116,7 +140,6 @@ export class KeyvDirStore<Value extends string> implements Keyv.Store<string> {
|
|
|
116
140
|
async has(key: string) {
|
|
117
141
|
return undefined !== (await this.get(key));
|
|
118
142
|
}
|
|
119
|
-
|
|
120
143
|
// Save expires into mtime, and value into file
|
|
121
144
|
/** @deprecated use KeyvDirStoreJSON */
|
|
122
145
|
static serialize({ value }: DeserializedData<any>): string {
|
package/package.json
CHANGED
|
@@ -1,12 +1,28 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "keyv-dir-store",
|
|
3
|
-
"version": "0.0
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "High performance Filesystem Keyv Store, caches each key-value pair into a $key.json. and more! *.JSON, *.YAML, *.CSV is also avaliable.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"keyv",
|
|
7
|
+
"keyv-store",
|
|
8
|
+
"dir"
|
|
9
|
+
],
|
|
10
|
+
"homepage": "https://github.com/snomiao/keyv-dir-store#readme",
|
|
11
|
+
"bugs": {
|
|
12
|
+
"url": "https://github.com/snomiao/keyv-dir-store/issues"
|
|
13
|
+
},
|
|
14
|
+
"repository": {
|
|
15
|
+
"type": "git",
|
|
16
|
+
"url": "git+https://github.com/snomiao/keyv-dir-store.git"
|
|
17
|
+
},
|
|
18
|
+
"license": "MIT",
|
|
4
19
|
"author": "snomiao <snomiao@gmail.com>",
|
|
5
20
|
"type": "module",
|
|
6
21
|
"exports": {
|
|
7
22
|
"import": "./dist/index.js",
|
|
8
23
|
"types": "./index.ts"
|
|
9
24
|
},
|
|
25
|
+
"main": "index.js",
|
|
10
26
|
"module": "index.ts",
|
|
11
27
|
"types": "./index.ts",
|
|
12
28
|
"files": [
|
|
@@ -15,26 +31,26 @@
|
|
|
15
31
|
],
|
|
16
32
|
"scripts": {
|
|
17
33
|
"build": "bun build index.ts --outdir=dist --target=bun",
|
|
34
|
+
"prepare": "husky",
|
|
18
35
|
"prerelease": "bun run build && bun run test",
|
|
19
36
|
"release": "bunx standard-version && git push --follow-tags && npm publish",
|
|
20
|
-
"test": "bun test"
|
|
21
|
-
"prepare": "husky"
|
|
37
|
+
"test": "bun test"
|
|
22
38
|
},
|
|
23
39
|
"dependencies": {
|
|
24
|
-
"@types/node": "^
|
|
40
|
+
"@types/node": "^25.3.3",
|
|
25
41
|
"md5": "^2.3.0",
|
|
26
42
|
"sanitize-filename": "^1.6.3",
|
|
27
|
-
"yaml": "^2.
|
|
43
|
+
"yaml": "^2.8.2"
|
|
28
44
|
},
|
|
29
45
|
"devDependencies": {
|
|
30
|
-
"@types/bun": "^1.
|
|
31
|
-
"@types/jest": "^
|
|
32
|
-
"@types/md5": "^2.3.
|
|
46
|
+
"@types/bun": "^1.3.9",
|
|
47
|
+
"@types/jest": "^30.0.0",
|
|
48
|
+
"@types/md5": "^2.3.6",
|
|
33
49
|
"husky": "^9.1.7",
|
|
34
|
-
"semantic-release": "^
|
|
35
|
-
"typescript": "^5.
|
|
50
|
+
"semantic-release": "^25.0.3",
|
|
51
|
+
"typescript": "^5.9.3"
|
|
36
52
|
},
|
|
37
53
|
"peerDependencies": {
|
|
38
|
-
"keyv": "^
|
|
54
|
+
"keyv": "^5.6.0"
|
|
39
55
|
}
|
|
40
56
|
}
|