Skip to content

Commit

Permalink
Add support for ActiveRecord enums
Browse files Browse the repository at this point in the history
  • Loading branch information
Envek authored and skryukov committed Nov 15, 2024
1 parent 8d5470d commit aea764b
Show file tree
Hide file tree
Showing 29 changed files with 48 additions and 32 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning].

## Added

- Add support for enum attributes declared using `ActiveRecord::Enum` or explicitly in serializers ([@envek])
- Add support for comments in generated TypeScript interfaces ([@envek])
- Add TypeScript verbatim module syntax support through `verbatim_module_syntax` config option ([@patvice])
- Add `typelizer:generate:refresh` command to clean output directory and regenerate all interfaces ([@patvice])
Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ end
You can also specify more complex type definitions using a lower-level API:

```ruby
typelize attribute_name: ["string", "Date", optional: true, nullable: true, multi: true]
typelize attribute_name: ["string", "Date", optional: true, nullable: true, multi: true, enum: %w[foo bar], comment: "Attribute description"]
```

### TypeScript Integration
Expand All @@ -117,6 +117,7 @@ Typelizer generates TypeScript interfaces in the specified output directory:
export interface Post {
id: number;
title: string;
category?: "news" | "article" | "blog" | null;
body: string;
published_at: string | null;
author_name: string;
Expand Down
1 change: 1 addition & 0 deletions lib/typelizer/interface.rb
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ def infer_types(props, hash_name = :_typelizer_attributes)
if dsl_type&.any?
next Property.new(prop.to_h.merge(dsl_type)).tap do |property|
property.comment ||= model_plugin.comment_for(property) if config.comments && property.comment != false
property.enum ||= model_plugin.enum_for(property) if property.enum != false
end
end
end
Expand Down
15 changes: 11 additions & 4 deletions lib/typelizer/model_plugins/active_record.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@ module Typelizer
module ModelPlugins
class ActiveRecord
def initialize(model_class:, config:)
@columns_hash = model_class&.columns_hash || {}
@model_class = model_class
@config = config
end

attr_reader :columns_hash, :config
attr_reader :model_class, :config

def infer_types(prop)
column = columns_hash[prop.column_name.to_s]
column = model_class&.columns_hash&.dig(prop.column_name.to_s)
return prop unless column

prop.multi = !!column.try(:array)
Expand All @@ -27,16 +27,23 @@ def infer_types(prop)

prop.type = @config.type_mapping[column.type]
prop.comment = comment_for(prop)
prop.enum = enum_for(prop)

prop
end

def comment_for(prop)
column = columns_hash[prop.column_name.to_s]
column = model_class&.columns_hash&.dig(prop.column_name.to_s)
return nil unless column

prop.comment = column.comment
end

def enum_for(prop)
return unless model_class&.defined_enums&.key?(prop.column_name.to_s)

prop.enum = model_class.defined_enums[prop.column_name.to_s].keys
end
end
end
end
4 changes: 4 additions & 0 deletions lib/typelizer/model_plugins/poro.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ def infer_types(prop)
def comment_for(prop)
nil
end

def enum_for(prop)
nil
end
end
end
end
4 changes: 3 additions & 1 deletion lib/typelizer/property.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
module Typelizer
Property = Struct.new(
:name, :type, :optional, :nullable,
:multi, :column_name, :comment,
:multi, :column_name, :comment, :enum,
keyword_init: true
) do
def inspect
Expand All @@ -20,6 +20,8 @@ def to_s
private

def type_name
return enum.map { |v| v.to_s.inspect }.join(" | ") if enum

type.respond_to?(:name) ? type.name : type || "unknown"
end
end
Expand Down
2 changes: 1 addition & 1 deletion spec/__snapshots__/AlbaInline.ts.snap
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Typelizer digest f5275d68218cedacb480ce36d1e6bbe2
// Typelizer digest 178ddab3063fd4d03443d5febfa7c551
//
// DO NOT MODIFY: This file was automatically generated by Typelizer.

Expand Down
2 changes: 1 addition & 1 deletion spec/__snapshots__/AlbaMeta.ts.snap
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Typelizer digest bf4b0c896fc166774c2208b110c6d2e9
// Typelizer digest 526732453f6aca249ef72f2dd8bc1cde
//
// DO NOT MODIFY: This file was automatically generated by Typelizer.

Expand Down
2 changes: 1 addition & 1 deletion spec/__snapshots__/AlbaMetaNil.ts.snap
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Typelizer digest aa6e6401d09df2e398c69ccd17c99ee5
// Typelizer digest 20994e3923784dec08006faf8465bf77
//
// DO NOT MODIFY: This file was automatically generated by Typelizer.

Expand Down
2 changes: 1 addition & 1 deletion spec/__snapshots__/AlbaPoro.ts.snap
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Typelizer digest 4a7987ac34502a3281b1f42e3f266099
// Typelizer digest 87487e81d77b218d3be41a33279d8e4c
//
// DO NOT MODIFY: This file was automatically generated by Typelizer.

Expand Down
4 changes: 2 additions & 2 deletions spec/__snapshots__/AlbaPost.ts.snap
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
// Typelizer digest 3ab2e20940a1c4559f44fb582ad7719d
// Typelizer digest a9453a41deef37fc65276aad80c95e46
//
// DO NOT MODIFY: This file was automatically generated by Typelizer.
import type {AlbaUser} from '@/types'

type AlbaPost = {
id: number;
title?: string | null;
category?: string | null;
category?: "news" | "article" | "blog" | null;
body?: string | null;
published_at?: string | null;
user: AlbaUser;
Expand Down
2 changes: 1 addition & 1 deletion spec/__snapshots__/AlbaUser.ts.snap
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Typelizer digest 480b9d1caeafc717431d31282ba0981c
// Typelizer digest b27b36237e51d59bd905f4931314eddd
//
// DO NOT MODIFY: This file was automatically generated by Typelizer.
import type {AlbaPost} from '@/types'
Expand Down
2 changes: 1 addition & 1 deletion spec/__snapshots__/AlbaUserAuthor.ts.snap
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Typelizer digest 6a70418b072c53d25848cea380599d44
// Typelizer digest e4ff2970ad7175d42c20d9a799d946f9
//
// DO NOT MODIFY: This file was automatically generated by Typelizer.
import type {AlbaPost} from '@/types'
Expand Down
2 changes: 1 addition & 1 deletion spec/__snapshots__/AlbaUserEmptyNested.ts.snap
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Typelizer digest 149809de5e88dc7e93c61dd1c8df854d
// Typelizer digest 6d6055ff99fc70aef66e59e124465b4e
//
// DO NOT MODIFY: This file was automatically generated by Typelizer.
import type {AlbaPost} from '@/types'
Expand Down
2 changes: 1 addition & 1 deletion spec/__snapshots__/AlbaUserSerializerFoo.ts.snap
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Typelizer digest 4e7d58f3d78c500545098dad7137b8c6
// Typelizer digest 0ac7beef74fefd38c7d3ad485d8f1a73
//
// DO NOT MODIFY: This file was automatically generated by Typelizer.
import type {AlbaUser, AlbaPost} from '@/types'
Expand Down
2 changes: 1 addition & 1 deletion spec/__snapshots__/AlbaVerbatimModuleSyntax.ts.snap
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Typelizer digest f82208b39a056eaa4fdfc6b8696f7c93
// Typelizer digest 6f3a4cfc73c5faede518b793ba0f25ed
//
// DO NOT MODIFY: This file was automatically generated by Typelizer.

Expand Down
4 changes: 2 additions & 2 deletions spec/__snapshots__/AmsPost.ts.snap
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
// Typelizer digest 49f4596d7eb72effcbb13a7b5a05ea44
// Typelizer digest f716d8f63d4d1ba1e27cb6ece3df7d29
//
// DO NOT MODIFY: This file was automatically generated by Typelizer.
import type {AmsUser} from '@/types'

type AmsPost = {
id: number;
title?: string | null;
category?: string | null;
category?: "news" | "article" | "blog" | null;
body?: string | null;
published_at?: string | null;
user: AmsUser;
Expand Down
2 changes: 1 addition & 1 deletion spec/__snapshots__/AmsUser.ts.snap
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Typelizer digest 1aea91828e4e0f1dfdd795922b602e40
// Typelizer digest 5e9abced7cd48e23138f5f764cc2c608
//
// DO NOT MODIFY: This file was automatically generated by Typelizer.
import type {AmsPost} from '@/types'
Expand Down
2 changes: 1 addition & 1 deletion spec/__snapshots__/AmsUserAuthor.ts.snap
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Typelizer digest 6b3157b1afb8bd20ec259745483e6069
// Typelizer digest 5ae23f300b01c30e04f7132b09621c12
//
// DO NOT MODIFY: This file was automatically generated by Typelizer.
import type {AmsPost} from '@/types'
Expand Down
2 changes: 1 addition & 1 deletion spec/__snapshots__/AmsUserEmptyNested.ts.snap
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Typelizer digest fe35a8cc2cd60cd90112d82d3886a6ad
// Typelizer digest 8b51f6ff077d5703402168d15790ecb7
//
// DO NOT MODIFY: This file was automatically generated by Typelizer.
import type {AmsPost} from '@/types'
Expand Down
2 changes: 1 addition & 1 deletion spec/__snapshots__/AmsUserSerializerFoo.ts.snap
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Typelizer digest 01c1c8d2bbca94c0ac46a9dedfc1d312
// Typelizer digest 8754172bae0da06a953a1c8690e05c10
//
// DO NOT MODIFY: This file was automatically generated by Typelizer.
import type {AmsUser, AmsPost} from '@/types'
Expand Down
2 changes: 1 addition & 1 deletion spec/__snapshots__/AmsVerbatimModuleSyntax.ts.snap
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Typelizer digest 7c09585f88197784fbfde340bfd5e36b
// Typelizer digest 92953120c1d10142beb7678b8c7b1cd1
//
// DO NOT MODIFY: This file was automatically generated by Typelizer.

Expand Down
2 changes: 1 addition & 1 deletion spec/__snapshots__/OjSerializersFlatUser.ts.snap
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Typelizer digest 5fc05a8d823c221cd138c49d17ccd54c
// Typelizer digest 1d3c1a45ff88689555089d3ed14de4b7
//
// DO NOT MODIFY: This file was automatically generated by Typelizer.
import type {OjSerializersUser, OjSerializersPost} from '@/types'
Expand Down
4 changes: 2 additions & 2 deletions spec/__snapshots__/OjSerializersPost.ts.snap
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
// Typelizer digest b05ae512914de90ee4c78f8b8d5ef96a
// Typelizer digest 491e0aed7fd3083b542c51fff940bdba
//
// DO NOT MODIFY: This file was automatically generated by Typelizer.
import type {OjSerializersUser} from '@/types'

type OjSerializersPost = {
id: number;
title?: string | null;
category?: string | null;
category?: "news" | "article" | "blog" | null;
body?: string | null;
published_at?: string | null;
user: OjSerializersUser;
Expand Down
2 changes: 1 addition & 1 deletion spec/__snapshots__/OjSerializersUser.ts.snap
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Typelizer digest fc111d0651504bd12951008cbc0bfffd
// Typelizer digest eff6dfac48c94f13ed9af03569b9f6d3
//
// DO NOT MODIFY: This file was automatically generated by Typelizer.
import type {OjSerializersPost} from '@/types'
Expand Down
2 changes: 1 addition & 1 deletion spec/__snapshots__/OjSerializersUserAuthor.ts.snap
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Typelizer digest 8b7f37c2d5f826ce3dfb592d5774a1a5
// Typelizer digest e37ce250dd4715f9565393c0f1049c2a
//
// DO NOT MODIFY: This file was automatically generated by Typelizer.
import type {OjSerializersPost} from '@/types'
Expand Down
2 changes: 1 addition & 1 deletion spec/__snapshots__/OjSerializersUserEmptyNested.ts.snap
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Typelizer digest 2ebe03be885472fb7f96144781d418f1
// Typelizer digest c34e6deb0554a1777fb0c41d6dc4a5d2
//
// DO NOT MODIFY: This file was automatically generated by Typelizer.
import type {OjSerializersPost} from '@/types'
Expand Down
2 changes: 1 addition & 1 deletion spec/__snapshots__/OjSerializersUserSerializerFoo.ts.snap
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Typelizer digest 220ec4296faaf24a55e668b3ff1cbccd
// Typelizer digest 0b80edf3c51be3e5b1e41e1034f45d5f
//
// DO NOT MODIFY: This file was automatically generated by Typelizer.
import type {OjSerializersUser, OjSerializersPost} from '@/types'
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Typelizer digest e4b0b8226d1bf89d94bd35bc366e5837
// Typelizer digest 7c167935b1871afe3b9e1ab2f0344e15
//
// DO NOT MODIFY: This file was automatically generated by Typelizer.

Expand Down

0 comments on commit aea764b

Please sign in to comment.