apiwork 0.6.0 → 0.7.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/lib/apiwork/adapter/serializer/error/default/api_builder.rb +6 -1
- data/lib/apiwork/adapter/serializer/resource/default/contract_builder.rb +2 -0
- data/lib/apiwork/adapter/standard/capability/writing/contract_builder.rb +1 -0
- data/lib/apiwork/api/base.rb +31 -0
- data/lib/apiwork/api/object.rb +12 -12
- data/lib/apiwork/contract/object.rb +74 -74
- data/lib/apiwork/controller.rb +6 -2
- data/lib/apiwork/export/apiwork.rb +20 -0
- data/lib/apiwork/export/apiwork_mapper.rb +232 -0
- data/lib/apiwork/export/open_api.rb +2 -0
- data/lib/apiwork/export/registry.rb +1 -1
- data/lib/apiwork/export/sorbus.rb +1 -5
- data/lib/apiwork/export/type_script.rb +1 -4
- data/lib/apiwork/export/type_script_mapper.rb +12 -4
- data/lib/apiwork/export/zod.rb +0 -9
- data/lib/apiwork/export/zod_mapper.rb +22 -1
- data/lib/apiwork/export.rb +1 -0
- data/lib/apiwork/introspection/api/resource.rb +9 -0
- data/lib/apiwork/introspection/dump/param.rb +9 -10
- data/lib/apiwork/introspection/dump/resource.rb +3 -1
- data/lib/apiwork/introspection/dump/type.rb +15 -4
- data/lib/apiwork/introspection/enum.rb +9 -0
- data/lib/apiwork/introspection/param/array.rb +3 -0
- data/lib/apiwork/introspection/param/base.rb +11 -0
- data/lib/apiwork/introspection/param/binary.rb +3 -0
- data/lib/apiwork/introspection/param/boolean.rb +3 -0
- data/lib/apiwork/introspection/param/date.rb +3 -0
- data/lib/apiwork/introspection/param/date_time.rb +3 -0
- data/lib/apiwork/introspection/param/decimal.rb +3 -0
- data/lib/apiwork/introspection/param/integer.rb +3 -0
- data/lib/apiwork/introspection/param/number.rb +3 -0
- data/lib/apiwork/introspection/param/record.rb +3 -0
- data/lib/apiwork/introspection/param/string.rb +3 -0
- data/lib/apiwork/introspection/param/time.rb +3 -0
- data/lib/apiwork/introspection/param/uuid.rb +3 -0
- data/lib/apiwork/introspection/type.rb +9 -0
- data/lib/apiwork/issue.rb +1 -1
- data/lib/apiwork/object.rb +99 -99
- data/lib/apiwork/reference_generator.rb +43 -0
- data/lib/apiwork/representation/attribute.rb +98 -2
- data/lib/apiwork/representation/base.rb +9 -0
- data/lib/apiwork/representation/serializer.rb +2 -0
- data/lib/apiwork/version.rb +1 -1
- data/lib/apiwork.rb +4 -0
- metadata +4 -3
- data/lib/apiwork/export/builder_mapper.rb +0 -184
|
@@ -21,6 +21,14 @@ module Apiwork
|
|
|
21
21
|
string: %i[date datetime email hostname ipv4 ipv6 password text url uuid],
|
|
22
22
|
}.freeze
|
|
23
23
|
|
|
24
|
+
# @!attribute [r] default
|
|
25
|
+
# @api public
|
|
26
|
+
# The default for this attribute.
|
|
27
|
+
#
|
|
28
|
+
# Returns `nil` for both "no default" and "default is explicitly `nil`".
|
|
29
|
+
# Use {#default?} to distinguish these cases.
|
|
30
|
+
#
|
|
31
|
+
# @return [Object, nil]
|
|
24
32
|
# @!attribute [r] description
|
|
25
33
|
# @api public
|
|
26
34
|
# The description for this attribute.
|
|
@@ -71,7 +79,8 @@ module Apiwork
|
|
|
71
79
|
# The type for this attribute.
|
|
72
80
|
#
|
|
73
81
|
# @return [Symbol]
|
|
74
|
-
attr_reader :
|
|
82
|
+
attr_reader :default,
|
|
83
|
+
:description,
|
|
75
84
|
:element,
|
|
76
85
|
:empty,
|
|
77
86
|
:enum,
|
|
@@ -83,12 +92,14 @@ module Apiwork
|
|
|
83
92
|
:of,
|
|
84
93
|
:optional,
|
|
85
94
|
:preload,
|
|
86
|
-
:type
|
|
95
|
+
:type,
|
|
96
|
+
:write_only
|
|
87
97
|
|
|
88
98
|
def initialize(
|
|
89
99
|
name,
|
|
90
100
|
owner_representation_class,
|
|
91
101
|
decode: nil,
|
|
102
|
+
default: UNSET,
|
|
92
103
|
deprecated: false,
|
|
93
104
|
description: nil,
|
|
94
105
|
empty: false,
|
|
@@ -105,6 +116,7 @@ module Apiwork
|
|
|
105
116
|
sortable: false,
|
|
106
117
|
type: nil,
|
|
107
118
|
writable: false,
|
|
119
|
+
write_only: false,
|
|
108
120
|
&block
|
|
109
121
|
)
|
|
110
122
|
@name = name
|
|
@@ -132,6 +144,24 @@ module Apiwork
|
|
|
132
144
|
type = :string if detected_enum && type == :integer
|
|
133
145
|
optional = detect_optional(name) if optional.nil?
|
|
134
146
|
nullable = detect_nullable(name) if nullable.nil?
|
|
147
|
+
default = detect_default(name, empty:, nullable:, optional:) if UNSET.equal?(default)
|
|
148
|
+
|
|
149
|
+
if @db_column && type == :string
|
|
150
|
+
detected_max = detect_string_max_length(name)
|
|
151
|
+
max = [max, detected_max].compact.min
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
if @db_column && type == :decimal
|
|
155
|
+
detected_min, detected_max = detect_decimal_bounds(name)
|
|
156
|
+
min = [min, detected_min].compact.max
|
|
157
|
+
max = [max, detected_max].compact.min
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
if @db_column && type == :integer
|
|
161
|
+
detected_min, detected_max = detect_integer_bounds(name)
|
|
162
|
+
min = [min, detected_min].compact.max
|
|
163
|
+
max = [max, detected_max].compact.min
|
|
164
|
+
end
|
|
135
165
|
rescue ActiveRecord::StatementInvalid, ActiveRecord::NoDatabaseError, ActiveRecord::ConnectionNotEstablished
|
|
136
166
|
@db_column = false
|
|
137
167
|
end
|
|
@@ -139,6 +169,7 @@ module Apiwork
|
|
|
139
169
|
|
|
140
170
|
optional = false if optional.nil?
|
|
141
171
|
nullable = false if nullable.nil?
|
|
172
|
+
default = '' if UNSET.equal?(default) && empty
|
|
142
173
|
|
|
143
174
|
@filterable = filterable
|
|
144
175
|
@preload = preload
|
|
@@ -157,12 +188,26 @@ module Apiwork
|
|
|
157
188
|
@example = example
|
|
158
189
|
@format = format
|
|
159
190
|
@deprecated = deprecated
|
|
191
|
+
@write_only = write_only
|
|
192
|
+
@default_set = !UNSET.equal?(default)
|
|
193
|
+
@default = @default_set ? default : nil
|
|
160
194
|
|
|
161
195
|
validate_min_max_range!
|
|
162
196
|
validate_format!
|
|
163
197
|
validate_empty!
|
|
164
198
|
end
|
|
165
199
|
|
|
200
|
+
# @api public
|
|
201
|
+
# Whether this attribute has a default value.
|
|
202
|
+
#
|
|
203
|
+
# Use this to distinguish "no default" from "default is explicitly `nil`".
|
|
204
|
+
# The {#default} accessor returns `nil` in both cases.
|
|
205
|
+
#
|
|
206
|
+
# @return [Boolean]
|
|
207
|
+
def default?
|
|
208
|
+
@default_set
|
|
209
|
+
end
|
|
210
|
+
|
|
166
211
|
# @api public
|
|
167
212
|
# Whether this attribute is deprecated.
|
|
168
213
|
#
|
|
@@ -225,6 +270,14 @@ module Apiwork
|
|
|
225
270
|
[true, action].include?(@writable)
|
|
226
271
|
end
|
|
227
272
|
|
|
273
|
+
# @api public
|
|
274
|
+
# Whether this attribute is write-only.
|
|
275
|
+
#
|
|
276
|
+
# @return [Boolean]
|
|
277
|
+
def write_only?
|
|
278
|
+
@write_only
|
|
279
|
+
end
|
|
280
|
+
|
|
228
281
|
def encode(value)
|
|
229
282
|
result = @empty && value.nil? ? '' : value
|
|
230
283
|
@encode ? @encode.call(result) : result
|
|
@@ -265,6 +318,32 @@ module Apiwork
|
|
|
265
318
|
end
|
|
266
319
|
end
|
|
267
320
|
|
|
321
|
+
def detect_string_max_length(name)
|
|
322
|
+
column = column_for(name)
|
|
323
|
+
return nil unless column
|
|
324
|
+
|
|
325
|
+
column.limit
|
|
326
|
+
end
|
|
327
|
+
|
|
328
|
+
def detect_decimal_bounds(name)
|
|
329
|
+
column = column_for(name)
|
|
330
|
+
return [nil, nil] unless column
|
|
331
|
+
return [nil, nil] unless column.precision
|
|
332
|
+
|
|
333
|
+
scale = column.scale || 0
|
|
334
|
+
max = (10**(column.precision - scale) - 10.0**(-scale)).to_f
|
|
335
|
+
[-max, max]
|
|
336
|
+
end
|
|
337
|
+
|
|
338
|
+
def detect_integer_bounds(name)
|
|
339
|
+
column = column_for(name)
|
|
340
|
+
return [nil, nil] unless column
|
|
341
|
+
|
|
342
|
+
limit = column.limit || 4
|
|
343
|
+
max = 2**(8 * limit - 1) - 1
|
|
344
|
+
[-max - 1, max]
|
|
345
|
+
end
|
|
346
|
+
|
|
268
347
|
def detect_optional(name)
|
|
269
348
|
return false unless @model_class
|
|
270
349
|
return false unless db_column?
|
|
@@ -277,6 +356,23 @@ module Apiwork
|
|
|
277
356
|
column.null
|
|
278
357
|
end
|
|
279
358
|
|
|
359
|
+
def detect_default(name, empty:, nullable:, optional:)
|
|
360
|
+
return UNSET unless @model_class
|
|
361
|
+
return UNSET unless db_column?
|
|
362
|
+
|
|
363
|
+
column = column_for(name)
|
|
364
|
+
return UNSET unless column
|
|
365
|
+
return UNSET if column.default_function
|
|
366
|
+
|
|
367
|
+
default = @model_class.column_defaults[name.to_s]
|
|
368
|
+
return default unless default.nil?
|
|
369
|
+
|
|
370
|
+
return '' if empty && nullable && optional
|
|
371
|
+
return nil if nullable && optional
|
|
372
|
+
|
|
373
|
+
UNSET
|
|
374
|
+
end
|
|
375
|
+
|
|
280
376
|
def detect_nullable(name)
|
|
281
377
|
return false unless @model_class
|
|
282
378
|
return false unless db_column?
|
|
@@ -184,6 +184,8 @@ module Apiwork
|
|
|
184
184
|
# The attribute name.
|
|
185
185
|
# @param decode [Proc, nil] (nil)
|
|
186
186
|
# Transform for request input (API to database). Must preserve the attribute type.
|
|
187
|
+
# @param default [Object] (UNSET)
|
|
188
|
+
# The default value. Omit to declare no default. Pass `nil` for an explicit null default. If omitted and name maps to a database column, auto-detected from the column's static default.
|
|
187
189
|
# @param deprecated [Boolean] (false)
|
|
188
190
|
# Whether deprecated. Metadata included in exports.
|
|
189
191
|
# @param description [String, nil] (nil)
|
|
@@ -222,6 +224,9 @@ module Apiwork
|
|
|
222
224
|
# Use an explicit type or block in those cases.
|
|
223
225
|
# @param writable [Boolean, Symbol] (false) [:create, :update]
|
|
224
226
|
# The write access. `true` for both create and update, `:create` for create only, `:update` for update only.
|
|
227
|
+
# @param write_only [Boolean] (false)
|
|
228
|
+
# Whether the attribute is write-only. Write-only attributes are excluded from response
|
|
229
|
+
# serialization and response types but remain in writable payloads.
|
|
225
230
|
# @yieldparam element [Representation::Element]
|
|
226
231
|
# @return [void]
|
|
227
232
|
#
|
|
@@ -270,6 +275,7 @@ module Apiwork
|
|
|
270
275
|
def attribute(
|
|
271
276
|
name,
|
|
272
277
|
decode: nil,
|
|
278
|
+
default: UNSET,
|
|
273
279
|
deprecated: false,
|
|
274
280
|
description: nil,
|
|
275
281
|
empty: nil,
|
|
@@ -286,6 +292,7 @@ module Apiwork
|
|
|
286
292
|
sortable: false,
|
|
287
293
|
type: nil,
|
|
288
294
|
writable: false,
|
|
295
|
+
write_only: false,
|
|
289
296
|
&block
|
|
290
297
|
)
|
|
291
298
|
self.attributes = attributes.merge(
|
|
@@ -293,6 +300,7 @@ module Apiwork
|
|
|
293
300
|
name,
|
|
294
301
|
self,
|
|
295
302
|
decode:,
|
|
303
|
+
default:,
|
|
296
304
|
deprecated:,
|
|
297
305
|
description:,
|
|
298
306
|
empty:,
|
|
@@ -309,6 +317,7 @@ module Apiwork
|
|
|
309
317
|
sortable:,
|
|
310
318
|
type:,
|
|
311
319
|
writable:,
|
|
320
|
+
write_only:,
|
|
312
321
|
&block
|
|
313
322
|
),
|
|
314
323
|
)
|
|
@@ -21,6 +21,8 @@ module Apiwork
|
|
|
21
21
|
add_discriminator_field(fields) if @representation_class.subclass?
|
|
22
22
|
|
|
23
23
|
@representation_class.attributes.each do |name, attribute|
|
|
24
|
+
next if attribute.write_only?
|
|
25
|
+
|
|
24
26
|
value = @representation.respond_to?(name) ? @representation.public_send(name) : @representation.record.public_send(name)
|
|
25
27
|
value = map_type_column_output(name, value)
|
|
26
28
|
value = attribute.encode(value)
|
data/lib/apiwork/version.rb
CHANGED
data/lib/apiwork.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: apiwork
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.7.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- skiftle
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-04-
|
|
11
|
+
date: 2026-04-17 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: rails
|
|
@@ -260,8 +260,9 @@ files:
|
|
|
260
260
|
- lib/apiwork/error_code/definition.rb
|
|
261
261
|
- lib/apiwork/error_code/registry.rb
|
|
262
262
|
- lib/apiwork/export.rb
|
|
263
|
+
- lib/apiwork/export/apiwork.rb
|
|
264
|
+
- lib/apiwork/export/apiwork_mapper.rb
|
|
263
265
|
- lib/apiwork/export/base.rb
|
|
264
|
-
- lib/apiwork/export/builder_mapper.rb
|
|
265
266
|
- lib/apiwork/export/open_api.rb
|
|
266
267
|
- lib/apiwork/export/pipeline.rb
|
|
267
268
|
- lib/apiwork/export/pipeline/writer.rb
|
|
@@ -1,184 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Apiwork
|
|
4
|
-
module Export
|
|
5
|
-
class BuilderMapper
|
|
6
|
-
class << self
|
|
7
|
-
def map(export, surface)
|
|
8
|
-
new(export).map(surface)
|
|
9
|
-
end
|
|
10
|
-
end
|
|
11
|
-
|
|
12
|
-
def initialize(export)
|
|
13
|
-
@export = export
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
def map(surface)
|
|
17
|
-
build_builders(surface.types)
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
def build_builders(types)
|
|
21
|
-
builders = types.sort_by { |name, _type| name.to_s }.flat_map do |name, type|
|
|
22
|
-
if type.union?
|
|
23
|
-
build_union_builders(name, type, types)
|
|
24
|
-
elsif type.object?
|
|
25
|
-
[build_object_builder(name, type)]
|
|
26
|
-
end
|
|
27
|
-
end.compact
|
|
28
|
-
|
|
29
|
-
builders.join("\n\n")
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
private
|
|
33
|
-
|
|
34
|
-
def build_object_builder(name, type)
|
|
35
|
-
type_name = pascal_case(name)
|
|
36
|
-
defaulted, required = classify_fields(type.shape)
|
|
37
|
-
|
|
38
|
-
if defaulted.empty?
|
|
39
|
-
build_passthrough_builder(type_name)
|
|
40
|
-
elsif required.empty?
|
|
41
|
-
build_all_defaulted_builder(type_name, defaulted)
|
|
42
|
-
else
|
|
43
|
-
build_mixed_builder(type_name, defaulted, required)
|
|
44
|
-
end
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
def build_passthrough_builder(type_name)
|
|
48
|
-
"export function build#{type_name}(fields: #{type_name}): #{type_name} {\n" \
|
|
49
|
-
" return fields;\n" \
|
|
50
|
-
'}'
|
|
51
|
-
end
|
|
52
|
-
|
|
53
|
-
def build_all_defaulted_builder(type_name, defaulted)
|
|
54
|
-
defaults = build_defaults_body(defaulted)
|
|
55
|
-
|
|
56
|
-
"export function build#{type_name}(fields?: Partial<#{type_name}>): #{type_name} {\n" \
|
|
57
|
-
" return {\n" \
|
|
58
|
-
"#{defaults}\n" \
|
|
59
|
-
" ...fields,\n" \
|
|
60
|
-
" };\n" \
|
|
61
|
-
'}'
|
|
62
|
-
end
|
|
63
|
-
|
|
64
|
-
def build_mixed_builder(type_name, defaulted, required)
|
|
65
|
-
required_keys = required.keys.map { |name| "'#{@export.transform_key(name)}'" }.sort.join(' | ')
|
|
66
|
-
fields_type = "Pick<#{type_name}, #{required_keys}> & Partial<#{type_name}>"
|
|
67
|
-
defaults = build_defaults_body(defaulted)
|
|
68
|
-
|
|
69
|
-
"export function build#{type_name}(fields: #{fields_type}): #{type_name} {\n" \
|
|
70
|
-
" return {\n" \
|
|
71
|
-
"#{defaults}\n" \
|
|
72
|
-
" ...fields,\n" \
|
|
73
|
-
" };\n" \
|
|
74
|
-
'}'
|
|
75
|
-
end
|
|
76
|
-
|
|
77
|
-
def build_defaults_body(defaulted)
|
|
78
|
-
defaulted.sort_by { |name, _param| name.to_s }.map do |name, param|
|
|
79
|
-
" #{@export.transform_key(name)}: #{serialize_default(param)},"
|
|
80
|
-
end.join("\n")
|
|
81
|
-
end
|
|
82
|
-
|
|
83
|
-
def build_union_builders(name, type, types)
|
|
84
|
-
type_name = pascal_case(name)
|
|
85
|
-
builders = [build_passthrough_builder(type_name)]
|
|
86
|
-
|
|
87
|
-
if type.discriminator
|
|
88
|
-
type.variants.each do |variant|
|
|
89
|
-
next unless variant.tag
|
|
90
|
-
next if variant.reference? && types.key?(variant.reference)
|
|
91
|
-
|
|
92
|
-
builders << build_variant_builder(type_name, type.discriminator, variant)
|
|
93
|
-
end
|
|
94
|
-
end
|
|
95
|
-
|
|
96
|
-
builders
|
|
97
|
-
end
|
|
98
|
-
|
|
99
|
-
def build_variant_builder(type_name, discriminator, variant)
|
|
100
|
-
discriminator_key = @export.transform_key(discriminator)
|
|
101
|
-
builder_name = variant.reference? ? "build#{pascal_case(variant.reference)}" : "build#{type_name}#{pascal_case(variant.tag)}"
|
|
102
|
-
extract_type = "Extract<#{type_name}, { #{discriminator_key}: '#{variant.tag}' }>"
|
|
103
|
-
|
|
104
|
-
variant_defaults = {}
|
|
105
|
-
variant_required = {}
|
|
106
|
-
|
|
107
|
-
variant_defaults, variant_required = classify_fields(variant.shape) if variant.object? && variant.shape.any?
|
|
108
|
-
|
|
109
|
-
fields_type = build_variant_fields_type(extract_type, discriminator_key, variant_defaults, variant_required)
|
|
110
|
-
|
|
111
|
-
body_lines = [" #{discriminator_key}: '#{variant.tag}',"]
|
|
112
|
-
variant_defaults.sort_by { |name, _param| name.to_s }.each do |name, param|
|
|
113
|
-
body_lines << " #{@export.transform_key(name)}: #{serialize_default(param)},"
|
|
114
|
-
end
|
|
115
|
-
body_lines << ' ...fields,'
|
|
116
|
-
|
|
117
|
-
"export function #{builder_name}(fields: #{fields_type}): #{type_name} {\n" \
|
|
118
|
-
" return {\n" \
|
|
119
|
-
"#{body_lines.join("\n")}\n" \
|
|
120
|
-
" };\n" \
|
|
121
|
-
'}'
|
|
122
|
-
end
|
|
123
|
-
|
|
124
|
-
def build_variant_fields_type(extract_type, discriminator_key, defaulted, required)
|
|
125
|
-
omitted_type = "Omit<#{extract_type}, '#{discriminator_key}'>"
|
|
126
|
-
|
|
127
|
-
if required.empty? && defaulted.empty?
|
|
128
|
-
omitted_type
|
|
129
|
-
elsif required.empty?
|
|
130
|
-
"Partial<#{omitted_type}>"
|
|
131
|
-
else
|
|
132
|
-
required_keys = required.keys.map { |name| "'#{@export.transform_key(name)}'" }.sort.join(' | ')
|
|
133
|
-
"Pick<#{omitted_type}, #{required_keys}> & Partial<#{omitted_type}>"
|
|
134
|
-
end
|
|
135
|
-
end
|
|
136
|
-
|
|
137
|
-
def classify_fields(shape)
|
|
138
|
-
defaulted = {}
|
|
139
|
-
required = {}
|
|
140
|
-
|
|
141
|
-
shape.sort_by { |name, _param| name.to_s }.each do |name, param|
|
|
142
|
-
if defaulted_field?(param)
|
|
143
|
-
defaulted[name] = param
|
|
144
|
-
else
|
|
145
|
-
required[name] = param
|
|
146
|
-
end
|
|
147
|
-
end
|
|
148
|
-
|
|
149
|
-
[defaulted, required]
|
|
150
|
-
end
|
|
151
|
-
|
|
152
|
-
def defaulted_field?(param)
|
|
153
|
-
return true if param.nullable?
|
|
154
|
-
return true if param.respond_to?(:default) && !param.default.nil?
|
|
155
|
-
|
|
156
|
-
false
|
|
157
|
-
end
|
|
158
|
-
|
|
159
|
-
def serialize_default(param)
|
|
160
|
-
if param.respond_to?(:default) && !param.default.nil?
|
|
161
|
-
serialize_value(param.default)
|
|
162
|
-
elsif param.nullable?
|
|
163
|
-
'null'
|
|
164
|
-
end
|
|
165
|
-
end
|
|
166
|
-
|
|
167
|
-
def serialize_value(value)
|
|
168
|
-
case value
|
|
169
|
-
when String then "'#{value.gsub("'", "\\\\'")}'"
|
|
170
|
-
when Integer, Float then value.to_s
|
|
171
|
-
when BigDecimal then value.to_s('F')
|
|
172
|
-
when TrueClass, FalseClass then value.to_s
|
|
173
|
-
when Array then '[]'
|
|
174
|
-
when Hash then '{}'
|
|
175
|
-
else value.to_s
|
|
176
|
-
end
|
|
177
|
-
end
|
|
178
|
-
|
|
179
|
-
def pascal_case(name)
|
|
180
|
-
name.to_s.camelize(:upper)
|
|
181
|
-
end
|
|
182
|
-
end
|
|
183
|
-
end
|
|
184
|
-
end
|