Skip to content

Commit

Permalink
Merge pull request #78 from starter-dev/master
Browse files Browse the repository at this point in the history
Feat: additional --use-enums flag
  • Loading branch information
tcampbPPU authored Jul 9, 2024
2 parents 453af86 + 7381f62 commit ececd20
Show file tree
Hide file tree
Showing 7 changed files with 49 additions and 26 deletions.
3 changes: 2 additions & 1 deletion readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ public function getFirstNameAttribute(): string // <- this
--model= : Generate typescript interfaces for a specific model
--global : Generate typescript interfaces in a global namespace named models
--json : Output the result as json
--use-enums : Use typescript enums instead of object literals
--plurals : Output model plurals
--no-relations : Do not include relations
--optional-relations : Make relations optional fields on the model type
Expand Down Expand Up @@ -378,6 +379,6 @@ export interface User {
}
```
> ModelTyper uses Object Literals instead of TS Enums [for opinionated reasons](https://maxheiber.medium.com/alternatives-to-typescript-enums-50e4c16600b1)
> ModelTyper uses Object Literals by default instead of TS Enums [for opinionated reasons](https://maxheiber.medium.com/alternatives-to-typescript-enums-50e4c16600b1). But you can use `--use-enums` option to use TS Enums instead of Object Literals.
> Notice how the comments are found and parsed - they must follow the specified format
16 changes: 8 additions & 8 deletions src/Actions/GenerateCliOutput.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ class GenerateCliOutput
* @param Collection<int, SplFileInfo> $models
* @param array<string, string> $mappings
*/
public function __invoke(Collection $models, array $mappings, bool $global = false, bool $plurals = false, bool $apiResources = false, bool $optionalRelations = false, bool $noRelations = false, bool $noHidden = false, bool $optionalNullables = false, bool $resolveAbstract = false, bool $fillables = false, string $fillableSuffix = 'Fillable'): string
public function __invoke(Collection $models, array $mappings, bool $global = false, bool $useEnums = false, bool $plurals = false, bool $apiResources = false, bool $optionalRelations = false, bool $noRelations = false, bool $noHidden = false, bool $optionalNullables = false, bool $resolveAbstract = false, bool $fillables = false, string $fillableSuffix = 'Fillable'): string
{
$modelBuilder = app(BuildModelDetails::class);
$colAttrWriter = app(WriteColumnAttribute::class);
Expand All @@ -45,7 +45,7 @@ public function __invoke(Collection $models, array $mappings, bool $global = fal
$this->indent = ' ';
}

$models->each(function (SplFileInfo $model) use ($mappings, $modelBuilder, $colAttrWriter, $relationWriter, $plurals, $apiResources, $optionalRelations, $noRelations, $noHidden, $optionalNullables, $resolveAbstract, $fillables, $fillableSuffix) {
$models->each(function (SplFileInfo $model) use ($mappings, $modelBuilder, $colAttrWriter, $relationWriter, $plurals, $apiResources, $optionalRelations, $noRelations, $noHidden, $optionalNullables, $resolveAbstract, $fillables, $fillableSuffix, $useEnums) {
$entry = '';
$modelDetails = $modelBuilder($model, $resolveAbstract);

Expand All @@ -70,8 +70,8 @@ public function __invoke(Collection $models, array $mappings, bool $global = fal

if ($columns->isNotEmpty()) {
$entry .= "{$this->indent} // columns\n";
$columns->each(function ($att) use (&$entry, $reflectionModel, $colAttrWriter, $noHidden, $optionalNullables, $mappings) {
[$line, $enum] = $colAttrWriter(reflectionModel: $reflectionModel, attribute: $att, mappings: $mappings, indent: $this->indent, noHidden: $noHidden, optionalNullables: $optionalNullables);
$columns->each(function ($att) use (&$entry, $reflectionModel, $colAttrWriter, $noHidden, $optionalNullables, $mappings, $useEnums) {
[$line, $enum] = $colAttrWriter(reflectionModel: $reflectionModel, attribute: $att, mappings: $mappings, indent: $this->indent, noHidden: $noHidden, optionalNullables: $optionalNullables, useEnums: $useEnums);
if (! empty($line)) {
$entry .= $line;
if ($enum) {
Expand All @@ -83,8 +83,8 @@ public function __invoke(Collection $models, array $mappings, bool $global = fal

if ($nonColumns->isNotEmpty()) {
$entry .= "{$this->indent} // mutators\n";
$nonColumns->each(function ($att) use (&$entry, $reflectionModel, $colAttrWriter, $noHidden, $optionalNullables, $mappings) {
[$line, $enum] = $colAttrWriter(reflectionModel: $reflectionModel, attribute: $att, mappings: $mappings, indent: $this->indent, noHidden: $noHidden, optionalNullables: $optionalNullables);
$nonColumns->each(function ($att) use (&$entry, $reflectionModel, $colAttrWriter, $noHidden, $optionalNullables, $mappings, $useEnums) {
[$line, $enum] = $colAttrWriter(reflectionModel: $reflectionModel, attribute: $att, mappings: $mappings, indent: $this->indent, noHidden: $noHidden, optionalNullables: $optionalNullables, useEnums: $useEnums);
if (! empty($line)) {
$entry .= $line;
if ($enum) {
Expand Down Expand Up @@ -139,8 +139,8 @@ public function __invoke(Collection $models, array $mappings, bool $global = fal

collect($this->enumReflectors)
->unique(fn (ReflectionClass $reflector) => $reflector->getName())
->each(function (ReflectionClass $reflector) {
$this->output .= app(WriteEnumConst::class)($reflector, $this->indent);
->each(function (ReflectionClass $reflector) use ($useEnums) {
$this->output .= app(WriteEnumConst::class)($reflector, $this->indent, false, $useEnums);
});

collect($this->imports)
Expand Down
12 changes: 6 additions & 6 deletions src/Actions/GenerateJsonOutput.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,14 @@ class GenerateJsonOutput
* @param Collection<int, \Symfony\Component\Finder\SplFileInfo> $models
* @param array<string, string> $mappings
*/
public function __invoke(Collection $models, array $mappings, bool $resolveAbstract = false): string
public function __invoke(Collection $models, array $mappings, bool $resolveAbstract = false, bool $useEnums = false): string
{
$modelBuilder = app(BuildModelDetails::class);
$colAttrWriter = app(WriteColumnAttribute::class);
$relationWriter = app(WriteRelationship::class);
$enumWriter = app(WriteEnumConst::class);

$models->each(function (SplFileInfo $model) use ($modelBuilder, $colAttrWriter, $relationWriter, $resolveAbstract, $mappings) {
$models->each(function (SplFileInfo $model) use ($modelBuilder, $colAttrWriter, $relationWriter, $resolveAbstract, $mappings, $useEnums) {
$modelDetails = $modelBuilder($model, $resolveAbstract);

if ($modelDetails === null) {
Expand All @@ -56,8 +56,8 @@ public function __invoke(Collection $models, array $mappings, bool $resolveAbstr
$this->output['interfaces'][$name] = $columns
->merge($nonColumns)
->merge($interfaces)
->map(function ($att) use ($reflectionModel, $colAttrWriter, $mappings) {
[$property, $enum] = $colAttrWriter(reflectionModel: $reflectionModel, mappings: $mappings, attribute: $att, jsonOutput: true);
->map(function ($att) use ($reflectionModel, $colAttrWriter, $mappings, $useEnums) {
[$property, $enum] = $colAttrWriter(reflectionModel: $reflectionModel, mappings: $mappings, attribute: $att, jsonOutput: true, useEnums: $useEnums);
if ($enum) {
$this->enumReflectors[] = $enum;
}
Expand All @@ -77,8 +77,8 @@ public function __invoke(Collection $models, array $mappings, bool $resolveAbstr
});
});

$this->output['enums'] = collect($this->enumReflectors)->map(function ($enum) use ($enumWriter) {
$enumConst = $enumWriter(reflection: $enum, jsonOutput: true);
$this->output['enums'] = collect($this->enumReflectors)->map(function ($enum) use ($enumWriter, $useEnums) {
$enumConst = $enumWriter(reflection: $enum, jsonOutput: true, useEnums: $useEnums);

return [
$enumConst['name'] => [
Expand Down
8 changes: 5 additions & 3 deletions src/Actions/Generator.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ class Generator
*
* @return string
*/
public function __invoke(?string $specificModel = null, bool $global = false, bool $json = false, bool $plurals = false, bool $apiResources = false, bool $optionalRelations = false, bool $noRelations = false, bool $noHidden = false, bool $timestampsDate = false, bool $optionalNullables = false, bool $resolveAbstract = false, bool $fillables = false, string $fillableSuffix = 'Fillable')
public function __invoke(?string $specificModel = null, bool $global = false, bool $json = false, bool $useEnums = false, bool $plurals = false, bool $apiResources = false, bool $optionalRelations = false, bool $noRelations = false, bool $noHidden = false, bool $timestampsDate = false, bool $optionalNullables = false, bool $resolveAbstract = false, bool $fillables = false, string $fillableSuffix = 'Fillable')
{
$models = app(GetModels::class)($specificModel);

Expand All @@ -33,6 +33,7 @@ public function __invoke(?string $specificModel = null, bool $global = false, bo
timestampsDate: $timestampsDate,
optionalNullables: $optionalNullables,
resolveAbstract: $resolveAbstract,
useEnums: $useEnums,
fillables: $fillables,
fillableSuffix: $fillableSuffix
);
Expand All @@ -43,18 +44,19 @@ public function __invoke(?string $specificModel = null, bool $global = false, bo
*
* @param Collection<int, \Symfony\Component\Finder\SplFileInfo> $models
*/
protected function display(Collection $models, bool $global = false, bool $json = false, bool $plurals = false, bool $apiResources = false, bool $optionalRelations = false, bool $noRelations = false, bool $noHidden = false, bool $timestampsDate = false, bool $optionalNullables = false, bool $resolveAbstract = false, bool $fillables = false, string $fillableSuffix = 'Fillable'): string
protected function display(Collection $models, bool $global = false, bool $json = false, bool $useEnums = false, bool $plurals = false, bool $apiResources = false, bool $optionalRelations = false, bool $noRelations = false, bool $noHidden = false, bool $timestampsDate = false, bool $optionalNullables = false, bool $resolveAbstract = false, bool $fillables = false, string $fillableSuffix = 'Fillable'): string
{
$mappings = app(GetMappings::class)(setTimestampsToDate: $timestampsDate);

if ($json) {
return app(GenerateJsonOutput::class)(models: $models, mappings: $mappings, resolveAbstract: $resolveAbstract);
return app(GenerateJsonOutput::class)(models: $models, mappings: $mappings, resolveAbstract: $resolveAbstract, useEnums: $useEnums);
}

return app(GenerateCliOutput::class)(
models: $models,
mappings: $mappings,
global: $global,
useEnums: $useEnums,
plurals: $plurals,
apiResources: $apiResources,
optionalRelations: $optionalRelations,
Expand Down
8 changes: 6 additions & 2 deletions src/Actions/WriteColumnAttribute.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class WriteColumnAttribute
* @param array<string, string> $mappings
* @return array{array{name: string, type: string}, ReflectionClass|null}|array{string, ReflectionClass|null}|array{null, null}
*/
public function __invoke(ReflectionClass $reflectionModel, array $attribute, array $mappings, string $indent = '', bool $jsonOutput = false, bool $noHidden = false, bool $optionalNullables = false): array
public function __invoke(ReflectionClass $reflectionModel, array $attribute, array $mappings, string $indent = '', bool $jsonOutput = false, bool $noHidden = false, bool $optionalNullables = false, bool $useEnums = false): array
{
$enumRef = null;
$returnType = app(MapReturnType::class);
Expand Down Expand Up @@ -98,6 +98,10 @@ public function __invoke(ReflectionClass $reflectionModel, array $attribute, arr
}
}

if ($useEnums) {
$type = $enumRef && $type ? ($type . 'Enum') : $type;
}

if ($attribute['nullable']) {
$type .= '|null';
}
Expand Down Expand Up @@ -139,7 +143,7 @@ protected function resolveEnum(string $returnTypeName): ?ReflectionClass
private function ensurePropertyIsValid(string $identifier): string
{
$firstCharacter = substr($identifier, 0, 1);

if (! ctype_digit($identifier) && ctype_digit($firstCharacter)) {
return "'$identifier'";
}
Expand Down
26 changes: 20 additions & 6 deletions src/Actions/WriteEnumConst.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ class WriteEnumConst
*
* @return array{type: string, name: string}|string
*/
public function __invoke(ReflectionClass $reflection, string $indent = '', bool $jsonOutput = false): array|string
public function __invoke(ReflectionClass $reflection, string $indent = '', bool $jsonOutput = false, bool $useEnums = false): array|string
{
$entry = '';

Expand All @@ -28,9 +28,13 @@ public function __invoke(ReflectionClass $reflection, string $indent = '', bool
$cases = collect($reflection->getConstants());

if ($cases->isNotEmpty()) {
$entry .= "{$indent}const {$reflection->getShortName()} = {\n";
if ($useEnums) {
$entry .= "{$indent}export const enum {$reflection->getShortName()} {\n";
} else {
$entry .= "{$indent}const {$reflection->getShortName()} = {\n";
}

$cases->each(function ($case) use ($indent, &$entry, $comments) {
$cases->each(function ($case) use ($indent, &$entry, $comments, $useEnums) {
$name = $case->name;
$value = is_string($case->value) ? "'{$case->value}'" : $case->value;

Expand All @@ -47,11 +51,21 @@ public function __invoke(ReflectionClass $reflection, string $indent = '', bool
}
}

$entry .= "{$indent} {$name}: {$value},\n";
if ($useEnums) {
$entry .= "{$indent} {$name} = {$value},\n";
} else {
$entry .= "{$indent} {$name}: {$value},\n";
}
});

$entry .= "{$indent}} as const;\n\n";
$entry .= "{$indent}export type {$reflection->getShortName()} = typeof {$reflection->getShortName()}[keyof typeof {$reflection->getShortName()}]\n\n";
if ($useEnums) {
$entry .= "{$indent}}\n\n";
$entry .= "{$indent}export type {$reflection->getShortName()}Enum = `\${{$reflection->getShortName()}}`\n\n";
} else {
$entry .= "{$indent}} as const;\n\n";
$entry .= "{$indent}export type {$reflection->getShortName()} = typeof {$reflection->getShortName()}[keyof typeof {$reflection->getShortName()}]\n\n";
}

}

if ($jsonOutput) {
Expand Down
2 changes: 2 additions & 0 deletions src/Commands/ModelTyperCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ class ModelTyperCommand extends Command
{--model= : Generate typescript interfaces for a specific model}
{--global : Generate typescript interfaces in a global namespace named models}
{--json : Output the result as json}
{--use-enums : Use typescript enums instead of object literals}
{--plurals : Output model plurals}
{--no-relations : Do not include relations}
{--optional-relations : Make relations optional fields on the model type}
Expand Down Expand Up @@ -65,6 +66,7 @@ public function handle(Generator $generator): int
$this->option('model'),
$this->option('global'),
$this->option('json'),
$this->option('use-enums'),
$this->option('plurals') || $this->option('all'),
$this->option('api-resources') || $this->option('all'),
$this->option('optional-relations'),
Expand Down

0 comments on commit ececd20

Please sign in to comment.