Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for ActiveRecord enums #23

Merged
merged 1 commit into from
Nov 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading