@cyanheads/pubchem-mcp-server 1.0.1

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 (127) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +236 -0
  3. package/dist/config/index.d.ts +98 -0
  4. package/dist/config/index.js +326 -0
  5. package/dist/index.d.ts +24 -0
  6. package/dist/index.js +214 -0
  7. package/dist/mcp-server/server.d.ts +21 -0
  8. package/dist/mcp-server/server.js +124 -0
  9. package/dist/mcp-server/tools/fetchAssaySummary/index.d.ts +7 -0
  10. package/dist/mcp-server/tools/fetchAssaySummary/index.js +7 -0
  11. package/dist/mcp-server/tools/fetchAssaySummary/logic.d.ts +71 -0
  12. package/dist/mcp-server/tools/fetchAssaySummary/logic.js +96 -0
  13. package/dist/mcp-server/tools/fetchAssaySummary/registration.d.ts +12 -0
  14. package/dist/mcp-server/tools/fetchAssaySummary/registration.js +68 -0
  15. package/dist/mcp-server/tools/fetchCompoundProperties/index.d.ts +7 -0
  16. package/dist/mcp-server/tools/fetchCompoundProperties/index.js +7 -0
  17. package/dist/mcp-server/tools/fetchCompoundProperties/logic.d.ts +131 -0
  18. package/dist/mcp-server/tools/fetchCompoundProperties/logic.js +100 -0
  19. package/dist/mcp-server/tools/fetchCompoundProperties/registration.d.ts +13 -0
  20. package/dist/mcp-server/tools/fetchCompoundProperties/registration.js +52 -0
  21. package/dist/mcp-server/tools/fetchCompoundXrefs/index.d.ts +7 -0
  22. package/dist/mcp-server/tools/fetchCompoundXrefs/index.js +7 -0
  23. package/dist/mcp-server/tools/fetchCompoundXrefs/logic.d.ts +89 -0
  24. package/dist/mcp-server/tools/fetchCompoundXrefs/logic.js +145 -0
  25. package/dist/mcp-server/tools/fetchCompoundXrefs/registration.d.ts +13 -0
  26. package/dist/mcp-server/tools/fetchCompoundXrefs/registration.js +52 -0
  27. package/dist/mcp-server/tools/fetchSubstanceDetails/index.d.ts +7 -0
  28. package/dist/mcp-server/tools/fetchSubstanceDetails/index.js +7 -0
  29. package/dist/mcp-server/tools/fetchSubstanceDetails/logic.d.ts +69 -0
  30. package/dist/mcp-server/tools/fetchSubstanceDetails/logic.js +97 -0
  31. package/dist/mcp-server/tools/fetchSubstanceDetails/registration.d.ts +13 -0
  32. package/dist/mcp-server/tools/fetchSubstanceDetails/registration.js +79 -0
  33. package/dist/mcp-server/tools/getCompoundImage/index.d.ts +7 -0
  34. package/dist/mcp-server/tools/getCompoundImage/index.js +7 -0
  35. package/dist/mcp-server/tools/getCompoundImage/logic.d.ts +42 -0
  36. package/dist/mcp-server/tools/getCompoundImage/logic.js +68 -0
  37. package/dist/mcp-server/tools/getCompoundImage/registration.d.ts +12 -0
  38. package/dist/mcp-server/tools/getCompoundImage/registration.js +57 -0
  39. package/dist/mcp-server/tools/searchAssaysByTarget/index.d.ts +7 -0
  40. package/dist/mcp-server/tools/searchAssaysByTarget/index.js +7 -0
  41. package/dist/mcp-server/tools/searchAssaysByTarget/logic.d.ts +35 -0
  42. package/dist/mcp-server/tools/searchAssaysByTarget/logic.js +64 -0
  43. package/dist/mcp-server/tools/searchAssaysByTarget/registration.d.ts +12 -0
  44. package/dist/mcp-server/tools/searchAssaysByTarget/registration.js +62 -0
  45. package/dist/mcp-server/tools/searchCompoundByIdentifier/index.d.ts +7 -0
  46. package/dist/mcp-server/tools/searchCompoundByIdentifier/index.js +7 -0
  47. package/dist/mcp-server/tools/searchCompoundByIdentifier/logic.d.ts +35 -0
  48. package/dist/mcp-server/tools/searchCompoundByIdentifier/logic.js +59 -0
  49. package/dist/mcp-server/tools/searchCompoundByIdentifier/registration.d.ts +12 -0
  50. package/dist/mcp-server/tools/searchCompoundByIdentifier/registration.js +51 -0
  51. package/dist/mcp-server/tools/searchCompoundsByFormula/index.d.ts +7 -0
  52. package/dist/mcp-server/tools/searchCompoundsByFormula/index.js +7 -0
  53. package/dist/mcp-server/tools/searchCompoundsByFormula/logic.d.ts +38 -0
  54. package/dist/mcp-server/tools/searchCompoundsByFormula/logic.js +75 -0
  55. package/dist/mcp-server/tools/searchCompoundsByFormula/registration.d.ts +12 -0
  56. package/dist/mcp-server/tools/searchCompoundsByFormula/registration.js +62 -0
  57. package/dist/mcp-server/tools/searchCompoundsBySimilarity/index.d.ts +7 -0
  58. package/dist/mcp-server/tools/searchCompoundsBySimilarity/index.js +7 -0
  59. package/dist/mcp-server/tools/searchCompoundsBySimilarity/logic.d.ts +41 -0
  60. package/dist/mcp-server/tools/searchCompoundsBySimilarity/logic.js +82 -0
  61. package/dist/mcp-server/tools/searchCompoundsBySimilarity/registration.d.ts +12 -0
  62. package/dist/mcp-server/tools/searchCompoundsBySimilarity/registration.js +62 -0
  63. package/dist/mcp-server/tools/searchCompoundsByStructure/index.d.ts +7 -0
  64. package/dist/mcp-server/tools/searchCompoundsByStructure/index.js +7 -0
  65. package/dist/mcp-server/tools/searchCompoundsByStructure/logic.d.ts +41 -0
  66. package/dist/mcp-server/tools/searchCompoundsByStructure/logic.js +78 -0
  67. package/dist/mcp-server/tools/searchCompoundsByStructure/registration.d.ts +13 -0
  68. package/dist/mcp-server/tools/searchCompoundsByStructure/registration.js +63 -0
  69. package/dist/mcp-server/transports/auth/core/authContext.d.ts +33 -0
  70. package/dist/mcp-server/transports/auth/core/authContext.js +24 -0
  71. package/dist/mcp-server/transports/auth/core/authTypes.d.ts +17 -0
  72. package/dist/mcp-server/transports/auth/core/authTypes.js +5 -0
  73. package/dist/mcp-server/transports/auth/core/authUtils.d.ts +18 -0
  74. package/dist/mcp-server/transports/auth/core/authUtils.js +45 -0
  75. package/dist/mcp-server/transports/auth/index.d.ts +10 -0
  76. package/dist/mcp-server/transports/auth/index.js +9 -0
  77. package/dist/mcp-server/transports/auth/strategies/jwt/jwtMiddleware.d.ts +27 -0
  78. package/dist/mcp-server/transports/auth/strategies/jwt/jwtMiddleware.js +149 -0
  79. package/dist/mcp-server/transports/auth/strategies/oauth/oauthMiddleware.d.ts +20 -0
  80. package/dist/mcp-server/transports/auth/strategies/oauth/oauthMiddleware.js +124 -0
  81. package/dist/mcp-server/transports/httpErrorHandler.d.ts +26 -0
  82. package/dist/mcp-server/transports/httpErrorHandler.js +73 -0
  83. package/dist/mcp-server/transports/httpTransport.d.ts +21 -0
  84. package/dist/mcp-server/transports/httpTransport.js +208 -0
  85. package/dist/mcp-server/transports/stdioTransport.d.ts +42 -0
  86. package/dist/mcp-server/transports/stdioTransport.js +63 -0
  87. package/dist/services/pubchem/pubchemApiClient.d.ts +52 -0
  88. package/dist/services/pubchem/pubchemApiClient.js +120 -0
  89. package/dist/types-global/errors.d.ts +127 -0
  90. package/dist/types-global/errors.js +126 -0
  91. package/dist/utils/index.d.ts +12 -0
  92. package/dist/utils/index.js +20 -0
  93. package/dist/utils/internal/errorHandler.d.ts +176 -0
  94. package/dist/utils/internal/errorHandler.js +335 -0
  95. package/dist/utils/internal/index.d.ts +9 -0
  96. package/dist/utils/internal/index.js +9 -0
  97. package/dist/utils/internal/logger.d.ts +148 -0
  98. package/dist/utils/internal/logger.js +430 -0
  99. package/dist/utils/internal/requestContext.d.ts +83 -0
  100. package/dist/utils/internal/requestContext.js +72 -0
  101. package/dist/utils/metrics/index.d.ts +7 -0
  102. package/dist/utils/metrics/index.js +7 -0
  103. package/dist/utils/metrics/tokenCounter.d.ts +35 -0
  104. package/dist/utils/metrics/tokenCounter.js +110 -0
  105. package/dist/utils/network/fetchWithTimeout.d.ts +21 -0
  106. package/dist/utils/network/fetchWithTimeout.js +59 -0
  107. package/dist/utils/network/index.d.ts +6 -0
  108. package/dist/utils/network/index.js +5 -0
  109. package/dist/utils/parsing/dateParser.d.ts +73 -0
  110. package/dist/utils/parsing/dateParser.js +107 -0
  111. package/dist/utils/parsing/index.d.ts +8 -0
  112. package/dist/utils/parsing/index.js +8 -0
  113. package/dist/utils/parsing/jsonParser.d.ts +82 -0
  114. package/dist/utils/parsing/jsonParser.js +126 -0
  115. package/dist/utils/scheduling/index.d.ts +6 -0
  116. package/dist/utils/scheduling/index.js +6 -0
  117. package/dist/utils/scheduling/scheduler.d.ts +72 -0
  118. package/dist/utils/scheduling/scheduler.js +152 -0
  119. package/dist/utils/security/idGenerator.d.ts +137 -0
  120. package/dist/utils/security/idGenerator.js +215 -0
  121. package/dist/utils/security/index.d.ts +9 -0
  122. package/dist/utils/security/index.js +9 -0
  123. package/dist/utils/security/rateLimiter.d.ts +108 -0
  124. package/dist/utils/security/rateLimiter.js +179 -0
  125. package/dist/utils/security/sanitization.d.ts +184 -0
  126. package/dist/utils/security/sanitization.js +453 -0
  127. package/package.json +108 -0
@@ -0,0 +1,72 @@
1
+ /**
2
+ * @fileoverview Utilities for creating and managing request contexts.
3
+ * A request context is an object carrying a unique ID, timestamp, and other
4
+ * relevant data for logging, tracing, and processing. It also defines
5
+ * configuration and operational context structures.
6
+ * @module src/utils/internal/requestContext
7
+ */
8
+ import { generateUUID } from "../index.js";
9
+ import { logger } from "./logger.js";
10
+ /**
11
+ * Singleton-like service object for managing request context operations.
12
+ * @private
13
+ */
14
+ const requestContextServiceInstance = {
15
+ /**
16
+ * Internal configuration store for the service.
17
+ */
18
+ config: {},
19
+ /**
20
+ * Configures the request context service with new settings.
21
+ * Merges the provided partial configuration with existing settings.
22
+ *
23
+ * @param config - A partial `ContextConfig` object containing settings to update or add.
24
+ * @returns A shallow copy of the newly updated configuration.
25
+ */
26
+ configure(config) {
27
+ this.config = {
28
+ ...this.config,
29
+ ...config,
30
+ };
31
+ const logContext = this.createRequestContext({
32
+ operation: "RequestContextService.configure",
33
+ newConfigState: { ...this.config },
34
+ });
35
+ logger.debug("RequestContextService configuration updated", logContext);
36
+ return { ...this.config };
37
+ },
38
+ /**
39
+ * Retrieves a shallow copy of the current service configuration.
40
+ * This prevents direct mutation of the internal configuration state.
41
+ *
42
+ * @returns A shallow copy of the current `ContextConfig`.
43
+ */
44
+ getConfig() {
45
+ return { ...this.config };
46
+ },
47
+ /**
48
+ * Creates a new {@link RequestContext} instance.
49
+ * Each context is assigned a unique `requestId` (UUID) and a current `timestamp` (ISO 8601).
50
+ * Additional custom properties can be merged into the context.
51
+ *
52
+ * @param additionalContext - An optional record of key-value pairs to be
53
+ * included in the created request context.
54
+ * @returns A new `RequestContext` object.
55
+ */
56
+ createRequestContext(additionalContext = {}) {
57
+ const requestId = generateUUID();
58
+ const timestamp = new Date().toISOString();
59
+ const context = {
60
+ requestId,
61
+ timestamp,
62
+ ...additionalContext,
63
+ };
64
+ return context;
65
+ },
66
+ };
67
+ /**
68
+ * Primary export for request context functionalities.
69
+ * This service provides methods to create and manage {@link RequestContext} instances,
70
+ * which are essential for logging, tracing, and correlating operations.
71
+ */
72
+ export const requestContextService = requestContextServiceInstance;
@@ -0,0 +1,7 @@
1
+ /**
2
+ * @fileoverview Barrel file for metrics-related utility modules.
3
+ * This file re-exports utilities for collecting and processing metrics,
4
+ * such as token counting.
5
+ * @module src/utils/metrics
6
+ */
7
+ export * from "./tokenCounter.js";
@@ -0,0 +1,7 @@
1
+ /**
2
+ * @fileoverview Barrel file for metrics-related utility modules.
3
+ * This file re-exports utilities for collecting and processing metrics,
4
+ * such as token counting.
5
+ * @module src/utils/metrics
6
+ */
7
+ export * from "./tokenCounter.js";
@@ -0,0 +1,35 @@
1
+ /**
2
+ * @fileoverview Provides utility functions for counting tokens in text and chat messages
3
+ * using the `tiktoken` library, specifically configured for 'gpt-4o' tokenization.
4
+ * These functions are essential for managing token limits and estimating costs
5
+ * when interacting with language models.
6
+ * @module src/utils/metrics/tokenCounter
7
+ */
8
+ import { ChatCompletionMessageParam } from "openai/resources/chat/completions";
9
+ import { RequestContext } from "../index.js";
10
+ /**
11
+ * Calculates the number of tokens for a given text string using the
12
+ * tokenizer specified by `TOKENIZATION_MODEL`.
13
+ * Wraps tokenization in `ErrorHandler.tryCatch` for robust error management.
14
+ *
15
+ * @param text - The input text to tokenize.
16
+ * @param context - Optional request context for logging and error handling.
17
+ * @returns A promise that resolves with the number of tokens in the text.
18
+ * @throws {McpError} If tokenization fails.
19
+ */
20
+ export declare function countTokens(text: string, context?: RequestContext): Promise<number>;
21
+ /**
22
+ * Calculates the estimated number of tokens for an array of chat messages.
23
+ * Uses the tokenizer specified by `TOKENIZATION_MODEL` and accounts for
24
+ * special tokens and message overhead according to OpenAI's guidelines.
25
+ *
26
+ * For multi-part content, only text parts are currently tokenized.
27
+ *
28
+ * Reference: {@link https://github.com/openai/openai-cookbook/blob/main/examples/How_to_count_tokens_with_tiktoken.ipynb}
29
+ *
30
+ * @param messages - An array of chat messages.
31
+ * @param context - Optional request context for logging and error handling.
32
+ * @returns A promise that resolves with the estimated total number of tokens.
33
+ * @throws {McpError} If tokenization fails.
34
+ */
35
+ export declare function countChatTokens(messages: ReadonlyArray<ChatCompletionMessageParam>, context?: RequestContext): Promise<number>;
@@ -0,0 +1,110 @@
1
+ import { encoding_for_model } from "tiktoken";
2
+ import { BaseErrorCode } from "../../types-global/errors.js";
3
+ import { ErrorHandler, logger } from "../index.js";
4
+ /**
5
+ * The specific Tiktoken model used for all tokenization operations in this module.
6
+ * This ensures consistent token counting.
7
+ * @private
8
+ */
9
+ const TOKENIZATION_MODEL = "gpt-4o";
10
+ /**
11
+ * Calculates the number of tokens for a given text string using the
12
+ * tokenizer specified by `TOKENIZATION_MODEL`.
13
+ * Wraps tokenization in `ErrorHandler.tryCatch` for robust error management.
14
+ *
15
+ * @param text - The input text to tokenize.
16
+ * @param context - Optional request context for logging and error handling.
17
+ * @returns A promise that resolves with the number of tokens in the text.
18
+ * @throws {McpError} If tokenization fails.
19
+ */
20
+ export async function countTokens(text, context) {
21
+ return ErrorHandler.tryCatch(() => {
22
+ let encoding = null;
23
+ try {
24
+ encoding = encoding_for_model(TOKENIZATION_MODEL);
25
+ const tokens = encoding.encode(text);
26
+ return tokens.length;
27
+ }
28
+ finally {
29
+ encoding?.free();
30
+ }
31
+ }, {
32
+ operation: "countTokens",
33
+ context: context,
34
+ input: { textSample: text.substring(0, 50) + "..." },
35
+ errorCode: BaseErrorCode.INTERNAL_ERROR,
36
+ });
37
+ }
38
+ /**
39
+ * Calculates the estimated number of tokens for an array of chat messages.
40
+ * Uses the tokenizer specified by `TOKENIZATION_MODEL` and accounts for
41
+ * special tokens and message overhead according to OpenAI's guidelines.
42
+ *
43
+ * For multi-part content, only text parts are currently tokenized.
44
+ *
45
+ * Reference: {@link https://github.com/openai/openai-cookbook/blob/main/examples/How_to_count_tokens_with_tiktoken.ipynb}
46
+ *
47
+ * @param messages - An array of chat messages.
48
+ * @param context - Optional request context for logging and error handling.
49
+ * @returns A promise that resolves with the estimated total number of tokens.
50
+ * @throws {McpError} If tokenization fails.
51
+ */
52
+ export async function countChatTokens(messages, context) {
53
+ return ErrorHandler.tryCatch(() => {
54
+ let encoding = null;
55
+ let num_tokens = 0;
56
+ try {
57
+ encoding = encoding_for_model(TOKENIZATION_MODEL);
58
+ const tokens_per_message = 3; // For gpt-4o, gpt-4, gpt-3.5-turbo
59
+ const tokens_per_name = 1; // For gpt-4o, gpt-4, gpt-3.5-turbo
60
+ for (const message of messages) {
61
+ num_tokens += tokens_per_message;
62
+ num_tokens += encoding.encode(message.role).length;
63
+ if (typeof message.content === "string") {
64
+ num_tokens += encoding.encode(message.content).length;
65
+ }
66
+ else if (Array.isArray(message.content)) {
67
+ for (const part of message.content) {
68
+ if (part.type === "text") {
69
+ num_tokens += encoding.encode(part.text).length;
70
+ }
71
+ else {
72
+ logger.warning(`Non-text content part found (type: ${part.type}), token count contribution ignored.`, context);
73
+ }
74
+ }
75
+ }
76
+ if ("name" in message && message.name) {
77
+ num_tokens += tokens_per_name;
78
+ num_tokens += encoding.encode(message.name).length;
79
+ }
80
+ if (message.role === "assistant" &&
81
+ "tool_calls" in message &&
82
+ message.tool_calls) {
83
+ for (const tool_call of message.tool_calls) {
84
+ if (tool_call.function.name) {
85
+ num_tokens += encoding.encode(tool_call.function.name).length;
86
+ }
87
+ if (tool_call.function.arguments) {
88
+ num_tokens += encoding.encode(tool_call.function.arguments).length;
89
+ }
90
+ }
91
+ }
92
+ if (message.role === "tool" &&
93
+ "tool_call_id" in message &&
94
+ message.tool_call_id) {
95
+ num_tokens += encoding.encode(message.tool_call_id).length;
96
+ }
97
+ }
98
+ num_tokens += 3; // Every reply is primed with <|start|>assistant<|message|>
99
+ return num_tokens;
100
+ }
101
+ finally {
102
+ encoding?.free();
103
+ }
104
+ }, {
105
+ operation: "countChatTokens",
106
+ context: context,
107
+ input: { messageCount: messages.length },
108
+ errorCode: BaseErrorCode.INTERNAL_ERROR,
109
+ });
110
+ }
@@ -0,0 +1,21 @@
1
+ /**
2
+ * @fileoverview Provides a utility function to make fetch requests with a specified timeout.
3
+ * @module src/utils/network/fetchWithTimeout
4
+ */
5
+ import type { RequestContext } from "../internal/requestContext.js";
6
+ /**
7
+ * Options for the fetchWithTimeout utility.
8
+ * Extends standard RequestInit but omits 'signal' as it's handled internally.
9
+ */
10
+ export type FetchWithTimeoutOptions = Omit<RequestInit, "signal">;
11
+ /**
12
+ * Fetches a resource with a specified timeout.
13
+ *
14
+ * @param url - The URL to fetch.
15
+ * @param timeoutMs - The timeout duration in milliseconds.
16
+ * @param context - The request context for logging.
17
+ * @param options - Optional fetch options (RequestInit), excluding 'signal'.
18
+ * @returns A promise that resolves to the Response object.
19
+ * @throws {McpError} If the request times out or another fetch-related error occurs.
20
+ */
21
+ export declare function fetchWithTimeout(url: string | URL, timeoutMs: number, context: RequestContext, options?: FetchWithTimeoutOptions): Promise<Response>;
@@ -0,0 +1,59 @@
1
+ /**
2
+ * @fileoverview Provides a utility function to make fetch requests with a specified timeout.
3
+ * @module src/utils/network/fetchWithTimeout
4
+ */
5
+ import { logger } from "../internal/logger.js"; // Adjusted import path
6
+ import { McpError, BaseErrorCode } from "../../types-global/errors.js";
7
+ /**
8
+ * Fetches a resource with a specified timeout.
9
+ *
10
+ * @param url - The URL to fetch.
11
+ * @param timeoutMs - The timeout duration in milliseconds.
12
+ * @param context - The request context for logging.
13
+ * @param options - Optional fetch options (RequestInit), excluding 'signal'.
14
+ * @returns A promise that resolves to the Response object.
15
+ * @throws {McpError} If the request times out or another fetch-related error occurs.
16
+ */
17
+ export async function fetchWithTimeout(url, timeoutMs, context, options) {
18
+ const controller = new AbortController();
19
+ const timeoutId = setTimeout(() => controller.abort(), timeoutMs);
20
+ const urlString = url.toString();
21
+ const operationDescription = `fetch ${options?.method || "GET"} ${urlString}`;
22
+ logger.debug(`Attempting ${operationDescription} with ${timeoutMs}ms timeout.`, context);
23
+ try {
24
+ const response = await fetch(url, {
25
+ ...options,
26
+ signal: controller.signal,
27
+ });
28
+ clearTimeout(timeoutId);
29
+ logger.debug(`Successfully fetched ${urlString}. Status: ${response.status}`, context);
30
+ return response;
31
+ }
32
+ catch (error) {
33
+ clearTimeout(timeoutId);
34
+ if (error instanceof Error && error.name === "AbortError") {
35
+ logger.error(`${operationDescription} timed out after ${timeoutMs}ms.`, {
36
+ ...context,
37
+ errorSource: "FetchTimeout",
38
+ });
39
+ throw new McpError(BaseErrorCode.TIMEOUT, `${operationDescription} timed out.`, { ...context, errorSource: "FetchTimeout" });
40
+ }
41
+ // Log and re-throw other errors as McpError
42
+ const errorMessage = error instanceof Error ? error.message : String(error);
43
+ logger.error(`Network error during ${operationDescription}: ${errorMessage}`, {
44
+ ...context,
45
+ originalErrorName: error instanceof Error ? error.name : "UnknownError",
46
+ errorSource: "FetchNetworkError",
47
+ });
48
+ if (error instanceof McpError) {
49
+ // If it's already an McpError, re-throw it
50
+ throw error;
51
+ }
52
+ throw new McpError(BaseErrorCode.SERVICE_UNAVAILABLE, // Generic error for network/service issues
53
+ `Network error during ${operationDescription}: ${errorMessage}`, {
54
+ ...context,
55
+ originalErrorName: error instanceof Error ? error.name : "UnknownError",
56
+ errorSource: "FetchNetworkErrorWrapper",
57
+ });
58
+ }
59
+ }
@@ -0,0 +1,6 @@
1
+ /**
2
+ * @fileoverview Barrel file for network utilities.
3
+ * @module src/utils/network/index
4
+ */
5
+ export * from "./fetchWithTimeout.js";
6
+ export type { FetchWithTimeoutOptions } from "./fetchWithTimeout.js";
@@ -0,0 +1,5 @@
1
+ /**
2
+ * @fileoverview Barrel file for network utilities.
3
+ * @module src/utils/network/index
4
+ */
5
+ export * from "./fetchWithTimeout.js";
@@ -0,0 +1,73 @@
1
+ /**
2
+ * @fileoverview Provides utility functions for parsing natural language date strings
3
+ * into Date objects or detailed parsing results using the `chrono-node` library.
4
+ * @module src/utils/parsing/dateParser
5
+ */
6
+ import * as chrono from "chrono-node";
7
+ import { RequestContext } from "../index.js";
8
+ /**
9
+ * Parses a natural language date string into a JavaScript Date object.
10
+ * Uses `chrono.parseDate` for lenient parsing of various date formats.
11
+ *
12
+ * @param text - The natural language date string to parse.
13
+ * @param context - The request context for logging and error tracking.
14
+ * @param refDate - Optional reference date for parsing relative dates. Defaults to current date/time.
15
+ * @returns A promise resolving with a Date object or `null` if parsing fails.
16
+ * @throws {McpError} If an unexpected error occurs during parsing.
17
+ * @private
18
+ */
19
+ declare function parseDateString(text: string, context: RequestContext, refDate?: Date): Promise<Date | null>;
20
+ /**
21
+ * Parses a natural language date string and returns detailed parsing results.
22
+ * Provides more information than just the Date object, including matched text and components.
23
+ *
24
+ * @param text - The natural language date string to parse.
25
+ * @param context - The request context for logging and error tracking.
26
+ * @param refDate - Optional reference date for parsing relative dates. Defaults to current date/time.
27
+ * @returns A promise resolving with an array of `chrono.ParsedResult` objects. Empty if no dates found.
28
+ * @throws {McpError} If an unexpected error occurs during parsing.
29
+ * @private
30
+ */
31
+ declare function parseDateStringDetailed(text: string, context: RequestContext, refDate?: Date): Promise<chrono.ParsedResult[]>;
32
+ /**
33
+ * An object providing date parsing functionalities.
34
+ *
35
+ * @example
36
+ * ```typescript
37
+ * import { dateParser, requestContextService } from './utils'; // Assuming utils/index.js exports these
38
+ * const context = requestContextService.createRequestContext({ operation: 'TestDateParsing' });
39
+ *
40
+ * async function testParsing() {
41
+ * const dateObj = await dateParser.parseDate("next Friday at 3pm", context);
42
+ * if (dateObj) {
43
+ * console.log("Parsed Date:", dateObj.toISOString());
44
+ * }
45
+ *
46
+ * const detailedResults = await dateParser.parse("Meeting on 2024-12-25 and another one tomorrow", context);
47
+ * detailedResults.forEach(result => {
48
+ * console.log("Detailed Result:", result.text, result.start.date());
49
+ * });
50
+ * }
51
+ * testParsing();
52
+ * ```
53
+ */
54
+ export declare const dateParser: {
55
+ /**
56
+ * Parses a natural language date string and returns detailed parsing results
57
+ * from `chrono-node`.
58
+ * @param text - The natural language date string to parse.
59
+ * @param context - The request context for logging and error tracking.
60
+ * @param refDate - Optional reference date for parsing relative dates.
61
+ * @returns A promise resolving with an array of `chrono.ParsedResult` objects.
62
+ */
63
+ parse: typeof parseDateStringDetailed;
64
+ /**
65
+ * Parses a natural language date string into a single JavaScript Date object.
66
+ * @param text - The natural language date string to parse.
67
+ * @param context - The request context for logging and error tracking.
68
+ * @param refDate - Optional reference date for parsing relative dates.
69
+ * @returns A promise resolving with a Date object or `null`.
70
+ */
71
+ parseDate: typeof parseDateString;
72
+ };
73
+ export {};
@@ -0,0 +1,107 @@
1
+ /**
2
+ * @fileoverview Provides utility functions for parsing natural language date strings
3
+ * into Date objects or detailed parsing results using the `chrono-node` library.
4
+ * @module src/utils/parsing/dateParser
5
+ */
6
+ import * as chrono from "chrono-node";
7
+ import { BaseErrorCode } from "../../types-global/errors.js";
8
+ import { ErrorHandler, logger } from "../index.js";
9
+ /**
10
+ * Parses a natural language date string into a JavaScript Date object.
11
+ * Uses `chrono.parseDate` for lenient parsing of various date formats.
12
+ *
13
+ * @param text - The natural language date string to parse.
14
+ * @param context - The request context for logging and error tracking.
15
+ * @param refDate - Optional reference date for parsing relative dates. Defaults to current date/time.
16
+ * @returns A promise resolving with a Date object or `null` if parsing fails.
17
+ * @throws {McpError} If an unexpected error occurs during parsing.
18
+ * @private
19
+ */
20
+ async function parseDateString(text, context, refDate) {
21
+ const operation = "parseDateString";
22
+ const logContext = { ...context, operation, inputText: text, refDate };
23
+ logger.debug(`Attempting to parse date string: "${text}"`, logContext);
24
+ return await ErrorHandler.tryCatch(async () => {
25
+ const parsedDate = chrono.parseDate(text, refDate, { forwardDate: true });
26
+ if (parsedDate) {
27
+ logger.debug(`Successfully parsed "${text}" to ${parsedDate.toISOString()}`, logContext);
28
+ return parsedDate;
29
+ }
30
+ else {
31
+ logger.warning(`Failed to parse date string: "${text}"`, logContext);
32
+ return null;
33
+ }
34
+ }, {
35
+ operation,
36
+ context: logContext,
37
+ input: { text, refDate },
38
+ errorCode: BaseErrorCode.PARSING_ERROR,
39
+ });
40
+ }
41
+ /**
42
+ * Parses a natural language date string and returns detailed parsing results.
43
+ * Provides more information than just the Date object, including matched text and components.
44
+ *
45
+ * @param text - The natural language date string to parse.
46
+ * @param context - The request context for logging and error tracking.
47
+ * @param refDate - Optional reference date for parsing relative dates. Defaults to current date/time.
48
+ * @returns A promise resolving with an array of `chrono.ParsedResult` objects. Empty if no dates found.
49
+ * @throws {McpError} If an unexpected error occurs during parsing.
50
+ * @private
51
+ */
52
+ async function parseDateStringDetailed(text, context, refDate) {
53
+ const operation = "parseDateStringDetailed";
54
+ const logContext = { ...context, operation, inputText: text, refDate };
55
+ logger.debug(`Attempting detailed parse of date string: "${text}"`, logContext);
56
+ return await ErrorHandler.tryCatch(async () => {
57
+ const results = chrono.parse(text, refDate, { forwardDate: true });
58
+ logger.debug(`Detailed parse of "${text}" resulted in ${results.length} result(s)`, logContext);
59
+ return results;
60
+ }, {
61
+ operation,
62
+ context: logContext,
63
+ input: { text, refDate },
64
+ errorCode: BaseErrorCode.PARSING_ERROR,
65
+ });
66
+ }
67
+ /**
68
+ * An object providing date parsing functionalities.
69
+ *
70
+ * @example
71
+ * ```typescript
72
+ * import { dateParser, requestContextService } from './utils'; // Assuming utils/index.js exports these
73
+ * const context = requestContextService.createRequestContext({ operation: 'TestDateParsing' });
74
+ *
75
+ * async function testParsing() {
76
+ * const dateObj = await dateParser.parseDate("next Friday at 3pm", context);
77
+ * if (dateObj) {
78
+ * console.log("Parsed Date:", dateObj.toISOString());
79
+ * }
80
+ *
81
+ * const detailedResults = await dateParser.parse("Meeting on 2024-12-25 and another one tomorrow", context);
82
+ * detailedResults.forEach(result => {
83
+ * console.log("Detailed Result:", result.text, result.start.date());
84
+ * });
85
+ * }
86
+ * testParsing();
87
+ * ```
88
+ */
89
+ export const dateParser = {
90
+ /**
91
+ * Parses a natural language date string and returns detailed parsing results
92
+ * from `chrono-node`.
93
+ * @param text - The natural language date string to parse.
94
+ * @param context - The request context for logging and error tracking.
95
+ * @param refDate - Optional reference date for parsing relative dates.
96
+ * @returns A promise resolving with an array of `chrono.ParsedResult` objects.
97
+ */
98
+ parse: parseDateStringDetailed,
99
+ /**
100
+ * Parses a natural language date string into a single JavaScript Date object.
101
+ * @param text - The natural language date string to parse.
102
+ * @param context - The request context for logging and error tracking.
103
+ * @param refDate - Optional reference date for parsing relative dates.
104
+ * @returns A promise resolving with a Date object or `null`.
105
+ */
106
+ parseDate: parseDateString,
107
+ };
@@ -0,0 +1,8 @@
1
+ /**
2
+ * @fileoverview Barrel file for parsing utility modules.
3
+ * This file re-exports utilities related to parsing various data formats,
4
+ * such as JSON and dates.
5
+ * @module src/utils/parsing
6
+ */
7
+ export * from "./dateParser.js";
8
+ export * from "./jsonParser.js";
@@ -0,0 +1,8 @@
1
+ /**
2
+ * @fileoverview Barrel file for parsing utility modules.
3
+ * This file re-exports utilities related to parsing various data formats,
4
+ * such as JSON and dates.
5
+ * @module src/utils/parsing
6
+ */
7
+ export * from "./dateParser.js";
8
+ export * from "./jsonParser.js";
@@ -0,0 +1,82 @@
1
+ import { RequestContext } from "../index.js";
2
+ /**
3
+ * Enum mirroring `partial-json`'s `Allow` constants. These specify
4
+ * what types of partial JSON structures are permissible during parsing.
5
+ * They can be combined using bitwise OR (e.g., `Allow.STR | Allow.OBJ`).
6
+ *
7
+ * The available properties are:
8
+ * - `STR`: Allow partial string.
9
+ * - `NUM`: Allow partial number.
10
+ * - `ARR`: Allow partial array.
11
+ * - `OBJ`: Allow partial object.
12
+ * - `NULL`: Allow partial null.
13
+ * - `BOOL`: Allow partial boolean.
14
+ * - `NAN`: Allow partial NaN. (Note: Standard JSON does not support NaN)
15
+ * - `INFINITY`: Allow partial Infinity. (Note: Standard JSON does not support Infinity)
16
+ * - `_INFINITY`: Allow partial -Infinity. (Note: Standard JSON does not support -Infinity)
17
+ * - `INF`: Allow both partial Infinity and -Infinity.
18
+ * - `SPECIAL`: Allow all special values (NaN, Infinity, -Infinity).
19
+ * - `ATOM`: Allow all atomic values (strings, numbers, booleans, null, special values).
20
+ * - `COLLECTION`: Allow all collection values (objects, arrays).
21
+ * - `ALL`: Allow all value types to be partial (default for `partial-json`'s parse).
22
+ * @see {@link https://github.com/promplate/partial-json-parser-js} for more details.
23
+ */
24
+ export declare const Allow: {
25
+ STR: number;
26
+ NUM: number;
27
+ ARR: number;
28
+ OBJ: number;
29
+ NULL: number;
30
+ BOOL: number;
31
+ NAN: number;
32
+ INFINITY: number;
33
+ _INFINITY: number;
34
+ INF: number;
35
+ SPECIAL: number;
36
+ ATOM: number;
37
+ COLLECTION: number;
38
+ ALL: number;
39
+ };
40
+ /**
41
+ * Utility class for parsing potentially partial JSON strings.
42
+ * Wraps the 'partial-json' library for robust JSON parsing, handling
43
+ * incomplete structures and optional <think> blocks from LLMs.
44
+ */
45
+ export declare class JsonParser {
46
+ /**
47
+ * Parses a JSON string, which may be partial or prefixed with a <think> block.
48
+ * If a <think> block is present, its content is logged, and parsing proceeds on the
49
+ * remainder. Uses 'partial-json' to handle incomplete JSON.
50
+ *
51
+ * @template T The expected type of the parsed JSON object. Defaults to `any`.
52
+ * @param jsonString - The JSON string to parse.
53
+ * @param allowPartial - Bitwise OR combination of `Allow` constants specifying permissible
54
+ * partial JSON types. Defaults to `Allow.ALL`.
55
+ * @param context - Optional `RequestContext` for logging and error correlation.
56
+ * @returns The parsed JavaScript value.
57
+ * @throws {McpError} If the string is empty after processing or if `partial-json` fails.
58
+ */
59
+ parse<T = any>(jsonString: string, allowPartial?: number, context?: RequestContext): T;
60
+ }
61
+ /**
62
+ * Singleton instance of the `JsonParser`.
63
+ * Use this instance to parse JSON strings, with support for partial JSON and <think> blocks.
64
+ * @example
65
+ * ```typescript
66
+ * import { jsonParser, Allow, requestContextService } from './utils';
67
+ * const context = requestContextService.createRequestContext({ operation: 'TestJsonParsing' });
68
+ *
69
+ * const fullJson = '{"key": "value"}';
70
+ * const parsedFull = jsonParser.parse(fullJson, Allow.ALL, context);
71
+ * console.log(parsedFull); // Output: { key: 'value' }
72
+ *
73
+ * const partialObject = '<think>This is a thought.</think>{"key": "value", "arr": [1,';
74
+ * try {
75
+ * const parsedPartial = jsonParser.parse(partialObject, undefined, context);
76
+ * console.log(parsedPartial);
77
+ * } catch (e) {
78
+ * console.error("Parsing partial object failed:", e);
79
+ * }
80
+ * ```
81
+ */
82
+ export declare const jsonParser: JsonParser;