|
| 1 | +# CLAUDE.md |
| 2 | + |
| 3 | +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. |
| 4 | + |
| 5 | +## Development Commands |
| 6 | + |
| 7 | +### Building |
| 8 | +```bash |
| 9 | +yarn build # Compile TypeScript to dist/ |
| 10 | +yarn typecheck # Run TypeScript type checking without emitting files |
| 11 | +``` |
| 12 | + |
| 13 | +### Testing |
| 14 | +```bash |
| 15 | +yarn test # Run all tests with coverage (Vitest) |
| 16 | +yarn test:node # Run tests in Node.js environment |
| 17 | +yarn test:browser # Run tests in browser environment (jsdom) |
| 18 | +yarn test:watch # Run tests in watch mode |
| 19 | +yarn test:update # Update test snapshots |
| 20 | +``` |
| 21 | + |
| 22 | +### Code Quality |
| 23 | +```bash |
| 24 | +yarn lint # Run ESLint on lib/ directory |
| 25 | +yarn prettier # Format all code files |
| 26 | +``` |
| 27 | + |
| 28 | +### Running Individual Tests |
| 29 | +To run a single test file: |
| 30 | +```bash |
| 31 | +npx vitest test/specs/circular/circular.spec.ts |
| 32 | +``` |
| 33 | + |
| 34 | +To run tests matching a pattern: |
| 35 | +```bash |
| 36 | +npx vitest --grep "circular" |
| 37 | +``` |
| 38 | + |
| 39 | +## Architecture Overview |
| 40 | + |
| 41 | +### Core Purpose |
| 42 | +This library parses, resolves, and dereferences JSON Schema `$ref` pointers. It handles references to: |
| 43 | +- External files (local filesystem) |
| 44 | +- HTTP/HTTPS URLs |
| 45 | +- Internal JSON pointers within schemas |
| 46 | +- Mixed JSON and YAML formats |
| 47 | +- Circular/recursive references |
| 48 | + |
| 49 | +### Key Architecture Components |
| 50 | + |
| 51 | +#### 1. $RefParser (lib/index.ts) |
| 52 | +The main entry point and orchestrator class. Provides four primary operations: |
| 53 | +- **parse()**: Reads a single schema file (JSON/YAML) without resolving references |
| 54 | +- **resolve()**: Parses and resolves all `$ref` pointers, returns a `$Refs` object mapping references to values |
| 55 | +- **bundle()**: Converts external `$ref` pointers to internal ones (single file output) |
| 56 | +- **dereference()**: Replaces all `$ref` pointers with their actual values (fully expanded schema) |
| 57 | + |
| 58 | +All methods support both callback and Promise-based APIs, with multiple overload signatures. |
| 59 | + |
| 60 | +#### 2. $Refs (lib/refs.ts) |
| 61 | +A map/registry of all resolved JSON references and their values. Tracks: |
| 62 | +- All file paths/URLs encountered |
| 63 | +- Circular reference detection |
| 64 | +- Helper methods to query references by type (file, http, etc.) |
| 65 | + |
| 66 | +#### 3. Pointer (lib/pointer.ts) |
| 67 | +Represents a single JSON pointer (`#/definitions/person`) and implements JSON Pointer RFC 6901 spec: |
| 68 | +- Parses JSON pointer syntax (`/`, `~0`, `~1` escaping) |
| 69 | +- Resolves pointers to actual values within objects |
| 70 | +- Handles edge cases (null values, missing properties) |
| 71 | + |
| 72 | +#### 4. $Ref (lib/ref.ts) |
| 73 | +Wraps a single reference with metadata: |
| 74 | +- The reference path/URL |
| 75 | +- The resolved value |
| 76 | +- Path type (file, http, etc.) |
| 77 | +- Error information (when continueOnError is enabled) |
| 78 | + |
| 79 | +#### 5. Plugin System |
| 80 | +Two types of plugins, both configurable via options: |
| 81 | + |
| 82 | +**Parsers** (lib/parsers/): |
| 83 | +- JSON parser (json.ts) |
| 84 | +- YAML parser (yaml.ts) - uses js-yaml |
| 85 | +- Text parser (text.ts) |
| 86 | +- Binary parser (binary.ts) |
| 87 | +- Execute in order based on `order` property and `canParse()` matching |
| 88 | + |
| 89 | +**Resolvers** (lib/resolvers/): |
| 90 | +- File resolver (file.ts) - reads from filesystem (Node.js only) |
| 91 | +- HTTP resolver (http.ts) - fetches from URLs using native fetch |
| 92 | +- Custom resolvers can be added via options |
| 93 | +- Execute in order based on `order` property and `canRead()` matching |
| 94 | + |
| 95 | +#### 6. Core Operations |
| 96 | + |
| 97 | +**lib/parse.ts**: Entry point for parsing a single schema file |
| 98 | +**lib/resolve-external.ts**: Crawls schema to find and resolve external `$ref` pointers |
| 99 | +**lib/bundle.ts**: Replaces external refs with internal refs |
| 100 | +**lib/dereference.ts**: Replaces all `$ref` pointers with actual values, handles circular references |
| 101 | + |
| 102 | +#### 7. Options System (lib/options.ts) |
| 103 | +Hierarchical configuration with defaults for: |
| 104 | +- Which parsers/resolvers to enable |
| 105 | +- Circular reference handling (boolean or "ignore") |
| 106 | +- External reference resolution (relative vs root) |
| 107 | +- Continue on error mode (collect all errors vs fail fast) |
| 108 | +- Bundle/dereference callbacks and matchers |
| 109 | +- Input mutation control (mutateInputSchema) |
| 110 | + |
| 111 | +### Key Design Patterns |
| 112 | + |
| 113 | +1. **Flexible Arguments**: normalizeArgs() (lib/normalize-args.ts) unifies various call signatures into consistent internal format |
| 114 | + |
| 115 | +2. **Path Handling**: Automatic conversion between filesystem paths and file:// URLs. Cross-platform support via util/url.ts and util/convert-path-to-posix.ts |
| 116 | + |
| 117 | +3. **Error Handling**: |
| 118 | + - Fail-fast by default |
| 119 | + - Optional continueOnError mode collects errors in JSONParserErrorGroup |
| 120 | + - Specific error types: JSONParserError, InvalidPointerError, MissingPointerError, ResolverError, ParserError |
| 121 | + |
| 122 | +4. **Circular Reference Management**: |
| 123 | + - Detected during dereference |
| 124 | + - Can throw error, ignore, or handle via dereference.circular option |
| 125 | + - Reference equality maintained (same `$ref` → same object instance) |
| 126 | + |
| 127 | +5. **Browser/Node Compatibility**: |
| 128 | + - Uses native fetch (requires Node 18+) |
| 129 | + - File resolver disabled in browser builds (package.json browser field) |
| 130 | + - Tests run in both environments |
| 131 | + |
| 132 | +## Testing Strategy |
| 133 | + |
| 134 | +Tests are organized in test/specs/ by scenario: |
| 135 | +- Each scenario has test files (*.spec.ts) and fixture data |
| 136 | +- Tests validate parse, resolve, bundle, and dereference operations |
| 137 | +- Extensive coverage of edge cases: circular refs, deep nesting, special characters in paths |
| 138 | +- Browser-specific tests use test/fixtures/server.ts for HTTP mocking |
| 139 | + |
| 140 | +Test utilities: |
| 141 | +- test/utils/helper.js: Common test patterns |
| 142 | +- test/utils/path.js: Path handling for cross-platform tests |
| 143 | +- test/utils/serializeJson.ts: Custom snapshot serializer |
| 144 | + |
| 145 | +## Important Constraints |
| 146 | + |
| 147 | +1. **TypeScript Strict Mode**: Project uses strict TypeScript including exactOptionalPropertyTypes |
| 148 | +2. **JSON Schema Support**: Compatible with JSON Schema v4, v6, and v7 |
| 149 | +3. **Minimum Node Version**: Requires Node >= 20 (for native fetch support) |
| 150 | +4. **Circular JSON**: Dereferenced schemas may contain circular references (not JSON.stringify safe) |
| 151 | +5. **Path Normalization**: Always converts filesystem paths to POSIX format internally |
| 152 | +6. **URL Safety**: HTTP resolver has safeUrlResolver option to block internal URLs (default: unsafe allowed) |
0 commit comments