@toolsdk.ai/registry 1.0.131 → 1.0.133

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/README.md +11 -10
  2. package/dist/api/index.js +4 -0
  3. package/dist/domains/executor/executor-types.d.ts +3 -1
  4. package/dist/domains/executor/local-executor.d.ts +1 -1
  5. package/dist/domains/executor/local-executor.js +3 -3
  6. package/dist/domains/executor/sandbox-executor.d.ts +1 -1
  7. package/dist/domains/executor/sandbox-executor.js +3 -3
  8. package/dist/domains/oauth/__tests__/oauth-session.test.d.ts +1 -0
  9. package/dist/domains/oauth/__tests__/oauth-session.test.js +272 -0
  10. package/dist/domains/oauth/__tests__/oauth-utils.test.d.ts +1 -0
  11. package/dist/domains/oauth/__tests__/oauth-utils.test.js +284 -0
  12. package/dist/domains/oauth/index.d.ts +9 -0
  13. package/dist/domains/oauth/index.js +9 -0
  14. package/dist/domains/oauth/oauth-handler.d.ts +65 -0
  15. package/dist/domains/oauth/oauth-handler.js +355 -0
  16. package/dist/domains/oauth/oauth-route.d.ts +11 -0
  17. package/dist/domains/oauth/oauth-route.js +138 -0
  18. package/dist/domains/oauth/oauth-schema.d.ts +257 -0
  19. package/dist/domains/oauth/oauth-schema.js +119 -0
  20. package/dist/domains/oauth/oauth-session.d.ts +54 -0
  21. package/dist/domains/oauth/oauth-session.js +116 -0
  22. package/dist/domains/oauth/oauth-types.d.ts +148 -0
  23. package/dist/domains/oauth/oauth-types.js +9 -0
  24. package/dist/domains/oauth/oauth-utils.d.ts +99 -0
  25. package/dist/domains/oauth/oauth-utils.js +267 -0
  26. package/dist/domains/package/package-handler.d.ts +2 -2
  27. package/dist/domains/package/package-handler.js +4 -4
  28. package/dist/domains/package/package-route.js +5 -5
  29. package/dist/domains/package/package-schema.d.ts +81 -4
  30. package/dist/domains/package/package-schema.js +17 -0
  31. package/dist/domains/package/package-so.d.ts +11 -3
  32. package/dist/domains/package/package-so.js +4 -3
  33. package/dist/shared/schemas/common-schema.d.ts +92 -4
  34. package/dist/shared/schemas/common-schema.js +13 -0
  35. package/dist/shared/scripts-helpers/index.d.ts +9 -1
  36. package/dist/shared/utils/mcp-client-util.d.ts +3 -3
  37. package/dist/shared/utils/mcp-client-util.js +22 -1
  38. package/indexes/categories-list.json +1 -0
  39. package/indexes/packages-list.json +15 -0
  40. package/package.json +2 -1
  41. package/packages/developer-tools/github-mcp.json +19 -0
package/README.md CHANGED
@@ -13,7 +13,7 @@
13
13
  <a href="https://github.com/toolsdk-ai/toolsdk-mcp-registry/actions/workflows/test.yaml">
14
14
  <img src="https://github.com/toolsdk-ai/toolsdk-mcp-registry/actions/workflows/test.yaml/badge.svg" alt="Build Status" />
15
15
  </a>
16
- <img src="https://img.shields.io/badge/MCP_Servers-4109-blue?style=flat-square" alt="MCP Servers Count" />
16
+ <img src="https://img.shields.io/badge/MCP_Servers-4110-blue?style=flat-square" alt="MCP Servers Count" />
17
17
  <img src="https://img.shields.io/badge/LICENSE-MIT-ff69b4?style=flat-square" alt="License" />
18
18
  </p>
19
19
 
@@ -24,7 +24,7 @@
24
24
  </p>
25
25
 
26
26
  <p align="center">
27
- 🚀 <b>Open-source</b>, <b>production-ready</b>, and <b>developer-friendly</b> registry for 4109+ Model Context Protocol (MCP) servers.
27
+ 🚀 <b>Open-source</b>, <b>production-ready</b>, and <b>developer-friendly</b> registry for 4110+ Model Context Protocol (MCP) servers.
28
28
  <br />
29
29
  <i>Perfect for <b>AI automation</b>, <b>chatbot development</b>, <b>LLM integrations</b>, and <b>enterprise AI deployments</b>.</i>
30
30
  </p>
@@ -34,7 +34,7 @@
34
34
  </p>
35
35
 
36
36
  <p align="center">
37
- <a href="#mcp-servers">🔍 <b>Browse 4109+ Tools</b></a>
37
+ <a href="#mcp-servers">🔍 <b>Browse 4110+ Tools</b></a>
38
38
  &nbsp;&nbsp;•&nbsp;&nbsp;
39
39
  <a href="#quick-start">🐳 <b>Deploy Private Registry</b></a>
40
40
  &nbsp;&nbsp;•&nbsp;&nbsp;
@@ -73,7 +73,7 @@ docker compose up -d
73
73
  - *See [Configuration Guide](./docs/DEVELOPMENT.md) for full details.*
74
74
 
75
75
  > 💡 **Tip for Private Deployment**:
76
- > This registry contains 4109+ public MCP servers. If you only need a specific subset for your private environment, you can prune the `packages/` directory.
76
+ > This registry contains 4110+ public MCP servers. If you only need a specific subset for your private environment, you can prune the `packages/` directory.
77
77
  > 📖 See [Package Management Guide](./docs/DEVELOPMENT.md#5--package-management-for-private-deployment) for details.
78
78
 
79
79
  That's it! Your self-hosted MCP registry is now running with:
@@ -85,7 +85,7 @@ That's it! Your self-hosted MCP registry is now running with:
85
85
 
86
86
  - 🌐 **Local Web Interface**: http://localhost:3003
87
87
  - 📚 **Swagger API Docs**: http://localhost:3003/swagger
88
- - 🔍 **Search & Execute** 4109+ MCP Servers remotely
88
+ - 🔍 **Search & Execute** 4110+ MCP Servers remotely
89
89
  - 🤖 **Integrate** with your AI agents, chatbots, and LLM applications
90
90
 
91
91
  #### 💻 Remote Tool Execution Example
@@ -169,7 +169,7 @@ mcp_servers = requests.get(
169
169
  ### 🎯 Key Features
170
170
 
171
171
  - 🔐 **Private & Self-Hosted** - Deploy your own secure MCP registry with Docker in minutes
172
- - 🤖 **4109+ MCP Servers** - Largest curated collection of MCP servers
172
+ - 🤖 **4110+ MCP Servers** - Largest curated collection of MCP servers
173
173
  - ⚡ **Remote Execution** - Run MCP tools in isolated sandbox environments via REST API
174
174
  - 🔍 **Powerful Search** - Fast, full-text search powered by Meilisearch
175
175
  - 📦 **NPM Integration** - Use as a TypeScript/Node.js SDK in your projects
@@ -225,7 +225,7 @@ graph TD
225
225
 
226
226
  This open-source registry provides:
227
227
 
228
- - 📚 **Structured Registry** - 4109+ validated MCP servers with metadata
228
+ - 📚 **Structured Registry** - 4110+ validated MCP servers with metadata
229
229
  - 🔗 **Multiple Formats** - JSON, npm package, and generated documentation
230
230
  - 🌐 **REST API** - Query and execute tools remotely
231
231
  - 📖 **Auto-Generated Docs** - Always up-to-date README and API documentation
@@ -313,7 +313,7 @@ Help grow the world's largest open-source MCP registry! Share your AI tools, plu
313
313
 
314
314
  - [Fork this repository](https://github.com/toolsdk-ai/toolsdk-mcp-registry/fork)
315
315
  - Create `your-mcp-server.json` in [packages/uncategorized](./packages/uncategorized)
316
- - Submit a PR and join 4109+ MCP servers!
316
+ - Submit a PR and join 4110+ MCP servers!
317
317
 
318
318
  **3. Get Discovered**
319
319
 
@@ -331,9 +331,9 @@ Your MCP server will be:
331
331
 
332
332
  ## 📋 MCP Servers Directory
333
333
 
334
- **4109+ AI Agent Tools, LLM Integrations & Automation Servers**
334
+ **4110+ AI Agent Tools, LLM Integrations & Automation Servers**
335
335
 
336
- - ✅ **Validated & Tested** (710) - Production-ready MCP servers
336
+ - ✅ **Validated & Tested** (711) - Production-ready MCP servers
337
337
  - ⚙️ **Community Contributed** (3399) - Requires configuration
338
338
 
339
339
  Browse by category: Developer Tools, AI Agents, Databases, Cloud Platforms, APIs, and more!
@@ -1908,6 +1908,7 @@ Enhance your development workflow with tools for coding and environment manageme
1908
1908
  - [✅ deepsource-mcp-server](https://github.com/sapientpants/deepsource-mcp-server): Integrates with DeepSource's code quality platform to provide access to project metrics, issues, and analysis results for monitoring and troubleshooting code quality directly in conversations. (10 tools) (node)
1909
1909
  - [✅ freecad-mcp](https://github.com/neka-nat/freecad-mcp): Enables AI-driven CAD modeling by providing a remote procedure call (RPC) server that allows programmatic control of FreeCAD, supporting operations like creating documents, inserting parts, editing objects, and executing Python code for generative design workflows. (10 tools) (python)
1910
1910
  - [✅ gistpad-mcp](https://github.com/lostintangent/gistpad-mcp): Transforms GitHub Gists into a personal knowledge management system with specialized handling for daily notes, reusable prompts with frontmatter support, and comprehensive gist operations including creation, updating, archiving, and commenting for version-controlled knowledge storage. (28 tools) (node)
1911
+ - [✅ github-mcp](https://github.com/Seey215/github-mcp): A powerful GitHub automation tool that seamlessly connects AI assistants to your GitHub repositories (2 tools) (node)
1911
1912
  - [✅ ios-simulator-mcp](https://github.com/joshuayoes/ios-simulator-mcp): Enables Claude to control iOS simulators for testing and debugging applications by providing tools for UI interaction, element inspection, and device information retrieval through Facebook's IDB tool. (10 tools) (node)
1912
1913
  - [✅ it-tools-mcp](https://github.com/wrenchpilot/it-tools-mcp): Provides 50+ developer utilities including cryptographic operations, text processing, data format conversion, network calculations, and encoding functions through a containerized TypeScript server with security features and rate limiting. (119 tools) (node)
1913
1914
  - [✅ jnews-mcp-server](https://github.com/juhemcp/jnews-mcp-server): Lightweight Python FastAPI server implementation for streamlined server-side interactions, using modern tooling like uv for dependency management and GitHub Actions for automated testing and deployment. (2 tools) (python)
package/dist/api/index.js CHANGED
@@ -4,6 +4,7 @@ import { serve } from "@hono/node-server";
4
4
  import { swaggerUI } from "@hono/swagger-ui";
5
5
  import { OpenAPIHono } from "@hono/zod-openapi";
6
6
  import { configRoutes } from "../domains/config/config-route";
7
+ import { oauthDemoRoutes, oauthRoutes } from "../domains/oauth/oauth-route";
7
8
  import { repository } from "../domains/package/package-handler";
8
9
  import { packageRoutes } from "../domains/package/package-route";
9
10
  import { initRegistryFactory } from "../domains/registry/registry-factory";
@@ -31,6 +32,9 @@ const app = new OpenAPIHono();
31
32
  // Domain routes
32
33
  app.route("/api/v1", packageRoutes);
33
34
  app.route("/api/v1/config", configRoutes);
35
+ app.route("/api/v1/oauth", oauthRoutes);
36
+ // Demo routes (serves demo-oauth.html and handles callbacks)
37
+ app.route("/demo", oauthDemoRoutes);
34
38
  if (isSearchEnabled()) {
35
39
  initializeSearchService().catch(console.error);
36
40
  app.route("/api/v1/search", searchRoutes);
@@ -6,6 +6,8 @@ export interface ToolExecuteRequest {
6
6
  inputData: Record<string, unknown>;
7
7
  envs?: Record<string, string>;
8
8
  sandboxProvider?: MCPSandboxProvider;
9
+ /** OAuth access token for MCP servers that require OAuth authentication */
10
+ accessToken?: string;
9
11
  }
10
12
  /**
11
13
  * Tool Executor Interface
@@ -13,5 +15,5 @@ export interface ToolExecuteRequest {
13
15
  */
14
16
  export interface ToolExecutor {
15
17
  executeTool(request: ToolExecuteRequest): Promise<unknown>;
16
- listTools(packageName: string, sandboxProvider?: MCPSandboxProvider): Promise<Tool[]>;
18
+ listTools(packageName: string, accessToken?: string): Promise<Tool[]>;
17
19
  }
@@ -8,5 +8,5 @@ export declare class LocalExecutor implements ToolExecutor {
8
8
  private readonly packageRepository;
9
9
  constructor();
10
10
  executeTool(request: ToolExecuteRequest): Promise<unknown>;
11
- listTools(packageName: string): Promise<Tool[]>;
11
+ listTools(packageName: string, accessToken?: string): Promise<Tool[]>;
12
12
  }
@@ -14,7 +14,7 @@ export class LocalExecutor {
14
14
  }
15
15
  async executeTool(request) {
16
16
  const mcpServerConfig = this.packageRepository.getPackageConfig(request.packageName);
17
- const { client, closeConnection } = await getMcpClient(mcpServerConfig, request.envs || {});
17
+ const { client, closeConnection } = await getMcpClient(mcpServerConfig, request.envs || {}, request.accessToken);
18
18
  try {
19
19
  const result = await client.callTool({
20
20
  name: request.toolKey,
@@ -27,7 +27,7 @@ export class LocalExecutor {
27
27
  await closeConnection();
28
28
  }
29
29
  }
30
- async listTools(packageName) {
30
+ async listTools(packageName, accessToken) {
31
31
  const mcpServerConfig = this.packageRepository.getPackageConfig(packageName);
32
32
  const mockEnvs = {};
33
33
  if (mcpServerConfig.env) {
@@ -35,7 +35,7 @@ export class LocalExecutor {
35
35
  mockEnvs[key] = "mock_value";
36
36
  });
37
37
  }
38
- const { client, closeConnection } = await getMcpClient(mcpServerConfig, mockEnvs);
38
+ const { client, closeConnection } = await getMcpClient(mcpServerConfig, mockEnvs, accessToken);
39
39
  try {
40
40
  const { tools } = await client.listTools();
41
41
  console.log(`[LocalExecutor] Tools list retrieved successfully for package ${packageName}`);
@@ -12,5 +12,5 @@ export declare class SandboxExecutor implements ToolExecutor {
12
12
  private readonly localExecutor;
13
13
  constructor(provider: MCPSandboxProvider);
14
14
  executeTool(request: ToolExecuteRequest): Promise<unknown>;
15
- listTools(packageName: string): Promise<Tool[]>;
15
+ listTools(packageName: string, accessToken?: string): Promise<Tool[]>;
16
16
  }
@@ -48,13 +48,13 @@ export class SandboxExecutor {
48
48
  await this.sandboxPool.release(runtime, this.provider);
49
49
  }
50
50
  }
51
- async listTools(packageName) {
51
+ async listTools(packageName, accessToken) {
52
52
  const mcpServerConfig = this.packageRepository.getPackageConfig(packageName);
53
53
  const runtime = mcpServerConfig.runtime || "python";
54
54
  // Sandbox only supports node runtime, fallback to LOCAL for other runtimes
55
55
  if (runtime !== "node") {
56
56
  console.log(`[SandboxExecutor] Runtime '${runtime}' is not supported in sandbox, using LOCAL execution`);
57
- return await this.localExecutor.listTools(packageName);
57
+ return await this.localExecutor.listTools(packageName, accessToken);
58
58
  }
59
59
  const sandboxClient = await this.sandboxPool.acquire(runtime, this.provider);
60
60
  try {
@@ -67,7 +67,7 @@ export class SandboxExecutor {
67
67
  console.warn(`[SandboxExecutor] sandbox list tools failed, falling back to LOCAL execution`);
68
68
  console.warn(`[SandboxExecutor] Error: ${error instanceof Error ? error.message : String(error)}`);
69
69
  try {
70
- const tools = await this.localExecutor.listTools(packageName);
70
+ const tools = await this.localExecutor.listTools(packageName, accessToken);
71
71
  console.log(`[SandboxExecutor] Tools list retrieved successfully with LOCAL fallback`);
72
72
  return tools;
73
73
  }
@@ -0,0 +1,272 @@
1
+ import { afterEach, beforeEach, describe, expect, it } from "vitest";
2
+ import { OAuthSessionStore } from "../oauth-session";
3
+ // Create a new instance for testing (not the singleton)
4
+ function createTestStore() {
5
+ const store = new OAuthSessionStore();
6
+ // Stop the cleanup timer to avoid interference with tests
7
+ store.stopCleanup();
8
+ return store;
9
+ }
10
+ function createMockSession(overrides = {}) {
11
+ return Object.assign({ sessionId: "test-session-id", state: "test-state", codeVerifier: "test-code-verifier", codeChallenge: "test-code-challenge", clientInfo: {
12
+ client_id: "test-client-id",
13
+ }, callbackBaseUrl: "http://localhost:3003/callback", mcpServerUrl: "http://localhost:3001/mcp", packageName: "github-mcp", oauthMetadata: {
14
+ issuer: "http://localhost:3001",
15
+ authorization_endpoint: "http://localhost:3001/authorize",
16
+ token_endpoint: "http://localhost:3001/token",
17
+ }, createdAt: Date.now() }, overrides);
18
+ }
19
+ describe("OAuthSessionStore", () => {
20
+ let store;
21
+ beforeEach(() => {
22
+ store = createTestStore();
23
+ });
24
+ afterEach(() => {
25
+ store.stopCleanup();
26
+ store.clear();
27
+ });
28
+ describe("set", () => {
29
+ it("should store a session", () => {
30
+ // Arrange
31
+ const session = createMockSession();
32
+ // Act
33
+ store.set(session);
34
+ // Assert
35
+ expect(store.has(session.sessionId)).toBe(true);
36
+ expect(store.size()).toBe(1);
37
+ });
38
+ it("should allow retrieval by sessionId after set", () => {
39
+ // Arrange
40
+ const session = createMockSession();
41
+ // Act
42
+ store.set(session);
43
+ const retrieved = store.get(session.sessionId);
44
+ // Assert
45
+ expect(retrieved).toEqual(session);
46
+ });
47
+ it("should allow retrieval by state after set", () => {
48
+ // Arrange
49
+ const session = createMockSession();
50
+ // Act
51
+ store.set(session);
52
+ const retrieved = store.getByState(session.state);
53
+ // Assert
54
+ expect(retrieved).toEqual(session);
55
+ });
56
+ it("should overwrite session with same sessionId", () => {
57
+ // Arrange
58
+ const session1 = createMockSession({ packageName: "package1" });
59
+ const session2 = createMockSession({ packageName: "package2" });
60
+ // Act
61
+ store.set(session1);
62
+ store.set(session2);
63
+ // Assert
64
+ const retrieved = store.get(session1.sessionId);
65
+ expect(retrieved === null || retrieved === void 0 ? void 0 : retrieved.packageName).toBe("package2");
66
+ expect(store.size()).toBe(1);
67
+ });
68
+ });
69
+ describe("get", () => {
70
+ it("should return undefined for non-existent session", () => {
71
+ // Act
72
+ const result = store.get("non-existent-id");
73
+ // Assert
74
+ expect(result).toBeUndefined();
75
+ });
76
+ it("should return session when exists", () => {
77
+ // Arrange
78
+ const session = createMockSession();
79
+ store.set(session);
80
+ // Act
81
+ const result = store.get(session.sessionId);
82
+ // Assert
83
+ expect(result).toEqual(session);
84
+ });
85
+ it("should return undefined for expired session", () => {
86
+ // Arrange - create session that expired 11 minutes ago
87
+ const expiredSession = createMockSession({
88
+ sessionId: "expired-session",
89
+ createdAt: Date.now() - 11 * 60 * 1000,
90
+ });
91
+ store.set(expiredSession);
92
+ // Act
93
+ const result = store.get("expired-session");
94
+ // Assert
95
+ expect(result).toBeUndefined();
96
+ expect(store.has("expired-session")).toBe(false);
97
+ });
98
+ it("should return session that is still valid (9 minutes old)", () => {
99
+ // Arrange
100
+ const validSession = createMockSession({
101
+ sessionId: "valid-session",
102
+ createdAt: Date.now() - 9 * 60 * 1000,
103
+ });
104
+ store.set(validSession);
105
+ // Act
106
+ const result = store.get("valid-session");
107
+ // Assert
108
+ expect(result).toBeDefined();
109
+ expect(result === null || result === void 0 ? void 0 : result.sessionId).toBe("valid-session");
110
+ });
111
+ });
112
+ describe("getByState", () => {
113
+ it("should return undefined for non-existent state", () => {
114
+ // Act
115
+ const result = store.getByState("non-existent-state");
116
+ // Assert
117
+ expect(result).toBeUndefined();
118
+ });
119
+ it("should return session when state exists", () => {
120
+ // Arrange
121
+ const session = createMockSession({ state: "unique-state" });
122
+ store.set(session);
123
+ // Act
124
+ const result = store.getByState("unique-state");
125
+ // Assert
126
+ expect(result).toEqual(session);
127
+ });
128
+ it("should return undefined for expired session by state", () => {
129
+ // Arrange
130
+ const expiredSession = createMockSession({
131
+ state: "expired-state",
132
+ createdAt: Date.now() - 11 * 60 * 1000,
133
+ });
134
+ store.set(expiredSession);
135
+ // Act
136
+ const result = store.getByState("expired-state");
137
+ // Assert
138
+ expect(result).toBeUndefined();
139
+ });
140
+ });
141
+ describe("delete", () => {
142
+ it("should return false for non-existent session", () => {
143
+ // Act
144
+ const result = store.delete("non-existent-id");
145
+ // Assert
146
+ expect(result).toBe(false);
147
+ });
148
+ it("should delete existing session and return true", () => {
149
+ // Arrange
150
+ const session = createMockSession();
151
+ store.set(session);
152
+ // Act
153
+ const result = store.delete(session.sessionId);
154
+ // Assert
155
+ expect(result).toBe(true);
156
+ expect(store.has(session.sessionId)).toBe(false);
157
+ expect(store.size()).toBe(0);
158
+ });
159
+ it("should also remove state mapping when session is deleted", () => {
160
+ // Arrange
161
+ const session = createMockSession({ state: "state-to-delete" });
162
+ store.set(session);
163
+ // Act
164
+ store.delete(session.sessionId);
165
+ const byState = store.getByState("state-to-delete");
166
+ // Assert
167
+ expect(byState).toBeUndefined();
168
+ });
169
+ });
170
+ describe("has", () => {
171
+ it("should return false for non-existent session", () => {
172
+ // Act
173
+ const result = store.has("non-existent-id");
174
+ // Assert
175
+ expect(result).toBe(false);
176
+ });
177
+ it("should return true for existing session", () => {
178
+ // Arrange
179
+ const session = createMockSession();
180
+ store.set(session);
181
+ // Act
182
+ const result = store.has(session.sessionId);
183
+ // Assert
184
+ expect(result).toBe(true);
185
+ });
186
+ });
187
+ describe("size", () => {
188
+ it("should return 0 for empty store", () => {
189
+ // Act
190
+ const result = store.size();
191
+ // Assert
192
+ expect(result).toBe(0);
193
+ });
194
+ it("should return correct count after adding sessions", () => {
195
+ // Arrange
196
+ store.set(createMockSession({ sessionId: "session-1", state: "state-1" }));
197
+ store.set(createMockSession({ sessionId: "session-2", state: "state-2" }));
198
+ store.set(createMockSession({ sessionId: "session-3", state: "state-3" }));
199
+ // Act
200
+ const result = store.size();
201
+ // Assert
202
+ expect(result).toBe(3);
203
+ });
204
+ it("should return correct count after deleting sessions", () => {
205
+ // Arrange
206
+ store.set(createMockSession({ sessionId: "session-1", state: "state-1" }));
207
+ store.set(createMockSession({ sessionId: "session-2", state: "state-2" }));
208
+ store.delete("session-1");
209
+ // Act
210
+ const result = store.size();
211
+ // Assert
212
+ expect(result).toBe(1);
213
+ });
214
+ });
215
+ describe("clear", () => {
216
+ it("should remove all sessions", () => {
217
+ // Arrange
218
+ store.set(createMockSession({ sessionId: "session-1", state: "state-1" }));
219
+ store.set(createMockSession({ sessionId: "session-2", state: "state-2" }));
220
+ // Act
221
+ store.clear();
222
+ // Assert
223
+ expect(store.size()).toBe(0);
224
+ expect(store.has("session-1")).toBe(false);
225
+ expect(store.has("session-2")).toBe(false);
226
+ });
227
+ it("should also clear state mappings", () => {
228
+ // Arrange
229
+ store.set(createMockSession({ sessionId: "session-1", state: "state-1" }));
230
+ // Act
231
+ store.clear();
232
+ const byState = store.getByState("state-1");
233
+ // Assert
234
+ expect(byState).toBeUndefined();
235
+ });
236
+ });
237
+ describe("multiple sessions", () => {
238
+ it("should handle multiple sessions with different states", () => {
239
+ var _a, _b, _c, _d;
240
+ // Arrange
241
+ const session1 = createMockSession({
242
+ sessionId: "session-1",
243
+ state: "state-1",
244
+ packageName: "package-1",
245
+ });
246
+ const session2 = createMockSession({
247
+ sessionId: "session-2",
248
+ state: "state-2",
249
+ packageName: "package-2",
250
+ });
251
+ // Act
252
+ store.set(session1);
253
+ store.set(session2);
254
+ // Assert
255
+ expect((_a = store.get("session-1")) === null || _a === void 0 ? void 0 : _a.packageName).toBe("package-1");
256
+ expect((_b = store.get("session-2")) === null || _b === void 0 ? void 0 : _b.packageName).toBe("package-2");
257
+ expect((_c = store.getByState("state-1")) === null || _c === void 0 ? void 0 : _c.packageName).toBe("package-1");
258
+ expect((_d = store.getByState("state-2")) === null || _d === void 0 ? void 0 : _d.packageName).toBe("package-2");
259
+ });
260
+ it("should not affect other sessions when deleting one", () => {
261
+ // Arrange
262
+ store.set(createMockSession({ sessionId: "session-1", state: "state-1" }));
263
+ store.set(createMockSession({ sessionId: "session-2", state: "state-2" }));
264
+ // Act
265
+ store.delete("session-1");
266
+ // Assert
267
+ expect(store.has("session-1")).toBe(false);
268
+ expect(store.has("session-2")).toBe(true);
269
+ expect(store.getByState("state-2")).toBeDefined();
270
+ });
271
+ });
272
+ });
@@ -0,0 +1 @@
1
+ export {};