Skip to content

keyv - fix: making PRE_SET work correctly on set function #1360

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
9 changes: 5 additions & 4 deletions packages/keyv/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@ import Keyv, { KeyvHooks } from 'keyv';
```js
//PRE_SET hook
const keyv = new Keyv();
keyv.hooks.addHandler(KeyvHooks.PRE_SET, (key, value) => console.log(`Setting key ${key} to ${value}`));
keyv.hooks.addHandler(KeyvHooks.PRE_SET, (data) => console.log(`Setting key ${data.key} to ${data.value}`));

//POST_SET hook
const keyv = new Keyv();
Expand All @@ -240,9 +240,10 @@ In these examples you can also manipulate the value before it is set. For exampl

```js
const keyv = new Keyv();
keyv.hooks.addHandler(KeyvHooks.PRE_SET, (key, value) => {
console.log(`Setting key ${key} to ${value}`);
key = `prefix-${key}`;
keyv.hooks.addHandler(KeyvHooks.PRE_SET, (data) => {
console.log(`Manipulating key ${data.key} and ${data.value}`);
data.key = `prefix-${data.key}`;
data.value = `prefix-${data.value}`;
});
```

Expand Down
21 changes: 11 additions & 10 deletions packages/keyv/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -566,32 +566,33 @@ export class Keyv<GenericValue = any> extends EventManager {
* @returns {boolean} if it sets then it will return a true. On failure will return false.
*/
async set<Value = GenericValue>(key: string, value: Value, ttl?: number): Promise<boolean> {
this.hooks.trigger(KeyvHooks.PRE_SET, {key, value, ttl});
const keyPrefixed = this._getKeyPrefix(key);
if (ttl === undefined) {
ttl = this._ttl;
const data = {key, value, ttl};
this.hooks.trigger(KeyvHooks.PRE_SET, data);
const keyPrefixed = this._getKeyPrefix(data.key);
if (data.ttl === undefined) {
data.ttl = this._ttl;
}

if (ttl === 0) {
ttl = undefined;
if (data.ttl === 0) {
data.ttl = undefined;
}

const {store} = this.opts;

const expires = (typeof ttl === 'number') ? (Date.now() + ttl) : null;
const expires = (typeof data.ttl === 'number') ? (Date.now() + data.ttl) : null;

if (typeof value === 'symbol') {
if (typeof data.value === 'symbol') {
this.emit('error', 'symbol cannot be serialized');
throw new Error('symbol cannot be serialized');
}

const formattedValue = {value, expires};
const formattedValue = {value: data.value, expires};
const serializedValue = await this.serializeData(formattedValue);

let result = true;

try {
const value = await store.set(keyPrefixed, serializedValue, ttl);
const value = await store.set(keyPrefixed, serializedValue, data.ttl);

if (typeof value === 'boolean') {
result = value;
Expand Down
16 changes: 16 additions & 0 deletions packages/keyv/test/keyv-hooks.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import * as test from 'vitest';
import {faker} from '@faker-js/faker';
import {KeyvSqlite} from '@keyv/sqlite';
import Keyv, {KeyvHooks} from '../src/index.js';

Expand All @@ -12,6 +13,21 @@ test.it('PRE_SET hook', async t => {
await keyv.set('foo', 'bar');
});

test.it('PRE_SET hook with manipulation', async t => {
const keyId = faker.string.alphanumeric(10);
const newKeyId = `${keyId}1`;
const keyValue = faker.lorem.sentence();
const keyv = new Keyv();
keyv.hooks.addHandler(KeyvHooks.PRE_SET, data => {
data.key = newKeyId;
});
t.expect(keyv.hooks.handlers.size).toBe(1);
await keyv.set(keyId, keyValue);

const value = await keyv.get(newKeyId);
t.expect(value).toBe(keyValue);
});

test.it('POST_SET hook', async t => {
const keyv = new Keyv();
keyv.hooks.addHandler(KeyvHooks.POST_SET, data => {
Expand Down
Loading