@code-rag/api-server 0.1.0

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 (66) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +26 -0
  3. package/dist/dashboard/data-collector.d.ts +61 -0
  4. package/dist/dashboard/data-collector.js +244 -0
  5. package/dist/dashboard/data-collector.js.map +1 -0
  6. package/dist/dashboard/data-collector.test.d.ts +1 -0
  7. package/dist/dashboard/data-collector.test.js +334 -0
  8. package/dist/dashboard/data-collector.test.js.map +1 -0
  9. package/dist/dashboard/index.d.ts +10 -0
  10. package/dist/dashboard/index.js +6 -0
  11. package/dist/dashboard/index.js.map +1 -0
  12. package/dist/dashboard/routes.d.ts +18 -0
  13. package/dist/dashboard/routes.js +150 -0
  14. package/dist/dashboard/routes.js.map +1 -0
  15. package/dist/dashboard/templates.d.ts +47 -0
  16. package/dist/dashboard/templates.js +591 -0
  17. package/dist/dashboard/templates.js.map +1 -0
  18. package/dist/dashboard/templates.test.d.ts +1 -0
  19. package/dist/dashboard/templates.test.js +408 -0
  20. package/dist/dashboard/templates.test.js.map +1 -0
  21. package/dist/dashboard/types.d.ts +119 -0
  22. package/dist/dashboard/types.js +4 -0
  23. package/dist/dashboard/types.js.map +1 -0
  24. package/dist/index.d.ts +21 -0
  25. package/dist/index.js +36 -0
  26. package/dist/index.js.map +1 -0
  27. package/dist/middleware/auth.d.ts +37 -0
  28. package/dist/middleware/auth.js +92 -0
  29. package/dist/middleware/auth.js.map +1 -0
  30. package/dist/middleware/rate-limit.d.ts +26 -0
  31. package/dist/middleware/rate-limit.js +79 -0
  32. package/dist/middleware/rate-limit.js.map +1 -0
  33. package/dist/openapi.d.ts +14 -0
  34. package/dist/openapi.js +363 -0
  35. package/dist/openapi.js.map +1 -0
  36. package/dist/routes/context.d.ts +15 -0
  37. package/dist/routes/context.js +84 -0
  38. package/dist/routes/context.js.map +1 -0
  39. package/dist/routes/history.d.ts +56 -0
  40. package/dist/routes/history.js +308 -0
  41. package/dist/routes/history.js.map +1 -0
  42. package/dist/routes/index-trigger.d.ts +21 -0
  43. package/dist/routes/index-trigger.js +47 -0
  44. package/dist/routes/index-trigger.js.map +1 -0
  45. package/dist/routes/search.d.ts +24 -0
  46. package/dist/routes/search.js +85 -0
  47. package/dist/routes/search.js.map +1 -0
  48. package/dist/routes/status.d.ts +14 -0
  49. package/dist/routes/status.js +37 -0
  50. package/dist/routes/status.js.map +1 -0
  51. package/dist/routes/team.d.ts +62 -0
  52. package/dist/routes/team.js +129 -0
  53. package/dist/routes/team.js.map +1 -0
  54. package/dist/routes/viewer.d.ts +78 -0
  55. package/dist/routes/viewer.js +387 -0
  56. package/dist/routes/viewer.js.map +1 -0
  57. package/dist/routes/viewer.test.d.ts +1 -0
  58. package/dist/routes/viewer.test.js +509 -0
  59. package/dist/routes/viewer.test.js.map +1 -0
  60. package/dist/server.d.ts +45 -0
  61. package/dist/server.js +227 -0
  62. package/dist/server.js.map +1 -0
  63. package/dist/server.test.d.ts +1 -0
  64. package/dist/server.test.js +620 -0
  65. package/dist/server.test.js.map +1 -0
  66. package/package.json +62 -0
@@ -0,0 +1,509 @@
1
+ import { describe, it, expect, vi } from 'vitest';
2
+ import express from 'express';
3
+ import request from 'supertest';
4
+ import { ok, err } from 'neverthrow';
5
+ import { createViewerRouter } from './viewer.js';
6
+ import { EmbedError } from '@coderag/core';
7
+ function makeMockRow(overrides = {}) {
8
+ return {
9
+ id: 'chunk-1',
10
+ vector: [0.1, 0.2, 0.3],
11
+ content: 'function hello() { return "world"; }',
12
+ nl_summary: 'A function that returns world',
13
+ chunk_type: 'function',
14
+ file_path: 'src/hello.ts',
15
+ language: 'typescript',
16
+ metadata: JSON.stringify({
17
+ name: 'hello',
18
+ chunk_type: 'function',
19
+ start_line: 1,
20
+ end_line: 3,
21
+ }),
22
+ ...overrides,
23
+ };
24
+ }
25
+ // --- Mock factories ---
26
+ function makeMockStore(tableRows = []) {
27
+ const mockTable = tableRows !== null
28
+ ? {
29
+ query: vi.fn().mockReturnValue({
30
+ toArray: vi.fn().mockResolvedValue(tableRows),
31
+ }),
32
+ countRows: vi.fn().mockResolvedValue(tableRows.length),
33
+ }
34
+ : null;
35
+ return {
36
+ count: vi.fn().mockResolvedValue(ok(tableRows?.length ?? 0)),
37
+ query: vi.fn().mockResolvedValue(ok([])),
38
+ upsert: vi.fn().mockResolvedValue(ok(undefined)),
39
+ delete: vi.fn().mockResolvedValue(ok(undefined)),
40
+ close: vi.fn(),
41
+ table: mockTable,
42
+ };
43
+ }
44
+ function makeMockGraph() {
45
+ return {
46
+ getAllNodes: vi.fn().mockReturnValue([
47
+ { id: 'node-1', filePath: 'src/hello.ts', symbols: ['hello'], type: 'function' },
48
+ { id: 'node-2', filePath: 'src/world.ts', symbols: ['world'], type: 'module' },
49
+ { id: 'node-3', filePath: 'src/utils/helper.ts', symbols: ['helper'], type: 'function' },
50
+ ]),
51
+ getAllEdges: vi.fn().mockReturnValue([
52
+ { source: 'node-1', target: 'node-2', type: 'imports' },
53
+ { source: 'node-3', target: 'node-1', type: 'calls' },
54
+ ]),
55
+ getNode: vi.fn(),
56
+ getEdges: vi.fn().mockReturnValue([]),
57
+ getIncomingEdges: vi.fn().mockReturnValue([]),
58
+ nodeCount: vi.fn().mockReturnValue(3),
59
+ edgeCount: vi.fn().mockReturnValue(2),
60
+ };
61
+ }
62
+ function makeMockHybridSearch() {
63
+ return {
64
+ search: vi.fn().mockResolvedValue(ok([])),
65
+ };
66
+ }
67
+ function makeSearchResult(overrides = {}) {
68
+ return {
69
+ chunkId: 'chunk-1',
70
+ content: 'function hello() {}',
71
+ nlSummary: 'A greeting function',
72
+ score: 0.95,
73
+ method: 'hybrid',
74
+ metadata: {
75
+ chunkType: 'function',
76
+ name: 'hello',
77
+ declarations: [],
78
+ imports: [],
79
+ exports: [],
80
+ },
81
+ chunk: {
82
+ id: 'chunk-1',
83
+ content: 'function hello() {}',
84
+ nlSummary: 'A greeting function',
85
+ filePath: 'src/utils/hello.ts',
86
+ startLine: 1,
87
+ endLine: 3,
88
+ language: 'typescript',
89
+ metadata: {
90
+ chunkType: 'function',
91
+ name: 'hello',
92
+ declarations: [],
93
+ imports: [],
94
+ exports: [],
95
+ },
96
+ },
97
+ ...overrides,
98
+ };
99
+ }
100
+ // --- Test app factory ---
101
+ function createTestApp(deps = {}) {
102
+ const app = express();
103
+ app.use(express.json());
104
+ const fullDeps = {
105
+ getStore: deps.getStore ?? (() => null),
106
+ getConfig: deps.getConfig ?? (() => null),
107
+ getHybridSearch: deps.getHybridSearch ?? (() => null),
108
+ getGraph: deps.getGraph ?? (() => null),
109
+ };
110
+ app.use('/api/v1/viewer', createViewerRouter(fullDeps));
111
+ return app;
112
+ }
113
+ // =====================================================
114
+ // GET /api/v1/viewer/stats
115
+ // =====================================================
116
+ describe('GET /api/v1/viewer/stats', () => {
117
+ it('should return index statistics when store is initialized', async () => {
118
+ const rows = [
119
+ makeMockRow(),
120
+ makeMockRow({ id: 'chunk-2', file_path: 'src/world.ts', language: 'python' }),
121
+ makeMockRow({ id: 'chunk-3', file_path: 'src/hello.ts', language: 'typescript' }),
122
+ ];
123
+ const store = makeMockStore(rows);
124
+ const app = createTestApp({
125
+ getStore: () => store,
126
+ });
127
+ const res = await request(app).get('/api/v1/viewer/stats');
128
+ expect(res.status).toBe(200);
129
+ expect(res.body.data).toEqual({
130
+ chunkCount: 3,
131
+ fileCount: 2,
132
+ languages: { typescript: 2, python: 1 },
133
+ storageBytes: null,
134
+ lastIndexed: null,
135
+ });
136
+ });
137
+ it('should return 503 when store is not initialized', async () => {
138
+ const app = createTestApp({
139
+ getStore: () => null,
140
+ });
141
+ const res = await request(app).get('/api/v1/viewer/stats');
142
+ expect(res.status).toBe(503);
143
+ expect(res.body).toHaveProperty('error', 'Service not initialized');
144
+ });
145
+ it('should handle table query errors', async () => {
146
+ const store = makeMockStore([]);
147
+ // Override the mock table to throw on query
148
+ store.table.query = vi.fn().mockReturnValue({
149
+ toArray: vi.fn().mockRejectedValue(new Error('DB connection lost')),
150
+ });
151
+ const app = createTestApp({
152
+ getStore: () => store,
153
+ });
154
+ const res = await request(app).get('/api/v1/viewer/stats');
155
+ expect(res.status).toBe(500);
156
+ expect(res.body.message).toContain('DB connection lost');
157
+ });
158
+ it('should return empty stats when table is null', async () => {
159
+ const store = makeMockStore(null);
160
+ const app = createTestApp({
161
+ getStore: () => store,
162
+ });
163
+ const res = await request(app).get('/api/v1/viewer/stats');
164
+ expect(res.status).toBe(200);
165
+ expect(res.body.data).toEqual({
166
+ chunkCount: 0,
167
+ fileCount: 0,
168
+ languages: {},
169
+ storageBytes: null,
170
+ lastIndexed: null,
171
+ });
172
+ });
173
+ });
174
+ // =====================================================
175
+ // GET /api/v1/viewer/chunks
176
+ // =====================================================
177
+ describe('GET /api/v1/viewer/chunks', () => {
178
+ const rows = [
179
+ makeMockRow({ id: 'c1', file_path: 'src/a.ts', language: 'typescript', chunk_type: 'function' }),
180
+ makeMockRow({ id: 'c2', file_path: 'src/b.py', language: 'python', chunk_type: 'class' }),
181
+ makeMockRow({ id: 'c3', file_path: 'src/c.ts', language: 'typescript', chunk_type: 'interface' }),
182
+ ];
183
+ it('should return paginated chunk listing', async () => {
184
+ const store = makeMockStore(rows);
185
+ const app = createTestApp({
186
+ getStore: () => store,
187
+ });
188
+ const res = await request(app).get('/api/v1/viewer/chunks');
189
+ expect(res.status).toBe(200);
190
+ expect(res.body.data).toHaveLength(3);
191
+ expect(res.body.meta).toEqual({
192
+ page: 1,
193
+ pageSize: 50,
194
+ total: 3,
195
+ totalPages: 1,
196
+ });
197
+ });
198
+ it('should filter by language', async () => {
199
+ const store = makeMockStore(rows);
200
+ const app = createTestApp({ getStore: () => store });
201
+ const res = await request(app)
202
+ .get('/api/v1/viewer/chunks')
203
+ .query({ language: 'typescript' });
204
+ expect(res.status).toBe(200);
205
+ expect(res.body.data).toHaveLength(2);
206
+ expect(res.body.data.every((c) => c.language === 'typescript')).toBe(true);
207
+ });
208
+ it('should filter by chunk type', async () => {
209
+ const store = makeMockStore(rows);
210
+ const app = createTestApp({ getStore: () => store });
211
+ const res = await request(app)
212
+ .get('/api/v1/viewer/chunks')
213
+ .query({ type: 'class' });
214
+ expect(res.status).toBe(200);
215
+ expect(res.body.data).toHaveLength(1);
216
+ expect(res.body.data[0].chunkType).toBe('class');
217
+ });
218
+ it('should filter by file path', async () => {
219
+ const store = makeMockStore(rows);
220
+ const app = createTestApp({ getStore: () => store });
221
+ const res = await request(app)
222
+ .get('/api/v1/viewer/chunks')
223
+ .query({ file: 'src/b.py' });
224
+ expect(res.status).toBe(200);
225
+ expect(res.body.data).toHaveLength(1);
226
+ expect(res.body.data[0].id).toBe('c2');
227
+ });
228
+ it('should filter by text query q', async () => {
229
+ const store = makeMockStore([
230
+ makeMockRow({ id: 'c1', content: 'function searchUser() {}' }),
231
+ makeMockRow({ id: 'c2', content: 'function getProduct() {}' }),
232
+ ]);
233
+ const app = createTestApp({ getStore: () => store });
234
+ const res = await request(app)
235
+ .get('/api/v1/viewer/chunks')
236
+ .query({ q: 'searchUser' });
237
+ expect(res.status).toBe(200);
238
+ expect(res.body.data).toHaveLength(1);
239
+ expect(res.body.data[0].id).toBe('c1');
240
+ });
241
+ it('should paginate results', async () => {
242
+ const manyRows = Array.from({ length: 5 }, (_, i) => makeMockRow({ id: `chunk-${i}` }));
243
+ const store = makeMockStore(manyRows);
244
+ const app = createTestApp({ getStore: () => store });
245
+ const res = await request(app)
246
+ .get('/api/v1/viewer/chunks')
247
+ .query({ page: 2, pageSize: 2 });
248
+ expect(res.status).toBe(200);
249
+ expect(res.body.data).toHaveLength(2);
250
+ expect(res.body.data[0].id).toBe('chunk-2');
251
+ expect(res.body.data[1].id).toBe('chunk-3');
252
+ expect(res.body.meta.total).toBe(5);
253
+ expect(res.body.meta.totalPages).toBe(3);
254
+ });
255
+ it('should validate pageSize max', async () => {
256
+ const store = makeMockStore(rows);
257
+ const app = createTestApp({ getStore: () => store });
258
+ const res = await request(app)
259
+ .get('/api/v1/viewer/chunks')
260
+ .query({ pageSize: 999 });
261
+ expect(res.status).toBe(400);
262
+ expect(res.body).toHaveProperty('error', 'Validation Error');
263
+ });
264
+ it('should handle empty results when table is null', async () => {
265
+ const store = makeMockStore(null);
266
+ const app = createTestApp({ getStore: () => store });
267
+ const res = await request(app).get('/api/v1/viewer/chunks');
268
+ expect(res.status).toBe(200);
269
+ expect(res.body.data).toHaveLength(0);
270
+ expect(res.body.meta.total).toBe(0);
271
+ });
272
+ it('should return 503 when store is not initialized', async () => {
273
+ const app = createTestApp({ getStore: () => null });
274
+ const res = await request(app).get('/api/v1/viewer/chunks');
275
+ expect(res.status).toBe(503);
276
+ expect(res.body).toHaveProperty('error', 'Service not initialized');
277
+ });
278
+ });
279
+ // =====================================================
280
+ // GET /api/v1/viewer/chunks/:id
281
+ // =====================================================
282
+ describe('GET /api/v1/viewer/chunks/:id', () => {
283
+ const row = makeMockRow({ id: 'chunk-abc' });
284
+ it('should return chunk detail for existing chunk', async () => {
285
+ const store = makeMockStore([row]);
286
+ const app = createTestApp({ getStore: () => store });
287
+ const res = await request(app).get('/api/v1/viewer/chunks/chunk-abc');
288
+ expect(res.status).toBe(200);
289
+ expect(res.body.data.id).toBe('chunk-abc');
290
+ expect(res.body.data.content).toBe(row.content);
291
+ expect(res.body.data.nlSummary).toBe(row.nl_summary);
292
+ expect(res.body.data).not.toHaveProperty('vector');
293
+ });
294
+ it('should return 404 for missing chunk', async () => {
295
+ const store = makeMockStore([row]);
296
+ const app = createTestApp({ getStore: () => store });
297
+ const res = await request(app).get('/api/v1/viewer/chunks/nonexistent');
298
+ expect(res.status).toBe(404);
299
+ expect(res.body).toHaveProperty('error', 'Chunk not found');
300
+ });
301
+ it('should include vector when includeVector=true', async () => {
302
+ const store = makeMockStore([row]);
303
+ const app = createTestApp({ getStore: () => store });
304
+ const res = await request(app)
305
+ .get('/api/v1/viewer/chunks/chunk-abc')
306
+ .query({ includeVector: 'true' });
307
+ expect(res.status).toBe(200);
308
+ expect(res.body.data.vector).toEqual([0.1, 0.2, 0.3]);
309
+ });
310
+ it('should not include vector when includeVector=false', async () => {
311
+ const store = makeMockStore([row]);
312
+ const app = createTestApp({ getStore: () => store });
313
+ const res = await request(app)
314
+ .get('/api/v1/viewer/chunks/chunk-abc')
315
+ .query({ includeVector: 'false' });
316
+ expect(res.status).toBe(200);
317
+ expect(res.body.data).not.toHaveProperty('vector');
318
+ });
319
+ it('should return 503 when store is not initialized', async () => {
320
+ const app = createTestApp({ getStore: () => null });
321
+ const res = await request(app).get('/api/v1/viewer/chunks/chunk-abc');
322
+ expect(res.status).toBe(503);
323
+ expect(res.body).toHaveProperty('error', 'Service not initialized');
324
+ });
325
+ it('should return 404 when table is null', async () => {
326
+ const store = makeMockStore(null);
327
+ const app = createTestApp({ getStore: () => store });
328
+ const res = await request(app).get('/api/v1/viewer/chunks/chunk-abc');
329
+ expect(res.status).toBe(404);
330
+ expect(res.body).toHaveProperty('error', 'Chunk not found');
331
+ });
332
+ });
333
+ // =====================================================
334
+ // GET /api/v1/viewer/graph
335
+ // =====================================================
336
+ describe('GET /api/v1/viewer/graph', () => {
337
+ it('should return graph nodes and edges', async () => {
338
+ const graph = makeMockGraph();
339
+ const app = createTestApp({ getGraph: () => graph });
340
+ const res = await request(app).get('/api/v1/viewer/graph');
341
+ expect(res.status).toBe(200);
342
+ expect(res.body.data.nodes).toHaveLength(3);
343
+ expect(res.body.data.edges).toHaveLength(2);
344
+ });
345
+ it('should filter nodes by file', async () => {
346
+ const graph = makeMockGraph();
347
+ const app = createTestApp({ getGraph: () => graph });
348
+ const res = await request(app)
349
+ .get('/api/v1/viewer/graph')
350
+ .query({ file: 'src/hello.ts' });
351
+ expect(res.status).toBe(200);
352
+ expect(res.body.data.nodes).toHaveLength(1);
353
+ expect(res.body.data.nodes[0].id).toBe('node-1');
354
+ // Only edges between filtered nodes
355
+ expect(res.body.data.edges).toHaveLength(0);
356
+ });
357
+ it('should filter nodes by type', async () => {
358
+ const graph = makeMockGraph();
359
+ const app = createTestApp({ getGraph: () => graph });
360
+ const res = await request(app)
361
+ .get('/api/v1/viewer/graph')
362
+ .query({ type: 'function' });
363
+ expect(res.status).toBe(200);
364
+ expect(res.body.data.nodes).toHaveLength(2);
365
+ expect(res.body.data.nodes.every((n) => n.type === 'function')).toBe(true);
366
+ });
367
+ it('should respect maxNodes limit', async () => {
368
+ const graph = makeMockGraph();
369
+ const app = createTestApp({ getGraph: () => graph });
370
+ const res = await request(app)
371
+ .get('/api/v1/viewer/graph')
372
+ .query({ maxNodes: 2 });
373
+ expect(res.status).toBe(200);
374
+ expect(res.body.data.nodes).toHaveLength(2);
375
+ });
376
+ it('should return 503 when graph is not initialized', async () => {
377
+ const app = createTestApp({ getGraph: () => null });
378
+ const res = await request(app).get('/api/v1/viewer/graph');
379
+ expect(res.status).toBe(503);
380
+ expect(res.body).toHaveProperty('error', 'Service not initialized');
381
+ });
382
+ });
383
+ // =====================================================
384
+ // GET /api/v1/viewer/search
385
+ // =====================================================
386
+ describe('GET /api/v1/viewer/search', () => {
387
+ it('should return search results with timing', async () => {
388
+ const hybridSearch = makeMockHybridSearch();
389
+ const results = [makeSearchResult()];
390
+ vi.mocked(hybridSearch.search).mockResolvedValue(ok(results));
391
+ const app = createTestApp({ getHybridSearch: () => hybridSearch });
392
+ const res = await request(app)
393
+ .get('/api/v1/viewer/search')
394
+ .query({ q: 'hello function' });
395
+ expect(res.status).toBe(200);
396
+ expect(res.body.data.results).toHaveLength(1);
397
+ expect(res.body.data.results[0]).toEqual({
398
+ chunkId: 'chunk-1',
399
+ filePath: 'src/utils/hello.ts',
400
+ chunkType: 'function',
401
+ name: 'hello',
402
+ content: 'function hello() {}',
403
+ nlSummary: 'A greeting function',
404
+ score: 0.95,
405
+ method: 'hybrid',
406
+ });
407
+ expect(res.body.data.timing).toHaveProperty('totalMs');
408
+ expect(typeof res.body.data.timing.totalMs).toBe('number');
409
+ });
410
+ it('should return 400 when q param is missing', async () => {
411
+ const hybridSearch = makeMockHybridSearch();
412
+ const app = createTestApp({ getHybridSearch: () => hybridSearch });
413
+ const res = await request(app).get('/api/v1/viewer/search');
414
+ expect(res.status).toBe(400);
415
+ expect(res.body).toHaveProperty('error', 'Validation Error');
416
+ });
417
+ it('should pass custom topK to search', async () => {
418
+ const hybridSearch = makeMockHybridSearch();
419
+ vi.mocked(hybridSearch.search).mockResolvedValue(ok([]));
420
+ const app = createTestApp({ getHybridSearch: () => hybridSearch });
421
+ await request(app)
422
+ .get('/api/v1/viewer/search')
423
+ .query({ q: 'test', topK: 5 });
424
+ expect(hybridSearch.search).toHaveBeenCalledWith('test', expect.objectContaining({ topK: 5 }));
425
+ });
426
+ it('should pass custom weights to search', async () => {
427
+ const hybridSearch = makeMockHybridSearch();
428
+ vi.mocked(hybridSearch.search).mockResolvedValue(ok([]));
429
+ const app = createTestApp({ getHybridSearch: () => hybridSearch });
430
+ await request(app)
431
+ .get('/api/v1/viewer/search')
432
+ .query({ q: 'test', vectorWeight: 0.8, bm25Weight: 0.2 });
433
+ expect(hybridSearch.search).toHaveBeenCalledWith('test', expect.objectContaining({ vectorWeight: 0.8, bm25Weight: 0.2 }));
434
+ });
435
+ it('should handle search errors', async () => {
436
+ const hybridSearch = makeMockHybridSearch();
437
+ vi.mocked(hybridSearch.search).mockResolvedValue(err(new EmbedError('Connection refused')));
438
+ const app = createTestApp({ getHybridSearch: () => hybridSearch });
439
+ const res = await request(app)
440
+ .get('/api/v1/viewer/search')
441
+ .query({ q: 'hello' });
442
+ expect(res.status).toBe(500);
443
+ expect(res.body.message).toContain('Connection refused');
444
+ });
445
+ it('should return 503 when search is not initialized', async () => {
446
+ const app = createTestApp({ getHybridSearch: () => null });
447
+ const res = await request(app)
448
+ .get('/api/v1/viewer/search')
449
+ .query({ q: 'hello' });
450
+ expect(res.status).toBe(503);
451
+ expect(res.body).toHaveProperty('error', 'Service not initialized');
452
+ });
453
+ });
454
+ // =====================================================
455
+ // GET /api/v1/viewer/embeddings
456
+ // =====================================================
457
+ describe('GET /api/v1/viewer/embeddings', () => {
458
+ it('should return embedding vectors', async () => {
459
+ const rows = [
460
+ makeMockRow({ id: 'c1', vector: [0.1, 0.2] }),
461
+ makeMockRow({ id: 'c2', vector: [0.3, 0.4] }),
462
+ ];
463
+ const store = makeMockStore(rows);
464
+ const app = createTestApp({ getStore: () => store });
465
+ const res = await request(app).get('/api/v1/viewer/embeddings');
466
+ expect(res.status).toBe(200);
467
+ expect(res.body.data).toHaveLength(2);
468
+ expect(res.body.data[0]).toEqual({
469
+ id: 'c1',
470
+ filePath: 'src/hello.ts',
471
+ chunkType: 'function',
472
+ language: 'typescript',
473
+ vector: [0.1, 0.2],
474
+ });
475
+ });
476
+ it('should respect limit parameter', async () => {
477
+ const rows = Array.from({ length: 10 }, (_, i) => makeMockRow({ id: `c-${i}`, vector: [i, i + 1] }));
478
+ const store = makeMockStore(rows);
479
+ const app = createTestApp({ getStore: () => store });
480
+ const res = await request(app)
481
+ .get('/api/v1/viewer/embeddings')
482
+ .query({ limit: 3 });
483
+ expect(res.status).toBe(200);
484
+ expect(res.body.data).toHaveLength(3);
485
+ });
486
+ it('should return empty array when table is null', async () => {
487
+ const store = makeMockStore(null);
488
+ const app = createTestApp({ getStore: () => store });
489
+ const res = await request(app).get('/api/v1/viewer/embeddings');
490
+ expect(res.status).toBe(200);
491
+ expect(res.body.data).toEqual([]);
492
+ });
493
+ it('should return 503 when store is not initialized', async () => {
494
+ const app = createTestApp({ getStore: () => null });
495
+ const res = await request(app).get('/api/v1/viewer/embeddings');
496
+ expect(res.status).toBe(503);
497
+ expect(res.body).toHaveProperty('error', 'Service not initialized');
498
+ });
499
+ it('should validate limit max value', async () => {
500
+ const store = makeMockStore([]);
501
+ const app = createTestApp({ getStore: () => store });
502
+ const res = await request(app)
503
+ .get('/api/v1/viewer/embeddings')
504
+ .query({ limit: 9999 });
505
+ expect(res.status).toBe(400);
506
+ expect(res.body).toHaveProperty('error', 'Validation Error');
507
+ });
508
+ });
509
+ //# sourceMappingURL=viewer.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"viewer.test.js","sourceRoot":"","sources":["../../src/routes/viewer.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,45 @@
1
+ import { type Express } from 'express';
2
+ import { type ApiKeyEntry } from './middleware/auth.js';
3
+ import { type IndexTriggerCallback } from './routes/index-trigger.js';
4
+ export declare const API_SERVER_VERSION = "0.1.0";
5
+ export interface ApiServerOptions {
6
+ /** Root directory of the project to index. */
7
+ readonly rootDir: string;
8
+ /** Port to listen on. Default: 3100 */
9
+ readonly port: number;
10
+ /** Parsed API keys. If not provided, reads from CODERAG_API_KEYS env var. */
11
+ readonly apiKeys?: ReadonlyArray<ApiKeyEntry>;
12
+ /** Custom index trigger callback. */
13
+ readonly onIndex?: IndexTriggerCallback | null;
14
+ /** CORS origin. Default: '*' */
15
+ readonly corsOrigin?: string;
16
+ }
17
+ export declare class ApiServer {
18
+ private readonly app;
19
+ private readonly rootDir;
20
+ private readonly port;
21
+ private httpServer;
22
+ private config;
23
+ private store;
24
+ private hybridSearch;
25
+ private contextExpander;
26
+ private reranker;
27
+ private graph;
28
+ private readonly dataCollector;
29
+ constructor(options: ApiServerOptions);
30
+ /**
31
+ * Initialize all core services: load config, connect LanceDB, build indices.
32
+ * The server still starts even if initialization errors occur.
33
+ */
34
+ initialize(): Promise<void>;
35
+ /**
36
+ * Start listening on the configured port.
37
+ */
38
+ start(): Promise<void>;
39
+ /**
40
+ * Gracefully shut down the HTTP server.
41
+ */
42
+ close(): Promise<void>;
43
+ /** Expose Express app for testing with supertest. */
44
+ getApp(): Express;
45
+ }