diff --git a/package-lock.json b/package-lock.json index 6aa8d31..8bd8307 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,15 +1,16 @@ { "name": "slack-cloudflare-workers", - "version": "0.14.3", + "version": "1.0.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "slack-cloudflare-workers", - "version": "0.14.3", + "version": "1.0.0", "license": "MIT", "dependencies": { - "slack-edge": "^0.14.4" + "@cloudflare/workers-types": "^4.20240725.0", + "slack-edge": "^1.0.0" }, "devDependencies": { "@biomejs/biome": "^1.8.3", @@ -180,19 +181,25 @@ "node": ">=14.21.3" } }, + "node_modules/@cloudflare/workers-types": { + "version": "4.20240725.0", + "resolved": "https://registry.npmjs.org/@cloudflare/workers-types/-/workers-types-4.20240725.0.tgz", + "integrity": "sha512-L6T/Bg50zm9IIACQVQ0CdVcQL+2nLkRXdPz6BsXF3SlzgjyWR5ndVctAbfr/HLV7aKYxWnnEZsIORsTWb+FssA==", + "license": "MIT OR Apache-2.0" + }, "node_modules/slack-edge": { - "version": "0.14.4", - "resolved": "https://registry.npmjs.org/slack-edge/-/slack-edge-0.14.4.tgz", - "integrity": "sha512-6KwwpZ5TTkD/YQrXuPCSK2Zcui/bFFnriF1QGzvPw6pjaq5HQgL3ccUXYX70Lc3RmXs6ZTJ/ccs6ZEYORyEsoQ==", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/slack-edge/-/slack-edge-1.0.0.tgz", + "integrity": "sha512-R+RaOp/RX90bgzVF2J1xojLB46kBp1gBXglIAQFwJrSQ6uTNWbXp5gGGDZluaoLhPuNq9V8wxWeh2m6OPRHALg==", "license": "MIT", "dependencies": { - "slack-web-api-client": "^0.13.5" + "slack-web-api-client": "^1.0.0" } }, "node_modules/slack-web-api-client": { - "version": "0.13.5", - "resolved": "https://registry.npmjs.org/slack-web-api-client/-/slack-web-api-client-0.13.5.tgz", - "integrity": "sha512-h3+jY86LRY+nXP6kQmaqUSsIqVYziiVwBnmvzEXh+42Bn0fpuGIUFf2I6zEXtvjJLoVK5WczmrLewWlAWuX2/Q==", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/slack-web-api-client/-/slack-web-api-client-1.0.0.tgz", + "integrity": "sha512-qIdEddzC2yyvDgUwJ5LSO4ZjHLnhfF8untU0FicLg+wiiPD1aiREeM80+AXJYHYaQJrtCB0Sm3NrYp0ntt0R/g==", "license": "MIT" }, "node_modules/typescript": { diff --git a/package.json b/package.json index 8d1bba6..6d594d8 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "slack-cloudflare-workers", - "version": "0.14.3", + "version": "1.0.0", "description": "Slack app development framework for Cloudflare Workers", "main": "dist/index.js", "scripts": { @@ -27,7 +27,8 @@ }, "homepage": "https://github.com/seratch/slack-cloudflare-workers#readme", "dependencies": { - "slack-edge": "^0.14.4" + "@cloudflare/workers-types": "^4.20240725.0", + "slack-edge": "^1.0.0" }, "devDependencies": { "@biomejs/biome": "^1.8.3", diff --git a/src/index.ts b/src/index.ts index 7185090..5d5edd2 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,5 +1,4 @@ export * from "slack-edge"; -export * from "./kv"; export * from "./kv-installation-store"; export * from "./kv-state-store"; diff --git a/src/kv-installation-store.ts b/src/kv-installation-store.ts index ba781e4..402cedd 100644 --- a/src/kv-installation-store.ts +++ b/src/kv-installation-store.ts @@ -1,3 +1,4 @@ +import { KVNamespace, KVNamespaceListResult } from "@cloudflare/workers-types"; import { AuthTestResponse, Authorize, @@ -9,14 +10,13 @@ import { SlackOAuthEnv, TokenRotator, } from "slack-edge"; -import { KV } from "./kv"; export class KVInstallationStore implements InstallationStore { #env: E; - #storage: KV; + #storage: KVNamespace; #tokenRotator: TokenRotator; - constructor(env: E, namespace: KV) { + constructor(env: E, namespace: KVNamespace) { this.#env = env; this.#storage = namespace; this.#tokenRotator = new TokenRotator({ @@ -62,10 +62,13 @@ export class KVInstallationStore implements Installatio var keys: string[] = []; const first = await this.#storage.list({ prefix }); keys = keys.concat(first.keys.map((k) => k.name)); - var cursor: string | undefined = first.cursor; - while (cursor) { - const response = await this.#storage.list({ prefix, cursor }); - keys = keys.concat(response.keys.map((k) => k.name)); + if (!first.list_complete) { + var cursor: string | undefined = first.cursor; + while (cursor) { + const response: KVNamespaceListResult = await this.#storage.list({ prefix, cursor }); + keys = keys.concat(response.keys.map((k) => k.name)); + cursor = response.list_complete ? undefined : response.cursor; + } } for (const key of keys) { await this.#storage.delete(key); diff --git a/src/kv-state-store.ts b/src/kv-state-store.ts index 77a628a..3318566 100644 --- a/src/kv-state-store.ts +++ b/src/kv-state-store.ts @@ -1,10 +1,10 @@ -import { KV } from "./kv"; import { StateStore } from "slack-edge"; +import { KVNamespace } from "@cloudflare/workers-types"; export class KVStateStore implements StateStore { - #storage: KV; + #storage: KVNamespace; - constructor(namespace: KV) { + constructor(namespace: KVNamespace) { this.#storage = namespace; } diff --git a/src/kv.ts b/src/kv.ts deleted file mode 100644 index 1f574fe..0000000 --- a/src/kv.ts +++ /dev/null @@ -1,67 +0,0 @@ -export type KV = { - // https://developers.cloudflare.com/kv/api/ - // we use only string for the value - - put(key: string, value: string): Promise; - - put( - key: string, - value: string, - options: { - expiration?: number; // seconds since epoch - expirationTtl?: number; // seconds from now - }, - ): Promise; - - get(key: string): Promise; - - delete(key: string): Promise; - - list(args: { prefix?: string; limit?: number; cursor?: string }): Promise<{ - keys: { - name: string; - expiration?: number; - metadata?: Record; - }[]; - list_complete: boolean; - cursor?: string; - }>; -}; - -export class MemoryKV implements KV { - #data: { [key: string]: string } = {}; - - async put(key: string, value: string): Promise { - this.#data[key] = value; - } - async putWithExpiration(key: string, value: string, options: { expiration?: number; expirationTtl?: number }): Promise { - this.#data[key] = value; - // TODO: implement the expiration - } - async get(key: string): Promise { - return this.#data[key]; - } - - async delete(key: string): Promise { - delete this.#data[key]; - } - - async list(args: { - prefix?: string; - limit?: number; - cursor?: string; - }): Promise<{ - keys: { - name: string; - expiration?: number; - metadata?: Record; - }[]; - list_complete: boolean; - cursor?: string; - }> { - const keys = Object.keys(this.#data).map((name) => { - return { name }; - }); - return { keys, list_complete: true }; - } -}