uxf / gen
    3.70.0
    2025-09-10 15:20 UTC
Requires
- php: ^8.3
- phpdocumentor/type-resolver: ^1.6
- phpstan/phpdoc-parser: ^2.0
- symfony/security-http: ^7.2
Suggests
- uxf/core: Required for bridge
- 3.x-dev
- 3.70.0
- 3.69.12
- 3.69.1
- 3.67.3
- 3.66.0
- 3.65.0
- 3.62.0
- 3.61.5
- 3.61.3
- 3.59.0
- 3.58.6
- 3.58.5
- 3.58.3
- 3.58.2
- 3.58.0
- 3.57.12
- 3.57.11
- 3.57.0
- 3.56.7
- 3.56.5
- 3.56.3
- 3.56.1
- 3.56.0
- 3.55.1
- 3.55.0
- 3.54.5
- 3.54.4
- 3.53.8
- 3.53.6
- 3.53.5
- 3.53.4
- 3.53.0
- 3.51.1
- 3.51.0
- 3.50.0
- 3.47.1
- 3.43.0
- 3.42.0
- 3.41.1
- 3.41.0
- 3.40.4
- 3.40.3
- 3.38.0
- 3.37.0
- 3.36.3
- 3.36.2
- 3.36.1
- 3.35.4
- 3.35.3
- 3.34.3
- 3.34.2
- 3.34.1
- 3.34.0
- 3.32.3
- 3.30.1
- 3.29.0
- 3.24.6
- 3.24.1
- 3.23.2
- 3.21.5
- 3.21.3
- 3.21.0
- 3.20.4
- 3.20.3
- 3.20.2
- 3.20.1
- 3.20.0
- 3.17.0
- 3.15.2
- 3.15.0
- 3.14.0
- 3.13.2
- 3.11.0
- 3.10.0
- 3.9.1
- 3.9.0
- 3.7.2
- 3.7.0
- 3.6.0
- 3.5.0
- 3.4.0
- 3.3.0
- 3.2.4
- 3.2.3
- 3.2.2
- 3.2.1
- 3.2.0
- 3.1.4
- 3.1.3
- 3.1.2
- 3.1.1
- 3.1.0
- 3.0.4
- 3.0.3
- 3.0.2
- 3.0.1
- 3.0.0
- 1.8.3
- 1.8.2
- 1.8.1
- 1.8.0
- 1.7.1
- 1.7.0
- 1.6.1
- 1.6.0
- 1.5.0
- 1.4.1
- 1.4.0
- 1.3.1
- 1.3.0
- 1.2.0
- 1.1.3
- 1.1.2
- 1.1.1
- 1.1.0
- 1.0.4
- 1.0.3
- 1.0.2
- 1.0.1
- 1.0.0
- v0.3.6
- v0.3.5
- v0.3.4
- v0.3.3
- v0.3.2
- v0.3.1
- v0.3.0
- v0.2.2
- v0.2.1
- v0.2.0
- v0.1.1
- v0.1.0
- dev-legacy
- dev-main
- dev-master
- dev-readonly
- dev-openapi-description
- dev-openapi-enums
This package is auto-updated.
Last update: 2025-10-10 13:41:59 UTC
README
Install
$ composer req uxf/gen
Run
$ bin/console uxf:gen
Config
// config/routes/uxf.php
use Symfony\Component\Routing\Loader\Configurator\RoutingConfigurator;
return static function (RoutingConfigurator $routingConfigurator): void {
    $routingConfigurator->import('@UXFGenBundle/config/routes.php');
};
// config/packages/uxf.php
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
return static function (ContainerConfigurator $containerConfigurator): void {
    $containerConfigurator->extension('uxf_gen', [
        'config' => [
            'prefix' => '/wow', // default '/api'
            // default config -> values from UXF bridge
            'disable_uxf_bridge' => false,
            'route_body_attribut' => FromBody::class,
            'route_query_attribute' => FromQuery::class,
            'route_header_attribute' => FromHeader::class,
            'route_entity_attribute' => Entity::class,
            'ignored_types' => [NotSet::class],
            'enum_as_union' => true, // default false
            'typescript_types' => [
                'DateTime' => '`${number}-${number}-${number}T${number}:${number}:${number}+${number}:${number}`',
                'Date' => '`${number}-${number}-${number}`',
                'Time' => '`${number}:${number}:${number}`',
            ],
        ],
        'open_api' => [
            'areas' => [
                'app' => [
                    'path_pattern' => '/^\/api\/article/',
                ],
            ],
        ],
        'hook' => [
            'areas' => [
                'admin' => [
                    'path_pattern' => '/^\/api\/article/',
                    'output' => 'swr', // default legacy (options: swr, swr-2.2, legacy, empty)
                    'with_enum_options' => true, // default false
                    'destination' => '%kernel.project_dir%/tests/generated/hook.ts', // or array
                    'prepends' => [
                        '/* eslint-disable */',
                        'import { useAxiosRequest, axiosRequest, RequestConfig } from "@lib/api";'
                    ],
                ],
            ],
        ],
        'apollo' => [
            'areas' => [
                'app' => [
                    'path_pattern' => '/^\/api\/article/',
                    'destination' => '%kernel.project_dir%/tests/generated/apollo.ts', // or array
                ],
            ],
        ],
    ]);
};
Example
InspectorPlugin
use UXF\Gen\Inspector\Schema\AppSchema;
use UXF\Gen\Inspector\Schema\RouteSchema;
use UXF\Gen\Inspector\Schema\TypeSchema;
use UXF\Gen\Inspector\Schema\TypeVariant;
use UXF\Gen\Inspector\TypeMap;
use UXF\Gen\Plugin\InspectorPluginInterface;
use UXF\GenTests\Project\FunZone\Entity\EntityNames;
class TestPlugin implements InspectorPluginInterface
{
    public function pre(string $configName, TypeMap $typeMap): void
    {
        if ($configName === 'hook') {
            $typeMap[EntityNames::class] = new TypeSchema(EntityNames::class, TypeVariant::ENUM, EntityNames::class);
        }
    }
    public function post(string $configName, AppSchema $appSchema): void
    {
        if ($configName === 'apollo') {
            $appSchema->routes['plugin'] = new RouteSchema(
                name: 'plugin',
                path: '/plugin',
                controller: 'FunZone\Ok',
                requestBody: null,
                requestQuery: null,
                pathParams: [],
                response: null,
                description: '',
                methods: ['get' => false],
            );
        }
    }
}
ConverterPlugin
use UXF\Core\Type\Date;
use UXF\Core\Type\DateTime;
use UXF\Core\Type\Time;
use UXF\Gen\Inspector\Schema\TypeSchema;
use UXF\Gen\Inspector\Schema\TypeVariant;
use UXF\Gen\Plugin\TypeConverterPlugin;
class UxfCoreTypeConverterPlugin implements TypeConverterPlugin
{
    public function convertToTypescript(TypeSchema $typeSchema): ?string
    {
        if (
            $typeSchema->variant === TypeVariant::SIMPLE &&
            in_array($typeSchema->name, [Date::class, DateTime::class, Time::class], true)
        ) {
            return 'string';
        }
        return null;
    }
    /**
     * @inheritDoc
     */
    public function convertToOpenApi(TypeSchema $typeSchema): ?array
    {
        if ($typeSchema->variant !== TypeVariant::SIMPLE) {
            return null;
        }
        return match ($typeSchema->name) {
            Date::class => [
                'type' => 'string',
                'format' => 'date',
            ],
            DateTime::class => [
                'type' => 'string',
                'format' => 'date-time',
            ],
            Time::class => [
                'type' => 'string',
                'pattern' => '^\d{2}:\d{2}:\d{2}$',
            ],
            default => null,
        };
    }
}
Description support
class TestController
{
    /**
     * PRIVATE INTERNAL DESCRIPTION (MUST BE BEFORE @description)
     *
     * @description Public hello world description
     * with multiline support bro!
     */
    public function __invoke(): StatusResponse
    {
        return new StatusResponse();
    }
}
Generic support (only for main response)
/**
 * @template T
 */
class GenericResponseBody
{
    /**
     * @param T $data
     */
    public function __construct(
        public readonly bool $success,
        public readonly mixed $data,
    ) {
    }
}
class GenericController
{
    /**
     * @return GenericResponseBody<TagResponse>
     */
    public function simple(): GenericResponseBody
    {
        ...
    }
    /**
     * @return GenericResponseBody<TagResponse[]>
     */
    public function array(): GenericResponseBody
    {
        ...
    }
}