- 
                Notifications
    
You must be signed in to change notification settings  - Fork 178
 
Description
What happened?
When using a dynamic array key inside a FormRequest’s rules() method, Scramble does not include the PHPDoc description written above it.
It works perfectly with static keys but fails when the key is generated dynamically.
Scramble should attach the docblock description to the field even when the key is defined using a dynamic expression, as long as the key can be resolved at runtime or the expression is documented above it.
How to reproduce the bug
Given a Laravel FormRequest:
public function rules()
{
    return [
            /**
             * The configuration for `fcm` channel.  
             * It is required when you send `fcm` in channels.
             */
            'fcm' => [
                Rule::requiredIf(fn(): bool => $this->needConfigurationForChannel(ChannelEnum::FCM)),
            ],
            /**
             * The Firebase registeration token of the user on it's device.  
             * This is the `token` field which is exists in result of call to:  
             *  https://fcmregistrations.googleapis.com/v1/projects/{PROJECT_ID}/registrations
             */
            'fcm.token' => [
                Rule::requiredIf(fn(): bool => $this->needConfigurationForChannel(ChannelEnum::FCM)),
                'string',
                'min:100',
                'max:200',
            ],
    ];
}✅ Works perfectly — Scramble shows the above description:
But this version loses the description:
public function rules()
{
    return [
            /**
             * The configuration for `fcm` channel.  
             * It is required when you send `fcm` in channels.
             */
            $this->channelName(ChannelEnum::FCM) => [
                Rule::requiredIf(fn(): bool => $this->needConfigurationForChannel(ChannelEnum::FCM)),
            ],
            /**
             * The Firebase registeration token of the user on it's device.  
             * This is the `token` field which is exists in result of call to:  
             *  https://fcmregistrations.googleapis.com/v1/projects/{PROJECT_ID}/registrations
             */
            $this->channelName(ChannelEnum::FCM, 'token') => [
                Rule::requiredIf(fn(): bool => $this->needConfigurationForChannel(ChannelEnum::FCM)),
                'string',
                'min:100',
                'max:200',
            ],
    ];
}❌ The field appears in the docs (if Scramble can detect it), but the description is missing:
Package Version
0.12.35
PHP Version
8.3.26
Laravel Version
12.31.1
Which operating systems does with happen with?
Linux
Notes
After inspecting the source, it seems this behavior is caused by how Scramble currently handles array keys and documentation extraction:
- 
In src/Infer/Handler/ArrayItemHandler.php, the key type is set only if it is a
LiteralStringType, and there’s even a@todocomment indicating dynamic keys are not yet handled:$keyType instanceof LiteralStringType ? $keyType->value : null, // @todo handle cases when key is something dynamic
As a result, any dynamic key (e.g.,
$this->channelName(ChannelEnum::FCM)) produces anArrayItemType_without a resolvable string key. - 
Then, in src/Support/OperationExtensions/ParameterExtractor/TypeBasedRulesDocumentationRetriever.php, the method
getDocNodes()ignores such entries because of this check:if (! $key = $this->getArrayItemKey($item)) { return []; // <- documentation for dynamic keys is discarded here }
 
Because the $key is null for dynamic expressions, the docblock is skipped entirely — even though the ArrayItemType_ may contain a valid docNode attribute.
A possible improvement would be to preserve the PHPDoc node for dynamic keys instead of discarding it, maybe by:
- Storing it under a placeholder name (e.g. 
"dynamic_key_<line_number>") - Or evaluate the rule and get the key