apiwork 0.4.0 → 0.6.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.
Files changed (52) hide show
  1. checksums.yaml +4 -4
  2. data/lib/apiwork/adapter/serializer/error/default/api_builder.rb +4 -4
  3. data/lib/apiwork/adapter/serializer/resource/base.rb +15 -0
  4. data/lib/apiwork/adapter/serializer/resource/default/contract_builder.rb +3 -2
  5. data/lib/apiwork/adapter/standard/capability/writing/contract_builder.rb +2 -2
  6. data/lib/apiwork/api/base.rb +67 -17
  7. data/lib/apiwork/api/element.rb +33 -2
  8. data/lib/apiwork/api/object.rb +70 -5
  9. data/lib/apiwork/api/router.rb +16 -0
  10. data/lib/apiwork/configuration/validatable.rb +1 -0
  11. data/lib/apiwork/configuration.rb +2 -0
  12. data/lib/apiwork/contract/element.rb +17 -2
  13. data/lib/apiwork/contract/object/coercer.rb +24 -2
  14. data/lib/apiwork/contract/object/deserializer.rb +5 -1
  15. data/lib/apiwork/contract/object/transformer.rb +15 -2
  16. data/lib/apiwork/contract/object/validator.rb +46 -3
  17. data/lib/apiwork/contract/object.rb +85 -7
  18. data/lib/apiwork/controller.rb +15 -2
  19. data/lib/apiwork/element.rb +33 -0
  20. data/lib/apiwork/export/base.rb +1 -4
  21. data/lib/apiwork/export/builder_mapper.rb +184 -0
  22. data/lib/apiwork/export/open_api.rb +9 -2
  23. data/lib/apiwork/export/sorbus.rb +5 -1
  24. data/lib/apiwork/export/sorbus_mapper.rb +3 -7
  25. data/lib/apiwork/export/type_analysis.rb +20 -6
  26. data/lib/apiwork/export/type_script.rb +4 -1
  27. data/lib/apiwork/export/type_script_mapper.rb +25 -2
  28. data/lib/apiwork/export/zod.rb +9 -0
  29. data/lib/apiwork/export/zod_mapper.rb +22 -1
  30. data/lib/apiwork/introspection/dump/action.rb +1 -1
  31. data/lib/apiwork/introspection/dump/param.rb +36 -20
  32. data/lib/apiwork/introspection/dump/type.rb +31 -25
  33. data/lib/apiwork/introspection/param/array.rb +26 -0
  34. data/lib/apiwork/introspection/param/base.rb +16 -18
  35. data/lib/apiwork/introspection/param/binary.rb +36 -0
  36. data/lib/apiwork/introspection/param/boolean.rb +36 -0
  37. data/lib/apiwork/introspection/param/date.rb +36 -0
  38. data/lib/apiwork/introspection/param/date_time.rb +36 -0
  39. data/lib/apiwork/introspection/param/decimal.rb +26 -0
  40. data/lib/apiwork/introspection/param/integer.rb +26 -0
  41. data/lib/apiwork/introspection/param/number.rb +26 -0
  42. data/lib/apiwork/introspection/param/record.rb +71 -0
  43. data/lib/apiwork/introspection/param/string.rb +26 -0
  44. data/lib/apiwork/introspection/param/time.rb +36 -0
  45. data/lib/apiwork/introspection/param/uuid.rb +36 -0
  46. data/lib/apiwork/introspection/param.rb +1 -0
  47. data/lib/apiwork/object.rb +252 -2
  48. data/lib/apiwork/representation/attribute.rb +1 -1
  49. data/lib/apiwork/representation/base.rb +105 -0
  50. data/lib/apiwork/representation/element.rb +15 -5
  51. data/lib/apiwork/version.rb +1 -1
  52. metadata +4 -2
@@ -69,6 +69,7 @@ module Apiwork
69
69
  class_attribute :inheritance, default: nil, instance_accessor: false
70
70
 
71
71
  class_attribute :_adapter_config, default: {}, instance_accessor: false
72
+ class_attribute :type_definitions, default: {}, instance_accessor: false
72
73
 
73
74
  # @!attribute [r] context
74
75
  # @api public
@@ -540,6 +541,110 @@ module Apiwork
540
541
  )
541
542
  end
542
543
 
544
+ # @api public
545
+ # Defines an object type for this representation.
546
+ #
547
+ # The type is copied to the contract that uses this representation. Attributes can reference
548
+ # it by name via `type:`. In exports, the type is scoped to the contract.
549
+ #
550
+ # @param name [Symbol]
551
+ # The object name.
552
+ # @param deprecated [Boolean] (false)
553
+ # Whether deprecated. Metadata included in exports.
554
+ # @param description [String, nil] (nil)
555
+ # The description. Metadata included in exports.
556
+ # @param example [Object, nil] (nil)
557
+ # The example. Metadata included in exports.
558
+ # @yieldparam object [API::Object]
559
+ # @return [void]
560
+ #
561
+ # @example Define and reference
562
+ # object :address do
563
+ # string :street
564
+ # string :city
565
+ # string :postal_code
566
+ # end
567
+ #
568
+ # attribute :shipping_address, type: :address
569
+ # attribute :billing_address, type: :address
570
+ def object(
571
+ name,
572
+ deprecated: false,
573
+ description: nil,
574
+ example: nil,
575
+ &block
576
+ )
577
+ self.type_definitions = type_definitions.merge(
578
+ name.to_sym => {
579
+ block:,
580
+ kind: :object,
581
+ options: {
582
+ deprecated:,
583
+ description:,
584
+ example:,
585
+ },
586
+ },
587
+ )
588
+ end
589
+
590
+ # @api public
591
+ # Defines a union type for this representation.
592
+ #
593
+ # The type is copied to the contract that uses this representation. Attributes can reference
594
+ # it by name via `type:`. In exports, the type is scoped to the contract.
595
+ #
596
+ # @param name [Symbol]
597
+ # The union name.
598
+ # @param deprecated [Boolean] (false)
599
+ # Whether deprecated. Metadata included in exports.
600
+ # @param description [String, nil] (nil)
601
+ # The description. Metadata included in exports.
602
+ # @param discriminator [Symbol, nil] (nil)
603
+ # The discriminator field name.
604
+ # @param example [Object, nil] (nil)
605
+ # The example. Metadata included in exports.
606
+ # @yieldparam union [API::Union]
607
+ # @return [void]
608
+ #
609
+ # @example Define and reference
610
+ # union :content_block, discriminator: :kind do
611
+ # variant tag: 'text' do
612
+ # object do
613
+ # string :body
614
+ # end
615
+ # end
616
+ # variant tag: 'image' do
617
+ # object do
618
+ # string :url
619
+ # integer :width
620
+ # integer :height
621
+ # end
622
+ # end
623
+ # end
624
+ #
625
+ # attribute :content, type: :content_block
626
+ def union(
627
+ name,
628
+ deprecated: false,
629
+ description: nil,
630
+ discriminator: nil,
631
+ example: nil,
632
+ &block
633
+ )
634
+ self.type_definitions = type_definitions.merge(
635
+ name.to_sym => {
636
+ block:,
637
+ kind: :union,
638
+ options: {
639
+ deprecated:,
640
+ description:,
641
+ discriminator:,
642
+ example:,
643
+ },
644
+ },
645
+ )
646
+ end
647
+
543
648
  # @api public
544
649
  # The type name for this representation.
545
650
  #
@@ -11,10 +11,11 @@ module Apiwork
11
11
  # Only complex types are allowed at the top level:
12
12
  # - {#object} for key-value structures
13
13
  # - {#array} for ordered collections
14
+ # - {#record} for key-value maps with typed values
14
15
  # - {#union} for polymorphic structures
15
16
  #
16
17
  # Inside these blocks, the full type DSL is available including
17
- # nested objects, arrays, primitives, and unions.
18
+ # nested objects, arrays, records, primitives, and unions.
18
19
  #
19
20
  # @see API::Element Block context for array elements
20
21
  # @see API::Object Block context for object fields
@@ -74,15 +75,15 @@ module Apiwork
74
75
  # end
75
76
  class Element < Apiwork::Element
76
77
  def validate!
77
- raise ConfigurationError, 'must define exactly one type (object, array, or union)' unless @defined
78
+ raise ConfigurationError, 'must define exactly one type (object, array, record, or union)' unless @defined
78
79
  end
79
80
 
80
81
  # @api public
81
82
  # Defines the element type.
82
83
  #
83
- # Only complex types (:object, :array, :union) are allowed.
84
+ # Only complex types (:object, :array, :record, :union) are allowed.
84
85
  #
85
- # @param type [Symbol] [:array, :object, :union]
86
+ # @param type [Symbol] [:array, :object, :record, :union]
86
87
  # The element type.
87
88
  # @param discriminator [Symbol, nil] (nil)
88
89
  # The discriminator field name. Unions only.
@@ -110,6 +111,15 @@ module Apiwork
110
111
  @inner = inner
111
112
  @shape = inner.shape
112
113
  @defined = true
114
+ when :record
115
+ raise ConfigurationError, 'record requires a block' unless block
116
+
117
+ inner = API::Element.new
118
+ block.arity.positive? ? yield(inner) : inner.instance_eval(&block)
119
+ inner.validate!
120
+ @type = :record
121
+ @inner = inner
122
+ @defined = true
113
123
  when :union
114
124
  raise ConfigurationError, 'union requires a block' unless block
115
125
 
@@ -120,7 +130,7 @@ module Apiwork
120
130
  @discriminator = discriminator
121
131
  @defined = true
122
132
  else
123
- raise ConfigurationError, "Representation::Element only supports :object, :array, :union - got #{type.inspect}"
133
+ raise ConfigurationError, "Representation::Element only supports :object, :array, :record, :union - got #{type.inspect}"
124
134
  end
125
135
  end
126
136
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Apiwork
4
- VERSION = '0.4.0'
4
+ VERSION = '0.6.0'
5
5
  end
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.0
4
+ version: 0.6.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-03-09 00:00:00.000000000 Z
11
+ date: 2026-04-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -261,6 +261,7 @@ files:
261
261
  - lib/apiwork/error_code/registry.rb
262
262
  - lib/apiwork/export.rb
263
263
  - lib/apiwork/export/base.rb
264
+ - lib/apiwork/export/builder_mapper.rb
264
265
  - lib/apiwork/export/open_api.rb
265
266
  - lib/apiwork/export/pipeline.rb
266
267
  - lib/apiwork/export/pipeline/writer.rb
@@ -306,6 +307,7 @@ files:
306
307
  - lib/apiwork/introspection/param/literal.rb
307
308
  - lib/apiwork/introspection/param/number.rb
308
309
  - lib/apiwork/introspection/param/object.rb
310
+ - lib/apiwork/introspection/param/record.rb
309
311
  - lib/apiwork/introspection/param/reference.rb
310
312
  - lib/apiwork/introspection/param/string.rb
311
313
  - lib/apiwork/introspection/param/time.rb