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,206 @@
1
+ // src/utils/source-registry.test.ts
2
+ import { describe, it, expect, beforeEach, vi, afterEach } from 'vitest';
3
+ import { getSource, getAllFreeSources, getSources, getSourceNames, searchMultipleSources, prefetchAllSources } from './source-registry.js';
4
+ // Mock pattern data for tests
5
+ const mockPattern = {
6
+ id: 'test-1',
7
+ title: 'Test Pattern',
8
+ url: 'https://example.com/test',
9
+ publishDate: '2024-01-01',
10
+ excerpt: 'Test excerpt',
11
+ content: 'Test content',
12
+ topics: ['swift'],
13
+ relevanceScore: 80,
14
+ hasCode: true,
15
+ };
16
+ describe('source-registry', () => {
17
+ // Mock the searchPatterns and fetchPatterns methods before each test
18
+ beforeEach(() => {
19
+ const sources = getAllFreeSources();
20
+ sources.forEach(source => {
21
+ vi.spyOn(source, 'searchPatterns').mockResolvedValue([mockPattern]);
22
+ vi.spyOn(source, 'fetchPatterns').mockResolvedValue([mockPattern]);
23
+ });
24
+ });
25
+ afterEach(() => {
26
+ vi.restoreAllMocks();
27
+ });
28
+ describe('getSource singleton caching', () => {
29
+ it('should return the same instance for multiple calls with the same source name', () => {
30
+ const source1 = getSource('sundell');
31
+ const source2 = getSource('sundell');
32
+ expect(source1).toBe(source2);
33
+ });
34
+ it('should return different instances for different source names', () => {
35
+ const sundell = getSource('sundell');
36
+ const vanderlee = getSource('vanderlee');
37
+ expect(sundell).not.toBe(vanderlee);
38
+ });
39
+ it('should cache all source types independently', () => {
40
+ const sources = ['sundell', 'vanderlee', 'nilcoalescing', 'pointfree'];
41
+ const instances = sources.map(name => getSource(name));
42
+ // Verify all instances are different
43
+ const uniqueInstances = new Set(instances);
44
+ expect(uniqueInstances.size).toBe(sources.length);
45
+ // Verify second calls return cached instances
46
+ sources.forEach((name, index) => {
47
+ expect(getSource(name)).toBe(instances[index]);
48
+ });
49
+ });
50
+ it('should persist cache across multiple calls', () => {
51
+ const first = getSource('nilcoalescing');
52
+ const second = getSource('nilcoalescing');
53
+ const third = getSource('nilcoalescing');
54
+ expect(first).toBe(second);
55
+ expect(second).toBe(third);
56
+ });
57
+ it('should have searchPatterns method on cached instances', () => {
58
+ const source = getSource('sundell');
59
+ expect(source).toHaveProperty('searchPatterns');
60
+ expect(typeof source.searchPatterns).toBe('function');
61
+ });
62
+ it('should have fetchPatterns method on cached instances', () => {
63
+ const source = getSource('pointfree');
64
+ expect(source).toHaveProperty('fetchPatterns');
65
+ expect(typeof source.fetchPatterns).toBe('function');
66
+ });
67
+ });
68
+ describe('getAllFreeSources', () => {
69
+ it('should return all source instances', () => {
70
+ const sources = getAllFreeSources();
71
+ expect(sources).toHaveLength(4);
72
+ });
73
+ it('should return cached instances', () => {
74
+ const sources1 = getAllFreeSources();
75
+ const sources2 = getAllFreeSources();
76
+ // Compare instances at each index
77
+ sources1.forEach((source, index) => {
78
+ expect(source).toBe(sources2[index]);
79
+ });
80
+ });
81
+ });
82
+ describe('getSources', () => {
83
+ it('should return single source when given one name', () => {
84
+ const sources = getSources('sundell');
85
+ expect(sources).toHaveLength(1);
86
+ expect(sources[0]).toBe(getSource('sundell'));
87
+ });
88
+ it('should return multiple sources when given array of names', () => {
89
+ const sources = getSources(['sundell', 'vanderlee']);
90
+ expect(sources).toHaveLength(2);
91
+ expect(sources[0]).toBe(getSource('sundell'));
92
+ expect(sources[1]).toBe(getSource('vanderlee'));
93
+ });
94
+ it('should return all sources when given "all"', () => {
95
+ const sources = getSources('all');
96
+ expect(sources).toHaveLength(4);
97
+ });
98
+ it('should return cached instances', () => {
99
+ const sources1 = getSources(['pointfree', 'nilcoalescing']);
100
+ const sources2 = getSources(['pointfree', 'nilcoalescing']);
101
+ expect(sources1[0]).toBe(sources2[0]);
102
+ expect(sources1[1]).toBe(sources2[1]);
103
+ });
104
+ });
105
+ describe('getSourceNames', () => {
106
+ it('should return single name in array for single source', () => {
107
+ const names = getSourceNames('sundell');
108
+ expect(names).toEqual(['sundell']);
109
+ });
110
+ it('should return array of names for array input', () => {
111
+ const names = getSourceNames(['sundell', 'vanderlee']);
112
+ expect(names).toEqual(['sundell', 'vanderlee']);
113
+ });
114
+ it('should return all source names for "all"', () => {
115
+ const names = getSourceNames('all');
116
+ expect(names).toHaveLength(4);
117
+ expect(names).toContain('sundell');
118
+ expect(names).toContain('vanderlee');
119
+ expect(names).toContain('nilcoalescing');
120
+ expect(names).toContain('pointfree');
121
+ });
122
+ });
123
+ describe('searchMultipleSources', () => {
124
+ it('should search all sources by default', async () => {
125
+ const results = await searchMultipleSources('swift async');
126
+ expect(Array.isArray(results)).toBe(true);
127
+ });
128
+ it('should handle individual source searches', async () => {
129
+ const results = await searchMultipleSources('swift', 'sundell');
130
+ expect(Array.isArray(results)).toBe(true);
131
+ });
132
+ it('should handle array of sources', async () => {
133
+ const results = await searchMultipleSources('swift', ['sundell', 'vanderlee']);
134
+ expect(Array.isArray(results)).toBe(true);
135
+ });
136
+ it('should collect results even if some sources fail', async () => {
137
+ // This tests the Promise.allSettled behavior
138
+ const results = await searchMultipleSources('test query');
139
+ // Should not throw even if individual sources fail
140
+ expect(Array.isArray(results)).toBe(true);
141
+ });
142
+ });
143
+ describe('prefetchAllSources', () => {
144
+ it('should return SettledResult array', async () => {
145
+ const results = await prefetchAllSources();
146
+ expect(Array.isArray(results)).toBe(true);
147
+ expect(results.length).toBe(4);
148
+ });
149
+ it('should return results with status property', async () => {
150
+ const results = await prefetchAllSources();
151
+ results.forEach(result => {
152
+ expect(result).toHaveProperty('status');
153
+ expect(['fulfilled', 'rejected']).toContain(result.status);
154
+ });
155
+ });
156
+ it('should handle partial failures gracefully', async () => {
157
+ // Even if some sources fail, the function should complete
158
+ const results = await prefetchAllSources();
159
+ expect(results).toBeDefined();
160
+ expect(results.length).toBe(4);
161
+ // Count successful and failed
162
+ const successful = results.filter(r => r.status === 'fulfilled').length;
163
+ const failed = results.filter(r => r.status === 'rejected').length;
164
+ expect(successful + failed).toBe(4);
165
+ });
166
+ it('should provide access to fulfilled results', async () => {
167
+ const results = await prefetchAllSources();
168
+ const fulfilled = results.filter((r) => r.status === 'fulfilled');
169
+ fulfilled.forEach(result => {
170
+ expect(result).toHaveProperty('value');
171
+ expect(Array.isArray(result.value)).toBe(true);
172
+ });
173
+ });
174
+ it('should provide access to rejection reasons', async () => {
175
+ const results = await prefetchAllSources();
176
+ const rejected = results.filter((r) => r.status === 'rejected');
177
+ rejected.forEach(result => {
178
+ expect(result).toHaveProperty('reason');
179
+ });
180
+ });
181
+ });
182
+ describe('cache persistence integration', () => {
183
+ it('should maintain same instances across different function calls', () => {
184
+ const direct = getSource('sundell');
185
+ const fromArray = getSources(['sundell'])[0];
186
+ const fromAll = getAllFreeSources()[0]; // Assuming sundell is first
187
+ expect(direct).toBe(fromArray);
188
+ // Note: fromAll might be in a different order, so we just check it's in the set
189
+ const allSources = getAllFreeSources();
190
+ expect(allSources).toContain(direct);
191
+ });
192
+ it('should use cached instances in search operations', async () => {
193
+ const sourceBefore = getSource('sundell');
194
+ await searchMultipleSources('test', 'sundell');
195
+ const sourceAfter = getSource('sundell');
196
+ expect(sourceBefore).toBe(sourceAfter);
197
+ });
198
+ it('should use cached instances in prefetch operations', async () => {
199
+ const sourceBefore = getSource('pointfree');
200
+ await prefetchAllSources();
201
+ const sourceAfter = getSource('pointfree');
202
+ expect(sourceBefore).toBe(sourceAfter);
203
+ });
204
+ });
205
+ });
206
+ //# sourceMappingURL=source-registry.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"source-registry.test.js","sourceRoot":"","sources":["../../src/utils/source-registry.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,61 @@
1
+ /**
2
+ * Shared utilities for analyzing Swift code content and detecting topics
3
+ */
4
+ /**
5
+ * Detect topics from text based on keyword matching
6
+ * @param text The text to analyze
7
+ * @param keywords Map of topic names to keyword arrays
8
+ * @returns Array of detected topic names
9
+ */
10
+ export declare function detectTopics(text: string, keywords: Record<string, string[]>): string[];
11
+ /**
12
+ * Check if content contains Swift code patterns
13
+ * @param content The content to check
14
+ * @returns True if Swift code patterns are detected
15
+ */
16
+ export declare function hasCodeContent(content: string): boolean;
17
+ /**
18
+ * Calculate relevance score based on keyword presence and code content
19
+ * @param text The text to analyze
20
+ * @param hasCode Whether the content has code
21
+ * @param qualitySignals Map of quality signals to point values
22
+ * @param baseScore Starting score (default: 50)
23
+ * @param codeBonus Bonus points for having code (default: 10-15)
24
+ * @returns Relevance score (0-100)
25
+ */
26
+ export declare function calculateRelevance(text: string, hasCode: boolean, qualitySignals: Record<string, number>, baseScore?: number, codeBonus?: number): number;
27
+ /**
28
+ * Extract code snippets from content
29
+ * @param content The content to extract from
30
+ * @param maxSnippets Maximum number of snippets to return (default: 2)
31
+ * @returns Array of code snippets
32
+ */
33
+ export declare function extractCodeSnippets(content: string, maxSnippets?: number): string[];
34
+ /**
35
+ * Extract Swift-specific techniques and APIs from content
36
+ * @param content The content to analyze
37
+ * @returns Array of detected techniques (max 5, unique)
38
+ */
39
+ export declare function extractTechniques(content: string): string[];
40
+ /**
41
+ * Detect complexity level of content
42
+ * @param content The content to analyze
43
+ * @param topics Detected topics
44
+ * @returns Complexity level
45
+ */
46
+ export declare function detectComplexity(content: string, topics: string[]): 'beginner' | 'intermediate' | 'advanced';
47
+ /**
48
+ * Truncate text at sentence boundary
49
+ * @param text Text to truncate
50
+ * @param maxLength Maximum length
51
+ * @returns Truncated text without trailing ellipsis
52
+ */
53
+ export declare function truncateAtSentence(text: string, maxLength: number): string;
54
+ /**
55
+ * Extract descriptive title from content
56
+ * @param content Content to extract from
57
+ * @param fallbackTitle Fallback if no good title found
58
+ * @returns Extracted or fallback title
59
+ */
60
+ export declare function extractDescriptiveTitle(content: string, fallbackTitle: string): string;
61
+ //# sourceMappingURL=swift-analysis.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"swift-analysis.d.ts","sourceRoot":"","sources":["../../src/utils/swift-analysis.ts"],"names":[],"mappings":"AAEA;;GAEG;AAEH;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,GAAG,MAAM,EAAE,CAWvF;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CA8BvD;AAED;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,OAAO,EAChB,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EACtC,SAAS,GAAE,MAAW,EACtB,SAAS,GAAE,MAAW,GACrB,MAAM,CAkBR;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,EAAE,WAAW,GAAE,MAAU,GAAG,MAAM,EAAE,CAiCtF;AAWD;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAqE3D;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,UAAU,GAAG,cAAc,GAAG,UAAU,CA2C5G;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAyC1E;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,MAAM,CAsCtF"}
@@ -0,0 +1,339 @@
1
+ // src/utils/swift-analysis.ts
2
+ /**
3
+ * Shared utilities for analyzing Swift code content and detecting topics
4
+ */
5
+ /**
6
+ * Detect topics from text based on keyword matching
7
+ * @param text The text to analyze
8
+ * @param keywords Map of topic names to keyword arrays
9
+ * @returns Array of detected topic names
10
+ */
11
+ export function detectTopics(text, keywords) {
12
+ const topics = [];
13
+ const lower = text.toLowerCase();
14
+ for (const [topic, words] of Object.entries(keywords)) {
15
+ if (words.some(w => lower.includes(w))) {
16
+ topics.push(topic);
17
+ }
18
+ }
19
+ return topics;
20
+ }
21
+ /**
22
+ * Check if content contains Swift code patterns
23
+ * @param content The content to check
24
+ * @returns True if Swift code patterns are detected
25
+ */
26
+ export function hasCodeContent(content) {
27
+ // Check for common Swift code patterns
28
+ if (/\b(func|class|struct|protocol|extension|enum|actor)\s+\w+/.test(content)) {
29
+ return true;
30
+ }
31
+ // Check for markdown code blocks
32
+ if (content.includes('```')) {
33
+ return true;
34
+ }
35
+ // Check for HTML code tags
36
+ if (content.includes('<code>') || content.includes('<pre>')) {
37
+ return true;
38
+ }
39
+ // Check for additional Swift-specific patterns
40
+ const codeIndicators = [
41
+ /\blet\s+\w+\s*[=:]/,
42
+ /\bvar\s+\w+\s*[=:]/,
43
+ /\breturn\s+\w+/,
44
+ /\bguard\s+let/,
45
+ /\bif\s+let/,
46
+ /\basync\s+(func|let|var|throws)/,
47
+ /\bawait\s+\w+/,
48
+ /\b\w+\s*\(\s*\)\s*->\s*\w+/,
49
+ /@\w+\s+(struct|class|func|var)/,
50
+ ];
51
+ return codeIndicators.some(pattern => pattern.test(content));
52
+ }
53
+ /**
54
+ * Calculate relevance score based on keyword presence and code content
55
+ * @param text The text to analyze
56
+ * @param hasCode Whether the content has code
57
+ * @param qualitySignals Map of quality signals to point values
58
+ * @param baseScore Starting score (default: 50)
59
+ * @param codeBonus Bonus points for having code (default: 10-15)
60
+ * @returns Relevance score (0-100)
61
+ */
62
+ export function calculateRelevance(text, hasCode, qualitySignals, baseScore = 50, codeBonus = 10) {
63
+ const lower = text.toLowerCase();
64
+ let score = baseScore;
65
+ // Add points for quality signals
66
+ for (const [keyword, points] of Object.entries(qualitySignals)) {
67
+ if (lower.includes(keyword)) {
68
+ score += points;
69
+ }
70
+ }
71
+ // Bonus for code content
72
+ if (hasCode) {
73
+ score += codeBonus;
74
+ }
75
+ // Cap at 100
76
+ return Math.min(100, score);
77
+ }
78
+ /**
79
+ * Extract code snippets from content
80
+ * @param content The content to extract from
81
+ * @param maxSnippets Maximum number of snippets to return (default: 2)
82
+ * @returns Array of code snippets
83
+ */
84
+ export function extractCodeSnippets(content, maxSnippets = 2) {
85
+ const snippets = [];
86
+ // Extract markdown code blocks (```swift or ```)
87
+ const markdownRegex = /```(?:swift)?\n?([\s\S]*?)```/g;
88
+ let match;
89
+ while ((match = markdownRegex.exec(content)) !== null) {
90
+ const code = match[1].trim();
91
+ if (code && code.split('\n').length >= 2) {
92
+ snippets.push(truncateSnippet(code));
93
+ }
94
+ if (snippets.length >= maxSnippets)
95
+ break;
96
+ }
97
+ // Extract HTML code blocks if we don't have enough snippets
98
+ if (snippets.length < maxSnippets) {
99
+ const htmlRegex = /<pre><code[^>]*>([\s\S]*?)<\/code><\/pre>/g;
100
+ while ((match = htmlRegex.exec(content)) !== null) {
101
+ const code = match[1]
102
+ .replace(/<[^>]+>/g, '') // Remove HTML tags
103
+ .replace(/&lt;/g, '<')
104
+ .replace(/&gt;/g, '>')
105
+ .replace(/&amp;/g, '&')
106
+ .replace(/&quot;/g, '"')
107
+ .trim();
108
+ if (code && code.split('\n').length >= 2) {
109
+ snippets.push(truncateSnippet(code));
110
+ }
111
+ if (snippets.length >= maxSnippets)
112
+ break;
113
+ }
114
+ }
115
+ return snippets.slice(0, maxSnippets);
116
+ }
117
+ /**
118
+ * Truncate a code snippet to ~10 lines
119
+ */
120
+ function truncateSnippet(code) {
121
+ const lines = code.split('\n');
122
+ if (lines.length <= 10)
123
+ return code;
124
+ return lines.slice(0, 10).join('\n') + '\n// ...';
125
+ }
126
+ /**
127
+ * Extract Swift-specific techniques and APIs from content
128
+ * @param content The content to analyze
129
+ * @returns Array of detected techniques (max 5, unique)
130
+ */
131
+ export function extractTechniques(content) {
132
+ const techniques = new Set();
133
+ // Swift attributes
134
+ const attributes = [
135
+ '@Observable', '@MainActor', '@State', '@Binding', '@Environment',
136
+ '@Query', '@Model', '@Published', '@StateObject', '@ObservedObject',
137
+ '@ViewBuilder', '@resultBuilder', '@available'
138
+ ];
139
+ for (const attr of attributes) {
140
+ if (content.includes(attr)) {
141
+ techniques.add(attr);
142
+ }
143
+ }
144
+ // Concurrency patterns
145
+ const concurrencyPatterns = [
146
+ { pattern: /\basync\s+(?:func|let|var|throws)/, name: 'async/await' },
147
+ { pattern: /\bawait\s+/, name: 'async/await' },
148
+ { pattern: /\bTask\s*{/, name: 'Task' },
149
+ { pattern: /\bTaskGroup/, name: 'TaskGroup' },
150
+ { pattern: /\bwithCheckedContinuation/, name: 'withCheckedContinuation' },
151
+ { pattern: /\bwithCheckedThrowingContinuation/, name: 'withCheckedThrowingContinuation' },
152
+ { pattern: /\bactor\s+\w+/, name: 'actor' },
153
+ { pattern: /\bSendable/, name: 'Sendable' },
154
+ ];
155
+ for (const { pattern, name } of concurrencyPatterns) {
156
+ if (pattern.test(content)) {
157
+ techniques.add(name);
158
+ }
159
+ }
160
+ // SwiftUI patterns
161
+ const swiftUIPatterns = [
162
+ 'NavigationStack', 'NavigationSplitView', '.navigationDestination',
163
+ '.sheet', '.fullScreenCover', '.toolbar', '.searchable',
164
+ 'List', 'Form', 'ScrollView', 'LazyVStack', 'LazyHStack'
165
+ ];
166
+ for (const pattern of swiftUIPatterns) {
167
+ if (content.includes(pattern)) {
168
+ techniques.add(pattern);
169
+ }
170
+ }
171
+ // SwiftData patterns
172
+ const swiftDataPatterns = ['@Model', '@Query', 'ModelContext', 'ModelContainer'];
173
+ for (const pattern of swiftDataPatterns) {
174
+ if (content.includes(pattern)) {
175
+ techniques.add(pattern);
176
+ }
177
+ }
178
+ // Frameworks (when used in code context)
179
+ const frameworks = ['SwiftUI', 'Combine', 'SwiftData', 'CoreData', 'UIKit'];
180
+ for (const framework of frameworks) {
181
+ // Check if framework appears near code indicators
182
+ if (content.includes(framework) && (content.includes(`import ${framework}`) ||
183
+ content.includes(`${framework}.`))) {
184
+ techniques.add(framework);
185
+ }
186
+ }
187
+ // Return up to 5 techniques
188
+ return Array.from(techniques).slice(0, 5);
189
+ }
190
+ /**
191
+ * Detect complexity level of content
192
+ * @param content The content to analyze
193
+ * @param topics Detected topics
194
+ * @returns Complexity level
195
+ */
196
+ export function detectComplexity(content, topics) {
197
+ const lower = content.toLowerCase();
198
+ // Advanced indicators
199
+ const advancedKeywords = [
200
+ 'performance', 'optimization', 'benchmark', 'profiling',
201
+ 'unsafe', 'pointer', 'memory management',
202
+ 'macro', '@attached', '@freestanding',
203
+ 'race condition', 'thread safety', 'atomic',
204
+ 'custom property wrapper', 'type erasure',
205
+ 'protocol witness', 'existential'
206
+ ];
207
+ const hasAdvancedKeyword = advancedKeywords.some(kw => lower.includes(kw));
208
+ // Beginner indicators
209
+ const beginnerKeywords = [
210
+ 'introduction', 'getting started', 'basics', 'tutorial',
211
+ 'hello world', 'first', 'simple example'
212
+ ];
213
+ const hasBeginnerKeyword = beginnerKeywords.some(kw => lower.includes(kw));
214
+ // Count complexity signals
215
+ const wordCount = content.split(/\s+/).length;
216
+ const codeBlocks = (content.match(/```/g) || []).length / 2;
217
+ const topicCount = topics.length;
218
+ // Decision logic
219
+ if (hasAdvancedKeyword || (topicCount >= 4 && codeBlocks >= 3)) {
220
+ return 'advanced';
221
+ }
222
+ if (hasBeginnerKeyword && topicCount <= 1 && wordCount < 500) {
223
+ return 'beginner';
224
+ }
225
+ if (topicCount <= 1 && codeBlocks <= 1 && wordCount < 300) {
226
+ return 'beginner';
227
+ }
228
+ // Default to intermediate for most content
229
+ return 'intermediate';
230
+ }
231
+ /**
232
+ * Truncate text at sentence boundary
233
+ * @param text Text to truncate
234
+ * @param maxLength Maximum length
235
+ * @returns Truncated text without trailing ellipsis
236
+ */
237
+ export function truncateAtSentence(text, maxLength) {
238
+ if (text.length <= maxLength) {
239
+ return text;
240
+ }
241
+ // Find sentence boundaries within reasonable range (60% allows more flexibility)
242
+ const minLength = Math.floor(maxLength * 0.6);
243
+ // Look for sentence endings (. ! ?) - check both with and without space
244
+ let bestPos = -1;
245
+ // Try to find sentence ending with space after (cleaner break)
246
+ for (const punct of ['. ', '! ', '? ']) {
247
+ const pos = text.lastIndexOf(punct, maxLength);
248
+ if (pos >= minLength && pos > bestPos) {
249
+ bestPos = pos + punct.length - 1; // Include punctuation, exclude trailing space
250
+ }
251
+ }
252
+ // If no sentence ending with space, try just the punctuation
253
+ if (bestPos === -1) {
254
+ for (const punct of ['.', '!', '?']) {
255
+ const pos = text.lastIndexOf(punct, maxLength);
256
+ if (pos >= minLength && pos > bestPos) {
257
+ bestPos = pos + 1; // Include the punctuation
258
+ }
259
+ }
260
+ }
261
+ if (bestPos > 0) {
262
+ return text.substring(0, bestPos).trim();
263
+ }
264
+ // Fall back to word boundary
265
+ const wordBoundary = text.lastIndexOf(' ', maxLength);
266
+ if (wordBoundary > minLength) {
267
+ return text.substring(0, wordBoundary).trim();
268
+ }
269
+ // Last resort: cut at maxLength but try to avoid mid-word
270
+ return text.substring(0, maxLength).trim();
271
+ }
272
+ /**
273
+ * Extract descriptive title from content
274
+ * @param content Content to extract from
275
+ * @param fallbackTitle Fallback if no good title found
276
+ * @returns Extracted or fallback title
277
+ */
278
+ export function extractDescriptiveTitle(content, fallbackTitle) {
279
+ // Try to find H1 in markdown
280
+ const h1Match = content.match(/^#\s+(.+)$/m);
281
+ if (h1Match) {
282
+ const title = cleanTitle(h1Match[1]);
283
+ if (!isGenericTitle(title)) {
284
+ return title;
285
+ }
286
+ }
287
+ // Try HTML H1
288
+ const htmlH1Match = content.match(/<h1[^>]*>(.*?)<\/h1>/i);
289
+ if (htmlH1Match) {
290
+ const title = cleanTitle(htmlH1Match[1]);
291
+ if (!isGenericTitle(title)) {
292
+ return title;
293
+ }
294
+ }
295
+ // Try H2 if H1 was generic
296
+ const h2Match = content.match(/^##\s+(.+)$/m);
297
+ if (h2Match) {
298
+ const title = cleanTitle(h2Match[1]);
299
+ if (!isGenericTitle(title)) {
300
+ return title;
301
+ }
302
+ }
303
+ // Try HTML H2
304
+ const htmlH2Match = content.match(/<h2[^>]*>(.*?)<\/h2>/i);
305
+ if (htmlH2Match) {
306
+ const title = cleanTitle(htmlH2Match[1]);
307
+ if (!isGenericTitle(title)) {
308
+ return title;
309
+ }
310
+ }
311
+ return fallbackTitle;
312
+ }
313
+ /**
314
+ * Clean title by removing HTML tags and extra whitespace
315
+ */
316
+ function cleanTitle(title) {
317
+ return title
318
+ .replace(/<[^>]+>/g, '') // Remove HTML tags
319
+ .replace(/&lt;/g, '<')
320
+ .replace(/&gt;/g, '>')
321
+ .replace(/&amp;/g, '&')
322
+ .replace(/&quot;/g, '"')
323
+ .replace(/\s+/g, ' ')
324
+ .trim();
325
+ }
326
+ /**
327
+ * Check if title is too generic to be useful
328
+ */
329
+ function isGenericTitle(title) {
330
+ const genericPatterns = [
331
+ /^newsletter\s*#?\d+$/i,
332
+ /^issue\s*#?\d+$/i,
333
+ /^swift by sundell$/i,
334
+ /^blog$/i,
335
+ /^article$/i,
336
+ ];
337
+ return genericPatterns.some(pattern => pattern.test(title));
338
+ }
339
+ //# sourceMappingURL=swift-analysis.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"swift-analysis.js","sourceRoot":"","sources":["../../src/utils/swift-analysis.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=swift-analysis.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"swift-analysis.test.d.ts","sourceRoot":"","sources":["../../src/utils/swift-analysis.test.ts"],"names":[],"mappings":""}