Repository: dedoc/scramble (php)

Issue:
Add ability to specify data format manually
Add an ability to specify data format in response:

```php
return [
    /**
     * @format date-time
     */
    'updated_at' => $this->updated_at->toDateTimeString(),
];
```

See: https://spec.openapis.org/oas/v3.1.0#data-types

Previous implementation: https://github.com/dedoc/scramble/pull/287

Concerns: 
- Is there a better API to do this? Maybe `string<date-time>` (but this type does not make sense for other static analysis tools). 
- Should it be available for both response and request fields?

Pull request description:
Added ability to specify data format in API resources
fixes #328 

Patch:
diff --git a/src/Support/Generator/TypeTransformer.php b/src/Support/Generator/TypeTransformer.php
index ddaee0c..0a075d0 100644
--- a/src/Support/Generator/TypeTransformer.php
+++ b/src/Support/Generator/TypeTransformer.php
@@ -108,6 +108,7 @@ class TypeTransformer
             $openApiType = $this->transform($type->value);
 
             if ($docNode = $type->getAttribute('docNode')) {
+                /** @var PhpDocNode $docNode */
                 $varNode = $docNode->getVarTagValues()[0] ?? null;
 
                 $openApiType = $varNode && $varNode->type
@@ -121,6 +122,10 @@ class TypeTransformer
                 if ($examples = ExamplesExtractor::make($docNode)->extract(preferString: $openApiType instanceof StringType)) {
                     $openApiType->examples($examples);
                 }
+
+                if ($format = array_values($docNode->getTagsByName('@format'))[0]->value->value ?? null) {
+                    $openApiType->format($format);
+                }
             }
         } elseif ($type instanceof Union) {
             if (count($type->types) === 2 && collect($type->types)->contains(fn ($t) => $t instanceof \Dedoc\Scramble\Support\Type\NullType)) {


Test patch:
diff --git a/tests/TypeToSchemaTransformerTest.php b/tests/TypeToSchemaTransformerTest.php
index 25280fe..191baff 100644
--- a/tests/TypeToSchemaTransformerTest.php
+++ b/tests/TypeToSchemaTransformerTest.php
@@ -180,6 +180,21 @@ it('supports @example tag in api resource', function () {
     ]);
 });
 
+it('supports @format tag in api resource', function () {
+    $transformer = new TypeTransformer($infer = app(Infer::class), $components = new Components, [JsonResourceTypeToSchema::class]);
+
+    $type = new ObjectType(ApiResourceTest_ResourceWithFormat::class);
+
+    expect($transformer->transform($type)->toArray())->toBe([
+        '$ref' => '#/components/schemas/ApiResourceTest_ResourceWithFormat',
+    ]);
+
+    expect($components->getSchema(ApiResourceTest_ResourceWithFormat::class)->toArray()['properties']['now'])->toBe([
+        'type' => 'string',
+        'format' => 'date-time',
+    ]);
+});
+
 class ComplexTypeHandlersTest_SampleType extends JsonResource
 {
     public function toArray($request)
@@ -300,6 +315,24 @@ class ApiResourceTest_ResourceWithExamples extends JsonResource
     }
 }
 
+/**
+ * @property SamplePostModel $resource
+ */
+class ApiResourceTest_ResourceWithFormat extends JsonResource
+{
+    public function toArray($request)
+    {
+        return [
+            /**
+             * @var string $now
+             *
+             * @format date-time
+             */
+            'now' => now(),
+        ];
+    }
+}
+
 enum StatusTwo: string
 {
     case DRAFT = 'draft';