diff --git a/src/Support/TypeScriptTransformer/DataTypeScriptCollector.php b/src/Support/TypeScriptTransformer/DataTypeScriptCollector.php new file mode 100644 index 00000000..364e40d1 --- /dev/null +++ b/src/Support/TypeScriptTransformer/DataTypeScriptCollector.php @@ -0,0 +1,22 @@ +isSubclassOf(BaseData::class)) { + return null; + } + + $transformer = new DataTypeScriptTransformer($this->config); + + return $transformer->transform($class, $class->getShortName()); + } +} diff --git a/src/Support/TypeScriptTransformer/DataTypeScriptTransformer.php b/src/Support/TypeScriptTransformer/DataTypeScriptTransformer.php index 21494cce..eb2e8cd2 100644 --- a/src/Support/TypeScriptTransformer/DataTypeScriptTransformer.php +++ b/src/Support/TypeScriptTransformer/DataTypeScriptTransformer.php @@ -2,21 +2,169 @@ namespace Spatie\LaravelData\Support\TypeScriptTransformer; +use phpDocumentor\Reflection\Fqsen; +use phpDocumentor\Reflection\Type; +use phpDocumentor\Reflection\Types\Array_; +use phpDocumentor\Reflection\Types\Boolean; +use phpDocumentor\Reflection\Types\Integer; +use phpDocumentor\Reflection\Types\Nullable; +use phpDocumentor\Reflection\Types\Object_; +use phpDocumentor\Reflection\Types\String_; use ReflectionClass; +use ReflectionProperty; +use RuntimeException; use Spatie\LaravelData\Contracts\BaseData; -use Spatie\TypeScriptTransformer\Transformers\ClassTransformer; +use Spatie\LaravelData\Enums\DataTypeKind; +use Spatie\LaravelData\Support\DataConfig; +use Spatie\LaravelData\Support\DataProperty; +use Spatie\LaravelData\Support\Lazy\ClosureLazy; +use Spatie\LaravelTypeScriptTransformer\Transformers\DtoTransformer; +use Spatie\TypeScriptTransformer\Attributes\Optional as TypeScriptOptional; +use Spatie\TypeScriptTransformer\Structures\MissingSymbolsCollection; +use Spatie\TypeScriptTransformer\TypeProcessors\DtoCollectionTypeProcessor; +use Spatie\TypeScriptTransformer\TypeProcessors\ReplaceDefaultsTypeProcessor; +use Spatie\TypeScriptTransformer\Types\StructType; -class DataTypeScriptTransformer extends ClassTransformer +class DataTypeScriptTransformer extends DtoTransformer { - protected function shouldTransform(ReflectionClass $reflection): bool + public function canTransform(ReflectionClass $class): bool { - return $reflection->implementsInterface(BaseData::class); + return $class->isSubclassOf(BaseData::class); } - protected function classPropertyProcessors(): array + protected function typeProcessors(): array { - return array_merge(parent::classPropertyProcessors(), [ - new DataUtilitiesClassPropertyProcessor(), + return [ + new ReplaceDefaultsTypeProcessor( + $this->config->getDefaultTypeReplacements() + ), + new RemoveLazyTypeProcessor(), + new RemoveOptionalTypeProcessor(), + new DtoCollectionTypeProcessor(), + ]; + } + + + protected function transformProperties( + ReflectionClass $class, + MissingSymbolsCollection $missingSymbols + ): string { + $dataClass = app(DataConfig::class)->getDataClass($class->getName()); + + $isOptional = $dataClass->attributes->contains( + fn (object $attribute) => $attribute instanceof TypeScriptOptional + ); + + return array_reduce( + $this->resolveProperties($class), + function (string $carry, ReflectionProperty $property) use ($isOptional, $dataClass, $missingSymbols) { + /** @var \Spatie\LaravelData\Support\DataProperty $dataProperty */ + $dataProperty = $dataClass->properties[$property->getName()]; + + $type = $this->resolveTypeForProperty($property, $dataProperty, $missingSymbols); + + if ($type === null) { + return $carry; + } + + $isOptional = $isOptional + || $dataProperty->attributes->contains( + fn (object $attribute) => $attribute instanceof TypeScriptOptional + ) + || ($dataProperty->type->lazyType && $dataProperty->type->lazyType !== ClosureLazy::class) + || $dataProperty->type->isOptional; + + $transformed = $this->typeToTypeScript( + $type, + $missingSymbols, + $property->getDeclaringClass()->getName(), + ); + + $propertyName = $dataProperty->outputMappedName ?? $dataProperty->name; + + if (! preg_match('/^[$_a-zA-Z][$_a-zA-Z0-9]*$/', $propertyName)) { + $propertyName = "'{$propertyName}'"; + } + + return $isOptional + ? "{$carry}{$propertyName}?: {$transformed};" . PHP_EOL + : "{$carry}{$propertyName}: {$transformed};" . PHP_EOL; + }, + '' + ); + } + + protected function resolveTypeForProperty( + ReflectionProperty $property, + DataProperty $dataProperty, + MissingSymbolsCollection $missingSymbols, + ): ?Type { + if (! $dataProperty->type->kind->isDataCollectable()) { + return $this->reflectionToType( + $property, + $missingSymbols, + ...$this->typeProcessors() + ); + } + + $collectionType = match ($dataProperty->type->kind) { + DataTypeKind::DataCollection, DataTypeKind::Array, DataTypeKind::Enumerable => $this->defaultCollectionType($dataProperty->type->dataClass), + DataTypeKind::Paginator, DataTypeKind::DataPaginatedCollection => $this->paginatedCollectionType($dataProperty->type->dataClass), + DataTypeKind::CursorPaginator, DataTypeKind::DataCursorPaginatedCollection => $this->cursorPaginatedCollectionType($dataProperty->type->dataClass), + null => throw new RuntimeException('Cannot end up here since the type is dataCollectable') + }; + + if ($dataProperty->type->isNullable()) { + return new Nullable($collectionType); + } + + return $collectionType; + } + + protected function defaultCollectionType(string $class): Type + { + return new Array_(new Object_(new Fqsen("\\{$class}"))); + } + + protected function paginatedCollectionType(string $class): Type + { + return new StructType([ + 'data' => $this->defaultCollectionType($class), + 'links' => new Array_(new StructType([ + 'url' => new Nullable(new String_()), + 'label' => new String_(), + 'active' => new Boolean(), + ])), + 'meta' => new StructType([ + 'current_page' => new Integer(), + 'first_page_url' => new String_(), + 'from' => new Nullable(new Integer()), + 'last_page' => new Integer(), + 'last_page_url' => new String_(), + 'next_page_url' => new Nullable(new String_()), + 'path' => new String_(), + 'per_page' => new Integer(), + 'prev_page_url' => new Nullable(new String_()), + 'to' => new Nullable(new Integer()), + 'total' => new Integer(), + + ]), + ]); + } + + protected function cursorPaginatedCollectionType(string $class): Type + { + return new StructType([ + 'data' => $this->defaultCollectionType($class), + 'links' => new Array_(), + 'meta' => new StructType([ + 'path' => new String_(), + 'per_page' => new Integer(), + 'next_cursor' => new Nullable(new String_()), + 'next_cursor_url' => new Nullable(new String_()), + 'prev_cursor' => new Nullable(new String_()), + 'prev_cursor_url' => new Nullable(new String_()), + ]), ]); } } diff --git a/src/Support/TypeScriptTransformer/DataUtilitiesClassPropertyProcessor.php b/src/Support/TypeScriptTransformer/DataUtilitiesClassPropertyProcessor.php deleted file mode 100644 index 5b7315e2..00000000 --- a/src/Support/TypeScriptTransformer/DataUtilitiesClassPropertyProcessor.php +++ /dev/null @@ -1,139 +0,0 @@ -getDeclaringClass()); - $dataProperty = $dataClass->properties->get($reflection->getName()); - - if ($dataProperty->hidden) { - return null; - } - - if ($dataProperty->outputMappedName) { - $property->name = new TypeScriptIdentifier($dataProperty->outputMappedName); - } - - if ($dataProperty->type->kind->isDataCollectable()) { - $property->type = $this->replaceCollectableTypeWithArray( - $reflection, - $property->type, - $dataProperty - ); - } - - if (! $property->type instanceof TypeScriptUnion) { - return $property; - } - - for ($i = 0; $i < count($property->type->types); $i++) { - $subType = $property->type->types[$i]; - - if ($subType instanceof TypeReference && $this->shouldHideReference($subType)) { - $property->isOptional = true; - - unset($property->type->types[$i]); - } - } - - $property->type->types = array_values($property->type->types); - - return $property; - } - - protected function replaceCollectableTypeWithArray( - ReflectionProperty $reflection, - TypeScriptNode $node, - DataProperty $dataProperty - ): TypeScriptNode { - if ($node instanceof TypeScriptUnion) { - foreach ($node->types as $i => $subNode) { - $node->types[$i] = $this->replaceCollectableTypeWithArray($reflection, $subNode, $dataProperty); - } - - return $node; - } - - if ( - $node instanceof TypeScriptGeneric - && $node->type instanceof TypeReference - && $this->findReplacementForDataCollectable($node->type) - ) { - $node->type = $this->findReplacementForDataCollectable($node->type); - - return $node; - } - - if ( - $node instanceof TypeReference - && $this->findReplacementForDataCollectable($node) - && $dataProperty->type->dataClass - ) { - return new TypeScriptGeneric( - $this->findReplacementForDataCollectable($node), - [new TypeReference(new ClassStringReference($dataProperty->type->dataClass))] - ); - } - - return $node; - } - - protected function findReplacementForDataCollectable( - TypeReference $reference - ): ?TypeScriptNode { - if (! $reference->reference instanceof ClassStringReference) { - return null; - } - - if ($reference->reference->classString === DataCollection::class) { - return new TypeScriptIdentifier('Array'); - } - - if ($reference->reference->classString === PaginatedDataCollection::class) { - return new TypeReference(new ClassStringReference(LengthAwarePaginator::class)); - } - - if ($reference->reference->classString === CursorPaginatedDataCollection::class) { - return new TypeReference(new ClassStringReference(CursorPaginator::class)); - } - - return null; - } - - protected function shouldHideReference( - TypeReference $reference - ): bool { - if (! $reference->reference instanceof ClassStringReference) { - return false; - } - - return is_a($reference->reference->classString, Lazy::class, true) - || is_a($reference->reference->classString, Optional::class, true); - } -} diff --git a/src/Support/TypeScriptTransformer/RemoveLazyTypeProcessor.php b/src/Support/TypeScriptTransformer/RemoveLazyTypeProcessor.php new file mode 100644 index 00000000..ce18e176 --- /dev/null +++ b/src/Support/TypeScriptTransformer/RemoveLazyTypeProcessor.php @@ -0,0 +1,47 @@ +getIterator())) + ->reject(function (Type $type) { + if (! $type instanceof Object_) { + return false; + } + + return is_a((string)$type->getFqsen(), Lazy::class, true); + }); + + if ($types->isEmpty()) { + throw new Exception("Type {$reflection->getDeclaringClass()->name}:{$reflection->getName()} cannot be only Lazy"); + } + + if ($types->count() === 1) { + return $types->first(); + } + + return new Compound($types->all()); + } +} diff --git a/src/Support/TypeScriptTransformer/RemoveOptionalTypeProcessor.php b/src/Support/TypeScriptTransformer/RemoveOptionalTypeProcessor.php new file mode 100644 index 00000000..274281ae --- /dev/null +++ b/src/Support/TypeScriptTransformer/RemoveOptionalTypeProcessor.php @@ -0,0 +1,47 @@ +getIterator())) + ->reject(function (Type $type) { + if (! $type instanceof Object_) { + return false; + } + + return is_a((string)$type->getFqsen(), Optional::class, true); + }); + + if ($types->isEmpty()) { + throw new Exception("Type {$reflection->getDeclaringClass()->name}:{$reflection->getName()} cannot be only Optional"); + } + + if ($types->count() === 1) { + return $types->first(); + } + + return new Compound($types->all()); + } +} diff --git a/tests/Support/TypeScriptTransformer/DataTypeScriptTransformerTest.php b/tests/Support/TypeScriptTransformer/DataTypeScriptTransformerTest.php index 8a96de9d..af797b73 100644 --- a/tests/Support/TypeScriptTransformer/DataTypeScriptTransformerTest.php +++ b/tests/Support/TypeScriptTransformer/DataTypeScriptTransformerTest.php @@ -19,54 +19,17 @@ use Spatie\Snapshots\Driver; use Spatie\TypeScriptTransformer\Attributes\Optional as TypeScriptOptional; -use Spatie\TypeScriptTransformer\References\Reference; -use Spatie\TypeScriptTransformer\Support\TransformationContext; -use Spatie\TypeScriptTransformer\Support\WritingContext; -use Spatie\TypeScriptTransformer\Transformed\Transformed; -use Spatie\TypeScriptTransformer\Transformed\Untransformable; +use Spatie\TypeScriptTransformer\TypeScriptTransformerConfig; function assertMatchesSnapshot($actual, Driver $driver = null): void { baseAssertMatchesSnapshot(str_replace('\\r\\n', '\\n', $actual), $driver); } -function transformData(Data $data): string -{ - $transformer = app(DataTypeScriptTransformer::class); - - $transformed = $transformer->transform( - new ReflectionClass($data), - new TransformationContext('SomeData', ['App', 'Data']) - ); - - return $transformed->typeScriptNode->write(new WritingContext( - fn (Reference $reference) => '{%'.$reference->humanFriendlyName().'%}' - )); -} - -it('will transform data objects', function () { - $transformer = app(DataTypeScriptTransformer::class); - - $transformed = $transformer->transform( - new ReflectionClass(SimpleData::class), - new TransformationContext('SomeData', ['App', 'Data']) - ); - - expect($transformed)->toBeInstanceOf(Transformed::class); - - $someClass = new class () { - }; - - $transformed = $transformer->transform( - new ReflectionClass($someClass::class), - new TransformationContext('SomeData', ['App', 'Data']) - ); - - expect($transformed)->toBeInstanceOf(Untransformable::class); -}); - it('can convert a data object to Typescript', function () { - $data = new class (null, Optional::create(), 42, true, 'Hello world', 3.14, ['the', 'meaning', 'of', 'life'], Lazy::create(fn () => 'Lazy'), Lazy::closure(fn () => 'Lazy'), SimpleData::from('Simple data'), new DataCollection(SimpleData::class, []), new DataCollection(SimpleData::class, []), new DataCollection(SimpleData::class, [])) extends Data { + $config = TypeScriptTransformerConfig::create(); + + $data = new class (null, Optional::create(), 42, true, 'Hello world', 3.14, ['the', 'meaning', 'of', 'life'], Lazy::create(fn () => 'Lazy'), Lazy::closure(fn () => 'Lazy'), SimpleData::from('Simple data'), SimpleData::collect([], DataCollection::class), SimpleData::collect([], DataCollection::class), SimpleData::collect([], DataCollection::class)) extends Data { public function __construct( public null|int $nullable, public Optional|int $undefineable, @@ -89,11 +52,18 @@ public function __construct( } }; - assertMatchesSnapshot(transformData($data)); + $transformer = new DataTypeScriptTransformer($config); + + $reflection = new ReflectionClass($data); + + expect($transformer->canTransform($reflection))->toBeTrue(); + assertMatchesSnapshot($transformer->transform($reflection, 'DataObject')->transformed); }); it('uses the correct types for data collection of attributes', function () { - $collection = new DataCollection(SimpleData::class, []); + $config = TypeScriptTransformerConfig::create(); + + $collection = SimpleData::collect([], DataCollection::class); $data = new class ($collection, $collection, $collection, $collection, $collection, $collection, $collection) extends Data { public function __construct( @@ -115,11 +85,18 @@ public function __construct( } }; - assertMatchesSnapshot(transformData($data)); + $transformer = new DataTypeScriptTransformer($config); + + $reflection = new ReflectionClass($data); + + expect($transformer->canTransform($reflection))->toBeTrue(); + assertMatchesSnapshot($transformer->transform($reflection, 'DataObject')->transformed); }); it('uses the correct types for paginated data collection for attributes ', function () { - $collection = new PaginatedDataCollection(SimpleData::class, new LengthAwarePaginator([], 0, 15)); + $config = TypeScriptTransformerConfig::create(); + + $collection = SimpleData::collect(new LengthAwarePaginator([], 0, 15), PaginatedDataCollection::class); $data = new class ($collection, $collection, $collection, $collection, $collection, $collection, $collection) extends Data { public function __construct( @@ -141,11 +118,18 @@ public function __construct( } }; - assertMatchesSnapshot(transformData($data)); + $transformer = new DataTypeScriptTransformer($config); + + $reflection = new ReflectionClass($data); + + expect($transformer->canTransform($reflection))->toBeTrue(); + assertMatchesSnapshot($transformer->transform($reflection, 'DataObject')->transformed); }); it('uses the correct types for cursor paginated data collection of attributes', function () { - $collection = new CursorPaginatedDataCollection(SimpleData::class, new CursorPaginator([], 15)); + $config = TypeScriptTransformerConfig::create(); + + $collection = SimpleData::collect(new CursorPaginator([], 15), CursorPaginatedDataCollection::class); $data = new class ($collection, $collection, $collection, $collection, $collection, $collection, $collection) extends Data { public function __construct( @@ -167,10 +151,17 @@ public function __construct( } }; - assertMatchesSnapshot(transformData($data)); + $transformer = new DataTypeScriptTransformer($config); + + $reflection = new ReflectionClass($data); + + expect($transformer->canTransform($reflection))->toBeTrue(); + assertMatchesSnapshot($transformer->transform($reflection, 'DataObject')->transformed); }); it('outputs types with properties using their mapped name', function () { + $config = TypeScriptTransformerConfig::create(); + $data = new class ('Good job Ruben', 'Hi Ruben') extends Data { public function __construct( #[MapOutputName(SnakeCaseMapper::class)] @@ -181,10 +172,16 @@ public function __construct( } }; - assertMatchesSnapshot(transformData($data)); + $transformer = new DataTypeScriptTransformer($config); + $reflection = new ReflectionClass($data); + + expect($transformer->canTransform($reflection))->toBeTrue(); + assertMatchesSnapshot($transformer->transform($reflection, 'DataObject')->transformed); }); it('it respects a TypeScript property optional attribute', function () { + $config = TypeScriptTransformerConfig::create(); + $data = new class (10, 'Ruben') extends Data { public function __construct( #[TypeScriptOptional] @@ -194,10 +191,24 @@ public function __construct( } }; - assertMatchesSnapshot(transformData($data)); + $transformer = new DataTypeScriptTransformer($config); + $reflection = new ReflectionClass($data); + + $this->assertTrue($transformer->canTransform($reflection)); + $this->assertEquals( + <<transform($reflection, 'DataObject')->transformed + ); }); it('it respects a TypeScript class optional attribute', function () { + $config = TypeScriptTransformerConfig::create(); + #[TypeScriptOptional] class DummyTypeScriptOptionalClass extends Data { @@ -206,7 +217,7 @@ public function __construct( public string $name, ) { } - } + }; $transformer = new DataTypeScriptTransformer($config); $reflection = new ReflectionClass(DummyTypeScriptOptionalClass::class); @@ -221,4 +232,4 @@ public function __construct( TXT, $transformer->transform($reflection, 'DataObject')->transformed ); -})->skip('Should be fixed in TS transformer'); +}); diff --git a/tests/Support/TypeScriptTransformer/__snapshots__/DataCollectableTypeProcessorTest__it_uses_the_correct_types_for_data_collection_of_attributes__1.txt b/tests/Support/TypeScriptTransformer/__snapshots__/DataCollectableTypeProcessorTest__it_uses_the_correct_types_for_data_collection_of_attributes__1.txt deleted file mode 100644 index 1a57ad5c..00000000 --- a/tests/Support/TypeScriptTransformer/__snapshots__/DataCollectableTypeProcessorTest__it_uses_the_correct_types_for_data_collection_of_attributes__1.txt +++ /dev/null @@ -1,5 +0,0 @@ -{ -dataCollection: Array<{%Spatie\LaravelData\Tests\Fakes\SimpleData%}>; -dataCollectionWithNull: Array<{%Spatie\LaravelData\Tests\Fakes\SimpleData%}> | null; -dataCollectionWithNullable: Array<{%Spatie\LaravelData\Tests\Fakes\SimpleData%}> | null; -} \ No newline at end of file diff --git a/tests/Support/TypeScriptTransformer/__snapshots__/DataCollectionTypeProcessorTest__it_uses_the_correct_types_for_data_collection_of_attributes__1.txt b/tests/Support/TypeScriptTransformer/__snapshots__/DataCollectionTypeProcessorTest__it_uses_the_correct_types_for_data_collection_of_attributes__1.txt deleted file mode 100644 index 1a57ad5c..00000000 --- a/tests/Support/TypeScriptTransformer/__snapshots__/DataCollectionTypeProcessorTest__it_uses_the_correct_types_for_data_collection_of_attributes__1.txt +++ /dev/null @@ -1,5 +0,0 @@ -{ -dataCollection: Array<{%Spatie\LaravelData\Tests\Fakes\SimpleData%}>; -dataCollectionWithNull: Array<{%Spatie\LaravelData\Tests\Fakes\SimpleData%}> | null; -dataCollectionWithNullable: Array<{%Spatie\LaravelData\Tests\Fakes\SimpleData%}> | null; -} \ No newline at end of file diff --git a/tests/Support/TypeScriptTransformer/__snapshots__/DataTypeScriptTransformerTest__it_can_covert_a_data_object_to_typescript__1.txt b/tests/Support/TypeScriptTransformer/__snapshots__/DataTypeScriptTransformerTest__it_can_covert_a_data_object_to_typescript__1.txt deleted file mode 100644 index 4bf2d0eb..00000000 --- a/tests/Support/TypeScriptTransformer/__snapshots__/DataTypeScriptTransformerTest__it_can_covert_a_data_object_to_typescript__1.txt +++ /dev/null @@ -1,14 +0,0 @@ -{ -nullable: number | null; -undefineable?: number; -int: number; -bool: boolean; -string: string; -float: number; -array: Array; -lazy?: string; -simpleData: {%Spatie\LaravelData\Tests\Fakes\SimpleData%}; -dataCollection: Array<{%Spatie\LaravelData\Tests\Fakes\SimpleData%}>; -dataCollectionAlternative: Array<{%Spatie\LaravelData\Tests\Fakes\SimpleData%}>; -dataCollectionWithAttribute: Array<{%Spatie\LaravelData\Tests\Fakes\SimpleData%}>; -} \ No newline at end of file diff --git a/tests/Support/TypeScriptTransformer/__snapshots__/DataTypeScriptTransformerTest__it_converts_nullable_properties_to_optional_ones__1.txt b/tests/Support/TypeScriptTransformer/__snapshots__/DataTypeScriptTransformerTest__it_converts_nullable_properties_to_optional_ones__1.txt deleted file mode 100644 index fdb4a630..00000000 --- a/tests/Support/TypeScriptTransformer/__snapshots__/DataTypeScriptTransformerTest__it_converts_nullable_properties_to_optional_ones__1.txt +++ /dev/null @@ -1,4 +0,0 @@ -{ -id?: number | null; -first_name?: string | null; -} \ No newline at end of file diff --git a/tests/Support/TypeScriptTransformer/__snapshots__/DataTypeScriptTransformerTest__it_outputs_types_with_properties_using_their_mapped_name__1.json b/tests/Support/TypeScriptTransformer/__snapshots__/DataTypeScriptTransformerTest__it_outputs_types_with_properties_using_their_mapped_name__1.json deleted file mode 100644 index 19765bd5..00000000 --- a/tests/Support/TypeScriptTransformer/__snapshots__/DataTypeScriptTransformerTest__it_outputs_types_with_properties_using_their_mapped_name__1.json +++ /dev/null @@ -1 +0,0 @@ -null diff --git a/tests/Support/TypeScriptTransformer/__snapshots__/DataTypeScriptTransformerTest__it_outputs_types_with_properties_using_their_mapped_name__1.txt b/tests/Support/TypeScriptTransformer/__snapshots__/DataTypeScriptTransformerTest__it_outputs_types_with_properties_using_their_mapped_name__1.txt deleted file mode 100644 index d6b17f4a..00000000 --- a/tests/Support/TypeScriptTransformer/__snapshots__/DataTypeScriptTransformerTest__it_outputs_types_with_properties_using_their_mapped_name__1.txt +++ /dev/null @@ -1,3 +0,0 @@ -{ -some_camel_case_property: string; -} \ No newline at end of file diff --git a/tests/Support/TypeScriptTransformer/__snapshots__/DataTypeScriptTransformerTest__it_uses_the_correct_types_for_cursor_paginated_data_collection_of_attributes__1.txt b/tests/Support/TypeScriptTransformer/__snapshots__/DataTypeScriptTransformerTest__it_uses_the_correct_types_for_cursor_paginated_data_collection_of_attributes__1.txt deleted file mode 100644 index b26c509c..00000000 --- a/tests/Support/TypeScriptTransformer/__snapshots__/DataTypeScriptTransformerTest__it_uses_the_correct_types_for_cursor_paginated_data_collection_of_attributes__1.txt +++ /dev/null @@ -1,9 +0,0 @@ -{ -collection: {data:Array<{%Spatie\LaravelData\Tests\Fakes\SimpleData%}>;links:Array;meta:{path:string;per_page:number;next_cursor:string | null;next_cursor_url:string | null;prev_cursor:string | null;prev_cursor_url:string | null;};}; -collectionWithNull: {data:Array<{%Spatie\LaravelData\Tests\Fakes\SimpleData%}>;links:Array;meta:{path:string;per_page:number;next_cursor:string | null;next_cursor_url:string | null;prev_cursor:string | null;prev_cursor_url:string | null;};} | null; -collectionWithNullable: {data:Array<{%Spatie\LaravelData\Tests\Fakes\SimpleData%}>;links:Array;meta:{path:string;per_page:number;next_cursor:string | null;next_cursor_url:string | null;prev_cursor:string | null;prev_cursor_url:string | null;};} | null; -optionalCollection?: {data:Array<{%Spatie\LaravelData\Tests\Fakes\SimpleData%}>;links:Array;meta:{path:string;per_page:number;next_cursor:string | null;next_cursor_url:string | null;prev_cursor:string | null;prev_cursor_url:string | null;};}; -optionalCollectionWithNullable?: {data:Array<{%Spatie\LaravelData\Tests\Fakes\SimpleData%}>;links:Array;meta:{path:string;per_page:number;next_cursor:string | null;next_cursor_url:string | null;prev_cursor:string | null;prev_cursor_url:string | null;};} | null; -lazyCollection?: {data:Array<{%Spatie\LaravelData\Tests\Fakes\SimpleData%}>;links:Array;meta:{path:string;per_page:number;next_cursor:string | null;next_cursor_url:string | null;prev_cursor:string | null;prev_cursor_url:string | null;};}; -lazyCollectionWithNullable?: {data:Array<{%Spatie\LaravelData\Tests\Fakes\SimpleData%}>;links:Array;meta:{path:string;per_page:number;next_cursor:string | null;next_cursor_url:string | null;prev_cursor:string | null;prev_cursor_url:string | null;};} | null; -} \ No newline at end of file diff --git a/tests/Support/TypeScriptTransformer/__snapshots__/DataTypeScriptTransformerTest__it_uses_the_correct_types_for_data_collection_of_attributes__1.txt b/tests/Support/TypeScriptTransformer/__snapshots__/DataTypeScriptTransformerTest__it_uses_the_correct_types_for_data_collection_of_attributes__1.txt deleted file mode 100644 index 2e46c020..00000000 --- a/tests/Support/TypeScriptTransformer/__snapshots__/DataTypeScriptTransformerTest__it_uses_the_correct_types_for_data_collection_of_attributes__1.txt +++ /dev/null @@ -1,9 +0,0 @@ -{ -collection: Array<{%Spatie\LaravelData\Tests\Fakes\SimpleData%}>; -collectionWithNull: Array<{%Spatie\LaravelData\Tests\Fakes\SimpleData%}> | null; -collectionWithNullable: Array<{%Spatie\LaravelData\Tests\Fakes\SimpleData%}> | null; -optionalCollection?: Array<{%Spatie\LaravelData\Tests\Fakes\SimpleData%}>; -optionalCollectionWithNullable?: Array<{%Spatie\LaravelData\Tests\Fakes\SimpleData%}> | null; -lazyCollection?: Array<{%Spatie\LaravelData\Tests\Fakes\SimpleData%}>; -lazyCollectionWithNullable?: Array<{%Spatie\LaravelData\Tests\Fakes\SimpleData%}> | null; -} \ No newline at end of file diff --git a/tests/Support/TypeScriptTransformer/__snapshots__/DataTypeScriptTransformerTest__it_uses_the_correct_types_for_paginated_data_collection_of_attributes__1.txt b/tests/Support/TypeScriptTransformer/__snapshots__/DataTypeScriptTransformerTest__it_uses_the_correct_types_for_paginated_data_collection_of_attributes__1.txt deleted file mode 100644 index fbeb4758..00000000 --- a/tests/Support/TypeScriptTransformer/__snapshots__/DataTypeScriptTransformerTest__it_uses_the_correct_types_for_paginated_data_collection_of_attributes__1.txt +++ /dev/null @@ -1,9 +0,0 @@ -{ -collection: {data:Array<{%Spatie\LaravelData\Tests\Fakes\SimpleData%}>;links:Array<{url:string | null;label:string;active:boolean;}>;meta:{current_page:number;first_page_url:string;from:number | null;last_page:number;last_page_url:string;next_page_url:string | null;path:string;per_page:number;prev_page_url:string | null;to:number | null;total:number;};}; -collectionWithNull: {data:Array<{%Spatie\LaravelData\Tests\Fakes\SimpleData%}>;links:Array<{url:string | null;label:string;active:boolean;}>;meta:{current_page:number;first_page_url:string;from:number | null;last_page:number;last_page_url:string;next_page_url:string | null;path:string;per_page:number;prev_page_url:string | null;to:number | null;total:number;};} | null; -collectionWithNullable: {data:Array<{%Spatie\LaravelData\Tests\Fakes\SimpleData%}>;links:Array<{url:string | null;label:string;active:boolean;}>;meta:{current_page:number;first_page_url:string;from:number | null;last_page:number;last_page_url:string;next_page_url:string | null;path:string;per_page:number;prev_page_url:string | null;to:number | null;total:number;};} | null; -optionalCollection?: {data:Array<{%Spatie\LaravelData\Tests\Fakes\SimpleData%}>;links:Array<{url:string | null;label:string;active:boolean;}>;meta:{current_page:number;first_page_url:string;from:number | null;last_page:number;last_page_url:string;next_page_url:string | null;path:string;per_page:number;prev_page_url:string | null;to:number | null;total:number;};}; -optionalCollectionWithNullable?: {data:Array<{%Spatie\LaravelData\Tests\Fakes\SimpleData%}>;links:Array<{url:string | null;label:string;active:boolean;}>;meta:{current_page:number;first_page_url:string;from:number | null;last_page:number;last_page_url:string;next_page_url:string | null;path:string;per_page:number;prev_page_url:string | null;to:number | null;total:number;};} | null; -lazyCollection?: {data:Array<{%Spatie\LaravelData\Tests\Fakes\SimpleData%}>;links:Array<{url:string | null;label:string;active:boolean;}>;meta:{current_page:number;first_page_url:string;from:number | null;last_page:number;last_page_url:string;next_page_url:string | null;path:string;per_page:number;prev_page_url:string | null;to:number | null;total:number;};}; -lazyCollectionWithNullable?: {data:Array<{%Spatie\LaravelData\Tests\Fakes\SimpleData%}>;links:Array<{url:string | null;label:string;active:boolean;}>;meta:{current_page:number;first_page_url:string;from:number | null;last_page:number;last_page_url:string;next_page_url:string | null;path:string;per_page:number;prev_page_url:string | null;to:number | null;total:number;};} | null; -} \ No newline at end of file diff --git a/tests/__snapshots__/DataTypeScriptTransformerTest__it_can_convert_a_data_object_to_Typescript__1.txt b/tests/__snapshots__/DataTypeScriptTransformerTest__it_can_convert_a_data_object_to_Typescript__1.txt index c441e148..8e3d7003 100644 --- a/tests/__snapshots__/DataTypeScriptTransformerTest__it_can_convert_a_data_object_to_Typescript__1.txt +++ b/tests/__snapshots__/DataTypeScriptTransformerTest__it_can_convert_a_data_object_to_Typescript__1.txt @@ -1,15 +1,15 @@ -export type SomeData = { -nullable: number | null -undefineable?: number -int: number -bool: boolean -string: string -float: number -array: Array -lazy?: string -closureLazy?: string -simpleData: {%class Spatie\LaravelData\Tests\Fakes\SimpleData%} -dataCollection: Array<{%class Spatie\LaravelData\Tests\Fakes\SimpleData%}> -dataCollectionAlternative: Array<{%class Spatie\LaravelData\Tests\Fakes\SimpleData%}> -dataCollectionWithAttribute: Array<{%class Spatie\LaravelData\Tests\Fakes\SimpleData%}> -}; +{ +nullable: number | null; +undefineable?: number; +int: number; +bool: boolean; +string: string; +float: number; +array: Array; +lazy?: string; +closureLazy: string; +simpleData: {%Spatie\LaravelData\Tests\Fakes\SimpleData%}; +dataCollection: Array<{%Spatie\LaravelData\Tests\Fakes\SimpleData%}>; +dataCollectionAlternative: Array<{%Spatie\LaravelData\Tests\Fakes\SimpleData%}>; +dataCollectionWithAttribute: Array<{%Spatie\LaravelData\Tests\Fakes\SimpleData%}>; +} \ No newline at end of file diff --git a/tests/__snapshots__/DataTypeScriptTransformerTest__it_can_covert_a_data_object_to_typescript__1.txt b/tests/__snapshots__/DataTypeScriptTransformerTest__it_can_covert_a_data_object_to_typescript__1.txt deleted file mode 100644 index 4cf1f171..00000000 --- a/tests/__snapshots__/DataTypeScriptTransformerTest__it_can_covert_a_data_object_to_typescript__1.txt +++ /dev/null @@ -1,11 +0,0 @@ -{ -nullable: number | null; -int: number; -bool: boolean; -string: string; -float: number; -array: Array; -lazy?: string; -simpleData: {%Spatie\LaravelData\Tests\Fakes\SimpleData%}; -dataCollection: Array<{%Spatie\LaravelData\Tests\Fakes\SimpleData%}>; -} \ No newline at end of file diff --git a/tests/__snapshots__/DataTypeScriptTransformerTest__it_it_respects_a_TypeScript_property_optional_attribute__1.txt b/tests/__snapshots__/DataTypeScriptTransformerTest__it_it_respects_a_TypeScript_property_optional_attribute__1.txt deleted file mode 100644 index 78333aca..00000000 --- a/tests/__snapshots__/DataTypeScriptTransformerTest__it_it_respects_a_TypeScript_property_optional_attribute__1.txt +++ /dev/null @@ -1,4 +0,0 @@ -export type SomeData = { -id?: number -name: string -}; diff --git a/tests/__snapshots__/DataTypeScriptTransformerTest__it_outputs_types_with_properties_using_their_mapped_name__1.txt b/tests/__snapshots__/DataTypeScriptTransformerTest__it_outputs_types_with_properties_using_their_mapped_name__1.txt index 4d0cd745..e5b50a34 100644 --- a/tests/__snapshots__/DataTypeScriptTransformerTest__it_outputs_types_with_properties_using_their_mapped_name__1.txt +++ b/tests/__snapshots__/DataTypeScriptTransformerTest__it_outputs_types_with_properties_using_their_mapped_name__1.txt @@ -1,4 +1,4 @@ -export type SomeData = { -some_camel_case_property: string -some:non:standard:property: string -}; +{ +some_camel_case_property: string; +'some:non:standard:property': string; +} \ No newline at end of file diff --git a/tests/__snapshots__/DataTypeScriptTransformerTest__it_uses_the_correct_types_for_cursor_paginated_data_collection_of_attributes__1.txt b/tests/__snapshots__/DataTypeScriptTransformerTest__it_uses_the_correct_types_for_cursor_paginated_data_collection_of_attributes__1.txt index 44d5fd37..b26c509c 100644 --- a/tests/__snapshots__/DataTypeScriptTransformerTest__it_uses_the_correct_types_for_cursor_paginated_data_collection_of_attributes__1.txt +++ b/tests/__snapshots__/DataTypeScriptTransformerTest__it_uses_the_correct_types_for_cursor_paginated_data_collection_of_attributes__1.txt @@ -1,9 +1,9 @@ -export type SomeData = { -collection: {%class Illuminate\Pagination\CursorPaginator%}<{%class Spatie\LaravelData\Tests\Fakes\SimpleData%}> -collectionWithNull: {%class Illuminate\Pagination\CursorPaginator%}<{%class Spatie\LaravelData\Tests\Fakes\SimpleData%}> | null -collectionWithNullable: {%class Illuminate\Pagination\CursorPaginator%}<{%class Spatie\LaravelData\Tests\Fakes\SimpleData%}> | null -optionalCollection?: {%class Illuminate\Pagination\CursorPaginator%}<{%class Spatie\LaravelData\Tests\Fakes\SimpleData%}> -optionalCollectionWithNullable?: {%class Illuminate\Pagination\CursorPaginator%}<{%class Spatie\LaravelData\Tests\Fakes\SimpleData%}> | null -lazyCollection?: {%class Illuminate\Pagination\CursorPaginator%}<{%class Spatie\LaravelData\Tests\Fakes\SimpleData%}> -lazyCollectionWithNullable?: {%class Illuminate\Pagination\CursorPaginator%}<{%class Spatie\LaravelData\Tests\Fakes\SimpleData%}> | null -}; +{ +collection: {data:Array<{%Spatie\LaravelData\Tests\Fakes\SimpleData%}>;links:Array;meta:{path:string;per_page:number;next_cursor:string | null;next_cursor_url:string | null;prev_cursor:string | null;prev_cursor_url:string | null;};}; +collectionWithNull: {data:Array<{%Spatie\LaravelData\Tests\Fakes\SimpleData%}>;links:Array;meta:{path:string;per_page:number;next_cursor:string | null;next_cursor_url:string | null;prev_cursor:string | null;prev_cursor_url:string | null;};} | null; +collectionWithNullable: {data:Array<{%Spatie\LaravelData\Tests\Fakes\SimpleData%}>;links:Array;meta:{path:string;per_page:number;next_cursor:string | null;next_cursor_url:string | null;prev_cursor:string | null;prev_cursor_url:string | null;};} | null; +optionalCollection?: {data:Array<{%Spatie\LaravelData\Tests\Fakes\SimpleData%}>;links:Array;meta:{path:string;per_page:number;next_cursor:string | null;next_cursor_url:string | null;prev_cursor:string | null;prev_cursor_url:string | null;};}; +optionalCollectionWithNullable?: {data:Array<{%Spatie\LaravelData\Tests\Fakes\SimpleData%}>;links:Array;meta:{path:string;per_page:number;next_cursor:string | null;next_cursor_url:string | null;prev_cursor:string | null;prev_cursor_url:string | null;};} | null; +lazyCollection?: {data:Array<{%Spatie\LaravelData\Tests\Fakes\SimpleData%}>;links:Array;meta:{path:string;per_page:number;next_cursor:string | null;next_cursor_url:string | null;prev_cursor:string | null;prev_cursor_url:string | null;};}; +lazyCollectionWithNullable?: {data:Array<{%Spatie\LaravelData\Tests\Fakes\SimpleData%}>;links:Array;meta:{path:string;per_page:number;next_cursor:string | null;next_cursor_url:string | null;prev_cursor:string | null;prev_cursor_url:string | null;};} | null; +} \ No newline at end of file diff --git a/tests/__snapshots__/DataTypeScriptTransformerTest__it_uses_the_correct_types_for_data_collection_of_attributes__1.txt b/tests/__snapshots__/DataTypeScriptTransformerTest__it_uses_the_correct_types_for_data_collection_of_attributes__1.txt index ae9089ca..2e46c020 100644 --- a/tests/__snapshots__/DataTypeScriptTransformerTest__it_uses_the_correct_types_for_data_collection_of_attributes__1.txt +++ b/tests/__snapshots__/DataTypeScriptTransformerTest__it_uses_the_correct_types_for_data_collection_of_attributes__1.txt @@ -1,9 +1,9 @@ -export type SomeData = { -collection: Array<{%class Spatie\LaravelData\Tests\Fakes\SimpleData%}> -collectionWithNull: Array<{%class Spatie\LaravelData\Tests\Fakes\SimpleData%}> | null -collectionWithNullable: Array<{%class Spatie\LaravelData\Tests\Fakes\SimpleData%}> | null -optionalCollection?: Array<{%class Spatie\LaravelData\Tests\Fakes\SimpleData%}> -optionalCollectionWithNullable?: Array<{%class Spatie\LaravelData\Tests\Fakes\SimpleData%}> | null -lazyCollection?: Array<{%class Spatie\LaravelData\Tests\Fakes\SimpleData%}> -lazyCollectionWithNullable?: Array<{%class Spatie\LaravelData\Tests\Fakes\SimpleData%}> | null -}; +{ +collection: Array<{%Spatie\LaravelData\Tests\Fakes\SimpleData%}>; +collectionWithNull: Array<{%Spatie\LaravelData\Tests\Fakes\SimpleData%}> | null; +collectionWithNullable: Array<{%Spatie\LaravelData\Tests\Fakes\SimpleData%}> | null; +optionalCollection?: Array<{%Spatie\LaravelData\Tests\Fakes\SimpleData%}>; +optionalCollectionWithNullable?: Array<{%Spatie\LaravelData\Tests\Fakes\SimpleData%}> | null; +lazyCollection?: Array<{%Spatie\LaravelData\Tests\Fakes\SimpleData%}>; +lazyCollectionWithNullable?: Array<{%Spatie\LaravelData\Tests\Fakes\SimpleData%}> | null; +} \ No newline at end of file diff --git a/tests/__snapshots__/DataTypeScriptTransformerTest__it_uses_the_correct_types_for_paginated_data_collection_for_attributes___1.txt b/tests/__snapshots__/DataTypeScriptTransformerTest__it_uses_the_correct_types_for_paginated_data_collection_for_attributes___1.txt index 199b0305..fbeb4758 100644 --- a/tests/__snapshots__/DataTypeScriptTransformerTest__it_uses_the_correct_types_for_paginated_data_collection_for_attributes___1.txt +++ b/tests/__snapshots__/DataTypeScriptTransformerTest__it_uses_the_correct_types_for_paginated_data_collection_for_attributes___1.txt @@ -1,9 +1,9 @@ -export type SomeData = { -collection: {%class Illuminate\Pagination\LengthAwarePaginator%}<{%class Spatie\LaravelData\Tests\Fakes\SimpleData%}> -collectionWithNull: {%class Illuminate\Pagination\LengthAwarePaginator%}<{%class Spatie\LaravelData\Tests\Fakes\SimpleData%}> | null -collectionWithNullable: {%class Illuminate\Pagination\LengthAwarePaginator%}<{%class Spatie\LaravelData\Tests\Fakes\SimpleData%}> | null -optionalCollection?: {%class Illuminate\Pagination\LengthAwarePaginator%}<{%class Spatie\LaravelData\Tests\Fakes\SimpleData%}> -optionalCollectionWithNullable?: {%class Illuminate\Pagination\LengthAwarePaginator%}<{%class Spatie\LaravelData\Tests\Fakes\SimpleData%}> | null -lazyCollection?: {%class Illuminate\Pagination\LengthAwarePaginator%}<{%class Spatie\LaravelData\Tests\Fakes\SimpleData%}> -lazyCollectionWithNullable?: {%class Illuminate\Pagination\LengthAwarePaginator%}<{%class Spatie\LaravelData\Tests\Fakes\SimpleData%}> | null -}; +{ +collection: {data:Array<{%Spatie\LaravelData\Tests\Fakes\SimpleData%}>;links:Array<{url:string | null;label:string;active:boolean;}>;meta:{current_page:number;first_page_url:string;from:number | null;last_page:number;last_page_url:string;next_page_url:string | null;path:string;per_page:number;prev_page_url:string | null;to:number | null;total:number;};}; +collectionWithNull: {data:Array<{%Spatie\LaravelData\Tests\Fakes\SimpleData%}>;links:Array<{url:string | null;label:string;active:boolean;}>;meta:{current_page:number;first_page_url:string;from:number | null;last_page:number;last_page_url:string;next_page_url:string | null;path:string;per_page:number;prev_page_url:string | null;to:number | null;total:number;};} | null; +collectionWithNullable: {data:Array<{%Spatie\LaravelData\Tests\Fakes\SimpleData%}>;links:Array<{url:string | null;label:string;active:boolean;}>;meta:{current_page:number;first_page_url:string;from:number | null;last_page:number;last_page_url:string;next_page_url:string | null;path:string;per_page:number;prev_page_url:string | null;to:number | null;total:number;};} | null; +optionalCollection?: {data:Array<{%Spatie\LaravelData\Tests\Fakes\SimpleData%}>;links:Array<{url:string | null;label:string;active:boolean;}>;meta:{current_page:number;first_page_url:string;from:number | null;last_page:number;last_page_url:string;next_page_url:string | null;path:string;per_page:number;prev_page_url:string | null;to:number | null;total:number;};}; +optionalCollectionWithNullable?: {data:Array<{%Spatie\LaravelData\Tests\Fakes\SimpleData%}>;links:Array<{url:string | null;label:string;active:boolean;}>;meta:{current_page:number;first_page_url:string;from:number | null;last_page:number;last_page_url:string;next_page_url:string | null;path:string;per_page:number;prev_page_url:string | null;to:number | null;total:number;};} | null; +lazyCollection?: {data:Array<{%Spatie\LaravelData\Tests\Fakes\SimpleData%}>;links:Array<{url:string | null;label:string;active:boolean;}>;meta:{current_page:number;first_page_url:string;from:number | null;last_page:number;last_page_url:string;next_page_url:string | null;path:string;per_page:number;prev_page_url:string | null;to:number | null;total:number;};}; +lazyCollectionWithNullable?: {data:Array<{%Spatie\LaravelData\Tests\Fakes\SimpleData%}>;links:Array<{url:string | null;label:string;active:boolean;}>;meta:{current_page:number;first_page_url:string;from:number | null;last_page:number;last_page_url:string;next_page_url:string | null;path:string;per_page:number;prev_page_url:string | null;to:number | null;total:number;};} | null; +} \ No newline at end of file diff --git a/tests/__snapshots__/DataTypeScriptTransformerTest__it_uses_the_correct_types_for_paginated_data_collection_of_attributes__1.txt b/tests/__snapshots__/DataTypeScriptTransformerTest__it_uses_the_correct_types_for_paginated_data_collection_of_attributes__1.txt deleted file mode 100644 index fbeb4758..00000000 --- a/tests/__snapshots__/DataTypeScriptTransformerTest__it_uses_the_correct_types_for_paginated_data_collection_of_attributes__1.txt +++ /dev/null @@ -1,9 +0,0 @@ -{ -collection: {data:Array<{%Spatie\LaravelData\Tests\Fakes\SimpleData%}>;links:Array<{url:string | null;label:string;active:boolean;}>;meta:{current_page:number;first_page_url:string;from:number | null;last_page:number;last_page_url:string;next_page_url:string | null;path:string;per_page:number;prev_page_url:string | null;to:number | null;total:number;};}; -collectionWithNull: {data:Array<{%Spatie\LaravelData\Tests\Fakes\SimpleData%}>;links:Array<{url:string | null;label:string;active:boolean;}>;meta:{current_page:number;first_page_url:string;from:number | null;last_page:number;last_page_url:string;next_page_url:string | null;path:string;per_page:number;prev_page_url:string | null;to:number | null;total:number;};} | null; -collectionWithNullable: {data:Array<{%Spatie\LaravelData\Tests\Fakes\SimpleData%}>;links:Array<{url:string | null;label:string;active:boolean;}>;meta:{current_page:number;first_page_url:string;from:number | null;last_page:number;last_page_url:string;next_page_url:string | null;path:string;per_page:number;prev_page_url:string | null;to:number | null;total:number;};} | null; -optionalCollection?: {data:Array<{%Spatie\LaravelData\Tests\Fakes\SimpleData%}>;links:Array<{url:string | null;label:string;active:boolean;}>;meta:{current_page:number;first_page_url:string;from:number | null;last_page:number;last_page_url:string;next_page_url:string | null;path:string;per_page:number;prev_page_url:string | null;to:number | null;total:number;};}; -optionalCollectionWithNullable?: {data:Array<{%Spatie\LaravelData\Tests\Fakes\SimpleData%}>;links:Array<{url:string | null;label:string;active:boolean;}>;meta:{current_page:number;first_page_url:string;from:number | null;last_page:number;last_page_url:string;next_page_url:string | null;path:string;per_page:number;prev_page_url:string | null;to:number | null;total:number;};} | null; -lazyCollection?: {data:Array<{%Spatie\LaravelData\Tests\Fakes\SimpleData%}>;links:Array<{url:string | null;label:string;active:boolean;}>;meta:{current_page:number;first_page_url:string;from:number | null;last_page:number;last_page_url:string;next_page_url:string | null;path:string;per_page:number;prev_page_url:string | null;to:number | null;total:number;};}; -lazyCollectionWithNullable?: {data:Array<{%Spatie\LaravelData\Tests\Fakes\SimpleData%}>;links:Array<{url:string | null;label:string;active:boolean;}>;meta:{current_page:number;first_page_url:string;from:number | null;last_page:number;last_page_url:string;next_page_url:string | null;path:string;per_page:number;prev_page_url:string | null;to:number | null;total:number;};} | null; -} \ No newline at end of file