rasul-front-laravel-api-auto-mapper
v0.1.0
Published
Generate typed Angular API clients from Laravel routes or OpenAPI specs. Stop hand-writing Angular services.
Maintainers
Readme
laravel-api-auto-mapper
Stop hand-writing Angular API services. Generate typed Angular clients from Laravel contracts.
laravel-api-auto-mapper reads your Laravel routes or OpenAPI spec and generates fully typed Angular services with HttpClient, Observable<T>, and proper TypeScript interfaces.
Features
- OpenAPI-first: Parse OpenAPI 3.x specs from Laravel tools (Scribe, Swagger, etc.)
- Route fallback: Parse
php artisan route:list --jsonoutput - Typed Angular services:
HttpClient,Observable<T>, typed params and responses - Model generation: TypeScript interfaces for request/response bodies
- Grouped by resource: Services auto-grouped by tag or route prefix
- Filtering: Include/exclude routes by tag, method, or pattern
- Dry-run mode: Preview changes before writing
- Watch mode: Auto-regenerate on file changes
- Prettier integration: Formatted output out of the box
Quick Start
# Install
npm install laravel-api-auto-mapper
# Initialize config
npx laravel-api-auto-mapper init
# Generate from OpenAPI spec
npx laravel-api-auto-mapper generate
# Generate from Laravel routes
npx laravel-api-auto-mapper generate --input ./routes.json --output ./src/app/api
# Preview without writing
npx laravel-api-auto-mapper generate --dry-runConfiguration
Create laravel-api-auto-mapper.config.js in your project root:
module.exports = {
input: {
type: 'openapi', // 'openapi' | 'routes' | 'manual'
path: './openapi.json',
},
output: {
dir: 'src/app/api',
serviceSuffix: 'Service',
modelSuffix: '',
},
angular: {
providedIn: 'root',
responseWrapper: false,
},
filters: {
includeTags: ['users', 'posts'],
excludeTags: ['internal'],
includeMethods: ['GET', 'POST', 'PUT', 'DELETE'],
},
naming: {
serviceCasing: 'pascal',
methodCasing: 'camel',
modelCasing: 'pascal',
prefixWithModule: false,
},
formatting: {
usePrettier: true,
},
};Input Modes
1. OpenAPI Spec (Recommended)
Generate a spec from Laravel using Swardoc or L5-Swagger:
# From Laravel
php artisan route:list --json > routes.json
# Or generate OpenAPI spec
php artisan swagger:generateThen configure:
module.exports = {
input: {
type: 'openapi',
path: './storage/api-docs/api-docs.json',
},
};2. Laravel Route List
Export routes as JSON:
php artisan route:list --json > routes.jsonConfigure:
module.exports = {
input: {
type: 'routes',
path: './routes.json',
},
};3. Manual Config
For edge cases, provide a pre-normalized JSON file matching the Endpoint[] interface.
Generated Output
src/app/api/
├── index.ts # Root barrel
├── api.config.ts # API_CONFIG injection token
├── services/
│ ├── index.ts # Service barrel
│ ├── users.service.ts # Generated service
│ └── posts.service.ts
└── models/
├── index.ts # Model barrel
├── user.ts
└── post.tsGenerated Service Example
import { Injectable } from '@angular/core';
import { HttpClient, HttpParams } from '@angular/common/http';
import { Observable } from 'rxjs';
import { User, CreateUserBody } from '../models';
@Injectable({ providedIn: 'root' })
export class UsersService {
constructor(private http: HttpClient) {}
getUsers(queryParams?: GetUsersParams): Observable<User[]> {
let httpParams = new HttpParams();
if (queryParams) {
Object.entries(queryParams).forEach(([key, value]) => {
if (value !== undefined && value !== null) {
httpParams = httpParams.set(key, String(value));
}
});
}
return this.http.get<User[]>('/api/users', { params: httpParams });
}
createUser(body: CreateUserBody): Observable<User> {
return this.http.post<User>('/api/users', body);
}
getUser(id: string | number): Observable<User> {
return this.http.get<User>(`/api/users/${id}`);
}
updateUser(id: string | number, body: CreateUserBody): Observable<User> {
return this.http.put<User>(`/api/users/${id}`, body);
}
deleteUser(id: string | number): Observable<void> {
return this.http.delete<void>(`/api/users/${id}`);
}
}Generated Model Example
export interface User {
id: number;
name: string;
email: string;
created_at: string;
updated_at: string;
}
export interface CreateUserBody {
name: string;
email: string;
password: string;
}
export interface GetUsersParams {
page?: number;
per_page?: number;
search?: string;
}CLI Commands
| Command | Description |
|---------|-------------|
| init | Create a new config file |
| generate | Generate Angular client code |
| watch | Watch for changes and regenerate |
generate Options
| Flag | Description |
|------|-------------|
| -c, --config <path> | Path to config file |
| -i, --input <path> | Input file path (overrides config) |
| -o, --output <path> | Output directory (overrides config) |
| --dry-run | Preview changes without writing files |
Angular Integration
Setup
Import the generated module in your Angular app:
// app.module.ts
import { UsersService, PostsService } from './api';
@NgModule({
providers: [UsersService, PostsService],
})
export class AppModule {}Auth Integration
Add an HTTP interceptor for auth tokens:
import { Injectable } from '@angular/core';
import { HttpInterceptor, HttpRequest, HttpHandler } from '@angular/common/http';
@Injectable()
export class AuthInterceptor implements HttpInterceptor {
intercept(req: HttpRequest<unknown>, next: HttpHandler) {
const token = localStorage.getItem('token');
const authReq = token
? req.clone({ setHeaders: { Authorization: `Bearer ${token}` } })
: req;
return next.handle(authReq);
}
}Base URL Configuration
import { API_CONFIG, DEFAULT_API_CONFIG } from './api';
@NgModule({
providers: [
{ provide: API_CONFIG, useValue: { ...DEFAULT_API_CONFIG, baseUrl: 'https://api.example.com' } },
],
})
export class AppModule {}Filtering
Include Only Specific Tags
module.exports = {
filters: {
includeTags: ['users', 'posts'],
},
};Exclude Internal Routes
module.exports = {
filters: {
excludeTags: ['internal', 'debug'],
excludeMethods: ['DELETE'],
},
};Pattern Matching
module.exports = {
filters: {
include: ['api/v1'],
exclude: ['webhooks', 'health'],
},
};Limitations
- Route lists alone cannot describe validation rules or response shapes. Use OpenAPI for accuracy.
- Complex Laravel responses (polymorphic, transformers) may need manual model overrides.
- Generated clients are predictable and conservative rather than overly magical.
- Manual customization zones are preserved during regeneration.
Roadmap
v0.1.0 (MVP)
- OpenAPI and Laravel route parsing
- Basic Angular service generation
- Model generation
- CLI with init, generate, watch
- Dry-run mode
- Filtering
v1.0.0
- Full response typing
- Header parameter support
- Auth interceptor generation
- Prettier integration
- File upload support
- Comprehensive test suite
v1.1.0
- Angular standalone component support
- Custom template overrides
- Multi-module generation
- Laravel Sail integration
- Watch mode improvements
v2.0.0
- React/Vue client generation
- GraphQL support
- Mock server generation
- CI/CD integration
- VS Code extension
License
MIT
