swift-skills 0.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 (247) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +410 -0
  3. package/build/cli/auth.d.ts +3 -0
  4. package/build/cli/auth.d.ts.map +1 -0
  5. package/build/cli/auth.js +44 -0
  6. package/build/cli/auth.js.map +1 -0
  7. package/build/cli/setup.d.ts +2 -0
  8. package/build/cli/setup.d.ts.map +1 -0
  9. package/build/cli/setup.js +150 -0
  10. package/build/cli/setup.js.map +1 -0
  11. package/build/cli/source-manager.d.ts +3 -0
  12. package/build/cli/source-manager.d.ts.map +1 -0
  13. package/build/cli/source-manager.js +117 -0
  14. package/build/cli/source-manager.js.map +1 -0
  15. package/build/config/creators.d.ts +11 -0
  16. package/build/config/creators.d.ts.map +1 -0
  17. package/build/config/creators.js +32 -0
  18. package/build/config/creators.js.map +1 -0
  19. package/build/config/sources.d.ts +91 -0
  20. package/build/config/sources.d.ts.map +1 -0
  21. package/build/config/sources.js +231 -0
  22. package/build/config/sources.js.map +1 -0
  23. package/build/config/sources.test.d.ts +2 -0
  24. package/build/config/sources.test.d.ts.map +1 -0
  25. package/build/config/sources.test.js +199 -0
  26. package/build/config/sources.test.js.map +1 -0
  27. package/build/config/swift-keywords.d.ts +29 -0
  28. package/build/config/swift-keywords.d.ts.map +1 -0
  29. package/build/config/swift-keywords.js +77 -0
  30. package/build/config/swift-keywords.js.map +1 -0
  31. package/build/index.d.ts +3 -0
  32. package/build/index.d.ts.map +1 -0
  33. package/build/index.js +181 -0
  34. package/build/index.js.map +1 -0
  35. package/build/integration/cache-behavior.test.d.ts +2 -0
  36. package/build/integration/cache-behavior.test.d.ts.map +1 -0
  37. package/build/integration/cache-behavior.test.js +521 -0
  38. package/build/integration/cache-behavior.test.js.map +1 -0
  39. package/build/integration/mcp-client.test.d.ts +2 -0
  40. package/build/integration/mcp-client.test.d.ts.map +1 -0
  41. package/build/integration/mcp-client.test.js +82 -0
  42. package/build/integration/mcp-client.test.js.map +1 -0
  43. package/build/integration/response-quality.test.d.ts +2 -0
  44. package/build/integration/response-quality.test.d.ts.map +1 -0
  45. package/build/integration/response-quality.test.js +230 -0
  46. package/build/integration/response-quality.test.js.map +1 -0
  47. package/build/integration/test-client.d.ts +25 -0
  48. package/build/integration/test-client.d.ts.map +1 -0
  49. package/build/integration/test-client.js +93 -0
  50. package/build/integration/test-client.js.map +1 -0
  51. package/build/sources/free/nilcoalescing.d.ts +8 -0
  52. package/build/sources/free/nilcoalescing.d.ts.map +1 -0
  53. package/build/sources/free/nilcoalescing.js +26 -0
  54. package/build/sources/free/nilcoalescing.js.map +1 -0
  55. package/build/sources/free/nilcoalescing.test.d.ts +2 -0
  56. package/build/sources/free/nilcoalescing.test.d.ts.map +1 -0
  57. package/build/sources/free/nilcoalescing.test.js +63 -0
  58. package/build/sources/free/nilcoalescing.test.js.map +1 -0
  59. package/build/sources/free/pointfree.d.ts +15 -0
  60. package/build/sources/free/pointfree.d.ts.map +1 -0
  61. package/build/sources/free/pointfree.js +175 -0
  62. package/build/sources/free/pointfree.js.map +1 -0
  63. package/build/sources/free/pointfree.test.d.ts +2 -0
  64. package/build/sources/free/pointfree.test.d.ts.map +1 -0
  65. package/build/sources/free/pointfree.test.js +86 -0
  66. package/build/sources/free/pointfree.test.js.map +1 -0
  67. package/build/sources/free/rssPatternSource.d.ts +42 -0
  68. package/build/sources/free/rssPatternSource.d.ts.map +1 -0
  69. package/build/sources/free/rssPatternSource.js +109 -0
  70. package/build/sources/free/rssPatternSource.js.map +1 -0
  71. package/build/sources/free/rssPatternSource.test.d.ts +2 -0
  72. package/build/sources/free/rssPatternSource.test.d.ts.map +1 -0
  73. package/build/sources/free/rssPatternSource.test.js +89 -0
  74. package/build/sources/free/rssPatternSource.test.js.map +1 -0
  75. package/build/sources/free/sundell.d.ts +8 -0
  76. package/build/sources/free/sundell.d.ts.map +1 -0
  77. package/build/sources/free/sundell.js +17 -0
  78. package/build/sources/free/sundell.js.map +1 -0
  79. package/build/sources/free/sundell.test.d.ts +2 -0
  80. package/build/sources/free/sundell.test.d.ts.map +1 -0
  81. package/build/sources/free/sundell.test.js +63 -0
  82. package/build/sources/free/sundell.test.js.map +1 -0
  83. package/build/sources/free/vanderlee.d.ts +8 -0
  84. package/build/sources/free/vanderlee.d.ts.map +1 -0
  85. package/build/sources/free/vanderlee.js +63 -0
  86. package/build/sources/free/vanderlee.js.map +1 -0
  87. package/build/sources/free/vanderlee.test.d.ts +2 -0
  88. package/build/sources/free/vanderlee.test.d.ts.map +1 -0
  89. package/build/sources/free/vanderlee.test.js +77 -0
  90. package/build/sources/free/vanderlee.test.js.map +1 -0
  91. package/build/sources/premium/patreon-dl.d.ts +45 -0
  92. package/build/sources/premium/patreon-dl.d.ts.map +1 -0
  93. package/build/sources/premium/patreon-dl.js +189 -0
  94. package/build/sources/premium/patreon-dl.js.map +1 -0
  95. package/build/sources/premium/patreon-fetch.d.ts +3 -0
  96. package/build/sources/premium/patreon-fetch.d.ts.map +1 -0
  97. package/build/sources/premium/patreon-fetch.js +18 -0
  98. package/build/sources/premium/patreon-fetch.js.map +1 -0
  99. package/build/sources/premium/patreon-oauth.d.ts +24 -0
  100. package/build/sources/premium/patreon-oauth.d.ts.map +1 -0
  101. package/build/sources/premium/patreon-oauth.js +208 -0
  102. package/build/sources/premium/patreon-oauth.js.map +1 -0
  103. package/build/sources/premium/patreon-zip.d.ts +17 -0
  104. package/build/sources/premium/patreon-zip.d.ts.map +1 -0
  105. package/build/sources/premium/patreon-zip.js +127 -0
  106. package/build/sources/premium/patreon-zip.js.map +1 -0
  107. package/build/sources/premium/patreon.d.ts +48 -0
  108. package/build/sources/premium/patreon.d.ts.map +1 -0
  109. package/build/sources/premium/patreon.js +221 -0
  110. package/build/sources/premium/patreon.js.map +1 -0
  111. package/build/sources/premium/youtube.d.ts +14 -0
  112. package/build/sources/premium/youtube.d.ts.map +1 -0
  113. package/build/sources/premium/youtube.js +92 -0
  114. package/build/sources/premium/youtube.js.map +1 -0
  115. package/build/tools/extract-cookie.d.ts +2 -0
  116. package/build/tools/extract-cookie.d.ts.map +1 -0
  117. package/build/tools/extract-cookie.js +40 -0
  118. package/build/tools/extract-cookie.js.map +1 -0
  119. package/build/tools/handlers/enableSource.d.ts +3 -0
  120. package/build/tools/handlers/enableSource.d.ts.map +1 -0
  121. package/build/tools/handlers/enableSource.js +25 -0
  122. package/build/tools/handlers/enableSource.js.map +1 -0
  123. package/build/tools/handlers/getPatreonPatterns.d.ts +3 -0
  124. package/build/tools/handlers/getPatreonPatterns.d.ts.map +1 -0
  125. package/build/tools/handlers/getPatreonPatterns.js +43 -0
  126. package/build/tools/handlers/getPatreonPatterns.js.map +1 -0
  127. package/build/tools/handlers/getSwiftPattern.d.ts +3 -0
  128. package/build/tools/handlers/getSwiftPattern.d.ts.map +1 -0
  129. package/build/tools/handlers/getSwiftPattern.js +72 -0
  130. package/build/tools/handlers/getSwiftPattern.js.map +1 -0
  131. package/build/tools/handlers/handlers.test.d.ts +2 -0
  132. package/build/tools/handlers/handlers.test.d.ts.map +1 -0
  133. package/build/tools/handlers/handlers.test.js +359 -0
  134. package/build/tools/handlers/handlers.test.js.map +1 -0
  135. package/build/tools/handlers/listContentSources.d.ts +3 -0
  136. package/build/tools/handlers/listContentSources.d.ts.map +1 -0
  137. package/build/tools/handlers/listContentSources.js +34 -0
  138. package/build/tools/handlers/listContentSources.js.map +1 -0
  139. package/build/tools/handlers/searchSwiftContent.d.ts +3 -0
  140. package/build/tools/handlers/searchSwiftContent.d.ts.map +1 -0
  141. package/build/tools/handlers/searchSwiftContent.js +121 -0
  142. package/build/tools/handlers/searchSwiftContent.js.map +1 -0
  143. package/build/tools/handlers/setupPatreon.d.ts +3 -0
  144. package/build/tools/handlers/setupPatreon.d.ts.map +1 -0
  145. package/build/tools/handlers/setupPatreon.js +40 -0
  146. package/build/tools/handlers/setupPatreon.js.map +1 -0
  147. package/build/tools/index.d.ts +3 -0
  148. package/build/tools/index.d.ts.map +1 -0
  149. package/build/tools/index.js +18 -0
  150. package/build/tools/index.js.map +1 -0
  151. package/build/tools/registry.d.ts +14 -0
  152. package/build/tools/registry.d.ts.map +1 -0
  153. package/build/tools/registry.js +21 -0
  154. package/build/tools/registry.js.map +1 -0
  155. package/build/tools/registry.test.d.ts +2 -0
  156. package/build/tools/registry.test.d.ts.map +1 -0
  157. package/build/tools/registry.test.js +54 -0
  158. package/build/tools/registry.test.js.map +1 -0
  159. package/build/tools/types.d.ts +67 -0
  160. package/build/tools/types.d.ts.map +1 -0
  161. package/build/tools/types.js +3 -0
  162. package/build/tools/types.js.map +1 -0
  163. package/build/utils/cache.d.ts +20 -0
  164. package/build/utils/cache.d.ts.map +1 -0
  165. package/build/utils/cache.js +186 -0
  166. package/build/utils/cache.js.map +1 -0
  167. package/build/utils/concurrency.d.ts +13 -0
  168. package/build/utils/concurrency.d.ts.map +1 -0
  169. package/build/utils/concurrency.js +33 -0
  170. package/build/utils/concurrency.js.map +1 -0
  171. package/build/utils/errors.d.ts +19 -0
  172. package/build/utils/errors.d.ts.map +1 -0
  173. package/build/utils/errors.js +35 -0
  174. package/build/utils/errors.js.map +1 -0
  175. package/build/utils/fetch.d.ts +6 -0
  176. package/build/utils/fetch.d.ts.map +1 -0
  177. package/build/utils/fetch.js +6 -0
  178. package/build/utils/fetch.js.map +1 -0
  179. package/build/utils/http.d.ts +21 -0
  180. package/build/utils/http.d.ts.map +1 -0
  181. package/build/utils/http.js +53 -0
  182. package/build/utils/http.js.map +1 -0
  183. package/build/utils/intent-cache.d.ts +94 -0
  184. package/build/utils/intent-cache.d.ts.map +1 -0
  185. package/build/utils/intent-cache.js +164 -0
  186. package/build/utils/intent-cache.js.map +1 -0
  187. package/build/utils/intent-cache.test.d.ts +2 -0
  188. package/build/utils/intent-cache.test.d.ts.map +1 -0
  189. package/build/utils/intent-cache.test.js +290 -0
  190. package/build/utils/intent-cache.test.js.map +1 -0
  191. package/build/utils/logger.d.ts +4 -0
  192. package/build/utils/logger.d.ts.map +1 -0
  193. package/build/utils/logger.js +9 -0
  194. package/build/utils/logger.js.map +1 -0
  195. package/build/utils/paths.d.ts +27 -0
  196. package/build/utils/paths.d.ts.map +1 -0
  197. package/build/utils/paths.js +43 -0
  198. package/build/utils/paths.js.map +1 -0
  199. package/build/utils/pattern-formatter.d.ts +40 -0
  200. package/build/utils/pattern-formatter.d.ts.map +1 -0
  201. package/build/utils/pattern-formatter.js +124 -0
  202. package/build/utils/pattern-formatter.js.map +1 -0
  203. package/build/utils/response-helpers.d.ts +17 -0
  204. package/build/utils/response-helpers.d.ts.map +1 -0
  205. package/build/utils/response-helpers.js +34 -0
  206. package/build/utils/response-helpers.js.map +1 -0
  207. package/build/utils/search-terms.d.ts +17 -0
  208. package/build/utils/search-terms.d.ts.map +1 -0
  209. package/build/utils/search-terms.js +71 -0
  210. package/build/utils/search-terms.js.map +1 -0
  211. package/build/utils/search-terms.test.d.ts +2 -0
  212. package/build/utils/search-terms.test.d.ts.map +1 -0
  213. package/build/utils/search-terms.test.js +107 -0
  214. package/build/utils/search-terms.test.js.map +1 -0
  215. package/build/utils/search.d.ts +48 -0
  216. package/build/utils/search.d.ts.map +1 -0
  217. package/build/utils/search.js +158 -0
  218. package/build/utils/search.js.map +1 -0
  219. package/build/utils/search.test.d.ts +2 -0
  220. package/build/utils/search.test.d.ts.map +1 -0
  221. package/build/utils/search.test.js +199 -0
  222. package/build/utils/search.test.js.map +1 -0
  223. package/build/utils/semantic-recall.d.ts +38 -0
  224. package/build/utils/semantic-recall.d.ts.map +1 -0
  225. package/build/utils/semantic-recall.js +134 -0
  226. package/build/utils/semantic-recall.js.map +1 -0
  227. package/build/utils/semantic-recall.test.d.ts +2 -0
  228. package/build/utils/semantic-recall.test.d.ts.map +1 -0
  229. package/build/utils/semantic-recall.test.js +326 -0
  230. package/build/utils/semantic-recall.test.js.map +1 -0
  231. package/build/utils/source-registry.d.ts +45 -0
  232. package/build/utils/source-registry.d.ts.map +1 -0
  233. package/build/utils/source-registry.js +113 -0
  234. package/build/utils/source-registry.js.map +1 -0
  235. package/build/utils/source-registry.test.d.ts +2 -0
  236. package/build/utils/source-registry.test.d.ts.map +1 -0
  237. package/build/utils/source-registry.test.js +206 -0
  238. package/build/utils/source-registry.test.js.map +1 -0
  239. package/build/utils/swift-analysis.d.ts +61 -0
  240. package/build/utils/swift-analysis.d.ts.map +1 -0
  241. package/build/utils/swift-analysis.js +339 -0
  242. package/build/utils/swift-analysis.js.map +1 -0
  243. package/build/utils/swift-analysis.test.d.ts +2 -0
  244. package/build/utils/swift-analysis.test.d.ts.map +1 -0
  245. package/build/utils/swift-analysis.test.js +473 -0
  246. package/build/utils/swift-analysis.test.js.map +1 -0
  247. package/package.json +85 -0
@@ -0,0 +1,18 @@
1
+ // src/tools/index.ts - Barrel export for tool handlers
2
+ export * from './types.js';
3
+ export * from './registry.js';
4
+ // Register handlers on import
5
+ import { registerHandler } from './registry.js';
6
+ import { getSwiftPatternHandler } from './handlers/getSwiftPattern.js';
7
+ import { searchSwiftContentHandler } from './handlers/searchSwiftContent.js';
8
+ import { listContentSourcesHandler } from './handlers/listContentSources.js';
9
+ import { enableSourceHandler } from './handlers/enableSource.js';
10
+ import { setupPatreonHandler } from './handlers/setupPatreon.js';
11
+ import { getPatreonPatternsHandler } from './handlers/getPatreonPatterns.js';
12
+ registerHandler('get_swift_pattern', getSwiftPatternHandler);
13
+ registerHandler('search_swift_content', searchSwiftContentHandler);
14
+ registerHandler('list_content_sources', listContentSourcesHandler);
15
+ registerHandler('enable_source', enableSourceHandler);
16
+ registerHandler('setup_patreon', setupPatreonHandler);
17
+ registerHandler('get_patreon_patterns', getPatreonPatternsHandler);
18
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAAA,uDAAuD;AAEvD,cAAc,YAAY,CAAC;AAC3B,cAAc,eAAe,CAAC;AAE9B,8BAA8B;AAC9B,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AACvE,OAAO,EAAE,yBAAyB,EAAE,MAAM,kCAAkC,CAAC;AAC7E,OAAO,EAAE,yBAAyB,EAAE,MAAM,kCAAkC,CAAC;AAC7E,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAAE,yBAAyB,EAAE,MAAM,kCAAkC,CAAC;AAE7E,eAAe,CAAC,mBAAmB,EAAE,sBAAsB,CAAC,CAAC;AAC7D,eAAe,CAAC,sBAAsB,EAAE,yBAAyB,CAAC,CAAC;AACnE,eAAe,CAAC,sBAAsB,EAAE,yBAAyB,CAAC,CAAC;AACnE,eAAe,CAAC,eAAe,EAAE,mBAAmB,CAAC,CAAC;AACtD,eAAe,CAAC,eAAe,EAAE,mBAAmB,CAAC,CAAC;AACtD,eAAe,CAAC,sBAAsB,EAAE,yBAAyB,CAAC,CAAC"}
@@ -0,0 +1,14 @@
1
+ import type { ToolHandler } from './types.js';
2
+ /**
3
+ * Register a tool handler by name
4
+ */
5
+ export declare function registerHandler(name: string, handler: ToolHandler): void;
6
+ /**
7
+ * Get a registered handler by name
8
+ */
9
+ export declare function getHandler(name: string): ToolHandler | undefined;
10
+ /**
11
+ * Check if a handler is registered
12
+ */
13
+ export declare function hasHandler(name: string): boolean;
14
+ //# sourceMappingURL=registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/tools/registry.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAI9C;;GAEG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,GAAG,IAAI,CAExE;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS,CAEhE;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEhD"}
@@ -0,0 +1,21 @@
1
+ // src/tools/registry.ts
2
+ const handlers = new Map();
3
+ /**
4
+ * Register a tool handler by name
5
+ */
6
+ export function registerHandler(name, handler) {
7
+ handlers.set(name, handler);
8
+ }
9
+ /**
10
+ * Get a registered handler by name
11
+ */
12
+ export function getHandler(name) {
13
+ return handlers.get(name);
14
+ }
15
+ /**
16
+ * Check if a handler is registered
17
+ */
18
+ export function hasHandler(name) {
19
+ return handlers.has(name);
20
+ }
21
+ //# sourceMappingURL=registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/tools/registry.ts"],"names":[],"mappings":"AAAA,wBAAwB;AAIxB,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAuB,CAAC;AAEhD;;GAEG;AACH,MAAM,UAAU,eAAe,CAAC,IAAY,EAAE,OAAoB;IAChE,QAAQ,CAAC,GAAG,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;AAC9B,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,UAAU,CAAC,IAAY;IACrC,OAAO,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;AAC5B,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,UAAU,CAAC,IAAY;IACrC,OAAO,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;AAC5B,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=registry.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.test.d.ts","sourceRoot":"","sources":["../../src/tools/registry.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,54 @@
1
+ // src/tools/registry.test.ts
2
+ import { describe, it, expect } from 'vitest';
3
+ // We need to test the registry in isolation, so we'll create a fresh module
4
+ // Since the registry uses module-level state, we test the exported functions
5
+ describe('Tool Registry', () => {
6
+ // Import fresh for each test to avoid state pollution
7
+ // In practice, the registry is populated at startup
8
+ it('should register and retrieve handlers', async () => {
9
+ const { registerHandler, getHandler } = await import('./registry.js');
10
+ const mockHandler = async () => ({ content: [{ type: 'text', text: 'test' }] });
11
+ registerHandler('test_tool', mockHandler);
12
+ const retrieved = getHandler('test_tool');
13
+ expect(retrieved).toBe(mockHandler);
14
+ });
15
+ it('should return undefined for unregistered handlers', async () => {
16
+ const { getHandler } = await import('./registry.js');
17
+ const result = getHandler('nonexistent_tool_12345');
18
+ expect(result).toBeUndefined();
19
+ });
20
+ it('should correctly report handler existence', async () => {
21
+ const { registerHandler, hasHandler } = await import('./registry.js');
22
+ const mockHandler = async () => ({ content: [{ type: 'text', text: 'test' }] });
23
+ registerHandler('exists_tool', mockHandler);
24
+ expect(hasHandler('exists_tool')).toBe(true);
25
+ expect(hasHandler('does_not_exist_12345')).toBe(false);
26
+ });
27
+ it('should allow overwriting handlers', async () => {
28
+ const { registerHandler, getHandler } = await import('./registry.js');
29
+ const handler1 = async () => ({ content: [{ type: 'text', text: 'first' }] });
30
+ const handler2 = async () => ({ content: [{ type: 'text', text: 'second' }] });
31
+ registerHandler('overwrite_test', handler1);
32
+ registerHandler('overwrite_test', handler2);
33
+ const retrieved = getHandler('overwrite_test');
34
+ expect(retrieved).toBe(handler2);
35
+ });
36
+ });
37
+ describe('Tool Registration Integration', () => {
38
+ it('should have core tools registered after import', async () => {
39
+ // Importing index.js registers all handlers
40
+ await import('./index.js');
41
+ const { hasHandler } = await import('./registry.js');
42
+ expect(hasHandler('get_swift_pattern')).toBe(true);
43
+ expect(hasHandler('search_swift_content')).toBe(true);
44
+ expect(hasHandler('list_content_sources')).toBe(true);
45
+ expect(hasHandler('enable_source')).toBe(true);
46
+ });
47
+ it('should return valid handler functions', async () => {
48
+ await import('./index.js');
49
+ const { getHandler } = await import('./registry.js');
50
+ const handler = getHandler('get_swift_pattern');
51
+ expect(typeof handler).toBe('function');
52
+ });
53
+ });
54
+ //# sourceMappingURL=registry.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.test.js","sourceRoot":"","sources":["../../src/tools/registry.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,67 @@
1
+ import type SourceManager from '../config/sources.js';
2
+ /**
3
+ * Pattern returned by Patreon source
4
+ */
5
+ export interface PatreonPattern {
6
+ id: string;
7
+ title: string;
8
+ url: string;
9
+ publishDate: string;
10
+ excerpt: string;
11
+ content: string;
12
+ creator: string;
13
+ topics: string[];
14
+ relevanceScore: number;
15
+ hasCode: boolean;
16
+ }
17
+ /**
18
+ * Creator info from Patreon
19
+ */
20
+ export interface CreatorInfo {
21
+ id: string;
22
+ name: string;
23
+ url: string;
24
+ isSwiftRelated: boolean;
25
+ }
26
+ /**
27
+ * Interface for PatreonSource class instances
28
+ */
29
+ export interface PatreonSourceInstance {
30
+ isConfigured(): Promise<boolean>;
31
+ isAvailable(): boolean;
32
+ getSubscribedCreators(): Promise<CreatorInfo[]>;
33
+ detectSwiftCreators(): Promise<CreatorInfo[]>;
34
+ fetchPatterns(creatorId?: string): Promise<PatreonPattern[]>;
35
+ searchPatterns(query: string): Promise<PatreonPattern[]>;
36
+ saveEnabledCreators(creatorIds: string[]): void;
37
+ }
38
+ /**
39
+ * Constructor type for PatreonSource class
40
+ */
41
+ export interface PatreonSourceConstructor {
42
+ new (): PatreonSourceInstance;
43
+ }
44
+ /**
45
+ * Context passed to tool handlers
46
+ */
47
+ export interface ToolContext {
48
+ sourceManager: SourceManager;
49
+ patreonSource: PatreonSourceConstructor | null;
50
+ }
51
+ /**
52
+ * Tool response format matching MCP SDK expectations
53
+ * Index signature allows additional SDK-required properties
54
+ */
55
+ export interface ToolResponse {
56
+ content: Array<{
57
+ type: string;
58
+ text: string;
59
+ }>;
60
+ isError?: boolean;
61
+ [key: string]: unknown;
62
+ }
63
+ /**
64
+ * Handler function type for MCP tools
65
+ */
66
+ export type ToolHandler = (args: Record<string, unknown>, context: ToolContext) => Promise<ToolResponse>;
67
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/tools/types.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,aAAa,MAAM,sBAAsB,CAAC;AAEtD;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,cAAc,EAAE,MAAM,CAAC;IACvB,OAAO,EAAE,OAAO,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,cAAc,EAAE,OAAO,CAAC;CACzB;AAED;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,YAAY,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;IACjC,WAAW,IAAI,OAAO,CAAC;IACvB,qBAAqB,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;IAChD,mBAAmB,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;IAC9C,aAAa,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC,CAAC;IAC7D,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC,CAAC;IACzD,mBAAmB,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;CACjD;AAED;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACvC,QAAQ,qBAAqB,CAAC;CAC/B;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,aAAa,EAAE,aAAa,CAAC;IAC7B,aAAa,EAAE,wBAAwB,GAAG,IAAI,CAAC;CAChD;AAED;;;GAGG;AACH,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC/C,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED;;GAEG;AACH,MAAM,MAAM,WAAW,GAAG,CACxB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,OAAO,EAAE,WAAW,KACjB,OAAO,CAAC,YAAY,CAAC,CAAC"}
@@ -0,0 +1,3 @@
1
+ // src/tools/types.ts
2
+ export {};
3
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/tools/types.ts"],"names":[],"mappings":"AAAA,qBAAqB"}
@@ -0,0 +1,20 @@
1
+ export declare class FileCache {
2
+ private cacheDir;
3
+ private memoryCache;
4
+ private inFlightFetches;
5
+ private cleanupInterval;
6
+ constructor(namespace?: string, maxMemoryEntries?: number);
7
+ private startPeriodicCleanup;
8
+ private ensureCacheDir;
9
+ private getCacheKey;
10
+ private getCachePath;
11
+ get<T>(key: string): Promise<T | null>;
12
+ set<T>(key: string, data: T, ttl?: number): Promise<void>;
13
+ getOrFetch<T>(key: string, fetcher: () => Promise<T>, ttl?: number): Promise<T>;
14
+ private isExpired;
15
+ clear(): void;
16
+ clearExpired(): number;
17
+ }
18
+ export declare const rssCache: FileCache;
19
+ export declare const articleCache: FileCache;
20
+ //# sourceMappingURL=cache.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../../src/utils/cache.ts"],"names":[],"mappings":"AAkBA,qBAAa,SAAS;IACpB,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,WAAW,CAAwC;IAC3D,OAAO,CAAC,eAAe,CAA4C;IACnE,OAAO,CAAC,eAAe,CAA+C;gBAE1D,SAAS,GAAE,MAAkB,EAAE,gBAAgB,GAAE,MAAmC;IAUhG,OAAO,CAAC,oBAAoB;IAU5B,OAAO,CAAC,cAAc;IAMtB,OAAO,CAAC,WAAW;IASnB,OAAO,CAAC,YAAY;IAId,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC;IAkCtC,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,GAAG,GAAE,MAAoB,GAAG,OAAO,CAAC,IAAI,CAAC;IAoBtE,UAAU,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EAAE,GAAG,GAAE,MAAoB,GAAG,OAAO,CAAC,CAAC,CAAC;IA6BlG,OAAO,CAAC,SAAS;IAKjB,KAAK,IAAI,IAAI;IAiBb,YAAY,IAAI,MAAM;CAqCvB;AAGD,eAAO,MAAM,QAAQ,WAAuB,CAAC;AAC7C,eAAO,MAAM,YAAY,WAA4B,CAAC"}
@@ -0,0 +1,186 @@
1
+ // src/utils/cache.ts
2
+ import fs from 'fs';
3
+ import path from 'path';
4
+ import { createHash } from 'crypto';
5
+ import QuickLRU from 'quick-lru';
6
+ import { getCacheDir } from './paths.js';
7
+ const DEFAULT_TTL = 86400; // 24 hours in seconds
8
+ const DEFAULT_MAX_MEMORY_ENTRIES = 100;
9
+ const CLEANUP_INTERVAL_MS = 60 * 60 * 1000; // 1 hour
10
+ export class FileCache {
11
+ cacheDir;
12
+ memoryCache;
13
+ inFlightFetches = new Map();
14
+ cleanupInterval = null;
15
+ constructor(namespace = 'default', maxMemoryEntries = DEFAULT_MAX_MEMORY_ENTRIES) {
16
+ this.cacheDir = getCacheDir(namespace);
17
+ this.memoryCache = new QuickLRU({ maxSize: maxMemoryEntries });
18
+ this.ensureCacheDir();
19
+ // Clean expired entries on startup
20
+ this.clearExpired();
21
+ // Start periodic cleanup
22
+ this.startPeriodicCleanup();
23
+ }
24
+ startPeriodicCleanup() {
25
+ // Avoid multiple intervals if constructor is called multiple times
26
+ if (this.cleanupInterval)
27
+ return;
28
+ this.cleanupInterval = setInterval(() => {
29
+ this.clearExpired();
30
+ }, CLEANUP_INTERVAL_MS);
31
+ // Don't keep the process alive just for cleanup
32
+ this.cleanupInterval.unref();
33
+ }
34
+ ensureCacheDir() {
35
+ if (!fs.existsSync(this.cacheDir)) {
36
+ fs.mkdirSync(this.cacheDir, { recursive: true });
37
+ }
38
+ }
39
+ getCacheKey(key) {
40
+ // Hash long keys to avoid filesystem issues
41
+ if (key.length > 100) {
42
+ return createHash('md5').update(key).digest('hex');
43
+ }
44
+ // Sanitize key for filesystem
45
+ return key.replace(/[^a-zA-Z0-9-_]/g, '_');
46
+ }
47
+ getCachePath(key) {
48
+ return path.join(this.cacheDir, `${this.getCacheKey(key)}.json`);
49
+ }
50
+ async get(key) {
51
+ // Check memory cache first
52
+ const memEntry = this.memoryCache.get(key);
53
+ if (memEntry) {
54
+ if (!this.isExpired(memEntry)) {
55
+ return memEntry.data;
56
+ }
57
+ // Remove expired entry from memory cache
58
+ this.memoryCache.delete(key);
59
+ }
60
+ // Check file cache
61
+ const cachePath = this.getCachePath(key);
62
+ try {
63
+ if (fs.existsSync(cachePath)) {
64
+ const content = fs.readFileSync(cachePath, 'utf-8');
65
+ const entry = JSON.parse(content);
66
+ if (!this.isExpired(entry)) {
67
+ // Populate memory cache
68
+ this.memoryCache.set(key, entry);
69
+ return entry.data;
70
+ }
71
+ else {
72
+ // Clean up expired entry
73
+ fs.unlinkSync(cachePath);
74
+ }
75
+ }
76
+ }
77
+ catch {
78
+ // Cache read failed, return null
79
+ }
80
+ return null;
81
+ }
82
+ async set(key, data, ttl = DEFAULT_TTL) {
83
+ const now = Date.now();
84
+ const entry = {
85
+ data,
86
+ timestamp: now,
87
+ ttl,
88
+ };
89
+ // Set in memory cache
90
+ this.memoryCache.set(key, entry);
91
+ // Set in file cache
92
+ const cachePath = this.getCachePath(key);
93
+ try {
94
+ fs.writeFileSync(cachePath, JSON.stringify(entry));
95
+ }
96
+ catch {
97
+ // Cache write failed, continue without caching
98
+ }
99
+ }
100
+ async getOrFetch(key, fetcher, ttl = DEFAULT_TTL) {
101
+ // Check cache first
102
+ const cached = await this.get(key);
103
+ if (cached !== null) {
104
+ return cached;
105
+ }
106
+ // Check if a fetch is already in progress for this key
107
+ const inFlight = this.inFlightFetches.get(key);
108
+ if (inFlight) {
109
+ return inFlight;
110
+ }
111
+ // Start a new fetch and track it
112
+ const fetchPromise = (async () => {
113
+ try {
114
+ const data = await fetcher();
115
+ await this.set(key, data, ttl);
116
+ return data;
117
+ }
118
+ finally {
119
+ // Remove from in-flight map when complete (success or failure)
120
+ this.inFlightFetches.delete(key);
121
+ }
122
+ })();
123
+ this.inFlightFetches.set(key, fetchPromise);
124
+ return fetchPromise;
125
+ }
126
+ isExpired(entry) {
127
+ const age = (Date.now() - entry.timestamp) / 1000; // age in seconds
128
+ return age > entry.ttl;
129
+ }
130
+ clear() {
131
+ // Clear memory cache
132
+ this.memoryCache.clear();
133
+ // Clear file cache
134
+ try {
135
+ if (fs.existsSync(this.cacheDir)) {
136
+ const files = fs.readdirSync(this.cacheDir);
137
+ for (const file of files) {
138
+ fs.unlinkSync(path.join(this.cacheDir, file));
139
+ }
140
+ }
141
+ }
142
+ catch {
143
+ // Ignore errors during clear
144
+ }
145
+ }
146
+ clearExpired() {
147
+ let cleared = 0;
148
+ // Clear expired from memory
149
+ for (const [key, entry] of this.memoryCache) {
150
+ if (this.isExpired(entry)) {
151
+ this.memoryCache.delete(key);
152
+ cleared++;
153
+ }
154
+ }
155
+ // Clear expired from files
156
+ try {
157
+ if (fs.existsSync(this.cacheDir)) {
158
+ const files = fs.readdirSync(this.cacheDir);
159
+ for (const file of files) {
160
+ const filePath = path.join(this.cacheDir, file);
161
+ try {
162
+ const content = fs.readFileSync(filePath, 'utf-8');
163
+ const entry = JSON.parse(content);
164
+ if (this.isExpired(entry)) {
165
+ fs.unlinkSync(filePath);
166
+ cleared++;
167
+ }
168
+ }
169
+ catch {
170
+ // Remove corrupted cache files
171
+ fs.unlinkSync(filePath);
172
+ cleared++;
173
+ }
174
+ }
175
+ }
176
+ }
177
+ catch {
178
+ // Ignore errors during cleanup
179
+ }
180
+ return cleared;
181
+ }
182
+ }
183
+ // Shared cache instances
184
+ export const rssCache = new FileCache('rss');
185
+ export const articleCache = new FileCache('articles');
186
+ //# sourceMappingURL=cache.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache.js","sourceRoot":"","sources":["../../src/utils/cache.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Concurrency utilities for parallel processing
3
+ */
4
+ /**
5
+ * Run async operations with a concurrency limit
6
+ * @param items - Array of items to process
7
+ * @param limit - Maximum number of concurrent operations (must be positive finite number)
8
+ * @param worker - Function to process each item
9
+ * @returns Promise resolving to array of results in same order as input
10
+ * @throws Error if limit is not a positive finite number
11
+ */
12
+ export declare function runWithConcurrency<T, R>(items: T[], limit: number, worker: (item: T) => Promise<R>): Promise<R[]>;
13
+ //# sourceMappingURL=concurrency.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"concurrency.d.ts","sourceRoot":"","sources":["../../src/utils/concurrency.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;;;;;;GAOG;AACH,wBAAsB,kBAAkB,CAAC,CAAC,EAAE,CAAC,EAC3C,KAAK,EAAE,CAAC,EAAE,EACV,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,GAC9B,OAAO,CAAC,CAAC,EAAE,CAAC,CA8Bd"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Concurrency utilities for parallel processing
3
+ */
4
+ /**
5
+ * Run async operations with a concurrency limit
6
+ * @param items - Array of items to process
7
+ * @param limit - Maximum number of concurrent operations (must be positive finite number)
8
+ * @param worker - Function to process each item
9
+ * @returns Promise resolving to array of results in same order as input
10
+ * @throws Error if limit is not a positive finite number
11
+ */
12
+ export async function runWithConcurrency(items, limit, worker) {
13
+ if (items.length === 0) {
14
+ return [];
15
+ }
16
+ // Validate limit is a positive finite number
17
+ if (!Number.isFinite(limit) || limit <= 0 || !Number.isInteger(limit)) {
18
+ throw new Error(`Invalid concurrency limit: ${limit}. Must be a positive finite integer, got ${typeof limit === 'number' ? limit : typeof limit}`);
19
+ }
20
+ const results = new Array(items.length);
21
+ let nextIndex = 0;
22
+ const runWorker = async () => {
23
+ while (nextIndex < items.length) {
24
+ const currentIndex = nextIndex++;
25
+ // Worker function should handle errors appropriately
26
+ results[currentIndex] = await worker(items[currentIndex]);
27
+ }
28
+ };
29
+ const workers = Array.from({ length: Math.min(limit, items.length) }, () => runWorker());
30
+ await Promise.all(workers);
31
+ return results;
32
+ }
33
+ //# sourceMappingURL=concurrency.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"concurrency.js","sourceRoot":"","sources":["../../src/utils/concurrency.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,KAAU,EACV,KAAa,EACb,MAA+B;IAE/B,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,6CAA6C;IAC7C,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC;QACtE,MAAM,IAAI,KAAK,CACb,8BAA8B,KAAK,4CAA4C,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,KAAK,EAAE,CAClI,CAAC;IACJ,CAAC;IAED,MAAM,OAAO,GAAQ,IAAI,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IAC7C,IAAI,SAAS,GAAG,CAAC,CAAC;IAElB,MAAM,SAAS,GAAG,KAAK,IAAmB,EAAE;QAC1C,OAAO,SAAS,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC;YAChC,MAAM,YAAY,GAAG,SAAS,EAAE,CAAC;YACjC,qDAAqD;YACrD,OAAO,CAAC,YAAY,CAAC,GAAG,MAAM,MAAM,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC,CAAC;QAC5D,CAAC;IACH,CAAC,CAAC;IAEF,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,CACxB,EAAE,MAAM,EAAE,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,KAAK,CAAC,MAAM,CAAC,EAAE,EACzC,GAAG,EAAE,CAAC,SAAS,EAAE,CAClB,CAAC;IAEF,MAAM,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IAC3B,OAAO,OAAO,CAAC;AACjB,CAAC"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Error handling utilities for consistent error logging across the codebase.
3
+ * Uses structured logger to keep output consistent.
4
+ */
5
+ /**
6
+ * Type guard to check if a value is an Error instance.
7
+ */
8
+ export declare function isError(value: unknown): value is Error;
9
+ /**
10
+ * Safely extracts an error message from any thrown value.
11
+ * Returns error.message if Error, String(error) otherwise.
12
+ */
13
+ export declare function toErrorMessage(error: unknown): string;
14
+ /**
15
+ * Logs an error with context prefix and optional details.
16
+ * Format: [context] message { details }
17
+ */
18
+ export declare function logError(context: string, error: unknown, details?: Record<string, unknown>): void;
19
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/utils/errors.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH;;GAEG;AACH,wBAAgB,OAAO,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,KAAK,CAEtD;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAKrD;AAED;;;GAGG;AACH,wBAAgB,QAAQ,CACtB,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,OAAO,EACd,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAChC,IAAI,CAQN"}
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Error handling utilities for consistent error logging across the codebase.
3
+ * Uses structured logger to keep output consistent.
4
+ */
5
+ import logger from './logger.js';
6
+ /**
7
+ * Type guard to check if a value is an Error instance.
8
+ */
9
+ export function isError(value) {
10
+ return value instanceof Error;
11
+ }
12
+ /**
13
+ * Safely extracts an error message from any thrown value.
14
+ * Returns error.message if Error, String(error) otherwise.
15
+ */
16
+ export function toErrorMessage(error) {
17
+ if (isError(error)) {
18
+ return error.message;
19
+ }
20
+ return String(error);
21
+ }
22
+ /**
23
+ * Logs an error with context prefix and optional details.
24
+ * Format: [context] message { details }
25
+ */
26
+ export function logError(context, error, details) {
27
+ const message = toErrorMessage(error);
28
+ const payload = { context, ...(details ?? {}) };
29
+ if (isError(error)) {
30
+ logger.error({ ...payload, err: error }, message);
31
+ return;
32
+ }
33
+ logger.error(payload, message);
34
+ }
35
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/utils/errors.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,MAAM,MAAM,aAAa,CAAC;AACjC;;GAEG;AACH,MAAM,UAAU,OAAO,CAAC,KAAc;IACpC,OAAO,KAAK,YAAY,KAAK,CAAC;AAChC,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,cAAc,CAAC,KAAc;IAC3C,IAAI,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACnB,OAAO,KAAK,CAAC,OAAO,CAAC;IACvB,CAAC;IACD,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;AACvB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,QAAQ,CACtB,OAAe,EACf,KAAc,EACd,OAAiC;IAEjC,MAAM,OAAO,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC;IACtC,MAAM,OAAO,GAAG,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,IAAI,EAAE,CAAC,EAAE,CAAC;IAChD,IAAI,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACnB,MAAM,CAAC,KAAK,CAAC,EAAE,GAAG,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,EAAE,OAAO,CAAC,CAAC;QAClD,OAAO;IACT,CAAC;IACD,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;AACjC,CAAC"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Shared fetch implementation based on undici.
3
+ */
4
+ import { fetch as undiciFetch } from 'undici';
5
+ export declare const fetch: typeof undiciFetch;
6
+ //# sourceMappingURL=fetch.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fetch.d.ts","sourceRoot":"","sources":["../../src/utils/fetch.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,KAAK,IAAI,WAAW,EAAE,MAAM,QAAQ,CAAC;AAE9C,eAAO,MAAM,KAAK,oBAAc,CAAC"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Shared fetch implementation based on undici.
3
+ */
4
+ import { fetch as undiciFetch } from 'undici';
5
+ export const fetch = undiciFetch;
6
+ //# sourceMappingURL=fetch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fetch.js","sourceRoot":"","sources":["../../src/utils/fetch.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,KAAK,IAAI,WAAW,EAAE,MAAM,QAAQ,CAAC;AAE9C,MAAM,CAAC,MAAM,KAAK,GAAG,WAAW,CAAC"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Shared HTTP utilities for making requests with timeouts and error handling
3
+ */
4
+ export interface FetchOptions {
5
+ timeout?: number;
6
+ headers?: Record<string, string>;
7
+ signal?: AbortSignal;
8
+ }
9
+ /**
10
+ * Build headers with optional authorization token
11
+ */
12
+ export declare function buildHeaders(userAgent: string, authToken?: string): Record<string, string>;
13
+ /**
14
+ * Fetch JSON data with timeout
15
+ */
16
+ export declare function fetchJson<T>(url: string, options?: FetchOptions): Promise<T>;
17
+ /**
18
+ * Fetch text content with timeout
19
+ */
20
+ export declare function fetchText(url: string, options?: FetchOptions): Promise<string>;
21
+ //# sourceMappingURL=http.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../../src/utils/http.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,MAAM,WAAW,YAAY;IAC3B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAID;;GAEG;AACH,wBAAgB,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAQ1F;AA8BD;;GAEG;AACH,wBAAsB,SAAS,CAAC,CAAC,EAC/B,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,YAAiB,GACzB,OAAO,CAAC,CAAC,CAAC,CAGZ;AAED;;GAEG;AACH,wBAAsB,SAAS,CAC7B,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,YAAiB,GACzB,OAAO,CAAC,MAAM,CAAC,CAGjB"}