|
| 1 | +# 开发调试测试指南 | Development, Debugging & Testing Guide |
| 2 | + |
| 3 | +> **English** | [中文](#中文版) |
| 4 | +
|
| 5 | +## Quick Start |
| 6 | + |
| 7 | +### Environment Setup |
| 8 | + |
| 9 | +```bash |
| 10 | +# Clone the repository |
| 11 | +git clone https://github.com/objectstack-ai/spec.git |
| 12 | +cd spec |
| 13 | + |
| 14 | +# Install dependencies and setup (one-time) |
| 15 | +pnpm setup |
| 16 | + |
| 17 | +# Run health check |
| 18 | +pnpm doctor |
| 19 | +``` |
| 20 | + |
| 21 | +### Development Workflow |
| 22 | + |
| 23 | +#### Using the ObjectStack CLI |
| 24 | + |
| 25 | +```bash |
| 26 | +# Build CLI first (if not built) |
| 27 | +pnpm --filter @objectstack/cli build |
| 28 | + |
| 29 | +# Compile configuration to JSON |
| 30 | +pnpm objectstack compile objectstack.config.ts dist/objectstack.json |
| 31 | + |
| 32 | +# Start development mode (watch mode for packages) |
| 33 | +pnpm objectstack dev [package-name] |
| 34 | + |
| 35 | +# Check environment health |
| 36 | +pnpm objectstack doctor |
| 37 | + |
| 38 | +# Create new project |
| 39 | +pnpm objectstack create plugin my-plugin |
| 40 | +pnpm objectstack create example my-app |
| 41 | +``` |
| 42 | + |
| 43 | +#### Common npm Shortcuts |
| 44 | + |
| 45 | +```bash |
| 46 | +# One-time setup |
| 47 | +pnpm setup # Install dependencies and build core packages |
| 48 | + |
| 49 | +# Development |
| 50 | +pnpm dev # Start development mode (default: msw-react-crud example) |
| 51 | +pnpm build # Build all packages |
| 52 | +pnpm test # Run tests |
| 53 | + |
| 54 | +# Diagnostics |
| 55 | +pnpm doctor # Check environment health |
| 56 | + |
| 57 | +# Cleanup |
| 58 | +pnpm clean # Clean build artifacts |
| 59 | +``` |
| 60 | + |
| 61 | +### Package Development |
| 62 | + |
| 63 | +#### Working on @objectstack/spec |
| 64 | + |
| 65 | +```bash |
| 66 | +# Watch mode (auto-rebuild on changes) |
| 67 | +cd packages/spec |
| 68 | +pnpm dev |
| 69 | + |
| 70 | +# Run tests in watch mode |
| 71 | +pnpm test:watch |
| 72 | + |
| 73 | +# Generate schemas and docs |
| 74 | +pnpm gen:schema |
| 75 | +pnpm gen:docs |
| 76 | +``` |
| 77 | + |
| 78 | +#### Creating a New Plugin |
| 79 | + |
| 80 | +```bash |
| 81 | +# Using CLI |
| 82 | +pnpm objectstack create plugin my-feature |
| 83 | + |
| 84 | +# Then develop |
| 85 | +cd packages/plugins/plugin-my-feature |
| 86 | +pnpm install |
| 87 | +pnpm dev |
| 88 | +``` |
| 89 | + |
| 90 | +#### Creating a New Example |
| 91 | + |
| 92 | +```bash |
| 93 | +# Using CLI |
| 94 | +pnpm objectstack create example my-app |
| 95 | + |
| 96 | +# Then develop |
| 97 | +cd examples/my-app |
| 98 | +pnpm install |
| 99 | +pnpm build |
| 100 | +``` |
| 101 | + |
| 102 | +### Testing |
| 103 | + |
| 104 | +#### Unit Tests |
| 105 | + |
| 106 | +```bash |
| 107 | +# Run all tests |
| 108 | +pnpm test |
| 109 | + |
| 110 | +# Run tests for specific package |
| 111 | +pnpm --filter @objectstack/spec test |
| 112 | + |
| 113 | +# Watch mode |
| 114 | +pnpm --filter @objectstack/spec test:watch |
| 115 | + |
| 116 | +# Coverage report |
| 117 | +pnpm --filter @objectstack/spec test:coverage |
| 118 | +``` |
| 119 | + |
| 120 | +#### Integration Tests |
| 121 | + |
| 122 | +```bash |
| 123 | +# Test CRM example |
| 124 | +cd examples/crm |
| 125 | +pnpm build |
| 126 | +pnpm test |
| 127 | +``` |
| 128 | + |
| 129 | +### Debugging |
| 130 | + |
| 131 | +#### VSCode Debugging |
| 132 | + |
| 133 | +Pre-configured launch configurations are available in `.vscode/launch.json`: |
| 134 | + |
| 135 | +1. **Debug Current TypeScript File** - Debug any .ts file |
| 136 | +2. **Debug @objectstack/spec Tests** - Debug spec tests |
| 137 | +3. **Debug CLI (compile)** - Debug compile command |
| 138 | +4. **Debug CLI (doctor)** - Debug doctor command |
| 139 | +5. **Debug Example (CRM)** - Debug CRM example |
| 140 | + |
| 141 | +**To use:** |
| 142 | +1. Open the file you want to debug |
| 143 | +2. Press `F5` or go to Run & Debug panel |
| 144 | +3. Select the appropriate configuration |
| 145 | +4. Set breakpoints and debug |
| 146 | + |
| 147 | +#### Command Line Debugging |
| 148 | + |
| 149 | +```bash |
| 150 | +# Debug with tsx |
| 151 | +tsx --inspect packages/cli/src/bin.ts doctor |
| 152 | + |
| 153 | +# Debug with node |
| 154 | +node --inspect $(which tsx) packages/cli/src/bin.ts compile |
| 155 | +``` |
| 156 | + |
| 157 | +#### Logging |
| 158 | + |
| 159 | +```bash |
| 160 | +# Enable verbose logging |
| 161 | +DEBUG=* pnpm build |
| 162 | + |
| 163 | +# Package-specific logging |
| 164 | +DEBUG=objectstack:* pnpm build |
| 165 | +``` |
| 166 | + |
| 167 | +### Common Tasks |
| 168 | + |
| 169 | +#### Adding a New Protocol Schema |
| 170 | + |
| 171 | +```typescript |
| 172 | +// 1. Create schema file: packages/spec/src/data/my-schema.zod.ts |
| 173 | +import { z } from 'zod'; |
| 174 | + |
| 175 | +/** |
| 176 | + * My new schema |
| 177 | + * @description Detailed description of the schema |
| 178 | + */ |
| 179 | +export const MySchema = z.object({ |
| 180 | + /** Field description */ |
| 181 | + name: z.string().describe('Machine name (snake_case)'), |
| 182 | + |
| 183 | + /** Another field */ |
| 184 | + value: z.number().optional().describe('Optional value'), |
| 185 | +}); |
| 186 | + |
| 187 | +export type MyType = z.infer<typeof MySchema>; |
| 188 | + |
| 189 | +// 2. Export from index |
| 190 | +// packages/spec/src/data/index.ts |
| 191 | +export * from './my-schema.zod.js'; |
| 192 | + |
| 193 | +// 3. Build to generate JSON schema |
| 194 | +pnpm --filter @objectstack/spec build |
| 195 | +``` |
| 196 | + |
| 197 | +#### Running Specific Package Commands |
| 198 | + |
| 199 | +```bash |
| 200 | +# Filter by package name |
| 201 | +pnpm --filter @objectstack/spec <command> |
| 202 | +pnpm --filter @objectstack/cli <command> |
| 203 | + |
| 204 | +# Filter pattern (all plugins) |
| 205 | +pnpm --filter "@objectstack/plugin-*" build |
| 206 | + |
| 207 | +# Run in all packages |
| 208 | +pnpm -r <command> |
| 209 | + |
| 210 | +# Run in parallel |
| 211 | +pnpm -r --parallel <command> |
| 212 | +``` |
| 213 | + |
| 214 | +### Performance Tips |
| 215 | + |
| 216 | +1. **Incremental Builds**: Use watch mode (`pnpm dev`) during development |
| 217 | +2. **Selective Testing**: Test only changed packages |
| 218 | +3. **Parallel Execution**: Use `--parallel` for independent tasks |
| 219 | +4. **Filter Packages**: Use `--filter` to target specific packages |
| 220 | + |
| 221 | +### Troubleshooting |
| 222 | + |
| 223 | +#### Common Issues |
| 224 | + |
| 225 | +**Dependencies not installed:** |
| 226 | +```bash |
| 227 | +pnpm doctor |
| 228 | +pnpm install |
| 229 | +``` |
| 230 | + |
| 231 | +**Build errors:** |
| 232 | +```bash |
| 233 | +# Clean and rebuild |
| 234 | +pnpm clean |
| 235 | +pnpm build |
| 236 | +``` |
| 237 | + |
| 238 | +**Type errors:** |
| 239 | +```bash |
| 240 | +# Ensure spec is built first |
| 241 | +pnpm --filter @objectstack/spec build |
| 242 | +``` |
| 243 | + |
| 244 | +**Watch mode not working:** |
| 245 | +```bash |
| 246 | +# Kill existing processes |
| 247 | +pkill -f "tsc --watch" |
| 248 | +# Restart |
| 249 | +pnpm dev |
| 250 | +``` |
| 251 | + |
| 252 | +#### Getting Help |
| 253 | + |
| 254 | +```bash |
| 255 | +# Check environment |
| 256 | +pnpm doctor |
| 257 | + |
| 258 | +# CLI help |
| 259 | +pnpm objectstack --help |
| 260 | +pnpm objectstack <command> --help |
| 261 | +``` |
| 262 | + |
| 263 | +## Architecture Overview |
| 264 | + |
| 265 | +### Monorepo Structure |
| 266 | + |
| 267 | +``` |
| 268 | +spec/ |
| 269 | +├── packages/ # Core packages |
| 270 | +│ ├── spec/ # Protocol definitions (Zod schemas) |
| 271 | +│ ├── cli/ # Command-line tools |
| 272 | +│ ├── objectql/ # Query engine |
| 273 | +│ ├── client/ # Client SDK |
| 274 | +│ ├── client-react/ # React hooks |
| 275 | +│ └── plugins/ # Plugin implementations |
| 276 | +│ ├── driver-memory/ |
| 277 | +│ ├── plugin-hono-server/ |
| 278 | +│ └── plugin-msw/ |
| 279 | +├── examples/ # Example applications |
| 280 | +│ ├── crm/ # Full CRM example |
| 281 | +│ ├── todo/ # Simple todo example |
| 282 | +│ └── ... |
| 283 | +├── apps/ # Applications |
| 284 | +│ └── docs/ # Documentation site |
| 285 | +└── packages/cli/ # Command-line tools |
| 286 | + ├── src/commands/ # CLI commands (dev, doctor, create, compile, serve) |
| 287 | + └── bin/ # Executable entry points |
| 288 | +``` |
| 289 | + |
| 290 | +### Starting a Server |
| 291 | + |
| 292 | +The `serve` command starts an ObjectStack server with plugins loaded from your configuration: |
| 293 | + |
| 294 | +```bash |
| 295 | +# Start server with default config |
| 296 | +pnpm objectstack serve |
| 297 | + |
| 298 | +# Start with custom config and port |
| 299 | +pnpm objectstack serve objectstack.config.ts --port 8080 |
| 300 | + |
| 301 | +# Start without HTTP server plugin (headless mode) |
| 302 | +pnpm objectstack serve --no-server |
| 303 | +``` |
| 304 | + |
| 305 | +**Configuration Example:** |
| 306 | + |
| 307 | +```typescript |
| 308 | +// objectstack.config.ts |
| 309 | +import { defineStack } from '@objectstack/spec'; |
| 310 | +import { HonoServerPlugin } from '@objectstack/plugin-hono-server'; |
| 311 | + |
| 312 | +export default defineStack({ |
| 313 | + metadata: { |
| 314 | + name: 'my-app', |
| 315 | + version: '1.0.0', |
| 316 | + }, |
| 317 | + |
| 318 | + objects: { |
| 319 | + // Your data objects |
| 320 | + }, |
| 321 | + |
| 322 | + plugins: [ |
| 323 | + // Add plugins to load |
| 324 | + new HonoServerPlugin({ port: 3000 }), |
| 325 | + ], |
| 326 | +}); |
| 327 | +``` |
| 328 | + |
| 329 | +The server will: |
| 330 | +1. Load your configuration file |
| 331 | +2. Register all plugins specified in `config.plugins` |
| 332 | +3. Start the HTTP server (unless `--no-server` is specified) |
| 333 | +4. Listen on the specified port (default: 3000) |
| 334 | + |
| 335 | +### Package Dependencies |
| 336 | + |
| 337 | +``` |
| 338 | +@objectstack/spec (Foundation - Zod schemas) |
| 339 | + ↓ |
| 340 | +@objectstack/cli (Uses spec for validation) |
| 341 | + ↓ |
| 342 | +@objectstack/objectql (Uses spec for types) |
| 343 | + ↓ |
| 344 | +@objectstack/client (Uses objectql) |
| 345 | + ↓ |
| 346 | +@objectstack/client-react (Uses client) |
| 347 | +``` |
| 348 | + |
| 349 | +### Build Order |
| 350 | + |
| 351 | +1. `@objectstack/spec` - Must build first (provides types) |
| 352 | +2. `@objectstack/cli` - Can build after spec |
| 353 | +3. Other packages - Can build in parallel after spec |
| 354 | +4. Examples - Build last |
| 355 | + |
| 356 | +## Best Practices |
| 357 | + |
| 358 | +### Code Organization |
| 359 | + |
| 360 | +1. **Zod First**: Always define schemas with Zod first |
| 361 | +2. **Type Derivation**: Use `z.infer<typeof Schema>` for types |
| 362 | +3. **Naming Conventions**: |
| 363 | + - Config keys: `camelCase` (e.g., `maxLength`) |
| 364 | + - Data values: `snake_case` (e.g., `project_task`) |
| 365 | +4. **Documentation**: Add JSDoc comments with `@description` |
| 366 | + |
| 367 | +### Testing |
| 368 | + |
| 369 | +1. Co-locate tests with source files (`*.test.ts`) |
| 370 | +2. Target 80%+ code coverage |
| 371 | +3. Use descriptive test names |
| 372 | +4. Test both success and error cases |
| 373 | + |
| 374 | +### Commits |
| 375 | + |
| 376 | +1. Use conventional commits format |
| 377 | +2. Reference issues in commit messages |
| 378 | +3. Keep changes focused and minimal |
| 379 | + |
| 380 | +### Pull Requests |
| 381 | + |
| 382 | +1. Run `pnpm doctor` before submitting |
| 383 | +2. Ensure all tests pass |
| 384 | +3. Update documentation if needed |
| 385 | +4. Follow the PR template |
| 386 | + |
| 387 | +## Resources |
| 388 | + |
| 389 | +- [CONTRIBUTING.md](./CONTRIBUTING.md) - Detailed contribution guide |
| 390 | +- [ARCHITECTURE.md](./ARCHITECTURE.md) - Architecture documentation |
| 391 | +- [Package Dependencies](./PACKAGE-DEPENDENCIES.md) - Dependency graph |
| 392 | +- [Quick Reference](./QUICK-REFERENCE.md) - API quick reference |
| 393 | + |
| 394 | +## License |
| 395 | + |
| 396 | +Apache 2.0 © ObjectStack |
| 397 | + |
0 commit comments