|
|
import swaggerJSDoc from 'swagger-jsdoc'; |
|
|
import path from 'path'; |
|
|
import fs from 'fs'; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const isRunningFromDist = __dirname.includes('dist'); |
|
|
const projectRoot = isRunningFromDist |
|
|
? path.resolve(__dirname, '../..') |
|
|
: path.resolve(__dirname, '..'); |
|
|
|
|
|
|
|
|
const routesPath = path.join(projectRoot, 'src/routes/*.ts'); |
|
|
|
|
|
console.log(`π Swagger looking for routes at: ${routesPath}`); |
|
|
console.log(`π Running from: ${isRunningFromDist ? 'dist' : 'src'}`); |
|
|
console.log(`π Project root: ${projectRoot}`); |
|
|
|
|
|
|
|
|
try { |
|
|
const routesDir = path.join(projectRoot, 'src/routes'); |
|
|
if (fs.existsSync(routesDir)) { |
|
|
const files = fs.readdirSync(routesDir); |
|
|
console.log(`π Found ${files.length} route files in ${routesDir}`); |
|
|
const tsFiles = files.filter(f => f.endsWith('.ts')); |
|
|
console.log(`π TypeScript route files: ${tsFiles.length}`); |
|
|
} else { |
|
|
console.warn(`β οΈ Routes directory not found: ${routesDir}`); |
|
|
} |
|
|
|
|
|
|
|
|
const testPattern = path.join(projectRoot, 'src/routes/*.ts'); |
|
|
console.log(`π Using pattern: ${testPattern}`); |
|
|
} catch (error) { |
|
|
console.warn('β οΈ Could not check routes directory:', error); |
|
|
} |
|
|
|
|
|
export const swaggerSpec = swaggerJSDoc({ |
|
|
definition: { |
|
|
openapi: '3.0.0', |
|
|
info: { |
|
|
title: 'Zurri API', |
|
|
version: '1.0.0', |
|
|
description: 'Zurri Agents Marketplace API with Wallet Point System', |
|
|
}, |
|
|
servers: [ |
|
|
{ |
|
|
url: process.env.API_BASE_URL || '/api', |
|
|
description: 'API Server' |
|
|
}, |
|
|
], |
|
|
components: { |
|
|
securitySchemes: { |
|
|
bearerAuth: { |
|
|
type: 'http', |
|
|
scheme: 'bearer', |
|
|
bearerFormat: 'JWT', |
|
|
}, |
|
|
}, |
|
|
schemas: { |
|
|
Agent: { |
|
|
type: 'object', |
|
|
properties: { |
|
|
id: { |
|
|
type: 'string', |
|
|
format: 'uuid', |
|
|
}, |
|
|
name: { |
|
|
type: 'string', |
|
|
example: 'PixelPainter', |
|
|
}, |
|
|
description: { |
|
|
type: 'string', |
|
|
example: 'I turn prompts into AI art!', |
|
|
}, |
|
|
endpoint: { |
|
|
type: 'string', |
|
|
format: 'uri', |
|
|
example: 'https://api.pixelpainter.ai/run', |
|
|
}, |
|
|
avatar: { |
|
|
type: 'string', |
|
|
format: 'uri', |
|
|
nullable: true, |
|
|
description: 'IPFS gateway URL for avatar image', |
|
|
}, |
|
|
category: { |
|
|
type: 'string', |
|
|
example: 'image generation', |
|
|
}, |
|
|
reputation: { |
|
|
type: 'number', |
|
|
format: 'float', |
|
|
example: 4.8, |
|
|
}, |
|
|
capabilities: { |
|
|
type: 'array', |
|
|
items: { |
|
|
type: 'string', |
|
|
}, |
|
|
example: ['text-to-image', 'image-editing'], |
|
|
}, |
|
|
pointsPerTask: { |
|
|
type: 'number', |
|
|
format: 'float', |
|
|
example: 10, |
|
|
}, |
|
|
status: { |
|
|
type: 'string', |
|
|
enum: ['pending', 'approved', 'rejected', 'suspended'], |
|
|
}, |
|
|
usageCount: { |
|
|
type: 'integer', |
|
|
example: 0, |
|
|
}, |
|
|
rating: { |
|
|
type: 'number', |
|
|
format: 'float', |
|
|
nullable: true, |
|
|
}, |
|
|
ratingCount: { |
|
|
type: 'integer', |
|
|
example: 0, |
|
|
}, |
|
|
creatorId: { |
|
|
type: 'string', |
|
|
format: 'uuid', |
|
|
}, |
|
|
createdAt: { |
|
|
type: 'string', |
|
|
format: 'date-time', |
|
|
}, |
|
|
updatedAt: { |
|
|
type: 'string', |
|
|
format: 'date-time', |
|
|
}, |
|
|
}, |
|
|
}, |
|
|
ChatMessage: { |
|
|
type: 'object', |
|
|
properties: { |
|
|
id: { |
|
|
type: 'string', |
|
|
format: 'uuid', |
|
|
}, |
|
|
role: { |
|
|
type: 'string', |
|
|
enum: ['user', 'assistant', 'system'], |
|
|
description: 'Message role (user = user message, assistant = agent response, system = system message)', |
|
|
}, |
|
|
content: { |
|
|
type: 'string', |
|
|
description: 'Message content', |
|
|
}, |
|
|
agentId: { |
|
|
type: 'string', |
|
|
format: 'uuid', |
|
|
}, |
|
|
userId: { |
|
|
type: 'string', |
|
|
format: 'uuid', |
|
|
nullable: true, |
|
|
}, |
|
|
conversationId: { |
|
|
type: 'string', |
|
|
nullable: true, |
|
|
description: 'Conversation ID this message belongs to', |
|
|
}, |
|
|
metadata: { |
|
|
type: 'object', |
|
|
description: 'Additional message metadata (files, IPFS hashes, etc.)', |
|
|
additionalProperties: true, |
|
|
}, |
|
|
createdAt: { |
|
|
type: 'string', |
|
|
format: 'date-time', |
|
|
}, |
|
|
}, |
|
|
}, |
|
|
ChatResponse: { |
|
|
type: 'object', |
|
|
properties: { |
|
|
response: { |
|
|
type: 'string', |
|
|
description: 'Agent\'s response message', |
|
|
}, |
|
|
conversationId: { |
|
|
type: 'string', |
|
|
description: 'Conversation ID for this chat session', |
|
|
}, |
|
|
metadata: { |
|
|
type: 'object', |
|
|
description: 'Additional response metadata from agent', |
|
|
additionalProperties: true, |
|
|
}, |
|
|
}, |
|
|
}, |
|
|
User: { |
|
|
type: 'object', |
|
|
properties: { |
|
|
id: { |
|
|
type: 'string', |
|
|
format: 'uuid', |
|
|
description: 'User ID', |
|
|
}, |
|
|
email: { |
|
|
type: 'string', |
|
|
format: 'email', |
|
|
description: 'User email address', |
|
|
}, |
|
|
name: { |
|
|
type: 'string', |
|
|
nullable: true, |
|
|
description: 'User display name', |
|
|
}, |
|
|
isAdmin: { |
|
|
type: 'boolean', |
|
|
default: false, |
|
|
description: 'Whether user has admin privileges', |
|
|
}, |
|
|
isCreator: { |
|
|
type: 'boolean', |
|
|
default: false, |
|
|
description: 'Whether user can create and manage agents', |
|
|
}, |
|
|
isActive: { |
|
|
type: 'boolean', |
|
|
default: true, |
|
|
description: 'Whether user account is active', |
|
|
}, |
|
|
createdAt: { |
|
|
type: 'string', |
|
|
format: 'date-time', |
|
|
description: 'Account creation timestamp', |
|
|
}, |
|
|
updatedAt: { |
|
|
type: 'string', |
|
|
format: 'date-time', |
|
|
description: 'Last update timestamp', |
|
|
}, |
|
|
}, |
|
|
}, |
|
|
}, |
|
|
}, |
|
|
security: [{ bearerAuth: [] }], |
|
|
}, |
|
|
apis: [routesPath], |
|
|
}); |
|
|
|
|
|
|
|
|
try { |
|
|
const spec = swaggerSpec as any; |
|
|
const paths = spec.paths ? Object.keys(spec.paths) : []; |
|
|
console.log(`π Swagger spec generated with ${paths.length} endpoints`); |
|
|
if (paths.length === 0) { |
|
|
console.warn('β οΈ No endpoints found in Swagger spec. Check route files.'); |
|
|
} |
|
|
} catch (error) { |
|
|
console.error('β Error generating Swagger spec:', error); |
|
|
} |
|
|
|