|
| 1 | +# CLAUDE.md |
| 2 | + |
| 3 | +This file provides guidance to Claude Code (claude.ai/code) when working with |
| 4 | +code in this repository. |
| 5 | + |
| 6 | +## Project Overview |
| 7 | + |
| 8 | +LoopBack 4 is a highly extensible Node.js and TypeScript framework for building |
| 9 | +APIs and microservices. This is the monorepo (`loopback-next`) containing all |
| 10 | +core packages, extensions, and examples. |
| 11 | + |
| 12 | +## Monorepo Structure |
| 13 | + |
| 14 | +- **packages/** — Core framework packages (~29 packages) |
| 15 | +- **extensions/** — Optional extensions (authentication-jwt, graphql, cron, |
| 16 | + metrics, logging, etc.) |
| 17 | +- **examples/** — Sample applications demonstrating features |
| 18 | +- **acceptance/** — Database connector acceptance tests |
| 19 | +- **fixtures/** — Test fixtures and mock services |
| 20 | +- **bodyparsers/** — Body parser extensions |
| 21 | +- **sandbox/** — For testing monorepo packages as local dependencies |
| 22 | +- **benchmark/** — Performance benchmarks |
| 23 | +- **docs/** — Jekyll-based documentation site |
| 24 | + |
| 25 | +Managed with **Lerna** (independent versioning) and **npm workspaces**. |
| 26 | + |
| 27 | +## Build & Development Commands |
| 28 | + |
| 29 | +```bash |
| 30 | +# Install dependencies (also auto-updates TypeScript project references) |
| 31 | +npm ci |
| 32 | + |
| 33 | +# Build all packages (incremental TypeScript compilation) |
| 34 | +npm run build |
| 35 | + |
| 36 | +# Full clean rebuild |
| 37 | +npm run clean && npm run build |
| 38 | + |
| 39 | +# Build a single package |
| 40 | +cd packages/<name> && npm run build |
| 41 | +``` |
| 42 | + |
| 43 | +## Testing |
| 44 | + |
| 45 | +```bash |
| 46 | +# Full test suite (clean + build + mocha + nyc + lint) |
| 47 | +npm test |
| 48 | + |
| 49 | +# Run mocha tests only (skips build/lint — useful for fast iteration) |
| 50 | +npm run mocha |
| 51 | + |
| 52 | +# Test a single package (builds & tests it) |
| 53 | +cd packages/<name> && npm test |
| 54 | + |
| 55 | +# Disable parallel test execution |
| 56 | +npm run mocha -- -j 1 |
| 57 | + |
| 58 | +# Run CI-only heavy tests locally |
| 59 | +CI=1 npm test |
| 60 | +``` |
| 61 | + |
| 62 | +Test framework: **Mocha** (parallel, 10s timeout) with **NYC** coverage. Tests |
| 63 | +run against compiled JS in `dist/__tests__/`. The `pretest` script auto-builds, |
| 64 | +so `npm test` in a package compiles then runs tests. |
| 65 | + |
| 66 | +Test files follow the convention `{name}.{test-type}.ts` where test-type is |
| 67 | +`unit`, `integration`, or `acceptance`, placed under |
| 68 | +`src/__tests__/{unit,integration,acceptance}/`. |
| 69 | + |
| 70 | +Build wrappers from `@loopback/build`: `lb-tsc`, `lb-mocha`, `lb-eslint`, |
| 71 | +`lb-prettier`, `lb-nyc`, `lb-clean`. |
| 72 | + |
| 73 | +## Linting & Formatting |
| 74 | + |
| 75 | +```bash |
| 76 | +# Run ESLint + Prettier checks |
| 77 | +npm run lint |
| 78 | + |
| 79 | +# Auto-fix lint and formatting issues |
| 80 | +npm run lint:fix |
| 81 | +``` |
| 82 | + |
| 83 | +**Prettier** config: |
| 84 | +`{bracketSpacing: false, singleQuote: true, printWidth: 80, trailingComma: "all", arrowParens: "avoid"}`. |
| 85 | + |
| 86 | +Pre-commit hook (Husky + lint-staged) auto-formats staged files. Bypass with |
| 87 | +`LINT_STAGED=0`. |
| 88 | + |
| 89 | +## Commit Message Convention |
| 90 | + |
| 91 | +Uses **Conventional Commits** enforced by commitlint: |
| 92 | + |
| 93 | +``` |
| 94 | +<type>(<scope>): <subject> |
| 95 | +``` |
| 96 | + |
| 97 | +- **type**: feat, fix, docs, style, refactor, perf, test, build, ci, chore, |
| 98 | + revert |
| 99 | +- **scope**: package directory name (e.g., `core`, `rest`, `context`, |
| 100 | + `repository`) |
| 101 | +- **subject**: imperative, lowercase, no trailing dot |
| 102 | + |
| 103 | +Use `git cz` (commitizen) for interactive commit message generation. |
| 104 | + |
| 105 | +## Key Architectural Concepts |
| 106 | + |
| 107 | +### Dependency Injection & Context |
| 108 | + |
| 109 | +The IoC container (`@loopback/context`) is the foundation. `@loopback/core` |
| 110 | +re-exports all of `@loopback/context`'s public API — application code should |
| 111 | +import from `@loopback/core`, not `@loopback/context` directly. |
| 112 | + |
| 113 | +**Core dependency chain**: `@loopback/metadata` → `@loopback/context` → |
| 114 | +`@loopback/core` → `@loopback/boot`, `@loopback/rest`, etc. |
| 115 | + |
| 116 | +### Foundation vs Framework Packages |
| 117 | + |
| 118 | +- **Foundation-level** (internal building blocks, not directly consumed by |
| 119 | + apps): `context`, `metadata`, `express`, `http-server`, `openapi-v3`, |
| 120 | + `repository-json-schema` |
| 121 | +- **Framework-level** (everything else — used directly by applications) |
| 122 | + |
| 123 | +In documentation and examples, always reference framework-level packages. |
| 124 | + |
| 125 | +### TypeScript Configuration |
| 126 | + |
| 127 | +Two sets of tsconfig files serve different purposes: |
| 128 | + |
| 129 | +- **Root `tsconfig.json`** — Used by VS Code for cross-package navigation |
| 130 | + (enables "go to definition" jumping to `.ts` source, cross-package rename |
| 131 | + refactoring) |
| 132 | +- **Root `tsconfig.build.json`** — Used by ESLint |
| 133 | +- **Per-package `tsconfig.json`** — Used by `npm run build` to compile each |
| 134 | + package to its `dist/` directory |
| 135 | + |
| 136 | +All extend `@loopback/build/config/tsconfig.common.json`. TypeScript project |
| 137 | +references are auto-updated via `bin/update-ts-project-refs.js` (runs on |
| 138 | +`postinstall`). |
| 139 | + |
| 140 | +Key compiler options: `strict: true`, `target: es2018`, `module: commonjs`, |
| 141 | +`experimentalDecorators: true`, `emitDecoratorMetadata: true`. |
| 142 | + |
| 143 | +## File Naming Convention |
| 144 | + |
| 145 | +Follows Angular-style dotted naming: `{name}.{artifact-type}.ts` |
| 146 | + |
| 147 | +Examples: `authenticate.decorator.ts`, `boot.component.ts`, |
| 148 | +`user.controller.ts`, `todo.repository.ts`, `application.acceptance.ts` |
| 149 | + |
| 150 | +## Code Style Rules (ESLint) |
| 151 | + |
| 152 | +- `@typescript-eslint/no-explicit-any`: **error** — avoid `any` types |
| 153 | +- `@typescript-eslint/no-floating-promises`: **error** — all promises must be |
| 154 | + awaited or handled |
| 155 | +- `@typescript-eslint/await-thenable`: **error** |
| 156 | +- `@typescript-eslint/no-misused-promises`: **error** |
| 157 | +- `@typescript-eslint/return-await`: **error** |
| 158 | +- `@typescript-eslint/no-shadow`: **error** |
| 159 | +- `mocha/no-exclusive-tests`: **error** — no `.only()` in committed tests |
| 160 | +- Naming: camelCase default, PascalCase for types, UPPER_CASE for constants, |
| 161 | + leading underscore for private/protected members, PascalCase for mixin |
| 162 | + functions ending in `Mixin` |
| 163 | + |
| 164 | +## Copyright Headers |
| 165 | + |
| 166 | +All source files must include the copyright header: |
| 167 | + |
| 168 | +```ts |
| 169 | +// Copyright IBM Corp. and LoopBack contributors <year>. All Rights Reserved. |
| 170 | +// Node module: <package-name> |
| 171 | +// This file is licensed under the MIT License. |
| 172 | +// License text available at https://opensource.org/licenses/MIT |
| 173 | +``` |
| 174 | + |
| 175 | +Run `lb4 copyright` to update headers automatically. |
| 176 | + |
| 177 | +## Adding a New Package |
| 178 | + |
| 179 | +Use the helper script: `node bin/create-package.js <package-name>`. It |
| 180 | +scaffolds, fixes up package.json, updates copyright, bootstraps dependencies, |
| 181 | +and updates TypeScript project references. |
| 182 | + |
| 183 | +After creation, update `CODEOWNERS` and `docs/site/MONOREPO.md`. |
| 184 | + |
| 185 | +## Connector Limitation in Monorepo |
| 186 | + |
| 187 | +When using datasource connectors inside the monorepo (e.g., in examples), |
| 188 | +require the connector module directly in the config instead of using a string |
| 189 | +name: |
| 190 | + |
| 191 | +```ts |
| 192 | +connector: require('loopback-connector-mongodb'); // not connector: 'mongodb' |
| 193 | +``` |
| 194 | + |
| 195 | +This is due to how Lerna symlinks resolve module paths. |
| 196 | + |
| 197 | +## Node.js Support |
| 198 | + |
| 199 | +Engines: Node.js 18, 20, or 22. npm >= 7. |
0 commit comments