Skip to content

Commit 3a242be

Browse files
committed
wip
1 parent b06b2f3 commit 3a242be

File tree

4 files changed

+101
-62
lines changed

4 files changed

+101
-62
lines changed

src/Mergeable.php

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -40,16 +40,23 @@ public function matchesOn();
4040
public function shouldAppend();
4141

4242
/**
43-
* Determine if the property has paths to append.
43+
* Determine if the property should merge at the root level (vs at specific paths).
4444
*
4545
* @return bool
4646
*/
47-
public function hasAppendPaths();
47+
public function shouldMergeAtRootLevel();
4848

4949
/**
50-
* Determine if the property has paths to prepend.
50+
* Get the paths to append when merging.
5151
*
52-
* @return bool
52+
* @return array<int, string>
53+
*/
54+
public function appendPaths(): array;
55+
56+
/**
57+
* Get the paths to prepend when merging.
58+
*
59+
* @return array<int, string>
5360
*/
54-
public function hasPrependPaths();
61+
public function prependPaths(): array;
5562
}

src/MergesProps.php

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -143,19 +143,11 @@ public function prepend(string|bool $key = true, ?string $matchOn = null): self
143143
}
144144

145145
/**
146-
* Determine if the property has paths to append.
146+
* Determine if the property should merge at the root level (vs at specific paths).
147147
*/
148-
public function hasAppendPaths(): bool
148+
public function shouldMergeAtRootLevel(): bool
149149
{
150-
return count($this->appendPaths) > 0;
151-
}
152-
153-
/**
154-
* Determine if the property has paths to prepend.
155-
*/
156-
public function hasPrependPaths(): bool
157-
{
158-
return count($this->prependPaths) > 0;
150+
return count($this->appendPaths) === 0 && count($this->prependPaths) === 0;
159151
}
160152

161153
/**
@@ -177,4 +169,5 @@ public function prependPaths(): array
177169
{
178170
return $this->prependPaths;
179171
}
172+
180173
}

src/Response.php

Lines changed: 79 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -483,54 +483,97 @@ public function resolveMergeProps(Request $request): array
483483
{
484484
$mergeProps = $this->getMergePropsForRequest($request);
485485

486-
$mergePropsWithAppendOrPrependPath = $mergeProps
487-
->filter(fn (Mergeable $prop) => $prop->hasAppendPaths() || $prop->hasPrependPaths())
488-
->keys();
486+
return array_filter([
487+
'mergeProps' => $this->resolveAppendMergeProps($mergeProps),
488+
'prependProps' => $this->resolvePrependMergeProps($mergeProps),
489+
'deepMergeProps' => $this->resolveDeepMergeProps($mergeProps),
490+
'matchPropsOn' => $this->resolveMergeMatchingKeys($mergeProps),
491+
], fn ($prop) => count($prop) > 0);
492+
}
489493

490-
$deepMergeProps = $mergeProps
491-
->reject(fn ($_, string $key) => $mergePropsWithAppendOrPrependPath->contains($key))
492-
->filter(fn (Mergeable $prop) => $prop->shouldDeepMerge())
494+
/**
495+
* Resolve props that should be appended during merging.
496+
*
497+
* @param \Illuminate\Support\Collection<string, \Inertia\Mergeable> $mergeProps
498+
* @return array<int, string>
499+
*/
500+
protected function resolveAppendMergeProps(Collection $mergeProps): array
501+
{
502+
[$regularMergeProps, $appendPaths] = $mergeProps
503+
->reject(fn (Mergeable $prop) => $prop->shouldDeepMerge())
504+
->partition(fn (Mergeable $prop) => $prop->shouldMergeAtRootLevel());
505+
506+
// Regular merge props (root level merging)
507+
$regularMergeProps = $regularMergeProps
508+
->filter(fn (Mergeable $prop) => $prop->shouldAppend())
493509
->keys();
494510

495-
$matchPropsOn = $mergeProps
496-
->map(function (Mergeable $prop, $key) {
497-
return collect($prop->matchesOn())
498-
->map(fn ($strategy) => $key.'.'.$strategy)
499-
->toArray();
500-
})
501-
->flatten()
511+
// Specific append paths from MergeProp instances
512+
$appendPaths = $appendPaths
513+
->flatMap(fn (Mergeable $prop, string $key) => collect($prop->appendPaths())->map(fn ($path) => $path ? $key.'.'.$path : $key))
514+
->unique()
502515
->values();
503516

504-
$prependProps = $mergeProps
505-
->reject(fn ($_, string $key) => $mergePropsWithAppendOrPrependPath->contains($key))
506-
->filter(fn (Mergeable $prop) => ! $prop->shouldAppend() && ! $prop->shouldDeepMerge())
507-
->keys();
517+
return $regularMergeProps->merge($appendPaths)->values()->toArray();
518+
}
519+
520+
/**
521+
* Resolve props that should be prepended during merging.
522+
*
523+
* @param \Illuminate\Support\Collection<string, \Inertia\Mergeable> $mergeProps
524+
* @return array<int, string>
525+
*/
526+
protected function resolvePrependMergeProps(Collection $mergeProps): array
527+
{
528+
[$regularPrependProps, $prependPaths] = $mergeProps
529+
->reject(fn (Mergeable $prop) => $prop->shouldDeepMerge())
530+
->partition(fn (Mergeable $prop) => $prop->shouldMergeAtRootLevel());
508531

509-
$mergeProps = $mergeProps
510-
->reject(fn ($_, string $key) => $mergePropsWithAppendOrPrependPath->contains($key))
511-
->filter(fn (Mergeable $prop) => $prop->shouldAppend() && ! $prop->shouldDeepMerge())
532+
// Regular prepend props (root level merging)
533+
$regularPrependProps = $regularPrependProps
534+
->filter(fn (Mergeable $prop) => ! $prop->shouldAppend())
512535
->keys();
513536

514-
$appendPaths = collect($this->props)
515-
->filter(fn ($prop) => $prop instanceof MergeProp)
516-
->flatMap(fn (MergeProp $prop, string $key) => collect($prop->appendPaths())->map(fn ($path) => $path ? $key.'.'.$path : $key))
537+
// Specific prepend paths from MergeProp instances
538+
$prependPaths = $mergeProps
539+
->flatMap(fn (Mergeable $prop, string $key) => collect($prop->prependPaths())->map(fn ($path) => $path ? $key.'.'.$path : $key))
517540
->unique()
518541
->values();
519542

520-
$prependPaths = collect($this->props)
521-
->filter(fn ($prop) => $prop instanceof MergeProp)
522-
->flatMap(fn (MergeProp $prop, string $key) => collect($prop->prependPaths())->map(fn ($path) => $path ? $key.'.'.$path : $key))
523-
->unique()
524-
->values();
543+
return $regularPrependProps->merge($prependPaths)->values()->toArray();
544+
}
525545

526-
return array_filter([
527-
'mergeProps' => $mergeProps->toArray(),
528-
'prependProps' => $prependProps->toArray(),
529-
'deepMergeProps' => $deepMergeProps->toArray(),
530-
'matchPropsOn' => $matchPropsOn->toArray(),
531-
'appendPaths' => $appendPaths->toArray(),
532-
'prependPaths' => $prependPaths->toArray(),
533-
], fn ($prop) => count($prop) > 0);
546+
/**
547+
* Resolve props that should be deep merged.
548+
*
549+
* @param \Illuminate\Support\Collection<string, \Inertia\Mergeable> $mergeProps
550+
* @return array<int, string>
551+
*/
552+
protected function resolveDeepMergeProps(Collection $mergeProps): array
553+
{
554+
return $mergeProps
555+
->filter(fn (Mergeable $prop) => $prop->shouldDeepMerge())
556+
->keys()
557+
->toArray();
558+
}
559+
560+
/**
561+
* Resolve the matching keys for merge props.
562+
*
563+
* @param \Illuminate\Support\Collection<string, \Inertia\Mergeable> $mergeProps
564+
* @return array<int, string>
565+
*/
566+
protected function resolveMergeMatchingKeys(Collection $mergeProps): array
567+
{
568+
return $mergeProps
569+
->map(function (Mergeable $prop, $key) {
570+
return collect($prop->matchesOn())
571+
->map(fn ($strategy) => $key.'.'.$strategy)
572+
->toArray();
573+
})
574+
->flatten()
575+
->values()
576+
->toArray();
534577
}
535578

536579
/**

tests/ResponseTest.php

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -235,14 +235,12 @@ public function test_server_response_with_merge_props_that_has_nested_paths_to_a
235235
$this->assertSame('Jonathan', $page['props']['user']['name']);
236236
$this->assertSame('/user/123', $page['url']);
237237
$this->assertSame('123', $page['version']);
238-
$this->assertArrayNotHasKey('mergeProps', $page);
239-
$this->assertArrayNotHasKey('prependProps', $page);
238+
$this->assertSame(['foo.data'], $page['mergeProps']);
239+
$this->assertSame(['bar.data.items'], $page['prependProps']);
240240
$this->assertArrayNotHasKey('matchPropsOn', $page);
241-
$this->assertSame(['foo.data'], $page['appendPaths']);
242-
$this->assertSame(['bar.data.items'], $page['prependPaths']);
243241
$this->assertFalse($page['clearHistory']);
244242
$this->assertFalse($page['encryptHistory']);
245-
$this->assertSame('<div id="app" data-page="{&quot;component&quot;:&quot;User\/Edit&quot;,&quot;props&quot;:{&quot;user&quot;:{&quot;name&quot;:&quot;Jonathan&quot;},&quot;foo&quot;:{&quot;data&quot;:[{&quot;id&quot;:1},{&quot;id&quot;:2}]},&quot;bar&quot;:{&quot;data&quot;:{&quot;items&quot;:[{&quot;uuid&quot;:1},{&quot;uuid&quot;:2}]}}},&quot;url&quot;:&quot;\/user\/123&quot;,&quot;version&quot;:&quot;123&quot;,&quot;clearHistory&quot;:false,&quot;encryptHistory&quot;:false,&quot;appendPaths&quot;:[&quot;foo.data&quot;],&quot;prependPaths&quot;:[&quot;bar.data.items&quot;]}"></div>', $view->render());
243+
$this->assertSame('<div id="app" data-page="{&quot;component&quot;:&quot;User\/Edit&quot;,&quot;props&quot;:{&quot;user&quot;:{&quot;name&quot;:&quot;Jonathan&quot;},&quot;foo&quot;:{&quot;data&quot;:[{&quot;id&quot;:1},{&quot;id&quot;:2}]},&quot;bar&quot;:{&quot;data&quot;:{&quot;items&quot;:[{&quot;uuid&quot;:1},{&quot;uuid&quot;:2}]}}},&quot;url&quot;:&quot;\/user\/123&quot;,&quot;version&quot;:&quot;123&quot;,&quot;clearHistory&quot;:false,&quot;encryptHistory&quot;:false,&quot;mergeProps&quot;:[&quot;foo.data&quot;],&quot;prependProps&quot;:[&quot;bar.data.items&quot;]}"></div>', $view->render());
246244
}
247245

248246
public function test_server_response_with_merge_props_that_has_nested_paths_to_append_and_prepend_with_match_on_strategies(): void
@@ -272,14 +270,12 @@ public function test_server_response_with_merge_props_that_has_nested_paths_to_a
272270
$this->assertSame('Jonathan', $page['props']['user']['name']);
273271
$this->assertSame('/user/123', $page['url']);
274272
$this->assertSame('123', $page['version']);
275-
$this->assertArrayNotHasKey('mergeProps', $page);
276-
$this->assertArrayNotHasKey('prependProps', $page);
277-
$this->assertSame(['foo.data'], $page['appendPaths']);
278-
$this->assertSame(['bar.data.items'], $page['prependPaths']);
273+
$this->assertSame(['foo.data'], $page['mergeProps']);
274+
$this->assertSame(['bar.data.items'], $page['prependProps']);
279275
$this->assertSame(['foo.data.id', 'bar.data.items.uuid'], $page['matchPropsOn']);
280276
$this->assertFalse($page['clearHistory']);
281277
$this->assertFalse($page['encryptHistory']);
282-
$this->assertSame('<div id="app" data-page="{&quot;component&quot;:&quot;User\/Edit&quot;,&quot;props&quot;:{&quot;user&quot;:{&quot;name&quot;:&quot;Jonathan&quot;},&quot;foo&quot;:{&quot;data&quot;:[{&quot;id&quot;:1},{&quot;id&quot;:2}]},&quot;bar&quot;:{&quot;data&quot;:{&quot;items&quot;:[{&quot;uuid&quot;:1},{&quot;uuid&quot;:2}]}}},&quot;url&quot;:&quot;\/user\/123&quot;,&quot;version&quot;:&quot;123&quot;,&quot;clearHistory&quot;:false,&quot;encryptHistory&quot;:false,&quot;matchPropsOn&quot;:[&quot;foo.data.id&quot;,&quot;bar.data.items.uuid&quot;],&quot;appendPaths&quot;:[&quot;foo.data&quot;],&quot;prependPaths&quot;:[&quot;bar.data.items&quot;]}"></div>', $view->render());
278+
$this->assertSame('<div id="app" data-page="{&quot;component&quot;:&quot;User\/Edit&quot;,&quot;props&quot;:{&quot;user&quot;:{&quot;name&quot;:&quot;Jonathan&quot;},&quot;foo&quot;:{&quot;data&quot;:[{&quot;id&quot;:1},{&quot;id&quot;:2}]},&quot;bar&quot;:{&quot;data&quot;:{&quot;items&quot;:[{&quot;uuid&quot;:1},{&quot;uuid&quot;:2}]}}},&quot;url&quot;:&quot;\/user\/123&quot;,&quot;version&quot;:&quot;123&quot;,&quot;clearHistory&quot;:false,&quot;encryptHistory&quot;:false,&quot;mergeProps&quot;:[&quot;foo.data&quot;],&quot;prependProps&quot;:[&quot;bar.data.items&quot;],&quot;matchPropsOn&quot;:[&quot;foo.data.id&quot;,&quot;bar.data.items.uuid&quot;]}"></div>', $view->render());
283279
}
284280

285281
public function test_server_response_with_deep_merge_props(): void

0 commit comments

Comments
 (0)