diff --git a/packages/ipuaro/README.md b/packages/ipuaro/README.md index 79340ab..068e952 100644 --- a/packages/ipuaro/README.md +++ b/packages/ipuaro/README.md @@ -151,6 +151,23 @@ ipuaro --model qwen2.5-coder:32b-instruct ipuaro --auto-apply ``` +## Quick Start + +Try ipuaro with our demo project: + +```bash +# Navigate to demo project +cd examples/demo-project + +# Install dependencies +npm install + +# Start ipuaro +npx @samiyev/ipuaro +``` + +See [examples/demo-project](./examples/demo-project) for detailed usage guide and example conversations. + ## Commands | Command | Description | diff --git a/packages/ipuaro/examples/demo-project/.gitignore b/packages/ipuaro/examples/demo-project/.gitignore new file mode 100644 index 0000000..dd6e803 --- /dev/null +++ b/packages/ipuaro/examples/demo-project/.gitignore @@ -0,0 +1,4 @@ +node_modules/ +dist/ +*.log +.DS_Store diff --git a/packages/ipuaro/examples/demo-project/.ipuaro.json b/packages/ipuaro/examples/demo-project/.ipuaro.json new file mode 100644 index 0000000..0c08765 --- /dev/null +++ b/packages/ipuaro/examples/demo-project/.ipuaro.json @@ -0,0 +1,21 @@ +{ + "redis": { + "host": "localhost", + "port": 6379 + }, + "llm": { + "model": "qwen2.5-coder:7b-instruct", + "temperature": 0.1 + }, + "project": { + "ignorePatterns": [ + "node_modules", + "dist", + ".git", + "*.log" + ] + }, + "edit": { + "autoApply": false + } +} diff --git a/packages/ipuaro/examples/demo-project/EXAMPLE_CONVERSATIONS.md b/packages/ipuaro/examples/demo-project/EXAMPLE_CONVERSATIONS.md new file mode 100644 index 0000000..73e02b7 --- /dev/null +++ b/packages/ipuaro/examples/demo-project/EXAMPLE_CONVERSATIONS.md @@ -0,0 +1,8 @@ +# Example Conversations with ipuaro + +This document shows realistic conversations you can have with ipuaro when working with the demo project. + +## Conversation 1: Understanding the Codebase + +``` +You: What does this project do? \ No newline at end of file diff --git a/packages/ipuaro/examples/demo-project/README.md b/packages/ipuaro/examples/demo-project/README.md new file mode 100644 index 0000000..2c268f2 --- /dev/null +++ b/packages/ipuaro/examples/demo-project/README.md @@ -0,0 +1,406 @@ +# ipuaro Demo Project + +This is a demo project showcasing ipuaro's capabilities as a local AI agent for codebase operations. + +## Project Overview + +A simple TypeScript application demonstrating: +- User management service +- Authentication service +- Validation utilities +- Logging utilities +- Unit tests + +The code intentionally includes various patterns (TODOs, FIXMEs, complex functions, dependencies) to demonstrate ipuaro's analysis tools. + +## Setup + +### Prerequisites + +1. **Redis** - Running locally +```bash +# macOS +brew install redis +redis-server --appendonly yes +``` + +2. **Ollama** - With qwen2.5-coder model +```bash +brew install ollama +ollama serve +ollama pull qwen2.5-coder:7b-instruct +``` + +3. **Node.js** - v20 or higher + +### Installation + +```bash +# Install dependencies +npm install + +# Or with pnpm +pnpm install +``` + +## Using ipuaro with Demo Project + +### Start ipuaro + +```bash +# From this directory +npx @samiyev/ipuaro + +# Or if installed globally +ipuaro +``` + +### Example Queries + +Try these queries to explore ipuaro's capabilities: + +#### 1. Understanding the Codebase + +``` +You: What is the structure of this project? +``` + +ipuaro will use `get_structure` to show the directory tree. + +``` +You: How does user creation work? +``` + +ipuaro will: +1. Use `get_structure` to find relevant files +2. Use `get_function` to read the `createUser` function +3. Use `find_references` to see where it's called +4. Explain the flow + +#### 2. Finding Issues + +``` +You: What TODOs and FIXMEs are in the codebase? +``` + +ipuaro will use `get_todos` to list all TODO/FIXME comments. + +``` +You: Which files are most complex? +``` + +ipuaro will use `get_complexity` to analyze and rank files by complexity. + +#### 3. Understanding Dependencies + +``` +You: What does the UserService depend on? +``` + +ipuaro will use `get_dependencies` to show imported modules. + +``` +You: What files use the validation utilities? +``` + +ipuaro will use `get_dependents` to show files importing validation.ts. + +#### 4. Code Analysis + +``` +You: Find all references to the ValidationError class +``` + +ipuaro will use `find_references` to locate all usages. + +``` +You: Where is the Logger class defined? +``` + +ipuaro will use `find_definition` to locate the definition. + +#### 5. Making Changes + +``` +You: Add a method to UserService to count total users +``` + +ipuaro will: +1. Read UserService class with `get_class` +2. Generate the new method +3. Use `edit_lines` to add it +4. Show diff and ask for confirmation + +``` +You: Fix the TODO in validation.ts about password validation +``` + +ipuaro will: +1. Find the TODO with `get_todos` +2. Read the function with `get_function` +3. Implement stronger password validation +4. Use `edit_lines` to apply changes + +#### 6. Testing + +``` +You: Run the tests +``` + +ipuaro will use `run_tests` to execute the test suite. + +``` +You: Add a test for the getUserByEmail method +``` + +ipuaro will: +1. Read existing tests with `get_lines` +2. Generate new test following the pattern +3. Use `edit_lines` to add it + +#### 7. Git Operations + +``` +You: What files have I changed? +``` + +ipuaro will use `git_status` to show modified files. + +``` +You: Show me the diff for UserService +``` + +ipuaro will use `git_diff` with the file path. + +``` +You: Commit these changes with message "feat: add user count method" +``` + +ipuaro will use `git_commit` after confirmation. + +## Tool Demonstration Scenarios + +### Scenario 1: Bug Fix Flow + +``` +You: There's a bug - we need to sanitize user input before storing. Fix this in UserService. + +Agent will: +1. get_function("src/services/user.ts", "createUser") +2. See that sanitization is missing +3. find_definition("sanitizeInput") to locate the utility +4. edit_lines to add sanitization call +5. run_tests to verify the fix +``` + +### Scenario 2: Refactoring Flow + +``` +You: Extract the ID generation logic into a separate utility function + +Agent will: +1. get_class("src/services/user.ts", "UserService") +2. Find generateId private method +3. create_file("src/utils/id.ts") with the utility +4. edit_lines to replace private method with import +5. find_references("generateId") to check no other usages +6. run_tests to ensure nothing broke +``` + +### Scenario 3: Feature Addition + +``` +You: Add password reset functionality to AuthService + +Agent will: +1. get_class("src/auth/service.ts", "AuthService") +2. get_dependencies to see what's available +3. Design the resetPassword method +4. edit_lines to add the method +5. Suggest creating a test +6. create_file("tests/auth.test.ts") if needed +``` + +### Scenario 4: Code Review + +``` +You: Review the code for security issues + +Agent will: +1. get_todos to find FIXME about XSS +2. get_complexity to find complex functions +3. get_function for suspicious functions +4. Suggest improvements +5. Optionally edit_lines to fix issues +``` + +## Slash Commands + +While exploring, you can use these commands: + +``` +/help # Show all commands and hotkeys +/status # Show system status (LLM, Redis, context) +/sessions list # List all sessions +/undo # Undo last file change +/clear # Clear chat history +/reindex # Force project reindexation +/auto-apply on # Enable auto-apply mode (skip confirmations) +``` + +## Hotkeys + +- `Ctrl+C` - Interrupt generation (1st) / Exit (2nd within 1s) +- `Ctrl+D` - Exit and save session +- `Ctrl+Z` - Undo last change +- `↑` / `↓` - Navigate input history + +## Project Files Overview + +``` +demo-project/ +├── src/ +│ ├── auth/ +│ │ └── service.ts # Authentication logic (login, logout, verify) +│ ├── services/ +│ │ └── user.ts # User CRUD operations +│ ├── utils/ +│ │ ├── logger.ts # Logging utility (multiple methods) +│ │ └── validation.ts # Input validation (with TODOs/FIXMEs) +│ ├── types/ +│ │ └── user.ts # TypeScript type definitions +│ └── index.ts # Application entry point +├── tests/ +│ └── user.test.ts # User service tests (vitest) +├── package.json # Project configuration +├── tsconfig.json # TypeScript configuration +├── vitest.config.ts # Test configuration +└── .ipuaro.json # ipuaro configuration +``` + +## What ipuaro Can Do With This Project + +### Read Tools ✅ +- **get_lines**: Read any file or specific line ranges +- **get_function**: Extract specific functions (login, createUser, etc.) +- **get_class**: Extract classes (UserService, AuthService, Logger, etc.) +- **get_structure**: See directory tree + +### Edit Tools ✅ +- **edit_lines**: Modify functions, fix bugs, add features +- **create_file**: Add new utilities, tests, services +- **delete_file**: Remove unused files + +### Search Tools ✅ +- **find_references**: Find all usages of ValidationError, User, etc. +- **find_definition**: Locate where Logger, UserService are defined + +### Analysis Tools ✅ +- **get_dependencies**: See what UserService imports +- **get_dependents**: See what imports validation.ts (multiple files!) +- **get_complexity**: Identify complex functions (createUser has moderate complexity) +- **get_todos**: Find 2 TODOs and 1 FIXME in the project + +### Git Tools ✅ +- **git_status**: Check working tree +- **git_diff**: See changes +- **git_commit**: Commit with AI-generated messages + +### Run Tools ✅ +- **run_command**: Execute npm scripts +- **run_tests**: Run vitest tests + +## Tips for Best Experience + +1. **Start Small**: Ask about structure first, then dive into specific files +2. **Be Specific**: "Show me the createUser function" vs "How does this work?" +3. **Use Tools Implicitly**: Just ask questions, let ipuaro choose the right tools +4. **Review Changes**: Always review diffs before applying edits +5. **Test Often**: Ask ipuaro to run tests after making changes +6. **Commit Incrementally**: Use git_commit for each logical change + +## Advanced Workflows + +### Workflow 1: Add New Feature + +``` +You: Add email verification to the authentication flow + +Agent will: +1. Analyze current auth flow +2. Propose design (new fields, methods) +3. Edit AuthService to add verification +4. Edit User types to add verified field +5. Create tests for verification +6. Run tests +7. Offer to commit +``` + +### Workflow 2: Performance Optimization + +``` +You: The user lookup is slow when we have many users. Optimize it. + +Agent will: +1. Analyze UserService.getUserByEmail +2. See it's using Array.find (O(n)) +3. Suggest adding an email index +4. Edit to add private emailIndex: Map +5. Update createUser to populate index +6. Update deleteUser to maintain index +7. Run tests to verify +``` + +### Workflow 3: Security Audit + +``` +You: Audit the code for security vulnerabilities + +Agent will: +1. get_todos to find FIXME about XSS +2. Review sanitizeInput implementation +3. Check password validation strength +4. Look for SQL injection risks (none here) +5. Suggest improvements +6. Optionally implement fixes +``` + +## Next Steps + +After exploring the demo project, try: + +1. **Your Own Project**: Run `ipuaro` in your real codebase +2. **Customize Config**: Edit `.ipuaro.json` to fit your needs +3. **Different Model**: Try `--model qwen2.5-coder:32b-instruct` for better results +4. **Auto-Apply Mode**: Use `--auto-apply` for faster iterations (with caution!) + +## Troubleshooting + +### Redis Not Connected +```bash +# Start Redis with persistence +redis-server --appendonly yes +``` + +### Ollama Model Not Found +```bash +# Pull the model +ollama pull qwen2.5-coder:7b-instruct + +# Check it's installed +ollama list +``` + +### Indexing Takes Long +The project is small (~10 files) so indexing should be instant. For larger projects, use ignore patterns in `.ipuaro.json`. + +## Learn More + +- [ipuaro Documentation](../../README.md) +- [Architecture Guide](../../ARCHITECTURE.md) +- [Tools Reference](../../TOOLS.md) +- [GitHub Repository](https://github.com/samiyev/puaros) + +--- + +**Happy coding with ipuaro!** 🎩✨ diff --git a/packages/ipuaro/examples/demo-project/package.json b/packages/ipuaro/examples/demo-project/package.json new file mode 100644 index 0000000..03778ae --- /dev/null +++ b/packages/ipuaro/examples/demo-project/package.json @@ -0,0 +1,20 @@ +{ + "name": "ipuaro-demo-project", + "version": "1.0.0", + "description": "Demo project for ipuaro - showcasing AI agent capabilities", + "private": true, + "type": "module", + "scripts": { + "dev": "tsx src/index.ts", + "test": "vitest", + "test:run": "vitest run", + "build": "tsc" + }, + "dependencies": {}, + "devDependencies": { + "@types/node": "^22.10.1", + "tsx": "^4.19.2", + "typescript": "^5.7.2", + "vitest": "^1.6.0" + } +} diff --git a/packages/ipuaro/examples/demo-project/src/auth/service.ts b/packages/ipuaro/examples/demo-project/src/auth/service.ts new file mode 100644 index 0000000..92338fa --- /dev/null +++ b/packages/ipuaro/examples/demo-project/src/auth/service.ts @@ -0,0 +1,85 @@ +/** + * Authentication service + */ + +import type { User, AuthToken } from "../types/user" +import { UserService } from "../services/user" +import { createLogger } from "../utils/logger" + +const logger = createLogger("AuthService") + +export class AuthService { + private tokens: Map = new Map() + + constructor(private userService: UserService) {} + + async login(email: string, password: string): Promise { + logger.info("Login attempt", { email }) + + // Get user + const user = await this.userService.getUserByEmail(email) + if (!user) { + logger.warn("Login failed - user not found", { email }) + throw new Error("Invalid credentials") + } + + // TODO: Implement actual password verification + // For demo purposes, we just check if password is provided + if (!password) { + logger.warn("Login failed - no password", { email }) + throw new Error("Invalid credentials") + } + + // Generate token + const token = this.generateToken(user) + this.tokens.set(token.token, token) + + logger.info("Login successful", { userId: user.id }) + return token + } + + async logout(tokenString: string): Promise { + logger.info("Logout", { token: tokenString.substring(0, 10) + "..." }) + + const token = this.tokens.get(tokenString) + if (!token) { + throw new Error("Invalid token") + } + + this.tokens.delete(tokenString) + logger.info("Logout successful", { userId: token.userId }) + } + + async verifyToken(tokenString: string): Promise { + logger.debug("Verifying token") + + const token = this.tokens.get(tokenString) + if (!token) { + throw new Error("Invalid token") + } + + if (token.expiresAt < new Date()) { + this.tokens.delete(tokenString) + throw new Error("Token expired") + } + + const user = await this.userService.getUserById(token.userId) + if (!user) { + throw new Error("User not found") + } + + return user + } + + private generateToken(user: User): AuthToken { + const token = `tok_${Date.now()}_${Math.random().toString(36).substring(7)}` + const expiresAt = new Date() + expiresAt.setHours(expiresAt.getHours() + 24) // 24 hours + + return { + token, + expiresAt, + userId: user.id + } + } +} diff --git a/packages/ipuaro/examples/demo-project/src/index.ts b/packages/ipuaro/examples/demo-project/src/index.ts new file mode 100644 index 0000000..038596d --- /dev/null +++ b/packages/ipuaro/examples/demo-project/src/index.ts @@ -0,0 +1,48 @@ +/** + * Demo application entry point + */ + +import { UserService } from "./services/user" +import { AuthService } from "./auth/service" +import { createLogger } from "./utils/logger" + +const logger = createLogger("App") + +async function main(): Promise { + logger.info("Starting demo application") + + // Initialize services + const userService = new UserService() + const authService = new AuthService(userService) + + try { + // Create a demo user + const user = await userService.createUser({ + email: "demo@example.com", + name: "Demo User", + password: "password123", + role: "admin" + }) + + logger.info("Demo user created", { userId: user.id }) + + // Login + const token = await authService.login("demo@example.com", "password123") + logger.info("Login successful", { token: token.token }) + + // Verify token + const verifiedUser = await authService.verifyToken(token.token) + logger.info("Token verified", { userId: verifiedUser.id }) + + // Logout + await authService.logout(token.token) + logger.info("Logout successful") + } catch (error) { + logger.error("Application error", error as Error) + process.exit(1) + } + + logger.info("Demo application finished") +} + +main() diff --git a/packages/ipuaro/examples/demo-project/src/services/user.ts b/packages/ipuaro/examples/demo-project/src/services/user.ts new file mode 100644 index 0000000..9da7571 --- /dev/null +++ b/packages/ipuaro/examples/demo-project/src/services/user.ts @@ -0,0 +1,102 @@ +/** + * User service - handles user-related operations + */ + +import type { User, CreateUserDto, UpdateUserDto } from "../types/user" +import { isValidEmail, isStrongPassword, ValidationError } from "../utils/validation" +import { createLogger } from "../utils/logger" + +const logger = createLogger("UserService") + +export class UserService { + private users: Map = new Map() + + async createUser(dto: CreateUserDto): Promise { + logger.info("Creating user", { email: dto.email }) + + // Validate email + if (!isValidEmail(dto.email)) { + throw new ValidationError("Invalid email address", "email") + } + + // Validate password + if (!isStrongPassword(dto.password)) { + throw new ValidationError("Password must be at least 8 characters", "password") + } + + // Check if user already exists + const existingUser = Array.from(this.users.values()).find( + (u) => u.email === dto.email + ) + + if (existingUser) { + throw new Error("User with this email already exists") + } + + // Create user + const user: User = { + id: this.generateId(), + email: dto.email, + name: dto.name, + role: dto.role || "user", + createdAt: new Date(), + updatedAt: new Date() + } + + this.users.set(user.id, user) + logger.info("User created", { userId: user.id }) + + return user + } + + async getUserById(id: string): Promise { + logger.debug("Getting user by ID", { userId: id }) + return this.users.get(id) || null + } + + async getUserByEmail(email: string): Promise { + logger.debug("Getting user by email", { email }) + return Array.from(this.users.values()).find((u) => u.email === email) || null + } + + async updateUser(id: string, dto: UpdateUserDto): Promise { + logger.info("Updating user", { userId: id }) + + const user = this.users.get(id) + if (!user) { + throw new Error("User not found") + } + + const updated: User = { + ...user, + ...(dto.name && { name: dto.name }), + ...(dto.role && { role: dto.role }), + updatedAt: new Date() + } + + this.users.set(id, updated) + logger.info("User updated", { userId: id }) + + return updated + } + + async deleteUser(id: string): Promise { + logger.info("Deleting user", { userId: id }) + + if (!this.users.has(id)) { + throw new Error("User not found") + } + + this.users.delete(id) + logger.info("User deleted", { userId: id }) + } + + async listUsers(): Promise { + logger.debug("Listing all users") + return Array.from(this.users.values()) + } + + private generateId(): string { + return `user_${Date.now()}_${Math.random().toString(36).substring(7)}` + } +} diff --git a/packages/ipuaro/examples/demo-project/src/types/user.ts b/packages/ipuaro/examples/demo-project/src/types/user.ts new file mode 100644 index 0000000..d5d9dda --- /dev/null +++ b/packages/ipuaro/examples/demo-project/src/types/user.ts @@ -0,0 +1,32 @@ +/** + * User-related type definitions + */ + +export interface User { + id: string + email: string + name: string + role: UserRole + createdAt: Date + updatedAt: Date +} + +export type UserRole = "admin" | "user" | "guest" + +export interface CreateUserDto { + email: string + name: string + password: string + role?: UserRole +} + +export interface UpdateUserDto { + name?: string + role?: UserRole +} + +export interface AuthToken { + token: string + expiresAt: Date + userId: string +} diff --git a/packages/ipuaro/examples/demo-project/src/utils/logger.ts b/packages/ipuaro/examples/demo-project/src/utils/logger.ts new file mode 100644 index 0000000..a563457 --- /dev/null +++ b/packages/ipuaro/examples/demo-project/src/utils/logger.ts @@ -0,0 +1,41 @@ +/** + * Simple logging utility + */ + +export type LogLevel = "debug" | "info" | "warn" | "error" + +export class Logger { + constructor(private context: string) {} + + debug(message: string, meta?: Record): void { + this.log("debug", message, meta) + } + + info(message: string, meta?: Record): void { + this.log("info", message, meta) + } + + warn(message: string, meta?: Record): void { + this.log("warn", message, meta) + } + + error(message: string, error?: Error, meta?: Record): void { + this.log("error", message, { ...meta, error: error?.message }) + } + + private log(level: LogLevel, message: string, meta?: Record): void { + const timestamp = new Date().toISOString() + const logEntry = { + timestamp, + level, + context: this.context, + message, + ...(meta && { meta }) + } + console.log(JSON.stringify(logEntry)) + } +} + +export function createLogger(context: string): Logger { + return new Logger(context) +} diff --git a/packages/ipuaro/examples/demo-project/src/utils/validation.ts b/packages/ipuaro/examples/demo-project/src/utils/validation.ts new file mode 100644 index 0000000..c3005bf --- /dev/null +++ b/packages/ipuaro/examples/demo-project/src/utils/validation.ts @@ -0,0 +1,28 @@ +/** + * Validation utilities + */ + +export function isValidEmail(email: string): boolean { + const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/ + return emailRegex.test(email) +} + +export function isStrongPassword(password: string): boolean { + // TODO: Add more sophisticated password validation + return password.length >= 8 +} + +export function sanitizeInput(input: string): string { + // FIXME: This is a basic implementation, needs XSS protection + return input.trim().replace(/[<>]/g, "") +} + +export class ValidationError extends Error { + constructor( + message: string, + public field: string + ) { + super(message) + this.name = "ValidationError" + } +} diff --git a/packages/ipuaro/examples/demo-project/tests/user.test.ts b/packages/ipuaro/examples/demo-project/tests/user.test.ts new file mode 100644 index 0000000..7bfabb5 --- /dev/null +++ b/packages/ipuaro/examples/demo-project/tests/user.test.ts @@ -0,0 +1,141 @@ +/** + * User service tests + */ + +import { describe, it, expect, beforeEach } from "vitest" +import { UserService } from "../src/services/user" +import { ValidationError } from "../src/utils/validation" + +describe("UserService", () => { + let userService: UserService + + beforeEach(() => { + userService = new UserService() + }) + + describe("createUser", () => { + it("should create a new user", async () => { + const user = await userService.createUser({ + email: "test@example.com", + name: "Test User", + password: "password123" + }) + + expect(user).toBeDefined() + expect(user.email).toBe("test@example.com") + expect(user.name).toBe("Test User") + expect(user.role).toBe("user") + }) + + it("should reject invalid email", async () => { + await expect( + userService.createUser({ + email: "invalid-email", + name: "Test User", + password: "password123" + }) + ).rejects.toThrow(ValidationError) + }) + + it("should reject weak password", async () => { + await expect( + userService.createUser({ + email: "test@example.com", + name: "Test User", + password: "weak" + }) + ).rejects.toThrow(ValidationError) + }) + + it("should prevent duplicate emails", async () => { + await userService.createUser({ + email: "test@example.com", + name: "Test User", + password: "password123" + }) + + await expect( + userService.createUser({ + email: "test@example.com", + name: "Another User", + password: "password123" + }) + ).rejects.toThrow("already exists") + }) + }) + + describe("getUserById", () => { + it("should return user by ID", async () => { + const created = await userService.createUser({ + email: "test@example.com", + name: "Test User", + password: "password123" + }) + + const found = await userService.getUserById(created.id) + expect(found).toEqual(created) + }) + + it("should return null for non-existent ID", async () => { + const found = await userService.getUserById("non-existent") + expect(found).toBeNull() + }) + }) + + describe("updateUser", () => { + it("should update user name", async () => { + const user = await userService.createUser({ + email: "test@example.com", + name: "Test User", + password: "password123" + }) + + const updated = await userService.updateUser(user.id, { + name: "Updated Name" + }) + + expect(updated.name).toBe("Updated Name") + expect(updated.email).toBe(user.email) + }) + + it("should throw error for non-existent user", async () => { + await expect( + userService.updateUser("non-existent", { name: "Test" }) + ).rejects.toThrow("not found") + }) + }) + + describe("deleteUser", () => { + it("should delete user", async () => { + const user = await userService.createUser({ + email: "test@example.com", + name: "Test User", + password: "password123" + }) + + await userService.deleteUser(user.id) + + const found = await userService.getUserById(user.id) + expect(found).toBeNull() + }) + }) + + describe("listUsers", () => { + it("should return all users", async () => { + await userService.createUser({ + email: "user1@example.com", + name: "User 1", + password: "password123" + }) + + await userService.createUser({ + email: "user2@example.com", + name: "User 2", + password: "password123" + }) + + const users = await userService.listUsers() + expect(users).toHaveLength(2) + }) + }) +}) diff --git a/packages/ipuaro/examples/demo-project/tsconfig.json b/packages/ipuaro/examples/demo-project/tsconfig.json new file mode 100644 index 0000000..536f05b --- /dev/null +++ b/packages/ipuaro/examples/demo-project/tsconfig.json @@ -0,0 +1,16 @@ +{ + "compilerOptions": { + "target": "ES2023", + "module": "ESNext", + "lib": ["ES2023"], + "moduleResolution": "Bundler", + "esModuleInterop": true, + "strict": true, + "skipLibCheck": true, + "resolveJsonModule": true, + "outDir": "dist", + "rootDir": "src" + }, + "include": ["src/**/*"], + "exclude": ["node_modules", "dist", "tests"] +} diff --git a/packages/ipuaro/examples/demo-project/vitest.config.ts b/packages/ipuaro/examples/demo-project/vitest.config.ts new file mode 100644 index 0000000..1e993cb --- /dev/null +++ b/packages/ipuaro/examples/demo-project/vitest.config.ts @@ -0,0 +1,8 @@ +import { defineConfig } from "vitest/config" + +export default defineConfig({ + test: { + globals: true, + environment: "node" + } +})