Giter Site home page Giter Site logo

riverwaysoft / php-converter Goto Github PK

View Code? Open in Web Editor NEW
8.0 1.0 2.0 3.32 MB

Generates TypeScript & Dart out of your PHP DTO classes.

License: MIT License

PHP 91.65% TypeScript 5.72% Dart 1.66% Go 0.09% Shell 0.14% Dockerfile 0.58% Makefile 0.17%
php code-converter dart typescript

php-converter's Issues

Nullable types

class User
{
    public int $id;

    public string $name;

    public ?string $address;
}

Should be transformed to this

export type User = {
    int: number;
    name: string;
    address: string | null;
}

Generate clickable @see links to the method implementation

Example:

/** @see FoodHierarchyController */
export const apiFoodHierarchyGet = (): Promise<FoodHierarchyNodeOutput[]> => {
  return axios
    .get<FoodHierarchyNodeOutput[]>(`/api/food_hierarchy`)
    .then((response) => response.data);
}

Such links only clickable in PHP files so they won't work in JS. But, we can still generate class and method so it's possible to go to the method by copying & globally searching the copied string:

/**
 * @see JobSheetMessagesApiController::createMessage
 */

Dart code generation improvements

  1. Generate fromJSON + mappers:
class UserOutput {
  final String id;
  final Profile? profile;
  final FullName name

  UserOutput({
    required this.id,
    required this.name,
    this.profile,
  })
  
  factory UserOutput.fromJson(Map<String, dynamic> json) {
    return UserOutput(
      id: json['id'],
      name: FullName.fromJson(json['name']),
      profile: json['profile'] != null ? Profile.fromJson(json['profile']) : null,
  }
}
  1. Investigate freezed: https://pub.dev/packages/freezed

Split generated output into different files

It should be possible to split the generated output (TypeScript or Dart) into different files. For example one class / enum per file with correct imports. To handle imports topological sort should be used.

ApiResource generator improvements

  • add optional filters query parameter that is going to work in GET requests
  • for GET requests the result should be wrapped with CollectionResponse the same it is wrapped for dart OldEnum

Investigate idea of generating types based on PHPStan's evaluation

For example having this code it'd nice to generate types based on PHPStan's type output:

  #[Route('/items', name: 'items_index', methods:['get'] )]
    public function index(ManagerRegistry $doctrine): JsonResponse
    {
        $products = $doctrine
            ->getRepository(Proassist::class)
            ->findAll();
   
        $data = [];
   
        foreach ($products as $product) {
           $data[] = [
               'id' => $product->getId(),
               'name' => $product->getName(),
               'description' => $product->getDescription(),
           ];
        }
   
        return $this->json($data);
    }

PHPStan should known that the type of $data is array<{id: ..., 'name': ..., 'description': ...}>

PHPStan under the hood talk: https://www.youtube.com/watch?v=85Aq2rWpGQE

Example projects (appeared randomly in GitHub search):

Class filters

  • Allow to skip class by using PHPDoc / PHP Attribute
  • Allow to include only classes with specific PHPDoc / PHP Attribute

Build PHAR executable

  • Provide an option to build a PHAR executable. This executable will be used by frontend / mobile team without pulling backend

Support ApiPlatform Input converting

  • Enums should be transformed into { key: { value: Enum } }
  • DateTimeImmutable/DateTime should be converted to string as usual
  • Doctrine ORM Embeddables should be typed manually inside dto-converter's config
  • Nested inputs should be supported

Replace kebab case / snake case with custom implementations

There is no need to use vendor package for simple things like kebab case / snake case conversion. The task is to remove jawira/case-converter from project and rewrite KebabCaseFileNameGenerator and SnakeCaseFileNameGenerator to use custom preg_replace_callback. Unit tests are required.

Provide an option to use TypeScript union types instead of Enum

At the moment dto-converter converts PHP enums to TS enums:

<?php

use MyCLabs\Enum\Enum;

class ColorEnum extends Enum
{
    private const RED = 0;
    private const GREEN = 1;
    private const BLUE = 2;
}

This will be converted to:

enum ColorEnum {
  RED = 0;
  GREEN = 1;
  BLUE = 2;
}

But it also makes sense to provide an option to convert PHP Enum to TypeScript union type if someone prefers union types over enums:

type ColorEnum = 0 | 1 | 2;

// or

type Gender = 'male' | 'female' | 'unkown';

This library already can generate union types but only when a specific condition is met: https://github.com/riverwaysoft/dto-converter/blob/8c35d6cafde77fac392ef702ee8dcf97c3d46ce1/src/Language/TypeScript/TypeScriptGenerator.php#L48

The task for PR:

  1. Add a bool flag to TypeScriptGenerator's constructor. Something like preferUnionTypeOverEnum: https://github.com/riverwaysoft/dto-converter/blob/master/src/Language/TypeScript/TypeScriptGenerator.php#L21

It should be false by default.

  1. If this flag is set to true - make an early return true from this function: https://github.com/riverwaysoft/dto-converter/blob/master/src/Language/TypeScript/TypeScriptGenerator.php#L61

  2. Write a test for this feature. Please add it to EndToEndTest.php: https://github.com/riverwaysoft/dto-converter/blob/master/tests/EndToEndTest.php

Array support

Make a fallback to doc block for array types

  • Entity[]

Built-in script to check if generated file is up-to-date

Currently the following bash can be used:

#!/bin/bash

set -e

GENERATED_FILE=generated.dart
PREV_GENERATED_FILE=current-generated.dart

cp $GENERATED_FILE $PREV_GENERATED_FILE
bin/php-converter.phar --from=./src --to=./ --config=./config/php-converter/dart-config.php

if diff -q $PREV_GENERATED_FILE $GENERATED_FILE; then
  echo "DTO ok"
  rm $PREV_GENERATED_FILE
else
  echo "Dto mismatch"
  rm $PREV_GENERATED_FILE
  exit 1
fi

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.