lua-cli 3.7.2 → 3.7.4

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 (78) hide show
  1. package/README.md +26 -0
  2. package/dist/api/chat.api.service.d.ts.map +1 -1
  3. package/dist/api/chat.api.service.js +4 -0
  4. package/dist/api/chat.api.service.js.map +1 -1
  5. package/dist/api/http.client.d.ts +25 -0
  6. package/dist/api/http.client.d.ts.map +1 -1
  7. package/dist/api/http.client.js +88 -5
  8. package/dist/api/http.client.js.map +1 -1
  9. package/dist/cli/command-definitions.d.ts.map +1 -1
  10. package/dist/cli/command-definitions.js +1 -6
  11. package/dist/cli/command-definitions.js.map +1 -1
  12. package/dist/commands/chat.js +1 -1
  13. package/dist/commands/chat.js.map +1 -1
  14. package/dist/commands/index.d.ts +0 -1
  15. package/dist/commands/index.d.ts.map +1 -1
  16. package/dist/commands/index.js +0 -1
  17. package/dist/commands/index.js.map +1 -1
  18. package/dist/commands/test.js +1 -1
  19. package/dist/commands/test.js.map +1 -1
  20. package/dist/config/constants.d.ts +7 -0
  21. package/dist/config/constants.d.ts.map +1 -1
  22. package/dist/config/constants.js +10 -0
  23. package/dist/config/constants.js.map +1 -1
  24. package/dist/services/analytics.d.ts +6 -0
  25. package/dist/services/analytics.d.ts.map +1 -1
  26. package/dist/services/analytics.js +19 -0
  27. package/dist/services/analytics.js.map +1 -1
  28. package/dist/services/auth.d.ts +11 -4
  29. package/dist/services/auth.d.ts.map +1 -1
  30. package/dist/services/auth.js +35 -6
  31. package/dist/services/auth.js.map +1 -1
  32. package/dist/utils/auth-flows.d.ts +4 -4
  33. package/dist/utils/auth-flows.d.ts.map +1 -1
  34. package/dist/utils/auth-flows.js +53 -37
  35. package/dist/utils/auth-flows.js.map +1 -1
  36. package/dist/utils/keytar-loader.d.ts.map +1 -1
  37. package/dist/utils/keytar-loader.js +8 -1
  38. package/dist/utils/keytar-loader.js.map +1 -1
  39. package/dist/utils/sandbox-storage.js +1 -1
  40. package/dist/utils/sandbox-storage.js.map +1 -1
  41. package/node_modules/@lua/shared-types/dist/index.d.mts +92 -0
  42. package/node_modules/@lua/shared-types/dist/index.d.ts +92 -0
  43. package/node_modules/@lua/shared-types/dist/index.js +104 -0
  44. package/node_modules/@lua/shared-types/dist/index.mjs +79 -0
  45. package/node_modules/@lua/shared-types/package.json +26 -0
  46. package/node_modules/@lua/shared-types/src/ai-generate.types.ts +79 -0
  47. package/node_modules/@lua/shared-types/src/ai-generate.utils.ts +19 -0
  48. package/node_modules/@lua/shared-types/src/channel.type.ts +21 -0
  49. package/node_modules/@lua/shared-types/src/index.ts +5 -0
  50. package/node_modules/@lua/shared-types/src/sandbox-contract.ts +42 -0
  51. package/node_modules/@lua/shared-types/src/unstructured-types.ts +58 -0
  52. package/node_modules/@lua/shared-types/tsconfig.json +12 -0
  53. package/node_modules/@lua/shared-types/tsup.config.ts +9 -0
  54. package/package.json +11 -18
  55. package/scripts/resolve-workspace-deps.cjs +61 -0
  56. package/dist/commands/dev.d.ts +0 -27
  57. package/dist/commands/dev.d.ts.map +0 -1
  58. package/dist/commands/dev.js +0 -130
  59. package/dist/commands/dev.js.map +0 -1
  60. package/dist/config/dev.constants.d.ts +0 -56
  61. package/dist/config/dev.constants.d.ts.map +0 -1
  62. package/dist/config/dev.constants.js +0 -70
  63. package/dist/config/dev.constants.js.map +0 -1
  64. package/dist/utils/dev-api.d.ts +0 -6
  65. package/dist/utils/dev-api.d.ts.map +0 -1
  66. package/dist/utils/dev-api.js +0 -6
  67. package/dist/utils/dev-api.js.map +0 -1
  68. package/dist/utils/dev-server.d.ts +0 -27
  69. package/dist/utils/dev-server.d.ts.map +0 -1
  70. package/dist/utils/dev-server.js +0 -736
  71. package/dist/utils/dev-server.js.map +0 -1
  72. package/dist/utils/dev-watcher.d.ts +0 -31
  73. package/dist/utils/dev-watcher.d.ts.map +0 -1
  74. package/dist/utils/dev-watcher.js +0 -126
  75. package/dist/utils/dev-watcher.js.map +0 -1
  76. package/dist/web/app.css +0 -7401
  77. package/dist/web/app.js +0 -204
  78. package/dist/web/index.html +0 -33
@@ -1,736 +0,0 @@
1
- /**
2
- * Dev Server Utilities
3
- * Handles HTTP server, WebSocket connections, and all HTTP endpoints for dev mode
4
- */
5
- import fs from 'fs';
6
- import path from 'path';
7
- import { fileURLToPath } from 'url';
8
- import { createServer } from 'http';
9
- import { WebSocketServer } from 'ws';
10
- import { readYamlConfig } from './files.js';
11
- import { skillHandler } from '../primitives/index.js';
12
- import { executeTool, createBroadcastConsole, loadEnvironmentVariables } from './sandbox.js';
13
- import { getSandboxSkillId } from './sandbox-storage.js';
14
- import { sendChatMessage } from './dev-api.js';
15
- import { CORS_HEADERS, HTTP_STATUS, DEV_DEFAULTS } from '../config/dev.constants.js';
16
- import { BASE_URLS } from '../config/constants.js';
17
- import ProductApi from '../api/products.api.service.js';
18
- import BasketApi from '../api/basket.api.service.js';
19
- import OrderApi from '../api/order.api.service.js';
20
- import CustomDataApi from '../api/custom.data.api.service.js';
21
- import { setAgentPersona } from '../compiler/index.js';
22
- import { loadManifest, getPrimitivesByKind, loadArtifact, getAgentPersona } from './artifact-loader.js';
23
- import { PrimitiveKind } from '../compiler/types.js';
24
- const __filename = fileURLToPath(import.meta.url);
25
- const __dirname = path.dirname(__filename);
26
- /**
27
- * Creates and starts the dev web server with chat interface and tool testing.
28
- *
29
- * @param apiKey - User's API key
30
- * @param agentId - Agent ID
31
- * @param skillId - Skill ID
32
- * @param sandboxId - Sandbox skill ID
33
- * @param port - Port to run server on
34
- * @param yamlConfig - YAML config with skills and processors
35
- * @returns Server instance with WebSocket and broadcast function
36
- */
37
- export function createChatServer(apiKey, agentId, skillId, sandboxId, port, yamlConfig) {
38
- const server = createServer((req, res) => {
39
- // Enable CORS
40
- Object.entries(CORS_HEADERS).forEach(([key, value]) => {
41
- res.setHeader(key, value);
42
- });
43
- if (req.method === 'OPTIONS') {
44
- res.writeHead(HTTP_STATUS.OK);
45
- res.end();
46
- return;
47
- }
48
- // Route handlers
49
- if (req.method === 'POST' && req.url === '/chat') {
50
- handleChatEndpoint(req, res, apiKey, agentId, skillId, sandboxId, yamlConfig);
51
- return;
52
- }
53
- if (req.method === 'GET' && req.url === '/persona') {
54
- handleGetPersonaEndpoint(req, res);
55
- return;
56
- }
57
- if (req.method === 'POST' && req.url === '/persona') {
58
- handlePostPersonaEndpoint(req, res);
59
- return;
60
- }
61
- if (req.method === 'GET' && req.url === '/api/config') {
62
- handleGetConfigEndpoint(req, res);
63
- return;
64
- }
65
- if (req.method === 'GET' && req.url === '/api/skills') {
66
- handleGetSkillsEndpoint(req, res);
67
- return;
68
- }
69
- if (req.method === 'GET' && req.url === '/env') {
70
- handleGetEnvEndpoint(req, res);
71
- return;
72
- }
73
- if (req.method === 'POST' && req.url === '/env') {
74
- handlePostEnvEndpoint(req, res);
75
- return;
76
- }
77
- if (req.method === 'GET' && req.url === '/tools') {
78
- handleGetToolsEndpoint(req, res);
79
- return;
80
- }
81
- if (req.method === 'POST' && req.url === '/tools/test') {
82
- handleToolTestEndpoint(req, res, apiKey, agentId, wss);
83
- return;
84
- }
85
- // Products routes
86
- if (req.url?.startsWith('/api/products')) {
87
- handleProductsEndpoint(req, res, apiKey, agentId);
88
- return;
89
- }
90
- // Baskets routes
91
- if (req.url?.startsWith('/api/baskets')) {
92
- handleBasketsEndpoint(req, res, apiKey, agentId);
93
- return;
94
- }
95
- // Orders routes
96
- if (req.url?.startsWith('/api/orders')) {
97
- handleOrdersEndpoint(req, res, apiKey, agentId);
98
- return;
99
- }
100
- // Custom Data routes
101
- if (req.url?.startsWith('/api/custom-data')) {
102
- handleCustomDataEndpoint(req, res, apiKey, agentId);
103
- return;
104
- }
105
- if (req.method === 'GET' && req.url === '/') {
106
- handleIndexEndpoint(req, res, apiKey, agentId, skillId, sandboxId);
107
- return;
108
- }
109
- if (req.method === 'GET' && req.url === '/app.js') {
110
- handleStaticFile(req, res, 'app.js', 'application/javascript');
111
- return;
112
- }
113
- if (req.method === 'GET' && req.url === '/app.css') {
114
- handleStaticFile(req, res, 'app.css', 'text/css');
115
- return;
116
- }
117
- if (req.method === 'GET' && req.url === '/tools-page.css') {
118
- handleStaticFile(req, res, 'tools-page.css', 'text/css');
119
- return;
120
- }
121
- res.writeHead(HTTP_STATUS.NOT_FOUND);
122
- res.end('Not Found');
123
- });
124
- // Create WebSocket server for log streaming
125
- const wss = new WebSocketServer({ server });
126
- wss.on('connection', (ws) => {
127
- ws.on('close', () => {
128
- // Client disconnected
129
- });
130
- ws.on('error', (error) => {
131
- console.error('WebSocket error:', error);
132
- });
133
- // Send initial connection message
134
- ws.send(JSON.stringify({
135
- type: 'log',
136
- subType: 'info',
137
- message: 'Connected to CLI dev server',
138
- timestamp: new Date().toISOString()
139
- }));
140
- });
141
- server.listen(port, () => {
142
- // Server started
143
- });
144
- // Function to broadcast logs to all connected clients
145
- const broadcastLog = (message, subType = 'info') => {
146
- const logMessage = {
147
- type: 'log',
148
- subType,
149
- message,
150
- timestamp: new Date().toISOString(),
151
- id: Date.now().toString()
152
- };
153
- wss.clients.forEach((client) => {
154
- if (client.readyState === 1) { // WebSocket.OPEN
155
- client.send(JSON.stringify(logMessage));
156
- }
157
- });
158
- };
159
- return { server, wss, broadcastLog };
160
- }
161
- // ============================================================================
162
- // ENDPOINT HANDLERS
163
- // ============================================================================
164
- /**
165
- * Handles POST /chat - Send chat messages
166
- */
167
- function handleChatEndpoint(req, res, apiKey, agentId, skillId, sandboxId, yamlConfig) {
168
- let body = '';
169
- req.on('data', (chunk) => {
170
- body += chunk.toString();
171
- });
172
- req.on('end', async () => {
173
- try {
174
- const { message, persona } = JSON.parse(body);
175
- const response = await sendChatMessage(apiKey, agentId, skillId, sandboxId, message, persona, yamlConfig);
176
- res.writeHead(HTTP_STATUS.OK, { 'Content-Type': 'application/json' });
177
- res.end(JSON.stringify({
178
- success: response !== null,
179
- text: response || 'Error sending message',
180
- error: response === null ? 'Failed to send message' : null
181
- }));
182
- }
183
- catch (error) {
184
- res.writeHead(HTTP_STATUS.SERVER_ERROR, { 'Content-Type': 'application/json' });
185
- res.end(JSON.stringify({ success: false, error: 'Invalid request' }));
186
- }
187
- });
188
- }
189
- /**
190
- * Handles GET /persona - Get current persona
191
- */
192
- function handleGetPersonaEndpoint(req, res) {
193
- try {
194
- const persona = getAgentPersona() ?? '';
195
- res.writeHead(HTTP_STATUS.OK, { 'Content-Type': 'application/json' });
196
- res.end(JSON.stringify({
197
- success: true,
198
- persona: persona
199
- }));
200
- }
201
- catch (error) {
202
- res.writeHead(HTTP_STATUS.SERVER_ERROR, { 'Content-Type': 'application/json' });
203
- res.end(JSON.stringify({ success: false, error: 'Failed to read persona' }));
204
- }
205
- }
206
- /**
207
- * Handles POST /persona - Update persona
208
- */
209
- function handlePostPersonaEndpoint(req, res) {
210
- let body = '';
211
- req.on('data', (chunk) => {
212
- body += chunk.toString();
213
- });
214
- req.on('end', async () => {
215
- try {
216
- const { persona } = JSON.parse(body);
217
- setAgentPersona(persona);
218
- res.writeHead(HTTP_STATUS.OK, { 'Content-Type': 'application/json' });
219
- res.end(JSON.stringify({
220
- success: true,
221
- message: 'Persona updated successfully'
222
- }));
223
- }
224
- catch (error) {
225
- res.writeHead(HTTP_STATUS.SERVER_ERROR, { 'Content-Type': 'application/json' });
226
- res.end(JSON.stringify({ success: false, error: 'Failed to update persona' }));
227
- }
228
- });
229
- }
230
- /**
231
- * Handles GET /api/config - Get agent configuration
232
- */
233
- function handleGetConfigEndpoint(req, res) {
234
- try {
235
- const config = readYamlConfig();
236
- res.writeHead(HTTP_STATUS.OK, { 'Content-Type': 'application/json' });
237
- res.end(JSON.stringify({
238
- agent: {
239
- agentId: config?.agent?.agentId || '',
240
- orgId: config?.agent?.orgId || ''
241
- }
242
- }));
243
- }
244
- catch (error) {
245
- console.error('Error reading config:', error);
246
- res.writeHead(HTTP_STATUS.SERVER_ERROR, { 'Content-Type': 'application/json' });
247
- res.end(JSON.stringify({ error: 'Failed to read configuration' }));
248
- }
249
- }
250
- /**
251
- * Handles GET /api/skills - Get all skills information from manifest
252
- */
253
- function handleGetSkillsEndpoint(req, res) {
254
- (async () => {
255
- try {
256
- const skillsData = [];
257
- const config = readYamlConfig();
258
- const yamlSkills = skillHandler.getFromYaml(config);
259
- // Try to read from manifest
260
- try {
261
- const manifest = loadManifest();
262
- const skills = getPrimitivesByKind(manifest, PrimitiveKind.SKILL);
263
- for (const skill of skills) {
264
- const yamlSkill = yamlSkills.find((s) => s.name === skill.name);
265
- const sandboxId = await getSandboxSkillId(skill.name);
266
- skillsData.push({
267
- name: skill.name || DEV_DEFAULTS.SKILL_NAME,
268
- description: skill.description || DEV_DEFAULTS.DESCRIPTION,
269
- context: skill.context || '',
270
- version: yamlSkill?.version || DEV_DEFAULTS.VERSION,
271
- skillId: yamlSkill?.skillId || '',
272
- sandboxId: sandboxId || '',
273
- tools: skill.tools || []
274
- });
275
- }
276
- }
277
- catch {
278
- // Fallback: Read from YAML config only (not compiled yet)
279
- const toolsDir = path.join(process.cwd(), 'src', 'tools');
280
- let toolNames = [];
281
- if (fs.existsSync(toolsDir)) {
282
- const toolFiles = fs.readdirSync(toolsDir)
283
- .filter((file) => file.endsWith('.ts'))
284
- .map((file) => file.replace('.ts', ''));
285
- toolNames = toolFiles;
286
- }
287
- for (const skill of yamlSkills) {
288
- const sandboxId = await getSandboxSkillId(skill.name);
289
- skillsData.push({
290
- name: skill.name || DEV_DEFAULTS.SKILL_NAME,
291
- description: DEV_DEFAULTS.NOT_COMPILED_DESCRIPTION,
292
- context: DEV_DEFAULTS.NOT_COMPILED_CONTEXT,
293
- version: skill.version || DEV_DEFAULTS.VERSION,
294
- skillId: skill.skillId || '',
295
- sandboxId: sandboxId || '',
296
- tools: toolNames // All tools for now since not compiled
297
- });
298
- }
299
- }
300
- res.writeHead(HTTP_STATUS.OK, { 'Content-Type': 'application/json' });
301
- res.end(JSON.stringify({
302
- success: true,
303
- skills: skillsData
304
- }));
305
- }
306
- catch (error) {
307
- console.error('Error reading skills:', error);
308
- res.writeHead(HTTP_STATUS.SERVER_ERROR, { 'Content-Type': 'application/json' });
309
- res.end(JSON.stringify({
310
- success: false,
311
- error: 'Failed to read skills configuration'
312
- }));
313
- }
314
- })();
315
- }
316
- /**
317
- * Handles GET /env - Get environment variables
318
- */
319
- function handleGetEnvEndpoint(req, res) {
320
- try {
321
- const envPath = path.join(process.cwd(), '.env');
322
- let envContent = '';
323
- if (fs.existsSync(envPath)) {
324
- envContent = fs.readFileSync(envPath, 'utf8');
325
- }
326
- res.writeHead(HTTP_STATUS.OK, { 'Content-Type': 'application/json' });
327
- res.end(JSON.stringify({
328
- success: true,
329
- content: envContent
330
- }));
331
- }
332
- catch (error) {
333
- res.writeHead(HTTP_STATUS.SERVER_ERROR, { 'Content-Type': 'application/json' });
334
- res.end(JSON.stringify({ success: false, error: 'Failed to read .env file' }));
335
- }
336
- }
337
- /**
338
- * Handles POST /env - Update environment variables
339
- */
340
- function handlePostEnvEndpoint(req, res) {
341
- let body = '';
342
- req.on('data', (chunk) => {
343
- body += chunk.toString();
344
- });
345
- req.on('end', async () => {
346
- try {
347
- const { content } = JSON.parse(body);
348
- const envPath = path.join(process.cwd(), '.env');
349
- // Write the .env file
350
- fs.writeFileSync(envPath, content || '', 'utf8');
351
- res.writeHead(HTTP_STATUS.OK, { 'Content-Type': 'application/json' });
352
- res.end(JSON.stringify({
353
- success: true,
354
- message: 'Environment variables updated successfully'
355
- }));
356
- }
357
- catch (error) {
358
- res.writeHead(HTTP_STATUS.SERVER_ERROR, { 'Content-Type': 'application/json' });
359
- res.end(JSON.stringify({ success: false, error: 'Failed to update .env file' }));
360
- }
361
- });
362
- }
363
- /**
364
- * Handles GET /tools - Get all tools from manifest
365
- */
366
- function handleGetToolsEndpoint(req, res) {
367
- try {
368
- const manifest = loadManifest();
369
- const toolPrimitives = getPrimitivesByKind(manifest, PrimitiveKind.TOOL);
370
- // Convert to tools object format expected by the UI
371
- const tools = {};
372
- for (const tool of toolPrimitives) {
373
- tools[tool.name] = {
374
- name: tool.name,
375
- description: tool.description,
376
- };
377
- }
378
- res.writeHead(HTTP_STATUS.OK, { 'Content-Type': 'application/json' });
379
- res.end(JSON.stringify({
380
- success: true,
381
- tools: tools
382
- }));
383
- }
384
- catch (error) {
385
- res.writeHead(HTTP_STATUS.NOT_FOUND, { 'Content-Type': 'application/json' });
386
- res.end(JSON.stringify({ success: false, error: 'Manifest not found. Run lua compile first.' }));
387
- }
388
- }
389
- /**
390
- * Handles POST /tools/test - Test a tool
391
- */
392
- function handleToolTestEndpoint(req, res, apiKey, agentId, wss) {
393
- let body = '';
394
- req.on('data', (chunk) => {
395
- body += chunk.toString();
396
- });
397
- req.on('end', async () => {
398
- try {
399
- const { toolName, inputs } = JSON.parse(body);
400
- // Load tool from manifest
401
- let manifest;
402
- try {
403
- manifest = loadManifest();
404
- }
405
- catch {
406
- res.writeHead(HTTP_STATUS.NOT_FOUND, { 'Content-Type': 'application/json' });
407
- res.end(JSON.stringify({ success: false, error: 'Manifest not found. Run lua compile first.' }));
408
- return;
409
- }
410
- const tools = getPrimitivesByKind(manifest, PrimitiveKind.TOOL);
411
- const tool = tools.find(t => t.name === toolName);
412
- if (!tool) {
413
- res.writeHead(HTTP_STATUS.NOT_FOUND, { 'Content-Type': 'application/json' });
414
- res.end(JSON.stringify({ success: false, error: 'Tool not found' }));
415
- return;
416
- }
417
- // Load environment variables from all sources (.env + yaml)
418
- const envVars = loadEnvironmentVariables();
419
- // Load tool code from artifact (already uncompressed)
420
- const toolCode = loadArtifact(tool, process.cwd());
421
- // Broadcast tool test start
422
- wss.clients.forEach((client) => {
423
- if (client.readyState === 1) {
424
- client.send(JSON.stringify({
425
- type: 'log',
426
- subType: 'info',
427
- message: `🧪 Testing tool: ${toolName}`,
428
- timestamp: new Date().toISOString(),
429
- id: Date.now().toString()
430
- }));
431
- }
432
- });
433
- // Create custom console that captures output and sends via WebSocket
434
- const customConsole = createBroadcastConsole((logData) => {
435
- wss.clients.forEach((client) => {
436
- if (client.readyState === 1) { // WebSocket.OPEN
437
- client.send(JSON.stringify(logData));
438
- }
439
- });
440
- });
441
- // Execute the tool using the common utility
442
- const result = await executeTool({
443
- toolCode,
444
- inputs,
445
- apiKey,
446
- agentId,
447
- channel: 'dev',
448
- customConsole
449
- });
450
- // Broadcast tool test completion
451
- wss.clients.forEach((client) => {
452
- if (client.readyState === 1) {
453
- client.send(JSON.stringify({
454
- type: 'log',
455
- subType: 'info',
456
- message: `✅ Tool test completed: ${toolName}`,
457
- timestamp: new Date().toISOString(),
458
- id: (Date.now() + 1).toString()
459
- }));
460
- }
461
- });
462
- res.writeHead(HTTP_STATUS.OK, { 'Content-Type': 'application/json' });
463
- res.end(JSON.stringify({
464
- success: true,
465
- result: result
466
- }));
467
- }
468
- catch (error) {
469
- res.writeHead(HTTP_STATUS.SERVER_ERROR, { 'Content-Type': 'application/json' });
470
- res.end(JSON.stringify({
471
- success: false,
472
- error: error.message || 'Tool execution failed'
473
- }));
474
- }
475
- });
476
- }
477
- /**
478
- * Handles GET / - Serve main HTML page
479
- */
480
- function handleIndexEndpoint(req, res, apiKey, agentId, skillId, sandboxId) {
481
- // Read the React app HTML template from dist directory
482
- const htmlTemplate = fs.readFileSync(path.join(__dirname, '..', 'web', 'index.html'), 'utf8');
483
- // Replace placeholders with actual values
484
- const html = htmlTemplate
485
- .replace('{{API_KEY}}', apiKey)
486
- .replace('{{AGENT_ID}}', agentId)
487
- .replace('{{SKILL_ID}}', skillId)
488
- .replace('{{SANDBOX_ID}}', sandboxId);
489
- res.writeHead(HTTP_STATUS.OK, { 'Content-Type': 'text/html' });
490
- res.end(html);
491
- }
492
- /**
493
- * Handles static file serving (JS, CSS)
494
- */
495
- function handleStaticFile(req, res, filename, contentType) {
496
- try {
497
- const content = fs.readFileSync(path.join(__dirname, '..', 'web', filename), 'utf8');
498
- res.writeHead(HTTP_STATUS.OK, { 'Content-Type': contentType });
499
- res.end(content);
500
- }
501
- catch (error) {
502
- res.writeHead(HTTP_STATUS.NOT_FOUND, { 'Content-Type': 'text/plain' });
503
- res.end(`${filename} not found`);
504
- }
505
- }
506
- /**
507
- * Handler for products API using ProductApi service
508
- */
509
- async function handleProductsEndpoint(req, res, apiKey, agentId) {
510
- const productApi = new ProductApi(BASE_URLS.API, apiKey, agentId);
511
- try {
512
- let result;
513
- if (req.method === 'GET') {
514
- if (req.url.includes('/search')) {
515
- const searchQuery = new URL(req.url, 'http://localhost').searchParams.get('searchQuery') || '';
516
- result = await productApi.search(searchQuery);
517
- }
518
- else if (req.url.match(/\/api\/products\/[^/]+$/)) {
519
- const productId = req.url.split('/').pop();
520
- result = await productApi.getById(productId);
521
- }
522
- else {
523
- const url = new URL(req.url, 'http://localhost');
524
- const page = parseInt(url.searchParams.get('page') || '1');
525
- const limit = parseInt(url.searchParams.get('limit') || '20');
526
- result = await productApi.get(page, limit);
527
- }
528
- res.writeHead(HTTP_STATUS.OK, { 'Content-Type': 'application/json' });
529
- res.end(JSON.stringify({ success: true, data: result }));
530
- }
531
- else if (req.method === 'POST') {
532
- const body = await new Promise((resolve) => {
533
- let data = '';
534
- req.on('data', (chunk) => { data += chunk; });
535
- req.on('end', () => resolve(data));
536
- });
537
- const productData = JSON.parse(body);
538
- result = await productApi.create(productData);
539
- res.writeHead(HTTP_STATUS.OK, { 'Content-Type': 'application/json' });
540
- res.end(JSON.stringify({ success: true, data: { product: result } }));
541
- }
542
- else if (req.method === 'PUT') {
543
- const body = await new Promise((resolve) => {
544
- let data = '';
545
- req.on('data', (chunk) => { data += chunk; });
546
- req.on('end', () => resolve(data));
547
- });
548
- const productData = JSON.parse(body);
549
- result = await productApi.update(productData, productData.id);
550
- res.writeHead(HTTP_STATUS.OK, { 'Content-Type': 'application/json' });
551
- res.end(JSON.stringify({ success: true, data: result }));
552
- }
553
- else if (req.method === 'DELETE') {
554
- const productId = req.url.split('/').pop();
555
- result = await productApi.delete(productId);
556
- res.writeHead(HTTP_STATUS.OK, { 'Content-Type': 'application/json' });
557
- res.end(JSON.stringify({ success: true, data: result }));
558
- }
559
- }
560
- catch (error) {
561
- res.writeHead(HTTP_STATUS.SERVER_ERROR, { 'Content-Type': 'application/json' });
562
- res.end(JSON.stringify({ success: false, error: error.message || 'API error' }));
563
- }
564
- }
565
- /**
566
- * Handler for baskets API using BasketApi service
567
- */
568
- async function handleBasketsEndpoint(req, res, apiKey, agentId) {
569
- const basketApi = new BasketApi(BASE_URLS.API, apiKey, agentId);
570
- try {
571
- let result;
572
- if (req.method === 'GET') {
573
- if (req.url.match(/\/api\/baskets\/[^/]+$/)) {
574
- const basketId = req.url.split('/').pop();
575
- result = await basketApi.getById(basketId);
576
- }
577
- else {
578
- const url = new URL(req.url, 'http://localhost');
579
- const statusParam = url.searchParams.get('status');
580
- result = await basketApi.get(statusParam);
581
- }
582
- res.writeHead(HTTP_STATUS.OK, { 'Content-Type': 'application/json' });
583
- res.end(JSON.stringify({ success: true, data: result }));
584
- }
585
- else if (req.method === 'POST') {
586
- const body = await new Promise((resolve) => {
587
- let data = '';
588
- req.on('data', (chunk) => { data += chunk; });
589
- req.on('end', () => resolve(data));
590
- });
591
- const basketData = JSON.parse(body);
592
- result = await basketApi.create(basketData);
593
- res.writeHead(HTTP_STATUS.OK, { 'Content-Type': 'application/json' });
594
- res.end(JSON.stringify({ success: true, data: result }));
595
- }
596
- else if (req.method === 'DELETE') {
597
- const basketId = req.url.split('/').pop();
598
- // Baskets don't have a direct delete in the API, use clear instead
599
- result = await basketApi.clear(basketId);
600
- res.writeHead(HTTP_STATUS.OK, { 'Content-Type': 'application/json' });
601
- res.end(JSON.stringify({ success: true, data: result }));
602
- }
603
- }
604
- catch (error) {
605
- res.writeHead(HTTP_STATUS.SERVER_ERROR, { 'Content-Type': 'application/json' });
606
- res.end(JSON.stringify({ success: false, error: error.message || 'API error' }));
607
- }
608
- }
609
- /**
610
- * Handler for orders API using OrderApi service
611
- */
612
- async function handleOrdersEndpoint(req, res, apiKey, agentId) {
613
- const orderApi = new OrderApi(BASE_URLS.API, apiKey, agentId);
614
- try {
615
- let result;
616
- if (req.method === 'GET') {
617
- if (req.url.match(/\/api\/orders\/[^/]+$/)) {
618
- const orderId = req.url.split('/').pop();
619
- result = await orderApi.getById(orderId);
620
- }
621
- else {
622
- const url = new URL(req.url, 'http://localhost');
623
- const statusParam = url.searchParams.get('status');
624
- result = await orderApi.get(statusParam);
625
- }
626
- res.writeHead(HTTP_STATUS.OK, { 'Content-Type': 'application/json' });
627
- res.end(JSON.stringify({ success: true, data: result }));
628
- }
629
- else if (req.method === 'POST') {
630
- const body = await new Promise((resolve) => {
631
- let data = '';
632
- req.on('data', (chunk) => { data += chunk; });
633
- req.on('end', () => resolve(data));
634
- });
635
- const orderData = JSON.parse(body);
636
- result = await orderApi.create(orderData);
637
- res.writeHead(HTTP_STATUS.OK, { 'Content-Type': 'application/json' });
638
- res.end(JSON.stringify({ success: true, data: result }));
639
- }
640
- else if (req.method === 'PUT') {
641
- if (req.url.includes('/status')) {
642
- const orderId = req.url.split('/')[3];
643
- const body = await new Promise((resolve) => {
644
- let data = '';
645
- req.on('data', (chunk) => { data += chunk; });
646
- req.on('end', () => resolve(data));
647
- });
648
- const { status } = JSON.parse(body);
649
- result = await orderApi.updateStatus(status, orderId);
650
- }
651
- else {
652
- const body = await new Promise((resolve) => {
653
- let data = '';
654
- req.on('data', (chunk) => { data += chunk; });
655
- req.on('end', () => resolve(data));
656
- });
657
- const orderData = JSON.parse(body);
658
- const orderId = req.url.split('/').pop();
659
- result = await orderApi.updateData(orderData, orderId);
660
- }
661
- res.writeHead(HTTP_STATUS.OK, { 'Content-Type': 'application/json' });
662
- res.end(JSON.stringify({ success: true, data: result }));
663
- }
664
- }
665
- catch (error) {
666
- res.writeHead(HTTP_STATUS.SERVER_ERROR, { 'Content-Type': 'application/json' });
667
- res.end(JSON.stringify({ success: false, error: error.message || 'API error' }));
668
- }
669
- }
670
- /**
671
- * Handler for custom data API using CustomDataApi service
672
- */
673
- async function handleCustomDataEndpoint(req, res, apiKey, agentId) {
674
- const customDataApi = new CustomDataApi(BASE_URLS.API, apiKey, agentId);
675
- try {
676
- let result;
677
- const pathParts = req.url.split('/');
678
- const collectionName = pathParts[3]; // /api/custom-data/{collection}
679
- if (req.method === 'GET') {
680
- if (req.url.includes('/search')) {
681
- const url = new URL(req.url, 'http://localhost');
682
- const searchText = url.searchParams.get('searchText') || '';
683
- const limit = parseInt(url.searchParams.get('limit') || '10');
684
- const scoreThreshold = parseFloat(url.searchParams.get('scoreThreshold') || '0.7');
685
- result = await customDataApi.search(collectionName, searchText, limit, scoreThreshold);
686
- }
687
- else if (pathParts.length > 4) {
688
- const entryId = pathParts[4];
689
- result = await customDataApi.getEntry(collectionName, entryId);
690
- }
691
- else {
692
- const url = new URL(req.url, 'http://localhost');
693
- const filter = url.searchParams.get('filter') ? JSON.parse(url.searchParams.get('filter')) : undefined;
694
- const page = parseInt(url.searchParams.get('page') || '1');
695
- const limit = parseInt(url.searchParams.get('limit') || '10');
696
- result = await customDataApi.get(collectionName, filter, page, limit);
697
- }
698
- res.writeHead(HTTP_STATUS.OK, { 'Content-Type': 'application/json' });
699
- res.end(JSON.stringify({ success: true, data: result }));
700
- }
701
- else if (req.method === 'POST') {
702
- const body = await new Promise((resolve) => {
703
- let data = '';
704
- req.on('data', (chunk) => { data += chunk; });
705
- req.on('end', () => resolve(data));
706
- });
707
- const { data, searchText } = JSON.parse(body);
708
- result = await customDataApi.create(collectionName, data, searchText);
709
- res.writeHead(HTTP_STATUS.OK, { 'Content-Type': 'application/json' });
710
- res.end(JSON.stringify({ success: true, data: result }));
711
- }
712
- else if (req.method === 'PUT') {
713
- const entryId = pathParts[4];
714
- const body = await new Promise((resolve) => {
715
- let data = '';
716
- req.on('data', (chunk) => { data += chunk; });
717
- req.on('end', () => resolve(data));
718
- });
719
- const updateData = JSON.parse(body);
720
- result = await customDataApi.update(collectionName, entryId, updateData.data, updateData.searchText);
721
- res.writeHead(HTTP_STATUS.OK, { 'Content-Type': 'application/json' });
722
- res.end(JSON.stringify({ success: true, data: result }));
723
- }
724
- else if (req.method === 'DELETE') {
725
- const entryId = pathParts[4];
726
- result = await customDataApi.delete(collectionName, entryId);
727
- res.writeHead(HTTP_STATUS.OK, { 'Content-Type': 'application/json' });
728
- res.end(JSON.stringify({ success: true, data: result }));
729
- }
730
- }
731
- catch (error) {
732
- res.writeHead(HTTP_STATUS.SERVER_ERROR, { 'Content-Type': 'application/json' });
733
- res.end(JSON.stringify({ success: false, error: error.message || 'API error' }));
734
- }
735
- }
736
- //# sourceMappingURL=dev-server.js.map