diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index ac9f46b..ccf6ee6 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -16,6 +16,7 @@ jobs: - "ai/slackbot-mcp-client/rich-responses/mcp-apps" - "ai/slackbot-mcp-client/slack-identity" - "block-kit" + - "methods" steps: - name: Checkout code uses: actions/checkout@v7 diff --git a/README.md b/README.md index 997d88e..0ec7209 100644 --- a/README.md +++ b/README.md @@ -6,3 +6,4 @@ This collections of examples highlights features of a Slack app in the language - **[AI in Slack](./ai)**: Agent experiences and MCP features in an interactive conversation interface. - **[Block Kit](./block-kit)**: The framework of visual components arranged to create app layouts. +- **[Methods](./methods)**: Individual Slack Web API method calls with the `@slack/web-api` client. diff --git a/methods/.gitignore b/methods/.gitignore new file mode 100644 index 0000000..3c3629e --- /dev/null +++ b/methods/.gitignore @@ -0,0 +1 @@ +node_modules diff --git a/methods/README.md b/methods/README.md new file mode 100644 index 0000000..88eccd1 --- /dev/null +++ b/methods/README.md @@ -0,0 +1,10 @@ +# Methods + +Individual Slack Web API method calls with the `@slack/web-api` client. + +Read the [docs](https://docs.slack.dev/reference/methods) to explore every method, or explore implementations of specific families. + +## What's on display + +- **[blocks](blocks/)**: Validate Block Kit payloads. [Implementation](./blocks/). +- **[chat](chat/)**: Send and manage messages. [Implementation](./chat/). diff --git a/methods/biome.json b/methods/biome.json new file mode 100644 index 0000000..01ff577 --- /dev/null +++ b/methods/biome.json @@ -0,0 +1,34 @@ +{ + "$schema": "./node_modules/@biomejs/biome/configuration_schema.json", + "vcs": { + "enabled": true, + "clientKind": "git", + "useIgnoreFile": true + }, + "files": { + "ignoreUnknown": false + }, + "formatter": { + "enabled": true, + "indentStyle": "space" + }, + "linter": { + "enabled": true, + "rules": { + "recommended": true + } + }, + "javascript": { + "formatter": { + "quoteStyle": "double" + } + }, + "assist": { + "enabled": true, + "actions": { + "source": { + "organizeImports": "on" + } + } + } +} diff --git a/methods/blocks/.slack/.gitignore b/methods/blocks/.slack/.gitignore new file mode 100644 index 0000000..973ba60 --- /dev/null +++ b/methods/blocks/.slack/.gitignore @@ -0,0 +1,2 @@ +apps.dev.json +cache/ diff --git a/methods/blocks/.slack/config.json b/methods/blocks/.slack/config.json new file mode 100644 index 0000000..909afbe --- /dev/null +++ b/methods/blocks/.slack/config.json @@ -0,0 +1,6 @@ +{ + "manifest": { + "source": "local" + }, + "project_id": "00000000-0000-0000-0000-000000000000" +} diff --git a/methods/blocks/.slack/hooks.json b/methods/blocks/.slack/hooks.json new file mode 100644 index 0000000..063cb30 --- /dev/null +++ b/methods/blocks/.slack/hooks.json @@ -0,0 +1,5 @@ +{ + "hooks": { + "get-hooks": "npx -q --no-install -p @slack/cli-hooks slack-cli-get-hooks" + } +} diff --git a/methods/blocks/README.md b/methods/blocks/README.md new file mode 100644 index 0000000..58d8281 --- /dev/null +++ b/methods/blocks/README.md @@ -0,0 +1,26 @@ +# blocks + +Validate Block Kit payloads. + +Read the [docs](https://docs.slack.dev/reference/methods#blocks) to explore more methods in the `blocks` family. + +## What's on display + +- **[blocks.validate](https://docs.slack.dev/reference/methods/blocks.validate)**: Validates blocks, messages, and views Block Kit JSON payloads. [Implementation](./src/blocks-validate.js). + +`blocks.validate` is not yet a typed method in `@slack/web-api`, so the example uses the generic `client.apiCall(...)` escape hatch instead of a typed `client.blocks.validate(...)` call. + +## Running an example + +This family is a self-contained Slack CLI app whose [`manifest.json`](./manifest.json) requests no scopes (`blocks.validate` requires none). From this directory, install the app and grab a token: + +```sh +slack install +``` + +Then set the token and run the example directly: + +```sh +export SLACK_TOKEN="xoxb-your-token" +node src/blocks-validate.js +``` diff --git a/methods/blocks/manifest.json b/methods/blocks/manifest.json new file mode 100644 index 0000000..0c294dd --- /dev/null +++ b/methods/blocks/manifest.json @@ -0,0 +1,22 @@ +{ + "display_information": { + "name": "Slack API Methods", + "description": "Example implementations to call \"blocks\" methods" + }, + "features": { + "bot_user": { + "display_name": "Slack API Methods", + "always_online": true + } + }, + "oauth_config": { + "scopes": { + "bot": [] + } + }, + "settings": { + "org_deploy_enabled": true, + "socket_mode_enabled": false, + "token_rotation_enabled": false + } +} diff --git a/methods/blocks/src/blocks-validate.js b/methods/blocks/src/blocks-validate.js new file mode 100644 index 0000000..2ed91d3 --- /dev/null +++ b/methods/blocks/src/blocks-validate.js @@ -0,0 +1,20 @@ +import { WebClient } from "@slack/web-api"; + +// Read a token from the environment variables +const token = process.env.SLACK_TOKEN; + +// Initialize +const client = new WebClient(token); + +// Call the blocks.validate method +await client.apiCall("blocks.validate", { + blocks: JSON.stringify([ + { + type: "section", + text: { + type: "plain_text", + text: "Hello world", + }, + }, + ]), +}); diff --git a/methods/blocks/tests/blocks-validate.test.js b/methods/blocks/tests/blocks-validate.test.js new file mode 100644 index 0000000..37021e1 --- /dev/null +++ b/methods/blocks/tests/blocks-validate.test.js @@ -0,0 +1,43 @@ +import * as assert from "node:assert"; +import { after, describe, it, mock } from "node:test"; + +describe("blocks.validate", () => { + after(() => { + mock.restoreAll(); + }); + + it("sends", async () => { + process.env.SLACK_TOKEN = "xoxb-test"; + + const fetchMock = mock.method( + globalThis, + "fetch", + async () => + new Response(JSON.stringify({ ok: true }), { + status: 200, + headers: { "content-type": "application/json" }, + }), + ); + + await import("../src/blocks-validate.js"); + + assert.strictEqual(fetchMock.mock.callCount(), 1); + const [url, init] = fetchMock.mock.calls[0].arguments; + assert.strictEqual(String(url), "https://slack.com/api/blocks.validate"); + assert.ok(init); + assert.deepStrictEqual( + Object.fromEntries(new URLSearchParams(String(init.body))), + { + blocks: JSON.stringify([ + { + type: "section", + text: { + type: "plain_text", + text: "Hello world", + }, + }, + ]), + }, + ); + }); +}); diff --git a/methods/chat/.slack/.gitignore b/methods/chat/.slack/.gitignore new file mode 100644 index 0000000..973ba60 --- /dev/null +++ b/methods/chat/.slack/.gitignore @@ -0,0 +1,2 @@ +apps.dev.json +cache/ diff --git a/methods/chat/.slack/config.json b/methods/chat/.slack/config.json new file mode 100644 index 0000000..909afbe --- /dev/null +++ b/methods/chat/.slack/config.json @@ -0,0 +1,6 @@ +{ + "manifest": { + "source": "local" + }, + "project_id": "00000000-0000-0000-0000-000000000000" +} diff --git a/methods/chat/.slack/hooks.json b/methods/chat/.slack/hooks.json new file mode 100644 index 0000000..063cb30 --- /dev/null +++ b/methods/chat/.slack/hooks.json @@ -0,0 +1,5 @@ +{ + "hooks": { + "get-hooks": "npx -q --no-install -p @slack/cli-hooks slack-cli-get-hooks" + } +} diff --git a/methods/chat/README.md b/methods/chat/README.md new file mode 100644 index 0000000..47f84f8 --- /dev/null +++ b/methods/chat/README.md @@ -0,0 +1,24 @@ +# chat + +Send and manage messages. + +Read the [docs](https://docs.slack.dev/reference/methods#chat) to explore more methods in the `chat` family. + +## What's on display + +- **[chat.postMessage](https://docs.slack.dev/reference/methods/chat.postmessage)**: Sends a message to a channel. [Implementation](./src/chat-post-message.js). + +## Running an example + +This family is a self-contained Slack CLI app whose [`manifest.json`](./manifest.json) requests only the scopes it needs (`chat:write`). From this directory, install the app and grab a bot token: + +```sh +slack install +``` + +Then set the token and run the example directly: + +```sh +export SLACK_TOKEN="xoxb-your-token" +node src/chat-post-message.js +``` diff --git a/methods/chat/manifest.json b/methods/chat/manifest.json new file mode 100644 index 0000000..ad13ee2 --- /dev/null +++ b/methods/chat/manifest.json @@ -0,0 +1,22 @@ +{ + "display_information": { + "name": "Slack API Methods", + "description": "Example implementations to call \"chat\" methods" + }, + "features": { + "bot_user": { + "display_name": "Slack API Methods", + "always_online": true + } + }, + "oauth_config": { + "scopes": { + "bot": ["chat:write"] + } + }, + "settings": { + "org_deploy_enabled": true, + "socket_mode_enabled": false, + "token_rotation_enabled": false + } +} diff --git a/methods/chat/src/chat-post-message.js b/methods/chat/src/chat-post-message.js new file mode 100644 index 0000000..0453a54 --- /dev/null +++ b/methods/chat/src/chat-post-message.js @@ -0,0 +1,13 @@ +import { WebClient } from "@slack/web-api"; + +// Read a token from the environment variables +const token = process.env.SLACK_TOKEN; + +// Initialize +const client = new WebClient(token); + +// Call the chat.postMessage method +await client.chat.postMessage({ + channel: "C123ABC456", + text: "Here's a message for you", +}); diff --git a/methods/chat/tests/chat-post-message.test.js b/methods/chat/tests/chat-post-message.test.js new file mode 100644 index 0000000..eec87d1 --- /dev/null +++ b/methods/chat/tests/chat-post-message.test.js @@ -0,0 +1,36 @@ +import * as assert from "node:assert"; +import { after, describe, it, mock } from "node:test"; + +describe("chat.postMessage", () => { + after(() => { + mock.restoreAll(); + }); + + it("sends", async () => { + process.env.SLACK_TOKEN = "xoxb-test"; + + const fetchMock = mock.method( + globalThis, + "fetch", + async () => + new Response(JSON.stringify({ ok: true }), { + status: 200, + headers: { "content-type": "application/json" }, + }), + ); + + await import("../src/chat-post-message.js"); + + assert.strictEqual(fetchMock.mock.callCount(), 1); + const [url, init] = fetchMock.mock.calls[0].arguments; + assert.strictEqual(String(url), "https://slack.com/api/chat.postMessage"); + assert.ok(init); + assert.deepStrictEqual( + Object.fromEntries(new URLSearchParams(String(init.body))), + { + channel: "C123ABC456", + text: "Here's a message for you", + }, + ); + }); +}); diff --git a/methods/package-lock.json b/methods/package-lock.json new file mode 100644 index 0000000..8cad385 --- /dev/null +++ b/methods/package-lock.json @@ -0,0 +1,387 @@ +{ + "name": "methods", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "dependencies": { + "@slack/web-api": "^8.0.0" + }, + "devDependencies": { + "@biomejs/biome": "^2.5.3", + "@slack/cli-hooks": "^2.0.0", + "@types/node": "^24.13.3", + "typescript": "^6.0.3" + } + }, + "node_modules/@biomejs/biome": { + "version": "2.5.3", + "resolved": "https://registry.npmjs.org/@biomejs/biome/-/biome-2.5.3.tgz", + "integrity": "sha512-MrJswFdei9EfDwwUy2tQrPDpK0AO+RmMFvBoaaJ6ayBc3sUbHdCE+XG5N8vp+5So41ZupZJQm0roHFFhMGVD7A==", + "dev": true, + "license": "MIT OR Apache-2.0", + "bin": { + "biome": "bin/biome" + }, + "engines": { + "node": ">=14.21.3" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/biome" + }, + "optionalDependencies": { + "@biomejs/cli-darwin-arm64": "2.5.3", + "@biomejs/cli-darwin-x64": "2.5.3", + "@biomejs/cli-linux-arm64": "2.5.3", + "@biomejs/cli-linux-arm64-musl": "2.5.3", + "@biomejs/cli-linux-x64": "2.5.3", + "@biomejs/cli-linux-x64-musl": "2.5.3", + "@biomejs/cli-win32-arm64": "2.5.3", + "@biomejs/cli-win32-x64": "2.5.3" + } + }, + "node_modules/@biomejs/cli-darwin-arm64": { + "version": "2.5.3", + "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-arm64/-/cli-darwin-arm64-2.5.3.tgz", + "integrity": "sha512-QhYP9muVQ0nUO5zztFuPbEwi4+94sJWVjaZds9aMi1l/KNZBiUjdiSUrGHsTaMGDXrYl+r4AS2sUKfgH3w+V3g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-darwin-x64": { + "version": "2.5.3", + "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-x64/-/cli-darwin-x64-2.5.3.tgz", + "integrity": "sha512-NC1Ss13UaW7QZX+y8j44bF7AP0jSJdBl6iRhe0MAkvaSqZy+mWg3GaXsrb+eSoHoGDBtaXWEbMVV0iVN2cZ7cQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-linux-arm64": { + "version": "2.5.3", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64/-/cli-linux-arm64-2.5.3.tgz", + "integrity": "sha512-ksx1KWeyYW18ILL04msF/J4ZBtBDN33znYK8Z/aNv/vlBVxL9/g3mGP+omgHJKy4+KWbK87vcmmpmurfNjSgiA==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-linux-arm64-musl": { + "version": "2.5.3", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64-musl/-/cli-linux-arm64-musl-2.5.3.tgz", + "integrity": "sha512-fccix0w6xp6csCXgxeC0dU/3ecgRQal0y+cv2SP9ajNlhe7Yrk2Ug7UDe2j9AT9ZDYitkXpvUKgZjjuoYeP4Vg==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-linux-x64": { + "version": "2.5.3", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64/-/cli-linux-x64-2.5.3.tgz", + "integrity": "sha512-yMkJtilsgvILDcVkh187aVLTb64xYsrxYajx5kym+r1ULkO5HUOfu9AYKLGQbOVLwJtT2utNw7hhFNg+17mUYA==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-linux-x64-musl": { + "version": "2.5.3", + "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64-musl/-/cli-linux-x64-musl-2.5.3.tgz", + "integrity": "sha512-O/yU9YKRUiHhmcjF2f38PSjseVk3G4VLWYc0G2HWpzdBVREV6G8IGWIVEFf7MFPfWIzNUIvPsEjeAZQIOgnLcQ==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-win32-arm64": { + "version": "2.5.3", + "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-arm64/-/cli-win32-arm64-2.5.3.tgz", + "integrity": "sha512-cX5z+GYwRcqEok0AH3KSfQGgqYd0Nomfp6Fbe1uiTtELE38hdH2k842wQ9wLNaF/JJ7r4rjJQ4VR+ce+fRmQbw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@biomejs/cli-win32-x64": { + "version": "2.5.3", + "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-x64/-/cli-win32-x64-2.5.3.tgz", + "integrity": "sha512-ExSaJWi4/u6+GXCszlSKpWSjKNbDseAYqqkCznsCsZ/4uidZ/BEqsCc5/3ctlq6dfIubdIIRSVLC/PG9xPl70Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT OR Apache-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=14.21.3" + } + }, + "node_modules/@slack/cli-hooks": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@slack/cli-hooks/-/cli-hooks-2.0.0.tgz", + "integrity": "sha512-VLxGqJZwbrH3S+ovRhqlrcrKWHRDJtn3toraZKAcLaPqca5CgqTa/PmiCvCq3uUowiFw9B7FOB0y3ikQoDppTw==", + "dev": true, + "license": "MIT", + "dependencies": { + "minimist": "^1.2.8", + "semver": "^7.5.4" + }, + "bin": { + "slack-cli-check-update": "src/check-update.js", + "slack-cli-doctor": "src/doctor.js", + "slack-cli-get-hooks": "src/get-hooks.js", + "slack-cli-get-manifest": "src/get-manifest.js", + "slack-cli-start": "src/start.js" + }, + "engines": { + "node": ">= 20", + "npm": ">=9.6.4" + } + }, + "node_modules/@slack/logger": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@slack/logger/-/logger-5.0.0.tgz", + "integrity": "sha512-VGXhmmgsAo9shdQYh4tFDndd+7nsgp0Y5h0UPDaUp8K359pBasI6YdkMqFW3mCOxLQkq09qj7o7cq6f3DuXcJQ==", + "license": "MIT", + "dependencies": { + "@types/node": ">=20" + }, + "engines": { + "node": ">= 20", + "npm": ">=9.6.4" + } + }, + "node_modules/@slack/types": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@slack/types/-/types-3.0.0.tgz", + "integrity": "sha512-KNOqpnNAlsFt5Jk9XBclslQ0lobRIg/0tnhpmvZJAglHJx9E8oceN8hC3gaBzkR6UzQ9Wzq4rLsJ98wUcxWPfw==", + "license": "MIT", + "engines": { + "node": ">= 20", + "npm": ">=9.6.4" + } + }, + "node_modules/@slack/web-api": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/@slack/web-api/-/web-api-8.0.0.tgz", + "integrity": "sha512-ORx3XQryQPq2Jnxv5giSKXVoQRUeylrrymIR2S9fPzLjPcCts8RayMeBSZMcpfpAqp6fnBRuPW2UB6dUPUTEZA==", + "license": "MIT", + "dependencies": { + "@slack/logger": "^5.0.0", + "@slack/types": "^3.0.0", + "@types/node": ">=20", + "@types/retry": "0.12.0", + "eventemitter3": "^5.0.1", + "p-queue": "^6", + "p-retry": "^4", + "retry": "^0.13.1" + }, + "engines": { + "node": ">= 20", + "npm": ">=9.6.4" + } + }, + "node_modules/@types/node": { + "version": "24.13.3", + "resolved": "https://registry.npmjs.org/@types/node/-/node-24.13.3.tgz", + "integrity": "sha512-Dh8vAsV36ig5wa9OX4pXvMc9D3Veibfw2wix0CUwYODLD8nkj9UsLjASr49nPg+2eKzxhBV+v7L8pXvT4e639Q==", + "license": "MIT", + "dependencies": { + "undici-types": "~7.18.0" + } + }, + "node_modules/@types/retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz", + "integrity": "sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==", + "license": "MIT" + }, + "node_modules/eventemitter3": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.4.tgz", + "integrity": "sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==", + "license": "MIT" + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/p-queue": { + "version": "6.6.2", + "resolved": "https://registry.npmjs.org/p-queue/-/p-queue-6.6.2.tgz", + "integrity": "sha512-RwFpb72c/BhQLEXIZ5K2e+AhgNVmIejGlTgiB9MzZ0e93GRvqZ7uSi0dvRF7/XIXDeNkra2fNHBxTyPDGySpjQ==", + "license": "MIT", + "dependencies": { + "eventemitter3": "^4.0.4", + "p-timeout": "^3.2.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-queue/node_modules/eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", + "license": "MIT" + }, + "node_modules/p-retry": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-4.6.2.tgz", + "integrity": "sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ==", + "license": "MIT", + "dependencies": { + "@types/retry": "0.12.0", + "retry": "^0.13.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-timeout": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-3.2.0.tgz", + "integrity": "sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==", + "license": "MIT", + "dependencies": { + "p-finally": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/retry": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", + "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/semver": { + "version": "7.8.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", + "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/typescript": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-6.0.3.tgz", + "integrity": "sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/undici-types": { + "version": "7.18.2", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.18.2.tgz", + "integrity": "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==", + "license": "MIT" + } + } +} diff --git a/methods/package.json b/methods/package.json new file mode 100644 index 0000000..dc7555c --- /dev/null +++ b/methods/package.json @@ -0,0 +1,29 @@ +{ + "$schema": "https://www.schemastore.org/package.json", + "private": true, + "type": "module", + "scripts": { + "check": "npx tsc -p tsconfig.json", + "lint": "npx @biomejs/biome check .", + "lint:fix": "npx @biomejs/biome check --write .", + "test": "node --test" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/slack-samples/bolt-js-examples.git" + }, + "author": "Slack Technologies, LLC", + "bugs": { + "url": "https://github.com/slack-samples/bolt-js-examples/issues" + }, + "homepage": "https://github.com/slack-samples/bolt-js-examples/blob/main/methods/README.md", + "dependencies": { + "@slack/web-api": "^8.0.0" + }, + "devDependencies": { + "@biomejs/biome": "^2.5.3", + "@slack/cli-hooks": "^2.0.0", + "@types/node": "^24.13.3", + "typescript": "^6.0.3" + } +} diff --git a/methods/tsconfig.json b/methods/tsconfig.json new file mode 100644 index 0000000..0b4db47 --- /dev/null +++ b/methods/tsconfig.json @@ -0,0 +1,12 @@ +{ + "compilerOptions": { + "checkJs": true, + "noEmit": true, + "allowJs": true, + "module": "nodenext", + "moduleResolution": "nodenext", + "target": "es2022", + "types": ["node"] + }, + "include": ["**/src/**/*.js", "**/tests/**/*.js"] +}