Scramble 0.12.x is here! Manual parameter docs, transformers API and more.
Learn more

Releases

Keep up with regular Scramble releases.
Latest versions:
Scramble: v0.12.27
Scramble PRO: v0.7.12
August 2025
Aug 3, 2025
v0.7.12 PRO

What’s Changed

  • Use self out type instead of self templates definition extensions
Aug 3, 2025
v0.12.27

Deeper setter analysis

When analyzing method calls, Scramble now infers much more useful type information thanks to deeper setter analysis.

Consider this example:

class Foo
{
    property int $foo;

    public function __construct()
    {
        $this->setFoo(42);
    }

    public function setFoo(int $foo): self
    {
        $this->foo = $foo;
        return $this;
    }
}

Previously, Scramble correctly inferred that new Foo() produces a Foo<42>.

However, if you move the setter call into a setup method, Scramble used to lose that information:

class Foo
{
    property int $foo;

    public function __construct()
    {
        $this->setup();
    }

    private function setup(): void
    {
        $this->setFoo(42);
    }

    public function setFoo(int $foo): self
    {
        $this->foo = $foo;
        return $this;
    }
}

In this case, Scramble would no longer know that $foo had been set to 42.

This release fixes that: the example above now works perfectly as expected. Deep setter analysis applies not only in __construct but in any class method.

This enhancement makes Scramble more accurate across a broader range of codebases, letting you focus on your business logic instead of adding extra annotations.

Performance improvements

Deeper setter analysis requires analyzing more code and doing more work. So initially, the draft version of this feature severely impacted Scramble’s performance (slowing it down by 2x — sic!).

Fixing this performance regression not only resulted in a 10% speed-up over the original performance levels but also slightly reduced memory usage.

Long story short: the performance gain came from skipping work that wasn’t absolutely necessary. So, going back to the latest example: if setup or setFoo methods are never called in places Scramble actually cares about (like API controllers), they won’t be analyzed — which significantly boosts performance.

Also, if you have a statement like return count(some_complex_function()), some_complex_function() won’t be analyzed at all, since count is known to return an int egardless of the arguments you pass.

This required some internal changes to how arguments are handled, which might technically be breaking changes — but they shouldn’t affect you, since it’s all internal.

🚨 Potentially breaking changes

This release does not introduce any changes to the public API documented in the docs. However, if you rely on undocumented internals to extend type inference, please note:

  • All call event classes’ arguments property is now an instance of Dedoc\Scramble\Infer\Contracts\ArgumentTypeBag, instead of plain array<string, Type>. This affects Dedoc\Scramble\Infer\Extensions\Event\{AnyMethodCallEvent, FunctionCallEvent, MethodCallEvent, SideEffectCallEvent, StaticMethodCallEvent} classes.
  • The early “side effects” concept has been replaced by industry-adopted self-out types (does anyone understand this sentence at all?). As a result, the following classes have been removed: Dedoc\Scramble\Support\Type\SideEffects\{SelfTemplateDefinition, ParentConstructCall}.

What’s Changed

  • Added 'present' validation rule support by @chrisvanlier2005 in #915
July 2025
Jul 27, 2025
v0.12.26

What’s Changed

  • Change extensions order to handle custom inference extensions before default inference extensions by @chrisvanlier2005 in #831
  • Reference type resolver cleanup by @romalytvynenko in #909
Jul 26, 2025
v0.12.25

What’s Changed

  • Validation rules documentation is retrieved from inferred type rather than from AST nodes by @romalytvynenko in #906
  • Fixed performance regression and too much memory usage by @romalytvynenko in #907
Jul 25, 2025
v0.7.11 PRO

What’s Changed

  • Fixed redefining types on query builder filters
Jul 25, 2025
v0.12.24

What’s Changed

  • Add support for adding custom headers to responses by @romalytvynenko in #884
  • Fixed issue when analyzing properties of internal classes by @romalytvynenko in #886
  • Fixed empty api_path config was not matching any routes by @romalytvynenko in #889
  • Improved documentation of complex query parameters (arrays, objects) by @romalytvynenko in #890
  • Added response attribute by @romalytvynenko in #894
  • Added between validation rule support by @romalytvynenko in #895
  • Simplified header attribute behavior by @romalytvynenko in #896
  • Fixed response type parsing with correct PHPDoc file name context by @romalytvynenko in #898
  • Preparation for the next release by @romalytvynenko in #899
  • Added support for binary and streamed responses automatic documentation by @romalytvynenko in #901
  • Cleaned up reference resolver (moved away vendor analysis responsibility) by @romalytvynenko in #903
Jul 9, 2025
v0.7.10 PRO

What’s Changed

  • Fixed issue when Scramble couldn’t document Laravel Data properties that were using RouteParameterReference external reference due to the rules being evaluated not in the expected route’s/request’s context
June 2025
Jun 17, 2025
v0.12.23

What’s Changed

  • Fixed document level tags ordering when using weight argument on #[Group] attribute by @romalytvynenko in #870
  • Fix setOperationId called in an operation transformer not working by @romalytvynenko in #872
Jun 3, 2025
v0.12.22

What’s Changed

  • Fixed incorrect generic creation when looking for JSON resource in anonymous resource collection by @romalytvynenko in #862
  • Fixed memory leak when running tests if there are extensions registered via programmatic API by @romalytvynenko in #864
  • Allow using #[Group] attribute on route’s controller methods by @romalytvynenko in #865
Jun 1, 2025
v0.12.21

What’s Changed

  • Fixed bool typehint on authorize prevented Scramble into properly inferring 403 response absence by @romalytvynenko in #857
  • Add support for inferring a type on property fetch or method call on an argument by @romalytvynenko in #858
  • Fixed fully qualified names resolution of methods defined in traits by @romalytvynenko in #860
May 2025
May 28, 2025
v0.7.9 PRO

What’s Changed

  • Added $attributes and $relationships properties support for timacdonald/json-api
  • Add json-api toLinks support by @romalytvynenko in #56
  • Added spatie/laravel-json-api-paginate support by @romalytvynenko in #57
  • json-api improvements by @romalytvynenko in #58
  • Bump dependabot/fetch-metadata from 2.2.0 to 2.4.0 by @dependabot in #59
  • PHPstan with baseline by @romalytvynenko in #60
May 28, 2025
v0.12.20

Paginated collections inference

Now, when returning API resource collections with paginators from the controllers, Scramble will automatically document the correct response. Previously you needed to manually annotate it. This is achieved by inferring the type of the paginators you get by calling a family of *paginate methods.

 /**
  * List available todo items.
- *
- * @response AnonymousResourceCollection<LengthAwarePaginator<TodoItemResource>>
  */
public function index()
{
    return TodoItemResource::collection(TodoItem::paginate());
}

This is particularly useful when you have some additional data together with the paginated collection. Previously it was tricky and not possible to have them both due to the annotation limitations.

public function index()
{
    $users = User::query()->paginate();

    return UserResource::collection($users)->additional([
        /** The total count of users */
        'count' => (int) $users->count(),
    ]);
}

Result:

<img width=“688” alt=“image” src=“https://github.com/user-attachments/assets/6a0ec1a2-e568-45f9-8842-1f9feddd1a7b” />

Authorization documentation improvements

Now Scramble recognizes possible 403 (authorization error) in more cases.

When you call Gate::authorize, Scramble will automatically document 403 response:

public function store(Request $request)
{
    Gate::authorize('create', User::class);

    $data = $request->validate([
        'name' => ['required', 'string'],
        'email' => ['required', 'email'],
    ]);

    return new UserResource(User::create($data));
}

Also now when you use the middleware created by Authorize::using, Scramble will also properly document the possible 403 response:

class CreateUserController extends Controller implements HasMiddleware
{
    public static function middleware(): array
    {
        return [
            Authorize::using('create', User::class)
        ];
    }

    public function store(Request $request)
    {
        $data = $request->validate([
            'name' => ['required', 'string'],
            'email' => ['required', 'email'],
        ]);

        return new UserResource(User::create($data));
    }
}

Thanks to @olivernybroe and @chrisvanlier2005 for these improvements.

What’s Changed

  • Add sometimes validation rule support by @SocolaDaiCa in #802
  • Fix authorization when using Authorize middleware by @olivernybroe in #820
  • Make logo optional to prevent broken image by @vinkla in #821
  • Extend inference API: added the ability to hook in into any method call, including cases when the object a method being called on is unknown by @romalytvynenko in #822
  • Remove “dependencies” concept from reference types by @romalytvynenko in #823
  • Pagination inference by @romalytvynenko in #826
  • Added ability to leave comment to array items in properties defaults by @romalytvynenko in #827
  • Add AuthorizationException when Gate::authorize is called by @chrisvanlier2005 in #828
  • Allow type inference for @property-read in JsonResource by @chrisvanlier2005 in #830
  • String literals decalred with var should be represented as enums not examples by @romalytvynenko in #843
  • Save tags to the OpenAPI document’s tags list by @romalytvynenko in #845
  • Make sure not to keep schemas extracted from request method calls if parameters are not used by @romalytvynenko in #846
  • Fixed accidental closures evaluation when evaluating rules containing closures (like Rule::prohibitedIf) by @romalytvynenko in #847
  • Added support for manual documentation on parameters with names defined as class’ consts by @romalytvynenko in #848
  • Added type inference for binary operators that return boolean by @romalytvynenko in #849
  • Fix error when configuring OpenAPI docs using a callback with DocumentTransformers parameter by @d3radicated in #853

New Contributors

  • @SocolaDaiCa made their first contribution in #802
  • @olivernybroe made their first contribution in #820
  • @vinkla made their first contribution in #821
  • @chrisvanlier2005 made their first contribution in #828
  • @d3radicated made their first contribution in #853
April 2025
Apr 23, 2025
v0.12.19

Error-tolerant rules evaluation

Previously, when Scramble evaluated validation rules (to document request parameters), it could fail due to code that couldn’t be evaluated.

For example, in your update controller method, you might have used data from a real model that exists in the database:

public function update(Request $request, User $user)
{
    $data = $request->validate([
        'level' => ['required', 'integer', Rule::in($user->account->getAvailableLevels())],
    ]);
}

Scramble evaluated such validation rules without sending a real request. So, during documentation generation, it didn’t have access to a “correct” $user model (and what does “correct” even mean without an actual request?). As a result, documentation generation would fail in such cases.

The new release introduces error-tolerant validation rules evaluation. In the example above, Scramble will no longer fail 🚀 This is achieved by evaluating each expression one by one. Scramble processes rules individually, and if it encounters an error — such as with Rule::in($user->account->getAvailableLevels()) — it will simply ignore that rule instead of failing the entire request documentation.

This fixes a whole family of errors where requests weren’t documented. Woohoo! 🎉

  • Improved validation rules evaluation to be more tolerant by @romalytvynenko in #809
Apr 14, 2025
v0.12.18

What’s Changed

  • Improve ExportDocumentation command by @lucascbittencourt in #800
  • Improved 204 response handling, fixed parameter types templates by @romalytvynenko in #801

New Contributors

  • @lucascbittencourt made their first contribution in #800
Apr 4, 2025
v0.7.8 PRO

Documenting query builders defined in called methods

Let’s say you have the following controller that retrieves a list of hotels and returns this list in a response:

class HotelsController
{
    public function __construct(public HotelsListService $hotelsListService) {}
    
    public function index()
    {
        $hotels = $this->hotelsListService->list($request->int('per_page', 15));
        
        return HotelResource::collection()
    }
}

And the following HotelsListService implementation:

class HotelsListService
{
    public function list(int $perPage): QueryBuilder
    {
        return QueryBuilder::for(Hotel::class)
            ->allowedFilters([
                'rooms',
                'name',
                'price',
            ])
            ->allowedSorts([
                'price',
                'rooms',
            ]);
    }
}

Prior to this version Scramble documented only query builders that were constructed in the controller method’s body. But now Scramble analyzes all method calls in the controller’s method so now it can document such cases!

What’s Changed

  • Looking for query builder definitions in the called methods
March 2025
Mar 18, 2025
v0.7.7 PRO

What’s Changed

  • Added toJson, toArray, and toResponse methods support on data objects
Mar 15, 2025
v0.7.6 PRO

This release adds complete only and except support on Laravel Data objects. This includes conditional only and except as well as support for onlyProperties and exceptProperties methods defined in data objects classes.

Consider the following example:

public function show(Company $company)
{
    return CompanyData::from($company)->only('id');
}

Now, Scramble will correctly document that this endpoint returns a structure containing only id property:

{
    "type": "object",
    "properties": {
        "id": {
            "type": "integer"
        }
    },
    "required": [
        "id"
    ]
}

What’s Changed

  • Added only and except support on Laravel Data objects
Mar 15, 2025
v0.7.5 PRO

What’s Changed

  • Fixed breaking change in Laravel Data 4.14 (attributes class was changed)
February 2025
Feb 27, 2025
v0.7.4 PRO

What’s Changed

  • Added Laravel 12.x compatibility
Feb 18, 2025
v0.7.3 PRO

What’s Changed

  • Fixed filter parameters becoming nested if dot used in a name
Scramble PRO
Comprehensive API documentation generation for Spatie’s Laravel Data, Laravel Query Builder, and other packages.