Skip to content
Merged
Show file tree
Hide file tree
Changes from 19 commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
4eafaff
keyv - feat: clean up of code with fixes and helpers
jaredwray Mar 27, 2026
78d4d96
Update vitest.config.ts
jaredwray Mar 27, 2026
a2a9363
clean up
jaredwray Mar 27, 2026
3924e4a
tests
jaredwray Mar 27, 2026
fba61ff
adding sanitizeKey
jaredwray Mar 27, 2026
93e7b82
Update keyv-test.test.ts
jaredwray Mar 27, 2026
da4a21e
moving iteratorfunction
jaredwray Mar 27, 2026
d772ffa
moving deprecatedHookAliases
jaredwray Mar 27, 2026
67c9b87
moving isDataExpired
jaredwray Mar 27, 2026
3bd71e8
removing isValidStorageAdapter
jaredwray Mar 27, 2026
46a8e18
moving to public on functions
jaredwray Mar 27, 2026
4e71cf5
property cleanup
jaredwray Mar 27, 2026
7615f03
iterator is now a function
jaredwray Mar 27, 2026
02960a1
private functions to the bottom
jaredwray Mar 27, 2026
9a52bc0
function organization
jaredwray Mar 27, 2026
66d59f9
moving deprecated hooks
jaredwray Mar 27, 2026
724e71f
clean up iterator format
jaredwray Mar 27, 2026
fc500f2
adding sanitizeKeys
jaredwray Mar 27, 2026
6005c11
moving to more isDataExpired
jaredwray Mar 27, 2026
e24ef1e
deleteExpiredKeys
jaredwray Mar 27, 2026
292f45d
adding ttl helpers
jaredwray Mar 27, 2026
02235b9
moving to KeyvValue
jaredwray Mar 27, 2026
f0d08a2
Update keyv-test.test.ts
jaredwray Mar 27, 2026
ab9fad9
fixing a named type
jaredwray Mar 27, 2026
979c7ea
dynamo fixes
jaredwray Mar 27, 2026
1193f3c
handling no namespace by default
jaredwray Mar 27, 2026
65c6d2e
Update keyv.test.ts
jaredwray Mar 27, 2026
b3b2257
memcache fix
jaredwray Mar 27, 2026
63d766b
lint
jaredwray Mar 27, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 59 additions & 5 deletions core/keyv/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ There are a few existing modules similar to Keyv, however Keyv is different beca
- [.emitErrors](#emiterrors)
- [.throwOnErrors](#throwonerrors)
- [.stats](#stats)
- [.sanitizeKey](#sanitizekey)
- [Keyv Instance](#keyv-instance)
- [.set(key, value, [ttl])](#setkey-value-ttl)
- [.setMany(entries)](#setmanyentries)
Expand Down Expand Up @@ -818,17 +819,21 @@ await keyv.disconnect();

## .iterator()

Iterate over all entries of the current namespace.
Iterate over all key-value pairs in the store. Automatically deserializes values, filters out expired entries, and deletes them.

Returns a iterable that can be iterated by for-of loops. For example:
Returns an async generator that yields `[key, value]` pairs. Use with `for await...of`:

```js
// please note that the "await" keyword should be used here
for await (const [key, value] of this.keyv.iterator()) {
for await (const [key, value] of keyv.iterator()) {
console.log(key, value);
};
}
```

The iterator works with any storage backend:
- **Map stores**: iterates using the built-in `Symbol.iterator`
- **Storage adapters**: delegates to the adapter's `iterator()` method (e.g., Redis SCAN, SQL cursor)
- **Unsupported stores**: emits an `error` event if the store does not support iteration

# API - Properties

## .namespace
Expand Down Expand Up @@ -1031,6 +1036,55 @@ keyv.stats.enabled = true; // Enable stats tracking
keyv.stats.enabled = false; // Disable stats tracking
```

## .sanitizeKey
Type: `boolean | KeyvSanitizeOptions`<br />
Default: `true`

Sanitizes keys to strip characters that could be dangerous for SQL, MongoDB, Redis, or filesystem-based storage backends. This is enabled by default to protect against injection attacks.

### Categories

| Category | Characters | Purpose |
|----------|-----------|---------|
| `sql` | `'` `"` `` ` `` `;` | Prevents SQL injection |
| `mongo` | `$` `{` `}` | Prevents MongoDB operator injection |
| `escape` | `\` `\0` `\n` `\r` | Strips escape sequences, null bytes, CRLF injection |
| `path` | `/` | Prevents path traversal |

### Usage

Enable all sanitization (default):
```js
const keyv = new Keyv(); // sanitizeKey defaults to true
await keyv.set("test'; DROP TABLE", "value");
// Key is stored as "test DROP TABLE"
```

Disable all sanitization:
```js
const keyv = new Keyv({ sanitizeKey: false });
```

Granular control per category:
```js
const keyv = new Keyv({
sanitizeKey: {
sql: true, // strip SQL chars (default: true)
mongo: false, // keep MongoDB chars
escape: true, // strip escape chars (default: true)
path: false, // keep path chars
}
});
```

You can also change the setting at runtime:
```js
keyv.sanitizeKey = false; // disable
keyv.sanitizeKey = { sql: true, mongo: false }; // granular
```

Sanitization is applied to all key-accepting methods: `get`, `set`, `delete`, `has`, `getMany`, `setMany`, `deleteMany`, `hasMany`, `getRaw`, `getManyRaw`, `setRaw`, and `setManyRaw`.

# Bun Support

We make a best effort to support [Bun](https://bun.sh/) as a runtime. Our default and primary target is Node.js, but we run tests against Bun to ensure compatibility. If you encounter any issues while using Keyv with Bun, please report them at our [GitHub issues](https://github.com/jaredwray/keyv/issues).
Expand Down
13 changes: 5 additions & 8 deletions core/keyv/src/generic-store.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
// biome-ignore-all lint/suspicious/noExplicitAny: map type
import { Hookified } from "hookified";
import {
Keyv,
type KeyvEntry,
type KeyvStorageAdapter,
type StoredData,
} from "./index.js";
import { Keyv } from "./keyv.js";
import type { KeyvEntry, KeyvStorageAdapter, StoredData } from "./types.js";
import { isDataExpired } from "./utils.js";

/**
* Configuration options for KeyvGenericStore.
Expand Down Expand Up @@ -220,7 +217,7 @@ export class KeyvGenericStore extends Hookified implements KeyvStorageAdapter {
}

// Check if it is expired
if (data.expires && Date.now() > data.expires) {
if (isDataExpired(data)) {
this._store.delete(keyPrefix);
return undefined;
}
Expand Down Expand Up @@ -350,7 +347,7 @@ export class KeyvGenericStore extends Hookified implements KeyvStorageAdapter {
}

// Check expiration
if (data?.expires && Date.now() > data.expires) {
if (data && isDataExpired(data)) {
this._store.delete(key);
continue;
}
Expand Down
Loading
Loading