types_from_serializers 0.1.3 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +13 -0
- data/lib/types_from_serializers/dsl.rb +17 -61
- data/lib/types_from_serializers/generator.rb +186 -111
- data/lib/types_from_serializers/railtie.rb +4 -1
- data/lib/types_from_serializers/version.rb +1 -1
- metadata +10 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 107bcbbe1708fd38efdb7943673c11112350eeee1e457e67e50934641e8081e7
|
4
|
+
data.tar.gz: dbb8a8732f99088318ae2d7c16b11dc219bb96357347d1d2174b106216e82599
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d6e0dc57e64062a6934f0e3f336412c897ec4fe5d7497b65536bf45c59c270f39e278fc183f299bfe0cdc6b55769e652d3f6b153bb298bc2f311a0edf2a8e3ad
|
7
|
+
data.tar.gz: 00f07fd96b3e9fa907b457969d227e641cfcce1c9e2f67a56bb9f5d9f07b8222d8861144737eb443508ed50024d31992836a3285a1c739e9588817912a6ca168
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,16 @@
|
|
1
|
+
## [2.0.0](https://github.com/ElMassimo/types_from_serializers/compare/types_from_serializers@0.1.2...types_from_serializers@2.0.0) (2023-04-02)
|
2
|
+
|
3
|
+
This version adds support for `oj_serializers-2.0.2`, supporting all changes in:
|
4
|
+
|
5
|
+
- https://github.com/ElMassimo/oj_serializers/pull/9
|
6
|
+
|
7
|
+
### Features ✨
|
8
|
+
|
9
|
+
- Now keys will match the [`transform_keys`](https://github.com/ElMassimo/oj_serializers#transforming-attribute-keys-) configuration instead of always being camelized
|
10
|
+
- Support for [`flat_one`](https://github.com/ElMassimo/oj_serializers#composing-serializers-)
|
11
|
+
- Use relative paths for imports to make the output configuration more flexible
|
12
|
+
- Define the order of properties in the interface with `sort_properties_by`
|
13
|
+
|
1
14
|
## [0.1.3](https://github.com/ElMassimo/types_from_serializers/compare/types_from_serializers@0.1.2...types_from_serializers@0.1.3) (2022-07-12)
|
2
15
|
|
3
16
|
|
@@ -3,7 +3,7 @@
|
|
3
3
|
require "active_support/concern"
|
4
4
|
|
5
5
|
# Internal: A DSL to specify types for serializer attributes.
|
6
|
-
module
|
6
|
+
module TypesFromSerializers
|
7
7
|
module DSL
|
8
8
|
extend ActiveSupport::Concern
|
9
9
|
|
@@ -16,74 +16,30 @@ module TypesFromSerializer
|
|
16
16
|
def object_as(name, model: nil, types_from: nil)
|
17
17
|
# NOTE: Avoid taking memory for type information that won't be used.
|
18
18
|
if Rails.env.development?
|
19
|
-
model ||= name.is_a?(Symbol) ? name : try(:_serializer_model_name)
|
20
|
-
|
21
|
-
|
19
|
+
model ||= name.is_a?(Symbol) ? name : try(:_serializer_model_name) || name
|
20
|
+
define_singleton_method(:_serializer_model_name) { model }
|
21
|
+
define_singleton_method(:_serializer_types_from) { types_from } if types_from
|
22
22
|
end
|
23
23
|
|
24
24
|
super(name)
|
25
25
|
end
|
26
26
|
|
27
|
-
# Public:
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
_typed_attributes.update(attrs.map { |key, type|
|
34
|
-
[key.to_s, type.is_a?(Hash) ? type : {type: type}]
|
35
|
-
}.to_h)
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
# Public: Allows to specify the type for a serializer method that will
|
40
|
-
# be defined immediately after calling this method.
|
41
|
-
def type(type = :unknown, optional: false)
|
42
|
-
@_current_attribute_type = {type: type, optional: optional}
|
43
|
-
end
|
44
|
-
|
45
|
-
# Internal: Intercept a method definition, tying a type that was
|
46
|
-
# previously specified to the name of the attribute.
|
47
|
-
def method_added(name)
|
48
|
-
super(name)
|
49
|
-
if @_current_attribute_type
|
50
|
-
serializer_attributes name
|
51
|
-
|
52
|
-
# NOTE: Avoid taking memory for type information that won't be used.
|
53
|
-
if Rails.env.development?
|
54
|
-
_typed_attributes[name.to_s] = @_current_attribute_type
|
55
|
-
end
|
56
|
-
|
57
|
-
@_current_attribute_type = nil
|
58
|
-
end
|
27
|
+
# Public: Shortcut for typing a serializer attribute.
|
28
|
+
#
|
29
|
+
# It specifies the type for a serializer method that will be defined
|
30
|
+
# immediately after calling this method.
|
31
|
+
def type(type, **options)
|
32
|
+
attribute type: type, **options
|
59
33
|
end
|
60
34
|
|
61
|
-
|
62
|
-
if Rails.env.development?
|
63
|
-
# Internal: Contains type information for serializer attributes.
|
64
|
-
def _typed_attributes
|
65
|
-
unless defined?(@_typed_attributes)
|
66
|
-
@_typed_attributes = superclass.try(:_typed_attributes)&.dup || {}
|
67
|
-
end
|
68
|
-
@_typed_attributes
|
69
|
-
end
|
70
|
-
|
71
|
-
# Internal: The name of the model that will be serialized by this
|
72
|
-
# serializer, used to infer field types from the SQL columns.
|
73
|
-
def _serializer_model_name
|
74
|
-
unless defined?(@_serializer_model_name)
|
75
|
-
@_serializer_model_name = superclass.try(:_serializer_model_name)
|
76
|
-
end
|
77
|
-
@_serializer_model_name
|
78
|
-
end
|
35
|
+
private
|
79
36
|
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
@_serializer_types_from
|
37
|
+
# Override: Remove unnecessary options in production, types are only
|
38
|
+
# used when generating code in development.
|
39
|
+
unless Rails.env.development?
|
40
|
+
def add_attribute(name, options)
|
41
|
+
options.except!(:type, :optional)
|
42
|
+
super
|
87
43
|
end
|
88
44
|
end
|
89
45
|
end
|
@@ -6,36 +6,7 @@ require "pathname"
|
|
6
6
|
|
7
7
|
# Public: Automatically generates TypeScript interfaces for Ruby serializers.
|
8
8
|
module TypesFromSerializers
|
9
|
-
|
10
|
-
Config = Struct.new(
|
11
|
-
:base_serializers,
|
12
|
-
:serializers_dirs,
|
13
|
-
:output_dir,
|
14
|
-
:name_from_serializer,
|
15
|
-
:native_types,
|
16
|
-
:sql_to_typescript_type_mapping,
|
17
|
-
keyword_init: true,
|
18
|
-
) do
|
19
|
-
def unknown_type
|
20
|
-
sql_to_typescript_type_mapping.default
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
# Internal: The type metadata for a serializer.
|
25
|
-
SerializerMetadata = Struct.new(
|
26
|
-
:attributes,
|
27
|
-
:associations,
|
28
|
-
:model_name,
|
29
|
-
:types_from,
|
30
|
-
keyword_init: true,
|
31
|
-
)
|
32
|
-
|
33
|
-
# Internal: The type metadata for a serializer field.
|
34
|
-
FieldMetadata = Struct.new(:name, :type, :optional, :many, keyword_init: true) do
|
35
|
-
def typescript_name
|
36
|
-
name.to_s.camelize(:lower)
|
37
|
-
end
|
38
|
-
end
|
9
|
+
DEFAULT_TRANSFORM_KEYS = ->(key) { key.camelize(:lower).chomp("?") }
|
39
10
|
|
40
11
|
# Internal: Extensions that simplify the implementation of the generator.
|
41
12
|
module SerializerRefinements
|
@@ -58,91 +29,185 @@ module TypesFromSerializers
|
|
58
29
|
|
59
30
|
refine Class do
|
60
31
|
# Internal: Name of the TypeScript interface.
|
61
|
-
def
|
32
|
+
def ts_name
|
62
33
|
TypesFromSerializers.config.name_from_serializer.call(name).tr_s(":", "")
|
63
34
|
end
|
64
35
|
|
65
36
|
# Internal: The base name of the TypeScript file to be written.
|
66
|
-
def
|
37
|
+
def ts_filename
|
67
38
|
TypesFromSerializers.config.name_from_serializer.call(name).gsub("::", "/")
|
68
39
|
end
|
69
40
|
|
70
|
-
# Internal:
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
types_from: _serializer_types_from,
|
75
|
-
attributes: _attributes.map { |key, options|
|
76
|
-
typed_attrs = _typed_attributes.fetch(key, {})
|
77
|
-
FieldMetadata.new(
|
78
|
-
**typed_attrs,
|
79
|
-
name: key,
|
80
|
-
optional: typed_attrs[:optional] || options.key?(:if),
|
81
|
-
)
|
82
|
-
},
|
83
|
-
associations: _associations.map { |key, options|
|
84
|
-
FieldMetadata.new(
|
85
|
-
name: options.fetch(:root, key),
|
86
|
-
type: options.fetch(:serializer),
|
87
|
-
optional: options.key?(:if),
|
88
|
-
many: options.fetch(:write_method) == :write_many,
|
89
|
-
)
|
90
|
-
},
|
91
|
-
)
|
41
|
+
# Internal: The columns corresponding to the serializer model, if it's a
|
42
|
+
# record.
|
43
|
+
def model_columns
|
44
|
+
@model_columns ||= _serializer_model_name&.to_model.try(:columns_hash) || {}
|
92
45
|
end
|
93
46
|
|
94
|
-
# Internal:
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
47
|
+
# Internal: The TypeScript properties of the serialzeir interface.
|
48
|
+
def ts_properties
|
49
|
+
@ts_properties ||= begin
|
50
|
+
types_from = try(:_serializer_types_from)
|
51
|
+
|
52
|
+
prepare_attributes(
|
53
|
+
sort_by: TypesFromSerializers.config.sort_properties_by,
|
54
|
+
transform_keys: TypesFromSerializers.config.transform_keys || try(:_transform_keys) || DEFAULT_TRANSFORM_KEYS,
|
55
|
+
)
|
56
|
+
.flat_map { |key, options|
|
57
|
+
if options[:association] == :flat
|
58
|
+
options.fetch(:serializer).ts_properties
|
59
|
+
else
|
60
|
+
Property.new(
|
61
|
+
name: key,
|
62
|
+
type: options[:serializer] || options[:type],
|
63
|
+
optional: options[:optional] || options.key?(:if),
|
64
|
+
multi: options[:association] == :many,
|
65
|
+
column_name: options.fetch(:value_from),
|
66
|
+
).tap do |property|
|
67
|
+
property.infer_type_from(model_columns, types_from)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
}
|
107
71
|
end
|
108
72
|
end
|
109
73
|
|
110
|
-
|
111
|
-
|
112
|
-
|
74
|
+
# Internal: A first pass of gathering types for the serializer attributes.
|
75
|
+
def ts_interface
|
76
|
+
@ts_interface ||= Interface.new(
|
77
|
+
name: ts_name,
|
78
|
+
filename: ts_filename,
|
79
|
+
properties: ts_properties,
|
80
|
+
)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
# Internal: The configuration for TypeScript generation.
|
86
|
+
Config = Struct.new(
|
87
|
+
:base_serializers,
|
88
|
+
:serializers_dirs,
|
89
|
+
:output_dir,
|
90
|
+
:custom_types_dir,
|
91
|
+
:name_from_serializer,
|
92
|
+
:global_types,
|
93
|
+
:sort_properties_by,
|
94
|
+
:sql_to_typescript_type_mapping,
|
95
|
+
:skip_serializer_if,
|
96
|
+
:transform_keys,
|
97
|
+
keyword_init: true,
|
98
|
+
) do
|
99
|
+
def relative_custom_types_dir
|
100
|
+
@relative_custom_types_dir ||= (custom_types_dir || output_dir.parent).relative_path_from(output_dir)
|
101
|
+
end
|
102
|
+
|
103
|
+
def unknown_type
|
104
|
+
sql_to_typescript_type_mapping.default
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
# Internal: Information to generate a TypeScript interface for a serializer.
|
109
|
+
Interface = Struct.new(
|
110
|
+
:name,
|
111
|
+
:filename,
|
112
|
+
:properties,
|
113
|
+
keyword_init: true,
|
114
|
+
) do
|
115
|
+
using SerializerRefinements
|
116
|
+
|
117
|
+
def inspect
|
118
|
+
to_h.inspect
|
119
|
+
end
|
120
|
+
|
121
|
+
# Internal: Returns a list of imports for types used in this interface.
|
122
|
+
def used_imports
|
123
|
+
association_serializers, attribute_types = properties.map(&:type).compact.uniq
|
124
|
+
.partition { |type| type.respond_to?(:ts_interface) }
|
125
|
+
|
126
|
+
serializer_type_imports = association_serializers.map(&:ts_interface)
|
127
|
+
.map { |type| [type.name, relative_path(type.pathname, pathname)] }
|
128
|
+
|
129
|
+
custom_type_imports = attribute_types
|
130
|
+
.flat_map { |type| extract_typescript_types(type.to_s) }
|
131
|
+
.uniq
|
132
|
+
.reject { |type| global_type?(type) }
|
133
|
+
.map { |type|
|
134
|
+
type_path = TypesFromSerializers.config.relative_custom_types_dir.join(type)
|
135
|
+
[type, relative_path(type_path, pathname)]
|
113
136
|
}
|
114
137
|
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
.reject { |type| typescript_native_type?(type) }
|
119
|
-
.map { |type|
|
120
|
-
[type, "~/types/#{type}"]
|
121
|
-
}
|
122
|
-
|
123
|
-
(assoc_imports + attr_imports).uniq.map { |interface, filename|
|
124
|
-
"import type #{interface} from '#{filename}'\n"
|
125
|
-
}.uniq
|
126
|
-
end
|
138
|
+
(custom_type_imports + serializer_type_imports)
|
139
|
+
.map { |interface, filename| "import type #{interface} from '#{filename}'\n" }
|
140
|
+
end
|
127
141
|
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
142
|
+
def as_typescript
|
143
|
+
<<~TS
|
144
|
+
interface #{name} {
|
145
|
+
#{properties.index_by(&:name).values.map(&:as_typescript).join("\n ")}
|
146
|
+
}
|
147
|
+
TS
|
148
|
+
end
|
149
|
+
|
150
|
+
protected
|
132
151
|
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
152
|
+
def pathname
|
153
|
+
@pathname ||= Pathname.new(filename)
|
154
|
+
end
|
155
|
+
|
156
|
+
# Internal: Calculates a relative path that can be used in an import.
|
157
|
+
def relative_path(target_path, importer_path)
|
158
|
+
path = target_path.relative_path_from(importer_path.parent).to_s
|
159
|
+
path.start_with?(".") ? path : "./#{path}"
|
160
|
+
end
|
161
|
+
|
162
|
+
# Internal: Extracts any types inside generics or array types.
|
163
|
+
def extract_typescript_types(type)
|
164
|
+
type.split(/[<>\[\],\s|]+/)
|
165
|
+
end
|
166
|
+
|
167
|
+
# NOTE: Treat uppercase names as custom types.
|
168
|
+
# Lowercase names would be native types, such as :string and :boolean.
|
169
|
+
def global_type?(type)
|
170
|
+
type[0] == type[0].downcase || TypesFromSerializers.config.global_types.include?(type)
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
# Internal: The type metadata for a serializer attribute.
|
175
|
+
Property = Struct.new(
|
176
|
+
:name,
|
177
|
+
:type,
|
178
|
+
:optional,
|
179
|
+
:multi,
|
180
|
+
:column_name,
|
181
|
+
keyword_init: true,
|
182
|
+
) do
|
183
|
+
using SerializerRefinements
|
184
|
+
|
185
|
+
def inspect
|
186
|
+
to_h.inspect
|
187
|
+
end
|
188
|
+
|
189
|
+
# Internal: Infers the property's type by checking a corresponding SQL
|
190
|
+
# column, or falling back to a TypeScript interface if provided.
|
191
|
+
def infer_type_from(columns_hash, ts_interface)
|
192
|
+
if type
|
193
|
+
type
|
194
|
+
elsif (column = columns_hash[column_name.to_s])
|
195
|
+
self.multi = true if column.try(:array)
|
196
|
+
self.optional = true if column.null && !column.default
|
197
|
+
self.type = TypesFromSerializers.config.sql_to_typescript_type_mapping[column.type]
|
198
|
+
elsif ts_interface
|
199
|
+
self.type = "#{ts_interface}['#{name}']"
|
137
200
|
end
|
201
|
+
end
|
138
202
|
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
}
|
203
|
+
def as_typescript
|
204
|
+
type_str = if type.respond_to?(:ts_name)
|
205
|
+
type.ts_name
|
206
|
+
else
|
207
|
+
type || TypesFromSerializers.config.unknown_type
|
145
208
|
end
|
209
|
+
|
210
|
+
"#{name}#{"?" if optional}: #{type_str}#{"[]" if multi}"
|
146
211
|
end
|
147
212
|
end
|
148
213
|
|
@@ -222,12 +287,10 @@ module TypesFromSerializers
|
|
222
287
|
|
223
288
|
# Internal: Defines a TypeScript interface for the serializer.
|
224
289
|
def generate_interface_for(serializer)
|
225
|
-
|
226
|
-
filename = serializer.typescript_interface_basename
|
290
|
+
interface = serializer.ts_interface
|
227
291
|
|
228
|
-
write_if_changed(filename: filename, cache_key:
|
229
|
-
|
230
|
-
serializer_interface_content(serializer, metadata)
|
292
|
+
write_if_changed(filename: interface.filename, cache_key: interface.inspect) {
|
293
|
+
serializer_interface_content(interface)
|
231
294
|
}
|
232
295
|
end
|
233
296
|
|
@@ -241,8 +304,11 @@ module TypesFromSerializers
|
|
241
304
|
end
|
242
305
|
|
243
306
|
# Internal: Checks if it should avoid generating an interface.
|
244
|
-
def skip_serializer?(
|
245
|
-
|
307
|
+
def skip_serializer?(serializer)
|
308
|
+
serializer.name.in?(config.base_serializers) ||
|
309
|
+
config.skip_serializer_if.call(serializer) ||
|
310
|
+
# NOTE: Ignore inline serializers.
|
311
|
+
serializer.ts_name.include?("Serializer")
|
246
312
|
end
|
247
313
|
|
248
314
|
# Internal: Returns an object compatible with FileUpdateChecker.
|
@@ -273,7 +339,7 @@ module TypesFromSerializers
|
|
273
339
|
.flat_map(&:descendants)
|
274
340
|
.uniq
|
275
341
|
.sort_by(&:name)
|
276
|
-
.reject { |s| skip_serializer?(s
|
342
|
+
.reject { |s| skip_serializer?(s) }
|
277
343
|
rescue NameError
|
278
344
|
raise ArgumentError, "Please ensure all your serializers extend BaseSerializer, or configure `config.base_serializers`."
|
279
345
|
end
|
@@ -293,12 +359,18 @@ module TypesFromSerializers
|
|
293
359
|
name_from_serializer: ->(name) { name.delete_suffix("Serializer") },
|
294
360
|
|
295
361
|
# Types that don't need to be imported in TypeScript.
|
296
|
-
|
362
|
+
global_types: [
|
297
363
|
"Array",
|
298
364
|
"Record",
|
299
365
|
"Date",
|
300
366
|
].to_set,
|
301
367
|
|
368
|
+
# Allows to choose a different sort order, alphabetical by default.
|
369
|
+
sort_properties_by: :name,
|
370
|
+
|
371
|
+
# Allows to avoid generating a serializer.
|
372
|
+
skip_serializer_if: ->(serializer) { false },
|
373
|
+
|
302
374
|
# Maps SQL column types to TypeScript native and custom types.
|
303
375
|
sql_to_typescript_type_mapping: {
|
304
376
|
boolean: :boolean,
|
@@ -311,6 +383,9 @@ module TypesFromSerializers
|
|
311
383
|
}.tap do |types|
|
312
384
|
types.default = :unknown
|
313
385
|
end,
|
386
|
+
|
387
|
+
# Allows to transform keys, useful when converting objects client-side.
|
388
|
+
transform_keys: nil,
|
314
389
|
)
|
315
390
|
end
|
316
391
|
|
@@ -335,18 +410,18 @@ module TypesFromSerializers
|
|
335
410
|
<<~TS
|
336
411
|
//
|
337
412
|
// DO NOT MODIFY: This file was automatically generated by TypesFromSerializers.
|
338
|
-
#{serializers.map { |s|
|
413
|
+
#{serializers.map { |s|
|
414
|
+
"export type { default as #{s.ts_name} } from './#{s.ts_filename}'"
|
415
|
+
}.join("\n")}
|
339
416
|
TS
|
340
417
|
end
|
341
418
|
|
342
|
-
def serializer_interface_content(
|
419
|
+
def serializer_interface_content(interface)
|
343
420
|
<<~TS
|
344
421
|
//
|
345
422
|
// DO NOT MODIFY: This file was automatically generated by TypesFromSerializers.
|
346
|
-
#{
|
347
|
-
export default
|
348
|
-
#{serializer.typescript_fields(metadata).join("\n")}
|
349
|
-
}
|
423
|
+
#{interface.used_imports.join}
|
424
|
+
export default #{interface.as_typescript}
|
350
425
|
TS
|
351
426
|
end
|
352
427
|
|
@@ -36,8 +36,11 @@ class TypesFromSerializers::Railtie < Rails::Railtie
|
|
36
36
|
desc "Generates TypeScript interfaces for each serializer in the app."
|
37
37
|
task generate: :environment do
|
38
38
|
require_relative "generator"
|
39
|
+
start_time = Time.zone.now
|
40
|
+
print "Generating TypeScript interfaces..."
|
39
41
|
serializers = TypesFromSerializers.generate(force: true)
|
40
|
-
puts "
|
42
|
+
puts "completed in #{(Time.zone.now - start_time).round(2)} seconds.\n"
|
43
|
+
puts "Found #{serializers.size} serializers:"
|
41
44
|
puts serializers.map { |s| "\t#{s.name}" }.join("\n")
|
42
45
|
end
|
43
46
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: types_from_serializers
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 2.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Máximo Mussini
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2023-04-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: railties
|
@@ -17,9 +17,6 @@ dependencies:
|
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: '5.1'
|
20
|
-
- - "<"
|
21
|
-
- !ruby/object:Gem::Version
|
22
|
-
version: '8'
|
23
20
|
type: :runtime
|
24
21
|
prerelease: false
|
25
22
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -27,23 +24,26 @@ dependencies:
|
|
27
24
|
- - ">="
|
28
25
|
- !ruby/object:Gem::Version
|
29
26
|
version: '5.1'
|
30
|
-
- - "<"
|
31
|
-
- !ruby/object:Gem::Version
|
32
|
-
version: '8'
|
33
27
|
- !ruby/object:Gem::Dependency
|
34
28
|
name: oj_serializers
|
35
29
|
requirement: !ruby/object:Gem::Requirement
|
36
30
|
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 2.0.2
|
37
34
|
- - "~>"
|
38
35
|
- !ruby/object:Gem::Version
|
39
|
-
version: '
|
36
|
+
version: '2.0'
|
40
37
|
type: :runtime
|
41
38
|
prerelease: false
|
42
39
|
version_requirements: !ruby/object:Gem::Requirement
|
43
40
|
requirements:
|
41
|
+
- - ">="
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: 2.0.2
|
44
44
|
- - "~>"
|
45
45
|
- !ruby/object:Gem::Version
|
46
|
-
version: '
|
46
|
+
version: '2.0'
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: listen
|
49
49
|
requirement: !ruby/object:Gem::Requirement
|