Skip to content

Commit 9e102b8

Browse files
committed
chore: initial non-ts compatible source code, awaiting next commit clean up
1 parent 8f2e514 commit 9e102b8

File tree

20 files changed

+3271
-77
lines changed

20 files changed

+3271
-77
lines changed

.gitignore

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
# Logs
2+
logs
3+
*.log
4+
npm-debug.log*
5+
yarn-debug.log*
6+
yarn-error.log*
7+
lerna-debug.log*
8+
.pnpm-debug.log*
9+
10+
# Diagnostic reports (https://nodejs.org/api/report.html)
11+
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
12+
13+
# Runtime data
14+
pids
15+
*.pid
16+
*.seed
17+
*.pid.lock
18+
19+
# Directory for instrumented libs generated by jscoverage/JSCover
20+
lib-cov
21+
22+
# Coverage directory used by tools like istanbul
23+
coverage
24+
*.lcov
25+
26+
# nyc test coverage
27+
.nyc_output
28+
29+
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
30+
.grunt
31+
32+
# Bower dependency directory (https://bower.io/)
33+
bower_components
34+
35+
# node-waf configuration
36+
.lock-wscript
37+
38+
# Compiled binary addons (https://nodejs.org/api/addons.html)
39+
build/Release
40+
41+
# Dependency directories
42+
node_modules/
43+
jspm_packages/
44+
45+
# Snowpack dependency directory (https://snowpack.dev/)
46+
web_modules/
47+
48+
# TypeScript cache
49+
*.tsbuildinfo
50+
51+
# Optional npm cache directory
52+
.npm
53+
54+
# Optional eslint cache
55+
.eslintcache
56+
57+
# Optional stylelint cache
58+
.stylelintcache
59+
60+
# Microbundle cache
61+
.rpt2_cache/
62+
.rts2_cache_cjs/
63+
.rts2_cache_es/
64+
.rts2_cache_umd/
65+
66+
# Optional REPL history
67+
.node_repl_history
68+
69+
# Output of 'npm pack'
70+
*.tgz
71+
72+
# Yarn Integrity file
73+
.yarn-integrity
74+
75+
# dotenv environment variable files
76+
.env
77+
.env.development.local
78+
.env.test.local
79+
.env.production.local
80+
.env.local
81+
82+
# parcel-bundler cache (https://parceljs.org/)
83+
.cache
84+
.parcel-cache
85+
86+
# Next.js build output
87+
.next
88+
out
89+
90+
# Nuxt.js build / generate output
91+
.nuxt
92+
dist
93+
94+
# Gatsby files
95+
.cache/
96+
# Comment in the public line in if your project uses Gatsby and not Next.js
97+
# https://nextjs.org/blog/next-9-1#public-directory-support
98+
# public
99+
100+
# vuepress build output
101+
.vuepress/dist
102+
103+
# vuepress v2.x temp and cache directory
104+
.temp
105+
.cache
106+
107+
# vitepress build output
108+
**/.vitepress/dist
109+
110+
# vitepress cache directory
111+
**/.vitepress/cache
112+
113+
# Docusaurus cache and generated files
114+
.docusaurus
115+
116+
# Serverless directories
117+
.serverless/
118+
119+
# FuseBox cache
120+
.fusebox/
121+
122+
# DynamoDB Local files
123+
.dynamodb/
124+
125+
# TernJS port file
126+
.tern-port
127+
128+
# Stores VSCode versions used for testing VSCode extensions
129+
.vscode-test
130+
131+
# yarn v2
132+
.yarn/cache
133+
.yarn/unplugged
134+
.yarn/build-state.yml
135+
.yarn/install-state.gz
136+
.pnp.*

__tests__/app.test.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import { test, describe } from 'node:test'
2+
import assert from 'node:assert'
3+
4+
describe('Node.js API Documentation Server', () => {
5+
test('Server should start successfully', async () => {
6+
// Your test code here
7+
})
8+
})

__tests__/app.test.ts

Lines changed: 0 additions & 17 deletions
This file was deleted.

__tests__/format.test.js

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import { describe, test } from 'node:test'
2+
import assert from 'node:assert'
3+
import { formatContent, normalizeModuleName } from '../src/utils/format.ts'
4+
5+
describe('Utils: format', () => {
6+
test('should replace single newlines with double newlines', () => {
7+
const input = 'Hello\nWorld\nTest'
8+
const expected = 'Hello\n\nWorld\n\nTest'
9+
const result = formatContent(input)
10+
assert.strictEqual(result, expected)
11+
})
12+
13+
test('should return empty string for null or undefined input', () => {
14+
const result1 = formatContent(null)
15+
const result2 = formatContent(undefined)
16+
assert.strictEqual(result1, '')
17+
assert.strictEqual(result2, '')
18+
})
19+
20+
test('should normalize module names', () => {
21+
const input1 = 'My_Module'
22+
const input2 = 'my-module'
23+
const input3 = 'my module'
24+
const expected = 'mymodule'
25+
assert.strictEqual(normalizeModuleName(input1), expected)
26+
assert.strictEqual(normalizeModuleName(input2), expected)
27+
assert.strictEqual(normalizeModuleName(input3), expected)
28+
})
29+
30+
test('should handle empty strings in normalization', () => {
31+
const result = normalizeModuleName('')
32+
assert.strictEqual(result, '')
33+
})
34+
35+
test('should handle special characters in normalization', () => {
36+
const input = 'My-Module_123'
37+
const expected = 'mymodule123'
38+
const result = normalizeModuleName(input)
39+
assert.strictEqual(result, expected)
40+
})
41+
42+
test('should handle numbers in normalization', () => {
43+
const input = 'Module123'
44+
const expected = 'module123'
45+
const result = normalizeModuleName(input)
46+
assert.strictEqual(result, expected)
47+
})
48+
49+
test('should handle mixed case in normalization', () => {
50+
const input = 'MyModule'
51+
const expected = 'mymodule'
52+
const result = normalizeModuleName(input)
53+
assert.strictEqual(result, expected)
54+
})
55+
})

eslint.config.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@ export default [
77
pluginSecurity.configs.recommended,
88
{
99
rules: {
10-
'no-process-exit': 'warn',
11-
'node/no-unsupported-features': 'off',
12-
'node/no-unpublished-require': 'off',
10+
'n/no-process-exit': 'off',
11+
'n/no-unsupported-features': 'off',
12+
'n/no-unpublished-require': 'off',
1313
'security/detect-non-literal-fs-filename': 'error',
1414
'security/detect-unsafe-regex': 'error',
1515
'security/detect-buffer-noassert': 'error',
@@ -29,4 +29,4 @@ export default [
2929
sourceType: 'module',
3030
},
3131
},
32-
]
32+
]

nodejs-sampling.js

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
2+
// sampling-service.ts
3+
import { Server } from "@anthropic-ai/mcp-server";
4+
5+
export class NodeDocSamplingService {
6+
constructor(private server: Server) {}
7+
8+
async generateCodeExample(moduleName: string, methodName: string, userPrompt: string) {
9+
// Implementation as shown above
10+
}
11+
12+
async compareApiApproaches(problem: string, apis: string[]) {
13+
// Implementation as shown above
14+
}
15+
16+
// Implement other sampling methods
17+
}
18+
19+
20+
async function getBestPractices(module, context) {
21+
return await server.sampling.createMessage({
22+
messages: [
23+
{
24+
role: "user",
25+
content: {
26+
type: "text",
27+
text: `What are the best practices for using the Node.js ${module} module in a ${context} context?`
28+
}
29+
}
30+
],
31+
systemPrompt: "You are a Node.js best practices advisor. Provide actionable recommendations for using Node.js APIs effectively, securely, and with optimal performance.",
32+
includeContext: "thisServer",
33+
maxTokens: 1000
34+
});
35+
}
36+
37+
//
38+
// server.ts
39+
import { Server } from "@anthropic-ai/mcp-server";
40+
import { NodeDocSamplingService } from "./sampling-service";
41+
import { z } from "zod";
42+
43+
export async function startServer() {
44+
const server = new Server({ /* your config */ });
45+
const samplingService = new NodeDocSamplingService(server);
46+
47+
// Your existing tools
48+
// ...
49+
50+
// Add sampling-based tools
51+
server.tool(
52+
"node-code-example",
53+
{
54+
module: z.string(),
55+
method: z.string().optional(),
56+
prompt: z.string()
57+
},
58+
async (params) => {
59+
const { module, method, prompt } = params;
60+
const result = await samplingService.generateCodeExample(module, method || "", prompt);
61+
return { content: [{ type: "text", text: result.content.text }] };
62+
}
63+
);
64+
65+
// Add more sampling-based tools
66+
// ...
67+
68+
return server;
69+
}
70+
71+
72+
//
73+
async function safelyGenerateSampling(samplingFn) {
74+
try {
75+
return await samplingFn();
76+
} catch (error) {
77+
logger.error({ err: error, msg: "Sampling request failed" });
78+
79+
// Provide a graceful fallback
80+
return {
81+
content: {
82+
type: "text",
83+
text: "Sorry, I wasn't able to generate the requested content. Please try again with a different query."
84+
}
85+
};
86+
}
87+
}
88+
89+
//
90+
import { RateLimiter } from "some-rate-limiter-library";
91+
92+
const samplingRateLimiter = new RateLimiter({
93+
tokensPerInterval: 50,
94+
interval: "minute"
95+
});
96+
97+
async function rateLimitedSampling(samplingFn) {
98+
if (!await samplingRateLimiter.tryAcquire(1)) {
99+
return {
100+
content: {
101+
type: "text",
102+
text: "Rate limit exceeded for sampling requests. Please try again later."
103+
}
104+
};
105+
}
106+
107+
return await safelyGenerateSampling(samplingFn);
108+
}

0 commit comments

Comments
 (0)