Fix calendar serviced and kvs client (#9551)

Signed-off-by: Denis Bykhov <bykhov.denis@gmail.com>
This commit is contained in:
Denis Bykhov
2025-07-15 15:34:58 +07:00
committed by GitHub
parent cae10ef694
commit e0da122e8d
5 changed files with 33 additions and 14 deletions
@@ -139,7 +139,11 @@ describe('KeyValueClient', () => {
describe('listKeys', () => {
it('should send GET request to namespace endpoint', async () => {
const testData = { key1: 'value1', key2: 'value2' }
const testData = {
count: 2,
keys: ['key1', 'key2'],
namespace: 'test-ns'
}
fetchMock.mockResponseOnce(JSON.stringify(testData), {
status: 200,
headers: { 'Content-Type': 'application/json' }
+3 -3
View File
@@ -14,7 +14,7 @@
//
import { concatLink } from '@hcengineering/core'
import { PlatformError } from '@hcengineering/platform'
import { KeyValueClient } from './types'
import { KeyValueClient, ListResult } from './types'
/**
* Get a KeyValueClient instance
@@ -92,12 +92,12 @@ class KeyValueClientImpl implements KeyValueClient {
})
}
async listKeys<T>(prefix?: string): Promise<Record<string, T> | null> {
async listKeys (prefix?: string): Promise<ListResult | null> {
let url = this.buildUrl()
if (prefix !== undefined) {
url += `?prefix=${encodeURIComponent(prefix)}`
}
return await this.sendRequest<Record<string, T>>(url, {
return await this.sendRequest<ListResult>(url, {
method: 'GET',
errorMessage: 'Failed to list keys'
})
+7 -1
View File
@@ -13,6 +13,12 @@
// limitations under the License.
//
export interface ListResult {
keys: string[]
count: number
namespace: string
}
/**
* Client for interacting with the key-value store API
* @public
@@ -45,5 +51,5 @@ export interface KeyValueClient {
* @param prefix - Optional prefix to filter keys by
* @returns Promise that resolves to an object with keys and their values
*/
listKeys: <T>(prefix?: string) => Promise<Record<string, T> | null>
listKeys: (prefix?: string) => Promise<ListResult | null>
}
@@ -92,7 +92,7 @@ export async function removeUserByEmail (user: User, email: GoogleEmail): Promis
export async function cleanUserByEmail (): Promise<void> {
const client = getKvsClient()
const keys = await client.listKeys<User>(`${CALENDAR_INTEGRATION}:users:`)
const keys = await client.listKeys(`${CALENDAR_INTEGRATION}:users:`)
if (keys == null) return
for (const key in keys) {
await client.deleteKey(key)
+17 -8
View File
@@ -33,11 +33,11 @@ export class WatchClient {
return watchClient
}
private async getWatches (): Promise<Record<string, Watch>> {
private async getWatches (): Promise<string[]> {
const client = getKvsClient()
const key = `${CALENDAR_INTEGRATION}:watch:${this.user.email}`
const watches = await client.listKeys<Watch>(key)
return watches ?? {}
const watches = await client.listKeys(key)
return watches?.keys ?? []
}
private async setToken (token: Credentials): Promise<void> {
@@ -65,7 +65,7 @@ export class WatchClient {
if (active.length === 0) {
const watches = await this.getWatches()
const client = getKvsClient()
for (const key in watches) {
for (const key of watches) {
await client.deleteKey(key)
}
}
@@ -187,7 +187,15 @@ export class WatchController {
private async getUserWatches (email: GoogleEmail): Promise<Record<string, Watch>> {
const client = getKvsClient()
const key = `${CALENDAR_INTEGRATION}:watch:${email}`
return (await client.listKeys<Watch>(key)) ?? {}
const keys = (await client.listKeys(key))?.keys ?? []
const res: Record<string, Watch> = {}
for (const key of keys) {
const watch = await client.getValue<Watch>(key)
if (watch != null) {
res[key] = watch
}
}
return res
}
async unsubscribe (user: Token): Promise<void> {
@@ -227,10 +235,11 @@ export class WatchController {
const expired = Date.now() + 24 * 60 * 60 * 1000
const client = getKvsClient()
const key = `${CALENDAR_INTEGRATION}:watch:`
const watches = (await client.listKeys<Watch>(key)) ?? {}
const watches = await client.listKeys(key)
const toRefresh: Watch[] = []
for (const key in watches) {
const watch = watches[key]
for (const key of watches?.keys ?? []) {
const watch = await client.getValue<Watch>(key)
if (watch == null) continue
if (watch.expired < expired) {
toRefresh.push(watch)
}