apia 3.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.
Files changed (120) hide show
  1. checksums.yaml +7 -0
  2. data/VERSION +1 -0
  3. data/lib/apia.rb +21 -0
  4. data/lib/apia/api.rb +100 -0
  5. data/lib/apia/argument_set.rb +221 -0
  6. data/lib/apia/authenticator.rb +57 -0
  7. data/lib/apia/callable_with_environment.rb +43 -0
  8. data/lib/apia/controller.rb +32 -0
  9. data/lib/apia/defineable.rb +60 -0
  10. data/lib/apia/definition.rb +27 -0
  11. data/lib/apia/definitions/api.rb +51 -0
  12. data/lib/apia/definitions/argument.rb +77 -0
  13. data/lib/apia/definitions/argument_set.rb +33 -0
  14. data/lib/apia/definitions/authenticator.rb +46 -0
  15. data/lib/apia/definitions/controller.rb +41 -0
  16. data/lib/apia/definitions/endpoint.rb +74 -0
  17. data/lib/apia/definitions/enum.rb +31 -0
  18. data/lib/apia/definitions/error.rb +59 -0
  19. data/lib/apia/definitions/field.rb +117 -0
  20. data/lib/apia/definitions/lookup_argument_set.rb +27 -0
  21. data/lib/apia/definitions/object.rb +29 -0
  22. data/lib/apia/definitions/polymorph.rb +29 -0
  23. data/lib/apia/definitions/polymorph_option.rb +53 -0
  24. data/lib/apia/definitions/scalar.rb +23 -0
  25. data/lib/apia/definitions/type.rb +109 -0
  26. data/lib/apia/dsl.rb +23 -0
  27. data/lib/apia/dsls/api.rb +37 -0
  28. data/lib/apia/dsls/argument.rb +27 -0
  29. data/lib/apia/dsls/argument_set.rb +35 -0
  30. data/lib/apia/dsls/authenticator.rb +38 -0
  31. data/lib/apia/dsls/concerns/has_fields.rb +38 -0
  32. data/lib/apia/dsls/controller.rb +34 -0
  33. data/lib/apia/dsls/endpoint.rb +79 -0
  34. data/lib/apia/dsls/enum.rb +19 -0
  35. data/lib/apia/dsls/error.rb +26 -0
  36. data/lib/apia/dsls/field.rb +27 -0
  37. data/lib/apia/dsls/lookup_argument_set.rb +24 -0
  38. data/lib/apia/dsls/object.rb +19 -0
  39. data/lib/apia/dsls/polymorph.rb +19 -0
  40. data/lib/apia/dsls/route_group.rb +43 -0
  41. data/lib/apia/dsls/route_set.rb +40 -0
  42. data/lib/apia/dsls/scalar.rb +23 -0
  43. data/lib/apia/dsls/scope_descriptions.rb +17 -0
  44. data/lib/apia/endpoint.rb +110 -0
  45. data/lib/apia/enum.rb +43 -0
  46. data/lib/apia/environment_error_handling.rb +74 -0
  47. data/lib/apia/error.rb +61 -0
  48. data/lib/apia/error_set.rb +15 -0
  49. data/lib/apia/errors/error_exception_error.rb +32 -0
  50. data/lib/apia/errors/field_spec_parse_error.rb +23 -0
  51. data/lib/apia/errors/invalid_argument_error.rb +68 -0
  52. data/lib/apia/errors/invalid_enum_option_error.rb +21 -0
  53. data/lib/apia/errors/invalid_helper_error.rb +6 -0
  54. data/lib/apia/errors/invalid_json_error.rb +23 -0
  55. data/lib/apia/errors/invalid_polymorph_value_error.rb +21 -0
  56. data/lib/apia/errors/invalid_scalar_value_error.rb +21 -0
  57. data/lib/apia/errors/manifest_error.rb +43 -0
  58. data/lib/apia/errors/missing_argument_error.rb +40 -0
  59. data/lib/apia/errors/null_field_value_error.rb +37 -0
  60. data/lib/apia/errors/parse_error.rb +10 -0
  61. data/lib/apia/errors/runtime_error.rb +30 -0
  62. data/lib/apia/errors/scope_not_granted_error.rb +15 -0
  63. data/lib/apia/errors/standard_error.rb +6 -0
  64. data/lib/apia/field_set.rb +76 -0
  65. data/lib/apia/field_spec.rb +155 -0
  66. data/lib/apia/helpers.rb +34 -0
  67. data/lib/apia/hook_set.rb +30 -0
  68. data/lib/apia/lookup_argument_set.rb +57 -0
  69. data/lib/apia/lookup_environment.rb +27 -0
  70. data/lib/apia/manifest_errors.rb +62 -0
  71. data/lib/apia/mock_request.rb +18 -0
  72. data/lib/apia/object.rb +68 -0
  73. data/lib/apia/object_set.rb +21 -0
  74. data/lib/apia/pagination_object.rb +34 -0
  75. data/lib/apia/polymorph.rb +50 -0
  76. data/lib/apia/rack.rb +184 -0
  77. data/lib/apia/rack_error.rb +17 -0
  78. data/lib/apia/request.rb +67 -0
  79. data/lib/apia/request_environment.rb +84 -0
  80. data/lib/apia/request_headers.rb +42 -0
  81. data/lib/apia/response.rb +64 -0
  82. data/lib/apia/route.rb +61 -0
  83. data/lib/apia/route_group.rb +20 -0
  84. data/lib/apia/route_set.rb +89 -0
  85. data/lib/apia/scalar.rb +52 -0
  86. data/lib/apia/scalars.rb +25 -0
  87. data/lib/apia/scalars/base64.rb +31 -0
  88. data/lib/apia/scalars/boolean.rb +37 -0
  89. data/lib/apia/scalars/date.rb +45 -0
  90. data/lib/apia/scalars/decimal.rb +36 -0
  91. data/lib/apia/scalars/integer.rb +34 -0
  92. data/lib/apia/scalars/string.rb +24 -0
  93. data/lib/apia/scalars/unix_time.rb +40 -0
  94. data/lib/apia/schema/api_controller_schema_type.rb +17 -0
  95. data/lib/apia/schema/api_schema_type.rb +43 -0
  96. data/lib/apia/schema/argument_schema_type.rb +28 -0
  97. data/lib/apia/schema/argument_set_schema_type.rb +21 -0
  98. data/lib/apia/schema/authenticator_schema_type.rb +22 -0
  99. data/lib/apia/schema/controller.rb +39 -0
  100. data/lib/apia/schema/controller_endpoint_schema_type.rb +17 -0
  101. data/lib/apia/schema/controller_schema_type.rb +32 -0
  102. data/lib/apia/schema/endpoint_schema_type.rb +35 -0
  103. data/lib/apia/schema/enum_schema_type.rb +20 -0
  104. data/lib/apia/schema/enum_value_schema_type.rb +14 -0
  105. data/lib/apia/schema/error_schema_type.rb +23 -0
  106. data/lib/apia/schema/field_schema_type.rb +38 -0
  107. data/lib/apia/schema/field_spec_options_schema_type.rb +16 -0
  108. data/lib/apia/schema/lookup_argument_set_schema_type.rb +25 -0
  109. data/lib/apia/schema/object_schema_polymorph.rb +31 -0
  110. data/lib/apia/schema/object_schema_type.rb +21 -0
  111. data/lib/apia/schema/polymorph_option_schema_type.rb +16 -0
  112. data/lib/apia/schema/polymorph_schema_type.rb +20 -0
  113. data/lib/apia/schema/request_method_enum.rb +21 -0
  114. data/lib/apia/schema/route_group_schema_type.rb +19 -0
  115. data/lib/apia/schema/route_schema_type.rb +31 -0
  116. data/lib/apia/schema/route_set_schema_type.rb +20 -0
  117. data/lib/apia/schema/scalar_schema_type.rb +15 -0
  118. data/lib/apia/schema/scope_type.rb +14 -0
  119. data/lib/apia/version.rb +12 -0
  120. metadata +188 -0
data/lib/apia/dsl.rb ADDED
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Apia
4
+ class DSL
5
+
6
+ def initialize(definition)
7
+ @definition = definition
8
+ end
9
+
10
+ def name(name)
11
+ @definition.name = name
12
+ end
13
+
14
+ def description(description)
15
+ @definition.description = description
16
+ end
17
+
18
+ def no_schema
19
+ @definition.schema = false
20
+ end
21
+
22
+ end
23
+ end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'apia/dsl'
4
+ require 'apia/helpers'
5
+ require 'apia/dsls/scope_descriptions'
6
+
7
+ module Apia
8
+ module DSLs
9
+ class API < DSL
10
+
11
+ def authenticator(klass = nil, &block)
12
+ if block_given?
13
+ id = "#{@definition.id}/#{Helpers.camelize(klass) || 'Authenticator'}"
14
+ klass = Apia::Authenticator.create(id, &block)
15
+ end
16
+
17
+ @definition.authenticator = klass
18
+ end
19
+
20
+ def exception_handler(block_var = nil, &block)
21
+ @definition.exception_handlers.add(block_var, &block)
22
+ end
23
+
24
+ def routes(&block)
25
+ @definition.route_set.dsl.instance_eval(&block) if block_given?
26
+ end
27
+
28
+ def scopes(&block)
29
+ return unless block_given?
30
+
31
+ dsl = DSLs::ScopeDescriptions.new(@definition)
32
+ dsl.instance_eval(&block)
33
+ end
34
+
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'apia/dsl'
4
+
5
+ module Apia
6
+ module DSLs
7
+ class Argument < DSL
8
+
9
+ def validation(name, &block)
10
+ @definition.validations << { name: name, block: block }
11
+ end
12
+
13
+ def required(value)
14
+ @definition.required = value
15
+ end
16
+
17
+ def array(value)
18
+ @definition.array = value
19
+ end
20
+
21
+ def default(value)
22
+ @definition.default = value
23
+ end
24
+
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'apia/dsl'
4
+ require 'apia/definitions/argument'
5
+ require 'apia/helpers'
6
+
7
+ module Apia
8
+ module DSLs
9
+ class ArgumentSet < DSL
10
+
11
+ def argument(name, *args, type: nil, **options, &block)
12
+ type = args[0] if type.nil?
13
+
14
+ argument = Definitions::Argument.new(name, id: "#{@definition.id}/#{Helpers.camelize(name.to_s)}Argument")
15
+
16
+ if type.is_a?(Array)
17
+ argument.type = type[0]
18
+ argument.array = true
19
+ else
20
+ argument.type = type
21
+ argument.array = false
22
+ end
23
+
24
+ argument.required = options[:required] if options.key?(:required)
25
+ argument.default = options[:default] if options.key?(:default)
26
+ argument.description = options[:description] if options.key?(:description)
27
+
28
+ argument.dsl.instance_eval(&block) if block_given?
29
+
30
+ @definition.arguments[name.to_sym] = argument
31
+ end
32
+
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'apia/dsl'
4
+ require 'apia/helpers'
5
+ require 'apia/errors/scope_not_granted_error'
6
+
7
+ module Apia
8
+ module DSLs
9
+ class Authenticator < DSL
10
+
11
+ def type(type)
12
+ @definition.type = type
13
+ end
14
+
15
+ def potential_error(klass, &block)
16
+ if block_given? && klass.is_a?(String)
17
+ id = "#{@definition.id}/#{Helpers.camelize(klass)}"
18
+ klass = Apia::Error.create(id, &block)
19
+ end
20
+
21
+ @definition.potential_errors << klass
22
+ end
23
+
24
+ def action(&block)
25
+ @definition.action = block
26
+ end
27
+
28
+ def scope_validator(&block)
29
+ unless @definition.potential_errors.include?(Apia::ScopeNotGrantedError)
30
+ potential_error Apia::ScopeNotGrantedError
31
+ end
32
+
33
+ @definition.scope_validator = block
34
+ end
35
+
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'apia/definitions/field'
4
+ require 'apia/helpers'
5
+
6
+ module Apia
7
+ module DSLs
8
+ module Concerns
9
+ module HasFields
10
+
11
+ def field(name, *args, type: nil, **options, &block)
12
+ type = args[0] if type.nil?
13
+
14
+ field = Definitions::Field.new(name, id: "#{@definition.id}/#{Helpers.camelize(name)}Field")
15
+
16
+ if type.is_a?(Array)
17
+ field.type = type[0]
18
+ field.array = true
19
+ else
20
+ field.type = type
21
+ field.array = false
22
+ end
23
+
24
+ field.null = options[:null] if options.key?(:null)
25
+ field.array = options[:array] if options.key?(:array)
26
+ field.include = options[:include] if options.key?(:include)
27
+ field.backend = options[:backend] if options.key?(:backend)
28
+ field.description = options[:description] if options.key?(:description)
29
+
30
+ field.dsl.instance_eval(&block) if block_given?
31
+
32
+ @definition.fields.add(field)
33
+ end
34
+
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'apia/dsl'
4
+ require 'apia/endpoint'
5
+
6
+ module Apia
7
+ module DSLs
8
+ class Controller < DSL
9
+
10
+ def authenticator(klass = nil, &block)
11
+ if block_given?
12
+ id = "#{@definition.id}/#{Helpers.camelize(klass) || 'Authenticator'}"
13
+ klass = Apia::Authenticator.create(id, &block)
14
+ end
15
+
16
+ @definition.authenticator = klass
17
+ end
18
+
19
+ def endpoint(name, klass = nil, &block)
20
+ if block_given?
21
+ id = "#{@definition.id}/#{klass || Helpers.camelize(name) + 'Endpoint'}"
22
+ klass = Apia::Endpoint.create(id, &block)
23
+ end
24
+
25
+ @definition.endpoints[name.to_sym] = klass
26
+ end
27
+
28
+ def helper(name, &block)
29
+ @definition.helpers[name] = block
30
+ end
31
+
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,79 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'apia/dsl'
4
+ require 'apia/dsls/concerns/has_fields'
5
+ require 'apia/pagination_object'
6
+
7
+ module Apia
8
+ module DSLs
9
+ class Endpoint < DSL
10
+
11
+ include DSLs::Concerns::HasFields
12
+
13
+ def authenticator(klass = nil, &block)
14
+ if block_given?
15
+ id = "#{@definition.id}/#{Helpers.camelize(klass) || 'Authenticator'}"
16
+ klass = Apia::Authenticator.create(id, &block)
17
+ end
18
+
19
+ @definition.authenticator = klass
20
+ end
21
+
22
+ def potential_error(klass, &block)
23
+ if block_given? && klass.is_a?(String)
24
+ id = "#{@definition.id}/#{Helpers.camelize(klass)}"
25
+ klass = Apia::Error.create(id, &block)
26
+ end
27
+
28
+ @definition.potential_errors << klass
29
+ end
30
+
31
+ def argument(*args, **kwargs, &block)
32
+ @definition.argument_set.argument(*args, **kwargs, &block)
33
+ end
34
+
35
+ def action(&block)
36
+ @definition.action = block
37
+ end
38
+
39
+ def http_status(status)
40
+ @definition.http_status = status
41
+ end
42
+
43
+ def field(name, *args, type: nil, **options, &block)
44
+ if pagination_options = options.delete(:paginate)
45
+
46
+ unless @definition.paginated_field.nil?
47
+ raise Apia::RuntimeError, 'Cannot define more than one paginated field per endpoint'
48
+ end
49
+
50
+ pagination_options = {} if pagination_options == true
51
+ @definition.paginated_field = name
52
+
53
+ argument :page, type: Scalars::Integer, default: 1 do
54
+ validation(:greater_than_zero) { |o| o.positive? }
55
+ end
56
+
57
+ argument :per_page, type: Scalars::Integer, default: 30 do
58
+ validation(:greater_than_zero) { |o| o.positive? }
59
+ validation(:less_than_or_equal_to_100) { |o| o <= (pagination_options[:maximum_per_page]&.to_i || 200) }
60
+ end
61
+
62
+ field :pagination, type: PaginationObject
63
+ end
64
+ super(name, *args, type: type, **options, &block)
65
+ end
66
+
67
+ def scopes(*names)
68
+ names.each { |name| scope(name) }
69
+ end
70
+
71
+ def scope(name)
72
+ return if @definition.scopes.include?(name.to_s)
73
+
74
+ @definition.scopes << name.to_s
75
+ end
76
+
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'apia/dsl'
4
+
5
+ module Apia
6
+ module DSLs
7
+ class Enum < DSL
8
+
9
+ def value(name, description = nil)
10
+ @definition.values[name.to_s] = { name: name.to_s, description: description }
11
+ end
12
+
13
+ def cast(&block)
14
+ @definition.cast = block
15
+ end
16
+
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'apia/dsl'
4
+ require 'apia/dsls/concerns/has_fields'
5
+
6
+ module Apia
7
+ module DSLs
8
+ class Error < DSL
9
+
10
+ include DSLs::Concerns::HasFields
11
+
12
+ def code(code)
13
+ @definition.code = code
14
+ end
15
+
16
+ def http_status(http_status)
17
+ @definition.http_status = http_status
18
+ end
19
+
20
+ def catch_exception(klass, &block)
21
+ @definition.catchable_exceptions[klass] = block
22
+ end
23
+
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'apia/dsl'
4
+
5
+ module Apia
6
+ module DSLs
7
+ class Field < DSL
8
+
9
+ def backend(&block)
10
+ @definition.backend = block
11
+ end
12
+
13
+ def null(value)
14
+ @definition.null = value
15
+ end
16
+
17
+ def array(value)
18
+ @definition.array = value
19
+ end
20
+
21
+ def condition(&block)
22
+ @definition.condition = block
23
+ end
24
+
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'apia/dsls/argument_set'
4
+
5
+ module Apia
6
+ module DSLs
7
+ class LookupArgumentSet < ArgumentSet
8
+
9
+ def potential_error(klass, &block)
10
+ if block_given? && klass.is_a?(String)
11
+ id = "#{@definition.id}/#{Helpers.camelize(klass)}"
12
+ klass = Apia::Error.create(id, &block)
13
+ end
14
+
15
+ @definition.potential_errors << klass
16
+ end
17
+
18
+ def resolver(&block)
19
+ @definition.resolver = block
20
+ end
21
+
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'apia/dsl'
4
+ require 'apia/definitions/field'
5
+ require 'apia/dsls/concerns/has_fields'
6
+
7
+ module Apia
8
+ module DSLs
9
+ class Object < DSL
10
+
11
+ include DSLs::Concerns::HasFields
12
+
13
+ def condition(&block)
14
+ @definition.conditions << block
15
+ end
16
+
17
+ end
18
+ end
19
+ end