4.2 KiB
CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Project Overview
L5-Swagger is a Laravel package that integrates swagger-php and swagger-ui into Laravel. It does NOT implement the OpenAPI spec — it wraps swagger-php for annotation scanning and swagger-ui for the documentation frontend.
Supports multiple independent documentation sets, each with its own routes, paths, and settings via a two-level config: defaults (shared) merged with documentations.{name} (per-doc overrides). ConfigFactory::mergeConfig() recursively merges associative arrays.
Development Commands
# Run all tests
composer run-script phpunit
# Run a single test file
vendor/bin/phpunit tests/Unit/GeneratorTest.php
# Run a single test method
vendor/bin/phpunit --filter testCanGenerateApiJsonFile
# Static analysis (PHPStan level 8)
composer run-script analyse
Architecture
Generation Pipeline
GeneratorFactory::make(documentation) → creates Generator with merged config → Generator::generateDocs() chains:
prepareDirectory()— ensure output dir exists/writabledefineConstants()— define PHP constants from config (usable in annotations)scanFilesForDocumentation()— swagger-php scans PHP files usingReflectionAnalyser+AttributeAnnotationFactorypopulateServers()— injects base path as a Server URLsaveJson()— writes JSON, thenSecurityDefinitions::generate()injects security schemesmakeYamlCopy()— optional YAML conversion viasymfony/yaml
Custom processors can be positioned relative to any existing processor via scanOptions.processors using ['class' => ..., 'after' => ...] syntax. A CustomGeneratorInterface implementation can be provided via scanOptions.generator_factory to supply a pre-configured OpenApi\Generator.
Service Container Bindings
L5SwaggerServiceProvider binds Generator::class as a factory — each resolution creates a new Generator via GeneratorFactory::make() using the l5-swagger.default documentation name. The GenerateDocsCommand is registered as a singleton under command.l5-swagger.generate.
Routing
Routes are registered dynamically in src/routes.php by iterating all documentation sets. Each set gets up to 4 routes (api UI, docs JSON/YAML, assets, OAuth2 callback), all wrapped with the Config middleware that sets the active documentation context. Route names follow l5-swagger.{documentation}.{type}.
Helpers
swagger_ui_dist_path() resolves swagger-ui asset paths with an allowlist of permitted files. l5_swagger_asset() generates versioned (cache-busted) URLs for those assets.
Testing
Tests use Orchestra Testbench (Tests\Unit\TestCase extends OrchestraTestCase) for a full Laravel environment.
Key patterns:
$this->fileSystemis a PHPUnit mock ofFilesystem, injected intoGeneratorvia reflection inmakeGeneratorWithMockedFileSystem()setAnnotationsPath()reconfigures the app to usetests/storage/annotations/OpenApi/fixtures and rebuilds the generatorsetCustomDocsFileName()overrides the output filename for JSON/YAML format testscopyAssets()copies swagger-ui dist into testbench's vendor directory in setUp;tearDowncleans up generated docs- PHPUnit attributes:
#[TestDox('...')],#[CoversClass(...)]
Test fixtures live in tests/storage/annotations/OpenApi/ with sample PHP attribute annotations.
Code Style
- StyleCI:
preset: laravel— enforced automatically - PHPStan: Level 8, analyzes
src/andtests/Unit/, ignoresargument.templateType - PHP 8.2+ required; uses constructor property promotion, union types, named arguments
- Supports Laravel 11.44+, 12.1+, and 13.0+
Environment Variables
| Variable | Purpose |
|---|---|
L5_SWAGGER_GENERATE_ALWAYS |
Regenerate docs on every request (dev mode) |
L5_SWAGGER_GENERATE_YAML_COPY |
Also create YAML version |
L5_SWAGGER_CONST_HOST |
Default host constant for annotations |
L5_SWAGGER_OPEN_API_SPEC_VERSION |
3.0.0 (default) or 3.1.0 |
L5_SWAGGER_UI_DARK_MODE |
Dark mode for Swagger UI |
SWAGGER_VERSION |
Used in tests to set OpenAPI version |