registryx-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 (49) hide show
  1. package/README.md +203 -0
  2. package/coverage/lcov-report/base.css +224 -0
  3. package/coverage/lcov-report/block-navigation.js +87 -0
  4. package/coverage/lcov-report/favicon.png +0 -0
  5. package/coverage/lcov-report/index.html +146 -0
  6. package/coverage/lcov-report/prettify.css +1 -0
  7. package/coverage/lcov-report/prettify.js +2 -0
  8. package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  9. package/coverage/lcov-report/sorter.js +210 -0
  10. package/coverage/lcov-report/src/adapters/crates.ts.html +847 -0
  11. package/coverage/lcov-report/src/adapters/index.html +176 -0
  12. package/coverage/lcov-report/src/adapters/index.ts.html +97 -0
  13. package/coverage/lcov-report/src/adapters/maven.ts.html +637 -0
  14. package/coverage/lcov-report/src/adapters/npm.ts.html +817 -0
  15. package/coverage/lcov-report/src/adapters/pypi.ts.html +730 -0
  16. package/coverage/lcov-report/src/cache.ts.html +202 -0
  17. package/coverage/lcov-report/src/config.ts.html +208 -0
  18. package/coverage/lcov-report/src/index.html +161 -0
  19. package/coverage/lcov-report/src/server.ts.html +1339 -0
  20. package/coverage/lcov-report/src/types.ts.html +373 -0
  21. package/coverage/lcov-report/src/utils/fetch.ts.html +220 -0
  22. package/coverage/lcov-report/src/utils/format.ts.html +130 -0
  23. package/coverage/lcov-report/src/utils/index.html +131 -0
  24. package/coverage/lcov.info +1686 -0
  25. package/dist/index.d.ts +1 -0
  26. package/dist/index.js +1210 -0
  27. package/eslint.config.mjs +16 -0
  28. package/package.json +41 -0
  29. package/src/adapters/crates.ts +254 -0
  30. package/src/adapters/index.ts +4 -0
  31. package/src/adapters/maven.ts +184 -0
  32. package/src/adapters/npm.ts +244 -0
  33. package/src/adapters/pypi.ts +215 -0
  34. package/src/cache.ts +39 -0
  35. package/src/config.ts +41 -0
  36. package/src/index.ts +25 -0
  37. package/src/server.ts +418 -0
  38. package/src/types.ts +96 -0
  39. package/src/utils/fetch.ts +45 -0
  40. package/src/utils/format.ts +15 -0
  41. package/test/adapters.test.ts +575 -0
  42. package/test/cache.test.ts +47 -0
  43. package/test/config.test.ts +69 -0
  44. package/test/fetch.test.ts +51 -0
  45. package/test/format.test.ts +35 -0
  46. package/test/server.test.ts +23 -0
  47. package/tsconfig.json +18 -0
  48. package/tsup.config.ts +11 -0
  49. package/vitest.config.ts +19 -0
@@ -0,0 +1,51 @@
1
+ import { describe, it, expect, vi } from 'vitest';
2
+ import { registryFetch } from '../src/utils/fetch.js';
3
+ import type { Config } from '../src/config.js';
4
+
5
+ const mockConfig: Config = {
6
+ registries: ['npm'],
7
+ timeoutMs: 5000,
8
+ cacheTtlMs: 0,
9
+ };
10
+
11
+ describe('registryFetch', () => {
12
+ it('rejects non-HTTPS URLs', async () => {
13
+ await expect(registryFetch('http://registry.npmjs.org/', mockConfig)).rejects.toThrow(
14
+ 'Only HTTPS'
15
+ );
16
+ });
17
+
18
+ it('rejects disallowed hosts', async () => {
19
+ await expect(registryFetch('https://evil.com/data', mockConfig)).rejects.toThrow(
20
+ 'Host not allowed'
21
+ );
22
+ });
23
+
24
+ it('allows registry.npmjs.org', async () => {
25
+ const mockResponse = { ok: true, json: () => ({}) };
26
+ vi.stubGlobal('fetch', vi.fn().mockResolvedValue(mockResponse));
27
+ const res = await registryFetch('https://registry.npmjs.org/express', mockConfig);
28
+ expect(res.ok).toBe(true);
29
+ vi.unstubAllGlobals();
30
+ });
31
+
32
+ it('adds npm auth header when token is set', async () => {
33
+ const configWithToken = { ...mockConfig, npmToken: 'secret' };
34
+ const mockResponse = { ok: true, json: () => ({}) };
35
+ const fetchSpy = vi.fn().mockResolvedValue(mockResponse);
36
+ vi.stubGlobal('fetch', fetchSpy);
37
+ await registryFetch('https://registry.npmjs.org/express', configWithToken);
38
+ const headers = fetchSpy.mock.calls[0][1].headers;
39
+ expect(headers.Authorization).toBe('Bearer secret');
40
+ vi.unstubAllGlobals();
41
+ });
42
+
43
+ it('throws on non-OK responses', async () => {
44
+ const mockResponse = { ok: false, status: 404 };
45
+ vi.stubGlobal('fetch', vi.fn().mockResolvedValue(mockResponse));
46
+ await expect(
47
+ registryFetch('https://registry.npmjs.org/nonexistent', mockConfig)
48
+ ).rejects.toThrow('HTTP 404');
49
+ vi.unstubAllGlobals();
50
+ });
51
+ });
@@ -0,0 +1,35 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { formatNumber, padRight, truncate } from '../src/utils/format.js';
3
+
4
+ describe('formatNumber', () => {
5
+ it('formats billions', () => {
6
+ expect(formatNumber(1_200_000_000)).toBe('1.2B');
7
+ });
8
+ it('formats millions', () => {
9
+ expect(formatNumber(45_000_000)).toBe('45.0M');
10
+ });
11
+ it('formats thousands', () => {
12
+ expect(formatNumber(1_500)).toBe('1.5K');
13
+ });
14
+ it('formats small numbers', () => {
15
+ expect(formatNumber(42)).toBe('42');
16
+ });
17
+ });
18
+
19
+ describe('padRight', () => {
20
+ it('pads shorter strings', () => {
21
+ expect(padRight('abc', 6)).toBe('abc ');
22
+ });
23
+ it('does not pad when already long enough', () => {
24
+ expect(padRight('abcdef', 3)).toBe('abcdef');
25
+ });
26
+ });
27
+
28
+ describe('truncate', () => {
29
+ it('truncates long strings', () => {
30
+ expect(truncate('a'.repeat(100), 10)).toBe('a'.repeat(7) + '...');
31
+ });
32
+ it('returns short strings unchanged', () => {
33
+ expect(truncate('hello', 10)).toBe('hello');
34
+ });
35
+ });
@@ -0,0 +1,23 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { createServer } from '../src/server.js';
3
+ import type { Config } from '../src/config.js';
4
+
5
+ const config: Config = {
6
+ registries: ['npm', 'pypi', 'maven', 'crates'],
7
+ timeoutMs: 5000,
8
+ cacheTtlMs: 0,
9
+ };
10
+
11
+ describe('createServer', () => {
12
+ it('creates a server instance', () => {
13
+ const server = createServer(config);
14
+ expect(server).toBeDefined();
15
+ });
16
+
17
+ it('throws for disabled registry', async () => {
18
+ const limitedConfig: Config = { ...config, registries: ['npm'] };
19
+ const server = createServer(limitedConfig);
20
+ // Server should still be created — the error is at tool call time
21
+ expect(server).toBeDefined();
22
+ });
23
+ });
package/tsconfig.json ADDED
@@ -0,0 +1,18 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "module": "ESNext",
5
+ "moduleResolution": "bundler",
6
+ "lib": ["ES2022"],
7
+ "outDir": "dist",
8
+ "rootDir": "src",
9
+ "strict": true,
10
+ "esModuleInterop": true,
11
+ "skipLibCheck": true,
12
+ "forceConsistentCasingInFileNames": true,
13
+ "declaration": true,
14
+ "resolveJsonModule": true
15
+ },
16
+ "include": ["src"],
17
+ "exclude": ["dist", "node_modules", "test"]
18
+ }
package/tsup.config.ts ADDED
@@ -0,0 +1,11 @@
1
+ import { defineConfig } from 'tsup';
2
+
3
+ export default defineConfig({
4
+ entry: ['src/index.ts'],
5
+ format: ['esm'],
6
+ dts: true,
7
+ clean: true,
8
+ banner: {
9
+ js: '#!/usr/bin/env node',
10
+ },
11
+ });
@@ -0,0 +1,19 @@
1
+ import { defineConfig } from 'vitest/config';
2
+
3
+ export default defineConfig({
4
+ test: {
5
+ globals: true,
6
+ coverage: {
7
+ provider: 'v8',
8
+ reporter: ['text', 'lcov'],
9
+ include: ['src/**/*.ts'],
10
+ exclude: ['src/index.ts'],
11
+ thresholds: {
12
+ lines: 75,
13
+ statements: 75,
14
+ functions: 85,
15
+ branches: 50,
16
+ },
17
+ },
18
+ },
19
+ });