@@ -113,7 +113,7 @@ enum: [0, 1],
113
113
if ($ this ->description !== null && $ this ->description !== '' && !$ isParameter ) {
114
114
$ values ['description ' ] = Helpers::cleanDocComment ($ this ->description );
115
115
}
116
- if ($ this ->items instanceof \ OpenAPIExtractor \ OpenApiType) {
116
+ if ($ this ->items instanceof OpenApiType) {
117
117
$ values ['items ' ] = $ this ->items ->toArray ();
118
118
}
119
119
if ($ this ->minLength !== null ) {
@@ -139,7 +139,7 @@ enum: [0, 1],
139
139
}
140
140
if ($ this ->properties !== null && $ this ->properties !== []) {
141
141
$ values ['properties ' ] = array_combine (array_keys ($ this ->properties ),
142
- array_map (static fn (OpenApiType $ property ): array |\ stdClass => $ property ->toArray (), array_values ($ this ->properties )),
142
+ array_map (static fn (OpenApiType $ property ): array |stdClass => $ property ->toArray (), array_values ($ this ->properties )),
143
143
);
144
144
}
145
145
if ($ this ->additionalProperties !== null ) {
@@ -150,13 +150,13 @@ enum: [0, 1],
150
150
}
151
151
}
152
152
if ($ this ->oneOf !== null ) {
153
- $ values ['oneOf ' ] = array_map (fn (OpenApiType $ type ): array |\ stdClass => $ type ->toArray (), $ this ->oneOf );
153
+ $ values ['oneOf ' ] = array_map (fn (OpenApiType $ type ): array |stdClass => $ type ->toArray (), $ this ->oneOf );
154
154
}
155
155
if ($ this ->anyOf !== null ) {
156
- $ values ['anyOf ' ] = array_map (fn (OpenApiType $ type ): array |\ stdClass => $ type ->toArray (), $ this ->anyOf );
156
+ $ values ['anyOf ' ] = array_map (fn (OpenApiType $ type ): array |stdClass => $ type ->toArray (), $ this ->anyOf );
157
157
}
158
158
if ($ this ->allOf !== null ) {
159
- $ values ['allOf ' ] = array_map (fn (OpenApiType $ type ): array |\ stdClass => $ type ->toArray (), $ this ->allOf );
159
+ $ values ['allOf ' ] = array_map (fn (OpenApiType $ type ): array |stdClass => $ type ->toArray (), $ this ->allOf );
160
160
}
161
161
162
162
return $ values !== [] ? $ values : new stdClass ();
@@ -184,9 +184,9 @@ public static function resolve(string $context, array $definitions, ParamTagValu
184
184
items: self ::resolve ($ context . ': items ' , $ definitions , $ node ->type ),
185
185
);
186
186
}
187
- if ($ node instanceof GenericTypeNode && ($ node ->type ->name === 'array ' || $ node ->type ->name === 'list ' || $ node ->type ->name === 'non-empty-list ' ) && count ($ node ->genericTypes ) === 1 ) {
188
- if ($ node ->type ->name === 'array ' ) {
189
- Logger::error ($ context , "The 'array<TYPE>' syntax for arrays is forbidden due to ambiguities. Use 'list<TYPE>' for JSON arrays or 'array<string, TYPE>' for JSON objects instead. " );
187
+ if ($ node instanceof GenericTypeNode && ($ node ->type ->name === 'array ' || $ node ->type ->name === 'non-empty-array ' || $ node -> type -> name === ' list ' || $ node ->type ->name === 'non-empty-list ' ) && count ($ node ->genericTypes ) === 1 ) {
188
+ if ($ node ->type ->name === 'array ' || $ node -> type -> name === ' non-empty-array ' ) {
189
+ Logger::error ($ context , "The 'array<TYPE>' and 'non-empty-array<TYPE>' syntax for arrays is forbidden due to ambiguities. Use 'list<TYPE>' for JSON arrays or 'non-empty- array<string, TYPE>' for JSON objects instead. " );
190
190
}
191
191
192
192
if ($ node ->genericTypes [0 ] instanceof IdentifierTypeNode && $ node ->genericTypes [0 ]->name === 'empty ' ) {
@@ -213,7 +213,7 @@ public static function resolve(string $context, array $definitions, ParamTagValu
213
213
foreach ($ node ->items as $ item ) {
214
214
$ name = $ item ->keyName instanceof ConstExprStringNode ? $ item ->keyName ->value : $ item ->keyName ->name ;
215
215
$ type = self ::resolve ($ context . ': ' . $ name , $ definitions , $ item ->valueType );
216
- $ comments = array_map (static fn (Comment $ comment ): ?string => preg_replace ('/^\/\/\s*/ ' , '' , $ comment ->text ), $ item ->keyName ->getAttribute (Attribute::COMMENTS ) ?? []);
216
+ $ comments = array_map (static fn (Comment $ comment ): ?string => preg_replace ('/^\/\/\s*/ ' , '' , $ comment ->text ), $ item ->keyName ->getAttribute (Attribute::COMMENTS ) ?? []);
217
217
if ($ comments !== []) {
218
218
$ type ->description = implode ("\n" , $ comments );
219
219
}
@@ -232,7 +232,11 @@ public static function resolve(string $context, array $definitions, ParamTagValu
232
232
);
233
233
}
234
234
235
- if ($ node instanceof GenericTypeNode && $ node ->type ->name === 'array ' && count ($ node ->genericTypes ) === 2 && $ node ->genericTypes [0 ] instanceof IdentifierTypeNode) {
235
+ if ($ node instanceof GenericTypeNode && in_array ($ node ->type ->name , ['array ' , 'non-empty-array ' ]) && count ($ node ->genericTypes ) === 2 && $ node ->genericTypes [0 ] instanceof IdentifierTypeNode) {
236
+ if ($ node ->type ->name !== 'non-empty-array ' ) {
237
+ Logger::error ($ context , 'You must ensure JSON objects are not empty using the "non-empty-array" type. To allow return empty JSON objects your code must manually check if the array is empty in order to return "new \\stdClass()" and use "non-empty-array| \\stdClass" as the type. ' );
238
+ }
239
+
236
240
$ allowedTypes = ['string ' , 'lowercase-string ' , 'non-empty-string ' , 'non-empty-lowercase-string ' ];
237
241
if (in_array ($ node ->genericTypes [0 ]->name , $ allowedTypes , true )) {
238
242
return new OpenApiType (
@@ -271,14 +275,14 @@ public static function resolve(string $context, array $definitions, ParamTagValu
271
275
272
276
$ isUnion = $ node instanceof UnionTypeNode || $ node instanceof UnionType;
273
277
$ isIntersection = $ node instanceof IntersectionTypeNode || $ node instanceof IntersectionType;
274
- if ($ isUnion && count ($ node ->types ) === count (array_filter ($ node ->types , fn ($ type ): bool => $ type instanceof ConstTypeNode && $ type ->constExpr instanceof ConstExprStringNode))) {
278
+ if ($ isUnion && count ($ node ->types ) === count (array_filter ($ node ->types , fn ($ type ): bool => $ type instanceof ConstTypeNode && $ type ->constExpr instanceof ConstExprStringNode))) {
275
279
$ values = [];
276
280
/** @var ConstTypeNode $type */
277
281
foreach ($ node ->types as $ type ) {
278
282
$ values [] = $ type ->constExpr ->value ;
279
283
}
280
284
281
- if (array_filter ($ values , fn (string $ value ): bool => $ value === '' ) !== []) {
285
+ if (array_filter ($ values , fn (string $ value ): bool => $ value === '' ) !== []) {
282
286
// Not a valid enum
283
287
return new OpenApiType (
284
288
context: $ context ,
@@ -292,14 +296,14 @@ public static function resolve(string $context, array $definitions, ParamTagValu
292
296
enum: $ values ,
293
297
);
294
298
}
295
- if ($ isUnion && count ($ node ->types ) === count (array_filter ($ node ->types , fn ($ type ): bool => $ type instanceof ConstTypeNode && $ type ->constExpr instanceof ConstExprIntegerNode))) {
299
+ if ($ isUnion && count ($ node ->types ) === count (array_filter ($ node ->types , fn ($ type ): bool => $ type instanceof ConstTypeNode && $ type ->constExpr instanceof ConstExprIntegerNode))) {
296
300
$ values = [];
297
301
/** @var ConstTypeNode $type */
298
302
foreach ($ node ->types as $ type ) {
299
303
$ values [] = (int )$ type ->constExpr ->value ;
300
304
}
301
305
302
- if (array_filter ($ values , fn (string $ value ): bool => $ value === '' ) !== []) {
306
+ if (array_filter ($ values , fn (string $ value ): bool => $ value === '' ) !== []) {
303
307
// Not a valid enum
304
308
return new OpenApiType (
305
309
context: $ context ,
@@ -355,7 +359,7 @@ enum: $values,
355
359
return $ item ->type ;
356
360
}, $ items );
357
361
358
- if (array_filter ($ itemTypes , static fn (?string $ type ): bool => $ type === null ) !== [] || count ($ itemTypes ) !== count (array_unique ($ itemTypes ))) {
362
+ if (array_filter ($ itemTypes , static fn (?string $ type ): bool => $ type === null ) !== [] || count ($ itemTypes ) !== count (array_unique ($ itemTypes ))) {
359
363
return new OpenApiType (
360
364
context: $ context ,
361
365
nullable: $ nullable ,
@@ -422,21 +426,21 @@ private static function mergeEnums(string $context, array $types): array {
422
426
}
423
427
}
424
428
425
- foreach (array_map (static fn (OpenApiType $ type ): ?string => $ type ->type , $ nonEnums ) as $ type ) {
429
+ foreach (array_map (static fn (OpenApiType $ type ): ?string => $ type ->type , $ nonEnums ) as $ type ) {
426
430
if (array_key_exists ($ type , $ enums )) {
427
431
unset($ enums [$ type ]);
428
432
}
429
433
}
430
434
431
- return array_merge ($ nonEnums , array_map (static fn (string $ type ): \ OpenAPIExtractor \ OpenApiType => new OpenApiType (
435
+ return array_merge ($ nonEnums , array_map (static fn (string $ type ): OpenApiType => new OpenApiType (
432
436
context: $ context ,
433
437
type: $ type , enum: $ enums [$ type ],
434
438
), array_keys ($ enums )));
435
439
}
436
440
437
441
private static function resolveIdentifier (string $ context , array $ definitions , string $ name ): OpenApiType {
438
442
if ($ name === 'array ' ) {
439
- Logger::error ($ context , "Instead of 'array' use: \n'new stdClass()' for empty objects \n'array<string, mixed>' for non-empty objects \n'array <emtpy>' for empty lists \n'array <YourTypeHere>' for lists " );
443
+ Logger::error ($ context , "Instead of 'array' use: \n'new stdClass()' for empty objects \n'non-empty- array<string, mixed>' for non-empty objects \n'list <emtpy>' for empty lists \n'list <YourTypeHere>' for lists " );
440
444
}
441
445
if (str_starts_with ($ name , '\\' )) {
442
446
$ name = substr ($ name , 1 );
@@ -455,7 +459,7 @@ private static function resolveIdentifier(string $context, array $definitions, s
455
459
'numeric ' => new OpenApiType (context: $ context , type: 'number ' ),
456
460
// https://www.php.net/manual/en/language.types.float.php: Both float and double are always stored with double precision
457
461
'float ' , 'double ' => new OpenApiType (context: $ context , type: 'number ' , format: 'double ' ),
458
- 'mixed ' , 'empty ' , ' array ' => new OpenApiType (context: $ context , type: 'object ' ),
462
+ 'mixed ' , 'empty ' => new OpenApiType (context: $ context , type: 'object ' ),
459
463
'object ' , 'stdClass ' => new OpenApiType (context: $ context , type: 'object ' , additionalProperties: true ),
460
464
'null ' => new OpenApiType (context: $ context , nullable: true ),
461
465
default => (function () use ($ context , $ definitions , $ name ) {
0 commit comments