claude-flow-novice 2.14.36 → 2.14.37

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.
package/dist/server.js ADDED
@@ -0,0 +1,194 @@
1
+ import express from 'express';
2
+ import { hello, healthCheck, createApiResponse } from './hello.js';
3
+ const app = express();
4
+ const PORT = process.env.PORT || 3000;
5
+ // Middleware for JSON parsing and security
6
+ app.use(express.json());
7
+ app.use(express.urlencoded({
8
+ extended: true
9
+ }));
10
+ // Security headers middleware
11
+ app.use((req, res, next)=>{
12
+ res.setHeader('X-Content-Type-Options', 'nosniff');
13
+ res.setHeader('X-Frame-Options', 'DENY');
14
+ res.setHeader('X-XSS-Protection', '1; mode=block');
15
+ next();
16
+ });
17
+ // Request logging middleware
18
+ app.use((req, res, next)=>{
19
+ console.log(`${new Date().toISOString()} - ${req.method} ${req.path}`);
20
+ next();
21
+ });
22
+ // API Routes
23
+ /**
24
+ * GET /api/hello
25
+ * Basic hello world endpoint
26
+ */ app.get('/api/hello', (req, res)=>{
27
+ try {
28
+ const message = hello();
29
+ const response = createApiResponse({
30
+ greeting: message
31
+ });
32
+ res.json(response);
33
+ } catch (error) {
34
+ console.error('Error in /api/hello:', error);
35
+ res.status(500).json({
36
+ success: false,
37
+ message: 'Internal server error',
38
+ timestamp: new Date().toISOString()
39
+ });
40
+ }
41
+ });
42
+ /**
43
+ * GET /api/hello/:name
44
+ * Personalized hello endpoint
45
+ */ app.get('/api/hello/:name', (req, res)=>{
46
+ try {
47
+ const { name } = req.params;
48
+ // Input validation
49
+ if (!name || typeof name !== 'string' || name.length > 100) {
50
+ return res.status(400).json({
51
+ success: false,
52
+ message: 'Invalid name parameter',
53
+ timestamp: new Date().toISOString()
54
+ });
55
+ }
56
+ // Sanitize input (remove potential XSS)
57
+ const sanitizedName = name.replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, '');
58
+ const message = hello(sanitizedName);
59
+ const response = createApiResponse({
60
+ greeting: message,
61
+ name: sanitizedName
62
+ });
63
+ res.json(response);
64
+ } catch (error) {
65
+ console.error('Error in /api/hello/:name:', error);
66
+ res.status(500).json({
67
+ success: false,
68
+ message: 'Internal server error',
69
+ timestamp: new Date().toISOString()
70
+ });
71
+ }
72
+ });
73
+ /**
74
+ * GET /api/health
75
+ * Health check endpoint
76
+ */ app.get('/api/health', (req, res)=>{
77
+ try {
78
+ const health = healthCheck();
79
+ const response = createApiResponse(health, 'Service is healthy');
80
+ res.json(response);
81
+ } catch (error) {
82
+ console.error('Error in /api/health:', error);
83
+ res.status(500).json({
84
+ success: false,
85
+ message: 'Health check failed',
86
+ timestamp: new Date().toISOString()
87
+ });
88
+ }
89
+ });
90
+ /**
91
+ * POST /api/hello
92
+ * Hello endpoint with POST body
93
+ */ app.post('/api/hello', (req, res)=>{
94
+ try {
95
+ const { name, language } = req.body;
96
+ // Input validation
97
+ if (name && (typeof name !== 'string' || name.length > 100)) {
98
+ return res.status(400).json({
99
+ success: false,
100
+ message: 'Invalid name in request body',
101
+ timestamp: new Date().toISOString()
102
+ });
103
+ }
104
+ // Support for different languages
105
+ let greeting = 'Hello';
106
+ if (language && typeof language === 'string') {
107
+ const greetings = {
108
+ 'es': 'Hola',
109
+ 'fr': 'Bonjour',
110
+ 'de': 'Hallo',
111
+ 'it': 'Ciao',
112
+ 'pt': 'Olá',
113
+ 'ja': 'こんにちは',
114
+ 'zh': '你好',
115
+ 'hi': 'नमस्ते',
116
+ 'ar': 'مرحبا'
117
+ };
118
+ greeting = greetings[language.toLowerCase()] || greeting;
119
+ }
120
+ const sanitizedName = name ? name.replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, '') : 'World';
121
+ const message = `${greeting} ${sanitizedName}!`;
122
+ const response = createApiResponse({
123
+ greeting: message,
124
+ name: sanitizedName,
125
+ language: language || 'en'
126
+ });
127
+ res.json(response);
128
+ } catch (error) {
129
+ console.error('Error in POST /api/hello:', error);
130
+ res.status(500).json({
131
+ success: false,
132
+ message: 'Internal server error',
133
+ timestamp: new Date().toISOString()
134
+ });
135
+ }
136
+ });
137
+ /**
138
+ * GET / - Root endpoint
139
+ */ app.get('/', (req, res)=>{
140
+ res.json({
141
+ success: true,
142
+ message: 'Hello World Backend Service',
143
+ version: '1.0.0',
144
+ endpoints: [
145
+ 'GET /api/hello - Basic hello world',
146
+ 'GET /api/hello/:name - Personalized greeting',
147
+ 'POST /api/hello - Greeting with language support',
148
+ 'GET /api/health - Health check'
149
+ ],
150
+ timestamp: new Date().toISOString()
151
+ });
152
+ });
153
+ /**
154
+ * 404 handler
155
+ */ app.use('*', (req, res)=>{
156
+ res.status(404).json({
157
+ success: false,
158
+ message: 'Endpoint not found',
159
+ path: req.originalUrl,
160
+ timestamp: new Date().toISOString()
161
+ });
162
+ });
163
+ /**
164
+ * Global error handler
165
+ */ app.use((error, req, res, next)=>{
166
+ console.error('Unhandled error:', error);
167
+ res.status(500).json({
168
+ success: false,
169
+ message: 'Internal server error',
170
+ timestamp: new Date().toISOString()
171
+ });
172
+ });
173
+ // Start server
174
+ const server = app.listen(PORT, ()=>{
175
+ console.log(`🚀 Hello World Backend Service running on port ${PORT}`);
176
+ console.log(`📖 API Documentation: http://localhost:${PORT}/`);
177
+ console.log(`❤️ Health Check: http://localhost:${PORT}/api/health`);
178
+ });
179
+ // Graceful shutdown
180
+ process.on('SIGTERM', ()=>{
181
+ console.log('SIGTERM received, shutting down gracefully');
182
+ server.close(()=>{
183
+ console.log('Process terminated');
184
+ });
185
+ });
186
+ process.on('SIGINT', ()=>{
187
+ console.log('SIGINT received, shutting down gracefully');
188
+ server.close(()=>{
189
+ console.log('Process terminated');
190
+ });
191
+ });
192
+ export default app;
193
+
194
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/server.js"],"sourcesContent":["import express from 'express';\nimport { hello, healthCheck, createApiResponse } from './hello.js';\n\nconst app = express();\nconst PORT = process.env.PORT || 3000;\n\n// Middleware for JSON parsing and security\napp.use(express.json());\napp.use(express.urlencoded({ extended: true }));\n\n// Security headers middleware\napp.use((req, res, next) => {\n res.setHeader('X-Content-Type-Options', 'nosniff');\n res.setHeader('X-Frame-Options', 'DENY');\n res.setHeader('X-XSS-Protection', '1; mode=block');\n next();\n});\n\n// Request logging middleware\napp.use((req, res, next) => {\n console.log(`${new Date().toISOString()} - ${req.method} ${req.path}`);\n next();\n});\n\n// API Routes\n\n/**\n * GET /api/hello\n * Basic hello world endpoint\n */\napp.get('/api/hello', (req, res) => {\n try {\n const message = hello();\n const response = createApiResponse({ greeting: message });\n res.json(response);\n } catch (error) {\n console.error('Error in /api/hello:', error);\n res.status(500).json({\n success: false,\n message: 'Internal server error',\n timestamp: new Date().toISOString()\n });\n }\n});\n\n/**\n * GET /api/hello/:name\n * Personalized hello endpoint\n */\napp.get('/api/hello/:name', (req, res) => {\n try {\n const { name } = req.params;\n \n // Input validation\n if (!name || typeof name !== 'string' || name.length > 100) {\n return res.status(400).json({\n success: false,\n message: 'Invalid name parameter',\n timestamp: new Date().toISOString()\n });\n }\n\n // Sanitize input (remove potential XSS)\n const sanitizedName = name.replace(/<script\\b[^<]*(?:(?!<\\/script>)<[^<]*)*<\\/script>/gi, '');\n const message = hello(sanitizedName);\n const response = createApiResponse({ \n greeting: message,\n name: sanitizedName \n });\n res.json(response);\n } catch (error) {\n console.error('Error in /api/hello/:name:', error);\n res.status(500).json({\n success: false,\n message: 'Internal server error',\n timestamp: new Date().toISOString()\n });\n }\n});\n\n/**\n * GET /api/health\n * Health check endpoint\n */\napp.get('/api/health', (req, res) => {\n try {\n const health = healthCheck();\n const response = createApiResponse(health, 'Service is healthy');\n res.json(response);\n } catch (error) {\n console.error('Error in /api/health:', error);\n res.status(500).json({\n success: false,\n message: 'Health check failed',\n timestamp: new Date().toISOString()\n });\n }\n});\n\n/**\n * POST /api/hello\n * Hello endpoint with POST body\n */\napp.post('/api/hello', (req, res) => {\n try {\n const { name, language } = req.body;\n \n // Input validation\n if (name && (typeof name !== 'string' || name.length > 100)) {\n return res.status(400).json({\n success: false,\n message: 'Invalid name in request body',\n timestamp: new Date().toISOString()\n });\n }\n\n // Support for different languages\n let greeting = 'Hello';\n if (language && typeof language === 'string') {\n const greetings = {\n 'es': 'Hola',\n 'fr': 'Bonjour',\n 'de': 'Hallo',\n 'it': 'Ciao',\n 'pt': 'Olá',\n 'ja': 'こんにちは',\n 'zh': '你好',\n 'hi': 'नमस्ते',\n 'ar': 'مرحبا'\n };\n greeting = greetings[language.toLowerCase()] || greeting;\n }\n\n const sanitizedName = name ? name.replace(/<script\\b[^<]*(?:(?!<\\/script>)<[^<]*)*<\\/script>/gi, '') : 'World';\n const message = `${greeting} ${sanitizedName}!`;\n \n const response = createApiResponse({ \n greeting: message,\n name: sanitizedName,\n language: language || 'en'\n });\n res.json(response);\n } catch (error) {\n console.error('Error in POST /api/hello:', error);\n res.status(500).json({\n success: false,\n message: 'Internal server error',\n timestamp: new Date().toISOString()\n });\n }\n});\n\n/**\n * GET / - Root endpoint\n */\napp.get('/', (req, res) => {\n res.json({\n success: true,\n message: 'Hello World Backend Service',\n version: '1.0.0',\n endpoints: [\n 'GET /api/hello - Basic hello world',\n 'GET /api/hello/:name - Personalized greeting',\n 'POST /api/hello - Greeting with language support',\n 'GET /api/health - Health check'\n ],\n timestamp: new Date().toISOString()\n });\n});\n\n/**\n * 404 handler\n */\napp.use('*', (req, res) => {\n res.status(404).json({\n success: false,\n message: 'Endpoint not found',\n path: req.originalUrl,\n timestamp: new Date().toISOString()\n });\n});\n\n/**\n * Global error handler\n */\napp.use((error, req, res, next) => {\n console.error('Unhandled error:', error);\n res.status(500).json({\n success: false,\n message: 'Internal server error',\n timestamp: new Date().toISOString()\n });\n});\n\n// Start server\nconst server = app.listen(PORT, () => {\n console.log(`🚀 Hello World Backend Service running on port ${PORT}`);\n console.log(`📖 API Documentation: http://localhost:${PORT}/`);\n console.log(`❤️ Health Check: http://localhost:${PORT}/api/health`);\n});\n\n// Graceful shutdown\nprocess.on('SIGTERM', () => {\n console.log('SIGTERM received, shutting down gracefully');\n server.close(() => {\n console.log('Process terminated');\n });\n});\n\nprocess.on('SIGINT', () => {\n console.log('SIGINT received, shutting down gracefully');\n server.close(() => {\n console.log('Process terminated');\n });\n});\n\nexport default app;"],"names":["express","hello","healthCheck","createApiResponse","app","PORT","process","env","use","json","urlencoded","extended","req","res","next","setHeader","console","log","Date","toISOString","method","path","get","message","response","greeting","error","status","success","timestamp","name","params","length","sanitizedName","replace","health","post","language","body","greetings","toLowerCase","version","endpoints","originalUrl","server","listen","on","close"],"mappings":"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"}
@@ -0,0 +1,207 @@
1
+ import request from 'supertest';
2
+ import app from '../src/server.js';
3
+ describe('Hello World Backend Service', ()=>{
4
+ describe('GET /', ()=>{
5
+ it('should return service information', async ()=>{
6
+ const response = await request(app).get('/').expect(200);
7
+ expect(response.body.success).toBe(true);
8
+ expect(response.body.message).toBe('Hello World Backend Service');
9
+ expect(response.body.endpoints).toBeDefined();
10
+ expect(response.body.timestamp).toBeDefined();
11
+ });
12
+ });
13
+ describe('GET /api/health', ()=>{
14
+ it('should return health status', async ()=>{
15
+ const response = await request(app).get('/api/health').expect(200);
16
+ expect(response.body.success).toBe(true);
17
+ expect(response.body.data.status).toBe('healthy');
18
+ expect(response.body.data.timestamp).toBeDefined();
19
+ expect(response.body.data.uptime).toBeDefined();
20
+ expect(response.body.timestamp).toBeDefined();
21
+ });
22
+ });
23
+ describe('GET /api/hello', ()=>{
24
+ it('should return basic hello world greeting', async ()=>{
25
+ const response = await request(app).get('/api/hello').expect(200);
26
+ expect(response.body.success).toBe(true);
27
+ expect(response.body.data.greeting).toBe('Hello World!');
28
+ expect(response.body.timestamp).toBeDefined();
29
+ });
30
+ });
31
+ describe('GET /api/hello/:name', ()=>{
32
+ it('should return personalized greeting', async ()=>{
33
+ const response = await request(app).get('/api/hello/John').expect(200);
34
+ expect(response.body.success).toBe(true);
35
+ expect(response.body.data.greeting).toBe('Hello John!');
36
+ expect(response.body.data.name).toBe('John');
37
+ expect(response.body.timestamp).toBeDefined();
38
+ });
39
+ it('should sanitize XSS attempts in name parameter', async ()=>{
40
+ const maliciousName = '<script>alert("xss")</script>John';
41
+ const response = await request(app).get(`/api/hello/${encodeURIComponent(maliciousName)}`).expect(200);
42
+ expect(response.body.success).toBe(true);
43
+ expect(response.body.data.greeting).not.toContain('<script>');
44
+ expect(response.body.data.name).not.toContain('<script>');
45
+ expect(response.body.data.greeting).toBe('Hello John!');
46
+ });
47
+ it('should handle empty name', async ()=>{
48
+ const response = await request(app).get('/api/hello/').expect(404);
49
+ });
50
+ it('should reject names longer than 100 characters', async ()=>{
51
+ const longName = 'a'.repeat(101);
52
+ const response = await request(app).get(`/api/hello/${longName}`).expect(400);
53
+ expect(response.body.success).toBe(false);
54
+ expect(response.body.message).toContain('Invalid name parameter');
55
+ });
56
+ });
57
+ describe('POST /api/hello', ()=>{
58
+ it('should return greeting with name from request body', async ()=>{
59
+ const response = await request(app).post('/api/hello').send({
60
+ name: 'Alice'
61
+ }).expect(200);
62
+ expect(response.body.success).toBe(true);
63
+ expect(response.body.data.greeting).toBe('Hello Alice!');
64
+ expect(response.body.data.name).toBe('Alice');
65
+ expect(response.body.data.language).toBe('en');
66
+ expect(response.body.timestamp).toBeDefined();
67
+ });
68
+ it('should handle greeting without name', async ()=>{
69
+ const response = await request(app).post('/api/hello').send({}).expect(200);
70
+ expect(response.body.success).toBe(true);
71
+ expect(response.body.data.greeting).toBe('Hello World!');
72
+ expect(response.body.data.name).toBe('World');
73
+ });
74
+ it('should support different languages', async ()=>{
75
+ const testCases = [
76
+ {
77
+ language: 'es',
78
+ expected: 'Hola'
79
+ },
80
+ {
81
+ language: 'fr',
82
+ expected: 'Bonjour'
83
+ },
84
+ {
85
+ language: 'de',
86
+ expected: 'Hallo'
87
+ },
88
+ {
89
+ language: 'it',
90
+ expected: 'Ciao'
91
+ },
92
+ {
93
+ language: 'pt',
94
+ expected: 'Olá'
95
+ },
96
+ {
97
+ language: 'ja',
98
+ expected: 'こんにちは'
99
+ },
100
+ {
101
+ language: 'zh',
102
+ expected: '你好'
103
+ },
104
+ {
105
+ language: 'hi',
106
+ expected: 'नमस्ते'
107
+ },
108
+ {
109
+ language: 'ar',
110
+ expected: 'مرحبا'
111
+ },
112
+ {
113
+ language: 'invalid',
114
+ expected: 'Hello'
115
+ }
116
+ ];
117
+ for (const testCase of testCases){
118
+ const response = await request(app).post('/api/hello').send({
119
+ name: 'World',
120
+ language: testCase.language
121
+ }).expect(200);
122
+ expect(response.body.success).toBe(true);
123
+ expect(response.body.data.greeting).toBe(`${testCase.expected} World!`);
124
+ expect(response.body.data.language).toBe(testCase.language);
125
+ }
126
+ });
127
+ it('should sanitize XSS attempts in POST request body', async ()=>{
128
+ const maliciousPayload = {
129
+ name: '<script>alert("xss")</script>Bob',
130
+ language: 'en'
131
+ };
132
+ const response = await request(app).post('/api/hello').send(maliciousPayload).expect(200);
133
+ expect(response.body.success).toBe(true);
134
+ expect(response.body.data.greeting).not.toContain('<script>');
135
+ expect(response.body.data.name).not.toContain('<script>');
136
+ expect(response.body.data.greeting).toBe('Hello Bob!');
137
+ });
138
+ it('should reject names longer than 100 characters', async ()=>{
139
+ const longName = 'a'.repeat(101);
140
+ const response = await request(app).post('/api/hello').send({
141
+ name: longName
142
+ }).expect(400);
143
+ expect(response.body.success).toBe(false);
144
+ expect(response.body.message).toContain('Invalid name');
145
+ });
146
+ it('should reject invalid language types', async ()=>{
147
+ const response = await request(app).post('/api/hello').send({
148
+ name: 'World',
149
+ language: 123
150
+ }).expect(200); // Should still work, language defaults to English
151
+ expect(response.body.success).toBe(true);
152
+ expect(response.body.data.greeting).toBe('Hello World!');
153
+ });
154
+ });
155
+ describe('Error Handling', ()=>{
156
+ it('should return 404 for non-existent endpoints', async ()=>{
157
+ const response = await request(app).get('/api/nonexistent').expect(404);
158
+ expect(response.body.success).toBe(false);
159
+ expect(response.body.message).toContain('Endpoint not found');
160
+ expect(response.body.path).toBe('/api/nonexistent');
161
+ });
162
+ it('should return 404 for nested non-existent endpoints', async ()=>{
163
+ const response = await request(app).get('/api/hello/nonexistent/deep').expect(404);
164
+ expect(response.body.success).toBe(false);
165
+ expect(response.body.message).toContain('Endpoint not found');
166
+ });
167
+ it('should handle malformed JSON in POST requests', async ()=>{
168
+ const response = await request(app).post('/api/hello').set('Content-Type', 'application/json').send('{"invalid": json}').expect(400);
169
+ });
170
+ });
171
+ describe('Security Headers', ()=>{
172
+ it('should include security headers', async ()=>{
173
+ const response = await request(app).get('/api/hello').expect(200);
174
+ expect(response.headers['x-content-type-options']).toBe('nosniff');
175
+ expect(response.headers['x-frame-options']).toBe('DENY');
176
+ expect(response.headers['x-xss-protection']).toBe('1; mode=block');
177
+ });
178
+ });
179
+ describe('Performance and Load Testing', ()=>{
180
+ it('should handle multiple concurrent requests', async ()=>{
181
+ const requests = Array(10).fill().map(()=>request(app).get('/api/hello'));
182
+ const responses = await Promise.all(requests);
183
+ responses.forEach((response)=>{
184
+ expect(response.status).toBe(200);
185
+ expect(response.body.success).toBe(true);
186
+ expect(response.body.data.greeting).toBe('Hello World!');
187
+ });
188
+ });
189
+ it('should handle requests with small delays', async ()=>{
190
+ for(let i = 0; i < 5; i++){
191
+ const response = await request(app).get('/api/hello/TestUser').expect(200);
192
+ expect(response.body.success).toBe(true);
193
+ expect(response.body.data.greeting).toBe('Hello TestUser!');
194
+ }
195
+ });
196
+ });
197
+ describe('Content-Type Handling', ()=>{
198
+ it('should handle form-urlencoded data', async ()=>{
199
+ const response = await request(app).post('/api/hello').send('name=FormUser&language=es').set('Content-Type', 'application/x-www-form-urlencoded').expect(200);
200
+ expect(response.body.success).toBe(true);
201
+ expect(response.body.data.greeting).toBe('Hola FormUser!');
202
+ expect(response.body.data.language).toBe('es');
203
+ });
204
+ });
205
+ });
206
+
207
+ //# sourceMappingURL=server.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/server.test.js"],"sourcesContent":["import request from 'supertest';\nimport app from '../src/server.js';\n\ndescribe('Hello World Backend Service', () => {\n describe('GET /', () => {\n it('should return service information', async () => {\n const response = await request(app)\n .get('/')\n .expect(200);\n\n expect(response.body.success).toBe(true);\n expect(response.body.message).toBe('Hello World Backend Service');\n expect(response.body.endpoints).toBeDefined();\n expect(response.body.timestamp).toBeDefined();\n });\n });\n\n describe('GET /api/health', () => {\n it('should return health status', async () => {\n const response = await request(app)\n .get('/api/health')\n .expect(200);\n\n expect(response.body.success).toBe(true);\n expect(response.body.data.status).toBe('healthy');\n expect(response.body.data.timestamp).toBeDefined();\n expect(response.body.data.uptime).toBeDefined();\n expect(response.body.timestamp).toBeDefined();\n });\n });\n\n describe('GET /api/hello', () => {\n it('should return basic hello world greeting', async () => {\n const response = await request(app)\n .get('/api/hello')\n .expect(200);\n\n expect(response.body.success).toBe(true);\n expect(response.body.data.greeting).toBe('Hello World!');\n expect(response.body.timestamp).toBeDefined();\n });\n });\n\n describe('GET /api/hello/:name', () => {\n it('should return personalized greeting', async () => {\n const response = await request(app)\n .get('/api/hello/John')\n .expect(200);\n\n expect(response.body.success).toBe(true);\n expect(response.body.data.greeting).toBe('Hello John!');\n expect(response.body.data.name).toBe('John');\n expect(response.body.timestamp).toBeDefined();\n });\n\n it('should sanitize XSS attempts in name parameter', async () => {\n const maliciousName = '<script>alert(\"xss\")</script>John';\n const response = await request(app)\n .get(`/api/hello/${encodeURIComponent(maliciousName)}`)\n .expect(200);\n\n expect(response.body.success).toBe(true);\n expect(response.body.data.greeting).not.toContain('<script>');\n expect(response.body.data.name).not.toContain('<script>');\n expect(response.body.data.greeting).toBe('Hello John!');\n });\n\n it('should handle empty name', async () => {\n const response = await request(app)\n .get('/api/hello/')\n .expect(404);\n });\n\n it('should reject names longer than 100 characters', async () => {\n const longName = 'a'.repeat(101);\n const response = await request(app)\n .get(`/api/hello/${longName}`)\n .expect(400);\n\n expect(response.body.success).toBe(false);\n expect(response.body.message).toContain('Invalid name parameter');\n });\n });\n\n describe('POST /api/hello', () => {\n it('should return greeting with name from request body', async () => {\n const response = await request(app)\n .post('/api/hello')\n .send({ name: 'Alice' })\n .expect(200);\n\n expect(response.body.success).toBe(true);\n expect(response.body.data.greeting).toBe('Hello Alice!');\n expect(response.body.data.name).toBe('Alice');\n expect(response.body.data.language).toBe('en');\n expect(response.body.timestamp).toBeDefined();\n });\n\n it('should handle greeting without name', async () => {\n const response = await request(app)\n .post('/api/hello')\n .send({})\n .expect(200);\n\n expect(response.body.success).toBe(true);\n expect(response.body.data.greeting).toBe('Hello World!');\n expect(response.body.data.name).toBe('World');\n });\n\n it('should support different languages', async () => {\n const testCases = [\n { language: 'es', expected: 'Hola' },\n { language: 'fr', expected: 'Bonjour' },\n { language: 'de', expected: 'Hallo' },\n { language: 'it', expected: 'Ciao' },\n { language: 'pt', expected: 'Olá' },\n { language: 'ja', expected: 'こんにちは' },\n { language: 'zh', expected: '你好' },\n { language: 'hi', expected: 'नमस्ते' },\n { language: 'ar', expected: 'مرحبا' },\n { language: 'invalid', expected: 'Hello' }\n ];\n\n for (const testCase of testCases) {\n const response = await request(app)\n .post('/api/hello')\n .send({ name: 'World', language: testCase.language })\n .expect(200);\n\n expect(response.body.success).toBe(true);\n expect(response.body.data.greeting).toBe(`${testCase.expected} World!`);\n expect(response.body.data.language).toBe(testCase.language);\n }\n });\n\n it('should sanitize XSS attempts in POST request body', async () => {\n const maliciousPayload = {\n name: '<script>alert(\"xss\")</script>Bob',\n language: 'en'\n };\n\n const response = await request(app)\n .post('/api/hello')\n .send(maliciousPayload)\n .expect(200);\n\n expect(response.body.success).toBe(true);\n expect(response.body.data.greeting).not.toContain('<script>');\n expect(response.body.data.name).not.toContain('<script>');\n expect(response.body.data.greeting).toBe('Hello Bob!');\n });\n\n it('should reject names longer than 100 characters', async () => {\n const longName = 'a'.repeat(101);\n const response = await request(app)\n .post('/api/hello')\n .send({ name: longName })\n .expect(400);\n\n expect(response.body.success).toBe(false);\n expect(response.body.message).toContain('Invalid name');\n });\n\n it('should reject invalid language types', async () => {\n const response = await request(app)\n .post('/api/hello')\n .send({ name: 'World', language: 123 })\n .expect(200); // Should still work, language defaults to English\n\n expect(response.body.success).toBe(true);\n expect(response.body.data.greeting).toBe('Hello World!');\n });\n });\n\n describe('Error Handling', () => {\n it('should return 404 for non-existent endpoints', async () => {\n const response = await request(app)\n .get('/api/nonexistent')\n .expect(404);\n\n expect(response.body.success).toBe(false);\n expect(response.body.message).toContain('Endpoint not found');\n expect(response.body.path).toBe('/api/nonexistent');\n });\n\n it('should return 404 for nested non-existent endpoints', async () => {\n const response = await request(app)\n .get('/api/hello/nonexistent/deep')\n .expect(404);\n\n expect(response.body.success).toBe(false);\n expect(response.body.message).toContain('Endpoint not found');\n });\n\n it('should handle malformed JSON in POST requests', async () => {\n const response = await request(app)\n .post('/api/hello')\n .set('Content-Type', 'application/json')\n .send('{\"invalid\": json}')\n .expect(400);\n });\n });\n\n describe('Security Headers', () => {\n it('should include security headers', async () => {\n const response = await request(app)\n .get('/api/hello')\n .expect(200);\n\n expect(response.headers['x-content-type-options']).toBe('nosniff');\n expect(response.headers['x-frame-options']).toBe('DENY');\n expect(response.headers['x-xss-protection']).toBe('1; mode=block');\n });\n });\n\n describe('Performance and Load Testing', () => {\n it('should handle multiple concurrent requests', async () => {\n const requests = Array(10).fill().map(() => \n request(app).get('/api/hello')\n );\n\n const responses = await Promise.all(requests);\n \n responses.forEach(response => {\n expect(response.status).toBe(200);\n expect(response.body.success).toBe(true);\n expect(response.body.data.greeting).toBe('Hello World!');\n });\n });\n\n it('should handle requests with small delays', async () => {\n for (let i = 0; i < 5; i++) {\n const response = await request(app)\n .get('/api/hello/TestUser')\n .expect(200);\n\n expect(response.body.success).toBe(true);\n expect(response.body.data.greeting).toBe('Hello TestUser!');\n }\n });\n });\n\n describe('Content-Type Handling', () => {\n it('should handle form-urlencoded data', async () => {\n const response = await request(app)\n .post('/api/hello')\n .send('name=FormUser&language=es')\n .set('Content-Type', 'application/x-www-form-urlencoded')\n .expect(200);\n\n expect(response.body.success).toBe(true);\n expect(response.body.data.greeting).toBe('Hola FormUser!');\n expect(response.body.data.language).toBe('es');\n });\n });\n});"],"names":["request","app","describe","it","response","get","expect","body","success","toBe","message","endpoints","toBeDefined","timestamp","data","status","uptime","greeting","name","maliciousName","encodeURIComponent","not","toContain","longName","repeat","post","send","language","testCases","expected","testCase","maliciousPayload","path","set","headers","requests","Array","fill","map","responses","Promise","all","forEach","i"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-flow-novice",
3
- "version": "2.14.36",
3
+ "version": "2.14.37",
4
4
  "description": "AI agent orchestration framework with namespace-isolated skills, agents, and CFN Loop validation. Safe installation with ~0.01% collision risk.",
5
5
  "main": "dist/index.js",
6
6
  "type": "module",
@@ -132,6 +132,7 @@
132
132
  "chalk": "^4.1.2",
133
133
  "commander": "^11.1.0",
134
134
  "dotenv": "^17.2.3",
135
+ "express": "^5.1.0",
135
136
  "glob": "^11.0.3",
136
137
  "ioredis": "^5.8.2",
137
138
  "lodash": "^4.17.21",