A utility package to analyze Laravel codebases, querying views, models, routes, classes and more directly from your codebase using a type-safe fluent API.
- 🔍 Query views, routes, classes and models with a fluent API
- 🔍 Use wildcards (
*) to match multiple views, routes, classes and models - 🪄 Parse properties, relationships + their types and more directly from Eloquent model code
- 🤖 (De-)serialize queries to/from JSON (perfect for LLM tool calling)
| Query | Available Filters |
|---|---|
| Views | name, path, used by view, uses view, extends |
| Routes | name, URI, controller + fn, methods, middleware |
| Classes | name / namespace, extends parent, implements interfaces, uses traits |
| ⤷ Models | ... relationships, properties, casts, fillable, hidden, read/writeable |
| ⤷ Commands | ... signature, description (coming soon) |
Name and a few other queries even support wildcard queries (e.g.
components.*.paragraph)
Are you working on a complex refactoring job and need to find all the places where a specific view is used? Are you building devtools or other things which need information about the codebase? Do you need structured schema information of your Eloquent data model?
These are all use cases where you need to introspect your codebase and find out where things are used, how they are used and what they are. This package does exactly that.
Install the package via composer:
composer require mateffy/laravel-introspect Note
Depending on your use case, it might make sense to install the package as a dev dependency by adding the --dev flag to the command.
use Mateffy\Introspect\Facades\Introspect;
$views = Introspect::views()
->whereNameEquals('components.*.button')
->whereUsedBy('pages.admin.*')
->get();
$routes = Introspect::routes()
->whereUsesController(MyController::class)
->whereUsesMiddleware('auth')
->whereUsesMethod('POST')
->get();
$classes = Introspect::classes()
->whereImplements(MyInterface::class)
->whereUses(MyTrait::class)
->get();
$models = Introspect::models()
->whereHasProperties(['name', 'email'])
->whereHasFillable('password')
->get();
// Access Eloquent properties, relationships, casts, etc. directly
$detail = Introspect::model(User::class);
// Model to JSON schema
$schema = $detail->schema();You can query all of the views you have in your codebase, including those that are provided by other packages and are
namespaced with a prefix::.
View queries return a Collection<string> of view names.
All queries support wildcards, e.g.
components.*.buttonor*.button
$views = Introspect::views()
// Supports wildcards
->whereNameEquals('*components.*item')
->get();
// -> ['components.item', 'filament::components.dropdown.list.item', ...]
$views = Introspect::views()
->whereNameStartsWith('filament::')
->get();
$views = Introspect::views()
->whereNameEndsWith('button')
->get();
$views = Introspect::views()
->whereNameContains('button')
->get();$routes = Introspect::views()
->whereUsedBy('pages.welcome')
->get();
// -> ['components.button', 'filament::components.button', ...]
$routes = Introspect::views()
->whereUsedBy('pages.*')
->get();
$routes = Introspect::views()
->whereNotUsedBy('pages.*')
->get();$routes = Introspect::views()
->whereUses('components.button')
->get();
$routes = Introspect::views()
->whereUses('*.button')
->get();
$routes = Introspect::views()
->whereDoesntUse('*.button')
->get();$routes = Introspect::views()
->whereExtends('layouts.app')
->get();
$routes = Introspect::views()
->whereExtends('layouts.*')
->get();
$routes = Introspect::views()
->whereDoesntExtend('layouts.*')
->get();Query through all the routes registered in your application (think like artisan route:list output), including those
registered by packages.
The routes are returned as a Collection<\Illuminate\Routing\Route>.
$routes = Introspect::routes()
->whereUsesController(MyController::class)
->get();
// -> [\Illuminate\Routing\Route, \Illuminate\Routing\Route, ...]
$routes = Introspect::routes()
->whereUsesController(MyController::class, 'index')
->get();
$routes = Introspect::routes()
->whereUsesController(SingleActionController::class, 'index')
->get();$routes = Introspect::routes()
->whereUsesMiddleware(MyMiddleware::class)
->get();
$routes = Introspect::routes()
->whereUsesMiddlewares(['tenant', 'auth'])
->get();
$routes = Introspect::routes()
// Match any of the middlewares
->whereUsesMiddlewares(['tenant', 'auth'], all: false)
->get();
$routes = Introspect::routes()
->whereDoesntUseMiddleware('api')
->get();"Name equals/contains" queries support wildcards, e.g.
api.products.*or*.products.*
$routes = Introspect::routes()
->whereNameEquals('api.products.*')
->get();
$routes = Introspect::routes()
->whereNameStartsWith('api.products.')
->get();
$routes = Introspect::routes()
->whereNameEndsWith('api.products.')
->get();
$routes = Introspect::routes()
->whereNameDoesntEqual('api.products.*')
->get();"Path equals/contains" queries support wildcards, e.g.
api/products/*or*/products/*
$routes = Introspect::routes()
->wherePathStartsWith('api/products')
->get();
$routes = Introspect::routes()
->wherePathEndsWith('products')
->get();
$routes = Introspect::routes()
->wherePathContains('products')
->get();
$routes = Introspect::routes()
->wherePathEquals('api/products*')
->get();$services = Introspect::classes()
->whereName('\App\Services')
->get();$blocks = Introspect::classes()
->whereExtends(CMS\Block::class)
->get();$blocks = Introspect::classes()
->whereImplements(CMS\Block::class)
->get();$blocks = Introspect::classes()
->whereUses(MyTrait::class)
->get();Query Eloquent models based on their properties, attributes (fillable, hidden, appended, readable, writable), and relationship existence. Model queries return a Collection of model class strings (e.g., App\Models\User::class).
Filter models based on whether they possess specific properties.
$models = Introspect::models()
->whereHasProperty('created_at')
->get();
// Also available: whereDoesntHaveProperty, whereHasProperties, whereDoesntHaveProperties
// Example with multiple properties (any):
$models = Introspect::models()
->whereHasProperties(['first_name', 'last_name'], all: false)
->get();Filter models based on their $fillable attributes.
$models = Introspect::models()
->whereHasFillable('title')
->get();
// Also available: whereDoesntHaveFillable, whereHasFillableProperties, etc.
$models = Introspect::models()
->whereHasFillableProperties(['name', 'description']) // all: true by default
->get();Query by Hidden Properties
Filter models based on their $hidden attributes.
$models = Introspect::models()
->whereHasHidden('password')
->get();
// Also available: whereDoesntHaveHidden, whereHasHiddenProperties, etc.
$models = Introspect::models()
->whereDoesntHaveHiddenProperties(['name', 'email'], all: false) // neither name nor email are hidden
->get();Filter models based on their $appends attributes (accessors).
$models = Introspect::models()
->whereHasAppended('full_name')
->get();
// Also available: whereDoesntHaveAppended, whereHasAppendedProperties, etc.
$models = Introspect::models()
->whereHasAppendedProperties(['is_active', 'resource_type'])
->get();Filter models based on "readable" properties (public getters, public properties, or attributes).
$models = Introspect::models()
->whereHasReadable('name')
->get();
// Also available: whereDoesntHaveReadable, whereHasReadableProperties, etc.
$models = Introspect::models()
->whereHasReadableProperties(['id', 'email'])
->get();Filter models based on "writable" properties (public setters or public properties).
$models = Introspect::models()
->whereHasWritable('status')
->get();
// Also available: whereDoesntHaveWritable, whereHasWritableProperties, etc.
$models = Introspect::models()
->whereHasWritableProperties(['name', 'settings'])
->get();Filter models based on the existence of specific relationship methods. Note: This currently checks for method presence, not relationship type or related model details.
$models = Introspect::models()
->whereHasRelationship('user')
->get();
$models = Introspect::models()
->whereDoesntHaveRelationship('logs')
->get();By default, any queries are combined with AND logic.
However, you can craft more complex queries by chaining together queries with OR logic, too.
This works for all queries, including models, routes, views and classes.
use \Mateffy\Introspect\Query\Contracts\RouteQueryInterface;
$routes = Introspect::routes()
->whereNameEquals('api.*')
->whereMethod('POST')
->or(fn (RouteQueryInterface $query) => $query
->whereHasParameter('product') //
->whereHasParameter('category')
)
->get();Some methods support multiple parameters, e.g. whereUsesMiddlewares([...]) or whereUsesProperties([...]).
These methods have an all parameter that defaults to true. If set to false, the values are checked with OR logic
too, matching on any of the values.
$routes = Introspect::routes()
->whereUsesMiddlewares(['tenant', 'auth'], all: false)
->get();Actual Laravel pagination (->paginate(...)) is not yet supported, but you can use limit and offset to get the
results you want.
$models = Introspect::models()
->limit(10)
->offset(20)
->get();$model = Introspect::model(User::class);
$properties = $models->properties();$schema = Introspect::model(User::class)->schema();
// -> ['type' => 'object',...]The MIT License (MIT). Please see License File for more information.
