Skip to content

Commit d942f2b

Browse files
abnegateclaude
andcommitted
fix: resolve PHPStan type errors from query lib extraction
Add a PHPStan stub for Utopia\Query\Query that declares `@return static` on all factory methods, so PHPStan correctly resolves return types when called via the Utopia\Database\Query subclass. Also fix groupByType() param type and remove dead instanceof checks in parse/parseQuery. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 44c19f9 commit d942f2b

3 files changed

Lines changed: 319 additions & 8 deletions

File tree

phpstan.neon

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
parameters:
2+
stubFiles:
3+
- stubs/Query.stub

src/Database/Query.php

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,6 @@ public static function parse(string $query): self
3232
try {
3333
return parent::parse($query);
3434
} catch (BaseQueryException $e) {
35-
if ($e instanceof QueryException) {
36-
throw $e;
37-
}
3835
throw new QueryException($e->getMessage(), $e->getCode(), $e);
3936
}
4037
}
@@ -49,9 +46,6 @@ public static function parseQuery(array $query): self
4946
try {
5047
return parent::parseQuery($query);
5148
} catch (BaseQueryException $e) {
52-
if ($e instanceof QueryException) {
53-
throw $e;
54-
}
5549
throw new QueryException($e->getMessage(), $e->getCode(), $e);
5650
}
5751
}
@@ -109,7 +103,7 @@ public function toArray(): array
109103
/**
110104
* Iterates through queries and groups them by type
111105
*
112-
* @param array<BaseQuery> $queries
106+
* @param array<Query> $queries
113107
* @return array{
114108
* filters: array<Query>,
115109
* selections: array<Query>,
@@ -133,7 +127,7 @@ public static function groupByType(array $queries): array
133127
$cursorDirection = null;
134128

135129
foreach ($queries as $query) {
136-
if (!$query instanceof BaseQuery) {
130+
if (!$query instanceof self) {
137131
continue;
138132
}
139133

stubs/Query.stub

Lines changed: 314 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,314 @@
1+
<?php
2+
3+
namespace Utopia\Query;
4+
5+
/** @phpstan-consistent-constructor */
6+
class Query
7+
{
8+
/** @param array<mixed> $values */
9+
public function __construct(string $method, string $attribute = '', array $values = []) {}
10+
11+
/** @return static */
12+
public static function parse(string $query): self {}
13+
14+
/**
15+
* @param array<string, mixed> $query
16+
* @return static
17+
*/
18+
public static function parseQuery(array $query): self {}
19+
20+
/**
21+
* @param array<string> $queries
22+
* @return array<static>
23+
*/
24+
public static function parseQueries(array $queries): array {}
25+
26+
/**
27+
* @param array<string|int|float|bool|array<mixed,mixed>> $values
28+
* @return static
29+
*/
30+
public static function equal(string $attribute, array $values): self {}
31+
32+
/**
33+
* @param string|int|float|bool|array<mixed,mixed> $value
34+
* @return static
35+
*/
36+
public static function notEqual(string $attribute, string|int|float|bool|array $value): self {}
37+
38+
/** @return static */
39+
public static function lessThan(string $attribute, string|int|float|bool $value): self {}
40+
41+
/** @return static */
42+
public static function lessThanEqual(string $attribute, string|int|float|bool $value): self {}
43+
44+
/** @return static */
45+
public static function greaterThan(string $attribute, string|int|float|bool $value): self {}
46+
47+
/** @return static */
48+
public static function greaterThanEqual(string $attribute, string|int|float|bool $value): self {}
49+
50+
/**
51+
* @param array<mixed> $values
52+
* @return static
53+
*/
54+
public static function contains(string $attribute, array $values): self {}
55+
56+
/**
57+
* @param array<mixed> $values
58+
* @return static
59+
*/
60+
public static function containsAny(string $attribute, array $values): self {}
61+
62+
/**
63+
* @param array<mixed> $values
64+
* @return static
65+
*/
66+
public static function notContains(string $attribute, array $values): self {}
67+
68+
/** @return static */
69+
public static function between(string $attribute, string|int|float|bool $start, string|int|float|bool $end): self {}
70+
71+
/** @return static */
72+
public static function notBetween(string $attribute, string|int|float|bool $start, string|int|float|bool $end): self {}
73+
74+
/** @return static */
75+
public static function search(string $attribute, string $value): self {}
76+
77+
/** @return static */
78+
public static function notSearch(string $attribute, string $value): self {}
79+
80+
/**
81+
* @param array<string> $attributes
82+
* @return static
83+
*/
84+
public static function select(array $attributes): self {}
85+
86+
/** @return static */
87+
public static function orderDesc(string $attribute = ''): self {}
88+
89+
/** @return static */
90+
public static function orderAsc(string $attribute = ''): self {}
91+
92+
/** @return static */
93+
public static function orderRandom(): self {}
94+
95+
/** @return static */
96+
public static function limit(int $value): self {}
97+
98+
/** @return static */
99+
public static function offset(int $value): self {}
100+
101+
/** @return static */
102+
public static function cursorAfter(mixed $value): self {}
103+
104+
/** @return static */
105+
public static function cursorBefore(mixed $value): self {}
106+
107+
/** @return static */
108+
public static function isNull(string $attribute): self {}
109+
110+
/** @return static */
111+
public static function isNotNull(string $attribute): self {}
112+
113+
/** @return static */
114+
public static function startsWith(string $attribute, string $value): self {}
115+
116+
/** @return static */
117+
public static function notStartsWith(string $attribute, string $value): self {}
118+
119+
/** @return static */
120+
public static function endsWith(string $attribute, string $value): self {}
121+
122+
/** @return static */
123+
public static function notEndsWith(string $attribute, string $value): self {}
124+
125+
/** @return static */
126+
public static function createdBefore(string $value): self {}
127+
128+
/** @return static */
129+
public static function createdAfter(string $value): self {}
130+
131+
/** @return static */
132+
public static function updatedBefore(string $value): self {}
133+
134+
/** @return static */
135+
public static function updatedAfter(string $value): self {}
136+
137+
/** @return static */
138+
public static function createdBetween(string $start, string $end): self {}
139+
140+
/** @return static */
141+
public static function updatedBetween(string $start, string $end): self {}
142+
143+
/**
144+
* @param array<Query> $queries
145+
* @return static
146+
*/
147+
public static function or(array $queries): self {}
148+
149+
/**
150+
* @param array<Query> $queries
151+
* @return static
152+
*/
153+
public static function and(array $queries): self {}
154+
155+
/**
156+
* @param array<mixed> $values
157+
* @return static
158+
*/
159+
public static function containsAll(string $attribute, array $values): self {}
160+
161+
/**
162+
* @param array<Query> $queries
163+
* @return static
164+
*/
165+
public static function elemMatch(string $attribute, array $queries): self {}
166+
167+
/**
168+
* @param array<static> $queries
169+
* @param array<string> $types
170+
* @return array<static>
171+
*/
172+
public static function getByType(array $queries, array $types, bool $clone = true): array {}
173+
174+
/**
175+
* @param array<static> $queries
176+
* @return array<static>
177+
*/
178+
public static function getCursorQueries(array $queries, bool $clone = true): array {}
179+
180+
/**
181+
* @param array<mixed> $queries
182+
* @return array{
183+
* filters: array<static>,
184+
* selections: array<static>,
185+
* limit: int|null,
186+
* offset: int|null,
187+
* orderAttributes: array<string>,
188+
* orderTypes: array<string>,
189+
* cursor: mixed,
190+
* cursorDirection: string|null
191+
* }
192+
*/
193+
public static function groupByType(array $queries): array {}
194+
195+
/** @return static */
196+
public function setMethod(string $method): self {}
197+
198+
/** @return static */
199+
public function setAttribute(string $attribute): self {}
200+
201+
/**
202+
* @param array<mixed> $values
203+
* @return static
204+
*/
205+
public function setValues(array $values): self {}
206+
207+
/** @return static */
208+
public function setValue(mixed $value): self {}
209+
210+
/**
211+
* @param array<mixed> $values
212+
* @return static
213+
*/
214+
public static function distanceEqual(string $attribute, array $values, int|float $distance, bool $meters = false): self {}
215+
216+
/**
217+
* @param array<mixed> $values
218+
* @return static
219+
*/
220+
public static function distanceNotEqual(string $attribute, array $values, int|float $distance, bool $meters = false): self {}
221+
222+
/**
223+
* @param array<mixed> $values
224+
* @return static
225+
*/
226+
public static function distanceGreaterThan(string $attribute, array $values, int|float $distance, bool $meters = false): self {}
227+
228+
/**
229+
* @param array<mixed> $values
230+
* @return static
231+
*/
232+
public static function distanceLessThan(string $attribute, array $values, int|float $distance, bool $meters = false): self {}
233+
234+
/**
235+
* @param array<mixed> $values
236+
* @return static
237+
*/
238+
public static function intersects(string $attribute, array $values): self {}
239+
240+
/**
241+
* @param array<mixed> $values
242+
* @return static
243+
*/
244+
public static function notIntersects(string $attribute, array $values): self {}
245+
246+
/**
247+
* @param array<mixed> $values
248+
* @return static
249+
*/
250+
public static function crosses(string $attribute, array $values): self {}
251+
252+
/**
253+
* @param array<mixed> $values
254+
* @return static
255+
*/
256+
public static function notCrosses(string $attribute, array $values): self {}
257+
258+
/**
259+
* @param array<mixed> $values
260+
* @return static
261+
*/
262+
public static function overlaps(string $attribute, array $values): self {}
263+
264+
/**
265+
* @param array<mixed> $values
266+
* @return static
267+
*/
268+
public static function notOverlaps(string $attribute, array $values): self {}
269+
270+
/**
271+
* @param array<mixed> $values
272+
* @return static
273+
*/
274+
public static function touches(string $attribute, array $values): self {}
275+
276+
/**
277+
* @param array<mixed> $values
278+
* @return static
279+
*/
280+
public static function notTouches(string $attribute, array $values): self {}
281+
282+
/**
283+
* @param array<float> $vector
284+
* @return static
285+
*/
286+
public static function vectorDot(string $attribute, array $vector): self {}
287+
288+
/**
289+
* @param array<float> $vector
290+
* @return static
291+
*/
292+
public static function vectorCosine(string $attribute, array $vector): self {}
293+
294+
/**
295+
* @param array<float> $vector
296+
* @return static
297+
*/
298+
public static function vectorEuclidean(string $attribute, array $vector): self {}
299+
300+
/** @return static */
301+
public static function regex(string $attribute, string $pattern): self {}
302+
303+
/**
304+
* @param array<string> $attributes
305+
* @return static
306+
*/
307+
public static function exists(array $attributes): self {}
308+
309+
/**
310+
* @param string|int|float|bool|array<mixed,mixed> $attribute
311+
* @return static
312+
*/
313+
public static function notExists(string|int|float|bool|array $attribute): self {}
314+
}

0 commit comments

Comments
 (0)