laravel-introspect

repository·main·Indexed 41 days ago

https://github.com/capevace/laravel-introspect

A utility package for Laravel providing a type-safe fluent API to introspect and query codebase elements including views, routes, classes, and Eloquent models. It enables analysis of application structure via the Introspect facade or interactive CLI commands, supporting pattern matching with wildcards and JSON serialization of model schemas for use in developer tools or LLMs.

Tokens
7.6K
Snippets
32
Records
33
Agent score
51%

What's inside laravel-introspect

  1. Overview of laravel-introspect capabilities

    main

    laravel-introspect is a utility package designed to analyze Laravel codebases through a type-safe fluent API. It allows you to query various components of your application using wildcards (*) for pattern matching.

    Supported Query Types and Filters

    Query TypeAvailable Filters
    Viewsname, path, used by view, uses view, extends
    Routesname, URI, controller + fn, methods, middleware
    Classesname / namespace, extends parent, implements interfaces, uses traits
    Models (via Classes)relationships, properties, casts, fillable, hidden, read/writeable
    Commands (via Classes)signature, description (coming soon)
  2. Chain queries with OR and AND logic

    main

    By default, all query methods are combined using AND logic. You can implement complex OR logic by passing a closure to the or() method. The closure receives a query interface (e.g., RouteQueryInterface) to build the nested condition.

    Additionally, methods that accept arrays (like whereUsesMiddlewares or whereHasProperties) support an all parameter. Setting all: false changes the internal logic for that specific array from AND to OR.

    use \Mateffy\Introspect\Query\Contracts\RouteQueryInterface;
    
    $routes = Introspect::routes()  
        ->whereNameEquals('api.*')
        ->whereMethod('POST')
        ->or(fn (RouteQueryInterface $query) => $query
            ->whereHasParameter('product')
            ->whereHasParameter('category')
        )
        ->get();
  3. Install laravel-introspect via Composer

    main

    Install the package as a regular dependency or as a development dependency using Composer. If you are building developer tools or refactoring utilities, consider adding it with the --dev flag.

    composer require mateffy/laravel-introspect
  4. Query application routes

    main

    Query all registered routes, including those from packages. Route queries return a Collection<\Illuminate\Routing\Route>.

    Controller queries

    • whereUsesController(string|class $controller, ?string $method = null): Filter by controller class and optionally a specific method.

    Middleware queries

    • whereUsesMiddleware(string|class $middleware)
    • whereUsesMiddlewares(array $middlewares, bool $all = true): Match multiple middlewares. Set $all: false to use OR logic (match any).
    • whereDoesntUseMiddleware(string|class $middleware)

    Name and Path queries

    • whereNameEquals, whereNameStartsWith, whereNameEndsWith, whereNameDoesntEqual: Match route names (supports wildcards).
    • wherePathEquals, wherePathStartsWith, wherePathEndsWith, wherePathContains: Match route paths (supports wildcards).
    // Query routes using a specific controller and method
    $routes = Introspect::routes()
        ->whereUsesController(MyController::class, 'index')
        ->get();
    
    // Query routes using any of these middlewares
    $routes = Introspect::routes()
        ->whereUsesMiddlewares(['tenant', 'auth'], all: false)
        ->get();
    
    // Query routes by path pattern
    $routes = Introspect::routes()
        ->wherePathStartsWith('api/products')
        ->get();
  5. Introspect Model Details and JSON Schema

    main

    You can inspect a specific model class directly using Introspect::model(string $class). This returns a DTO that allows you to access metadata about the model.

    Available methods on the Model DTO

    • properties(): Returns the model's properties.
    • schema(): Returns a JSON schema representation of the model (e.g., ['type' => 'object', ...]).
    // Get model properties
    $model = Introspect::model(User::class);
    $properties = $model->properties();
    
    // Get model as JSON schema
    $schema = Introspect::model(User::class)->schema();
  6. Query PHP classes

    main

    Query classes within your application based on their structure and hierarchy.

    • whereName(string $namespace): Filter by namespace.
    • whereExtends(string $class): Filter by parent class.
    • whereImplements(string $interface): Filter by implemented interface.
    • whereUses(string $trait): Filter by used trait.
    $blocks = Introspect::classes()
        ->whereImplements(CMS\Block::class)
        ->whereUses(MyTrait::class)
        ->get();
  7. Query Blade views

    main

    You can query all views in your codebase, including those from packages (prefixed with prefix::). View queries return a Collection<string> of view names. All queries support wildcards (e.g., components.*.button).

    Path-based queries

    • whereNameEquals(string $name): Match exact name (supports wildcards).
    • whereNameStartsWith(string $prefix)
    • whereNameEndsWith(string $suffix)
    • whereNameContains(string $substring)

    Usage/Dependency queries

    • whereUsedBy(string $viewName): Find views that are used by a specific view.
    • whereNotUsedBy(string $viewName)
    • whereUses(string $viewName): Find views that use a specific view.
    • whereDoesntUse(string $viewName)
    • whereExtends(string $viewName): Find views that extend a specific layout.
    • whereDoesntExtend(string $viewName)
    // Query by name with wildcards
    $views = Introspect::views()
        ->whereNameEquals('*components.*item')
        ->get();
    
    // Query views used by a specific view
    $views = Introspect::views()
        ->whereUsedBy('pages.welcome')
        ->get();
    
    // Query views that extend a layout
    $views = Introspect::views()
        ->whereExtends('layouts.app')
        ->get();
  8. Query Eloquent models

    main

    Query Eloquent models based on their properties, attributes, and relationships. Model queries return a Collection of model class strings (e.g., App\Models\User::class).

    Property and Attribute queries

    • Existence: whereHasProperty, whereDoesntHaveProperty, whereHasProperties, whereDoesntHaveProperties.
    • Fillable: whereHasFillable, whereDoesntHaveFillable, whereHasFillableProperties, whereDoesntHaveFillableProperties.
    • Hidden: whereHasHidden, whereDoesntHaveHidden, whereHasHiddenProperties, whereDoesntHaveHiddenProperties.
    • Appended: whereHasAppended, whereDoesntHaveAppended, whereHasAppendedProperties, whereDoesntHaveAppendedProperties.
    • Readable: whereHasReadable, whereDoesntHaveReadable, whereHasReadableProperties, whereDoesntHaveReadableProperties.
    • Writable: whereHasWritable, whereDoesntHaveWritable, whereHasWritableProperties, whereDoesntHaveWritableProperties.

    Note: For methods accepting arrays (e.g., whereHasProperties), use the all: bool parameter to toggle between AND (true) and OR (false) logic.

    Relationship queries

    • whereHasRelationship(string $method): Checks for the presence of a relationship method.
    • whereDoesntHaveRelationship(string $method)
    // Find models that have specific fillable properties
    $models = Introspect::models()
        ->whereHasFillableProperties(['name', 'description'], all: true)
        ->get();
    
    // Find models that have a 'user' relationship
    $models = Introspect::models()
        ->whereHasRelationship('user')
        ->get();
  9. Query views interactively via the introspect command

    main

    When using the introspect command to inspect Views, you can chain multiple query conditions. The interactive prompt allows you to select an operator and provide a value. You can continue adding queries to build a combined filter until you choose to stop.

    Available View Query Operators:

    • Name Equals: Filter views by an exact name match.
    • Name Doesn't Equal: Filter views that do not match the name.
    • Used By: Filter views that are used by a specific component/resource.
    • Not Used By: Filter views that are NOT used by a specific component/resource.
    • Uses: Filter views that use a specific component/resource.
    • Doesn't Use: Filter views that do not use a specific component/resource.
    • Skip: Exit the query builder loop.
    What do you want to introspect? [Views, Routes, Models, Classes]
    > Views
    
    Query [Name Equals, Name Doesn't Equal, Used By, Not Used By, Uses, Doesn't Use, Skip]
    > Name Equals
    
    Value [Enter the value you want to query for]
    > welcome
    
    Do you want to add another query? [yes/no]
    > no
  10. Get the SQLite connection for the index

    main

    The db() method returns an instance of Illuminate\Database\SQLiteConnection. It automatically calls ensureDbExists() and establishes a dedicated Laravel database connection named introspect. This connection is configured with foreign_key_constraints enabled.

    $builder = new IndexBuilder(base_path());
    $connection = $builder->db();
    
    // You can now use the connection to run queries
    $results = $connection->table('some_table')->get();
  11. Access the Introspect API via the Introspect Facade

    main

    The Introspect facade provides a static entry point to the introspection engine. You can use it to inspect various parts of your Laravel application, including models, classes, views, and routes.

    Available static methods:

    • model(string $class): Returns a ModelReflector for the specified class.
    • classes(): Returns a ClassQueryInterface to query your codebase classes.
    • models(): Returns a ModelQueryInterface to query your Eloquent models.
    • views(): Returns a ViewQueryInterface to query your application views.
    • routes(): Returns a RouteQueryInterface to query your application routes.
    use Mateffy\Introspect\Facades\Introspect;
    
    // Example: Querying models
    $models = Introspect::models()->where('namespace', 'App\Models')->get();
    
    // Example: Inspecting a specific model
    $reflector = Introspect::model('App\Models\User');