mortymer 0.0.7 → 0.0.8

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c454029d3e20ca350725c27aa1352769467599d1dcc06fa91bc79eda2f63c967
4
- data.tar.gz: f1a4f441ec003b1bcc7d54ad1451fdd11ef796802931f98c1d0ee765d0758c3d
3
+ metadata.gz: c13887be646cf5c591070d4d51c85e657c3509b11858d3d1cc7fa9650ec3c5ed
4
+ data.tar.gz: 0ca382da28037d53ab387f553854fc24047450b1b1d8589078f091130b15cbee
5
5
  SHA512:
6
- metadata.gz: cde4a983859216b21cc13f9f5e582d3e47b4b6a7436fa17598afc0c69f750f0538fc0f95b71c298d876c0da03d78251e7d31868ab54d23f850dde3b1e30e6bb8
7
- data.tar.gz: 47213cc011672d545cc97b97f2393f1064e3f658a883fec3352047034ea539991a795561879d13dea1a46fb9f953ccea0e2fa4f14875bc3759a4de1b881c898a
6
+ metadata.gz: 5fbe4192b479624078104e07290a0e6052eb7b752a59d566ad4501c197f325c97080ec00605654f9ecdda34a16f466a71fb0ea8807a6da0e08ed0b1bee65c1fd
7
+ data.tar.gz: 7da23bf7783533a1ba3dbe56ec41a800c5e1473ab22b51bd9d1fc4ab595dae81b43f48767c145d1d429b13c601d225d1599bbaff31746b263bea68aa19be4b9c
@@ -50,6 +50,23 @@ module Mortymer
50
50
  register_endpoint(:delete, input, output, path, security || @__endpoint_security__)
51
51
  end
52
52
 
53
+ # Register an exception handler for the next endpoint
54
+ # @param exception [Class] The exception class to handle
55
+ # @param status [Symbol, Integer] The HTTP status code to return
56
+ # @param output [Class] The output schema class for the error response
57
+ # @yield [exception] Optional block to transform the exception into a response
58
+ # @yieldparam exception [Exception] The caught exception
59
+ # @yieldreturn [Hash] The response body
60
+ def handles_exception(exception, status: 400, output: nil, &block)
61
+ @__endpoint_exception_handlers__ ||= []
62
+ @__endpoint_exception_handlers__ << {
63
+ exception: exception,
64
+ status: status,
65
+ output: output,
66
+ handler: block
67
+ }
68
+ end
69
+
53
70
  private
54
71
 
55
72
  def method_added(method_name)
@@ -60,18 +77,30 @@ module Mortymer
60
77
  name: reflect_method_name(method_name), action: method_name
61
78
  ))
62
79
  input_class = @__endpoint_signature__[:input_class]
80
+ handlers = @__endpoint_signature__[:exception_handlers]
63
81
  @__endpoint_signature__ = nil
64
82
  return unless defined?(::Rails) && ::Rails.application.config.morty.wrap_methods
65
83
 
66
- rails_wrap_method_with_no_params_call(method_name, input_class)
84
+ rails_wrap_method_with_no_params_call(method_name, input_class, handlers)
67
85
  end
68
86
 
69
- def rails_wrap_method_with_no_params_call(method_name, input_class)
87
+ def rails_wrap_method_with_no_params_call(method_name, input_class, handlers)
70
88
  original_method = instance_method(method_name)
71
89
  define_method(method_name) do
72
- input = input_class.new(params.to_unsafe_h.to_h.deep_transform_keys(&:to_sym))
90
+ input = input_class.structify(params.to_unsafe_h.to_h.deep_transform_keys(&:to_sym))
73
91
  output = original_method.bind_call(self, input)
74
92
  render json: output.to_h, status: :ok
93
+ rescue StandardError => e
94
+ handler = handlers.find { |h| e.is_a?(h[:exception]) }
95
+ raise unless handler
96
+
97
+ response = if handler[:handler]
98
+ handler[:handler].call(e)
99
+ else
100
+ { error: e.message || e.class.name.underscore }
101
+ end
102
+
103
+ render json: response, status: handler[:status]
75
104
  end
76
105
  end
77
106
 
@@ -84,8 +113,10 @@ module Mortymer
84
113
  path: path,
85
114
  controller_class: self,
86
115
  security: security,
87
- tags: @__endpoint_tags__ || __default_tag_for_endpoint__
116
+ tags: @__endpoint_tags__ || __default_tag_for_endpoint__,
117
+ exception_handlers: [*(@__endpoint_exception_handlers__ || [])]
88
118
  }
119
+ @__endpoint_exception_handlers__ = nil
89
120
  end
90
121
 
91
122
  def reflect_method_name(method_name)
@@ -19,7 +19,7 @@ module Mortymer
19
19
  # Global configuration for Mortymer
20
20
  class Configuration
21
21
  attr_accessor :container, :serve_swagger, :swagger_title, :swagger_path, :swagger_root, :api_version,
22
- :api_description, :security_schemes
22
+ :api_description, :security_schemes, :api_prefix
23
23
 
24
24
  def initialize
25
25
  @container = Mortymer::Container.new
@@ -30,6 +30,7 @@ module Mortymer
30
30
  @api_description = "An awsome API developed with MORTYMER"
31
31
  @api_version = "v1"
32
32
  @security_schemes = {}
33
+ @api_prefix = "/api/v1"
33
34
  end
34
35
  end
35
36
  end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "moldeable"
4
+ require "dry/validation"
5
+ require "dry/validation/contract"
6
+ require_relative "generator"
7
+
8
+ module Mortymer
9
+ # A base model for defining schemas
10
+ class Contract < Dry::Validation::Contract
11
+ include Mortymer::Moldeable
12
+
13
+ # Exception raised when an error occours in a contract
14
+ class ContractError < StandardError
15
+ attr_reader :errors
16
+
17
+ def initialize(errors)
18
+ super
19
+ @errors = errors
20
+ end
21
+ end
22
+
23
+ def self.json_schema
24
+ Generator.new.from_validation(self)
25
+ end
26
+
27
+ def self.structify(params)
28
+ result = new.call(params)
29
+ raise ContractError.new(result.errors.to_h) unless result.errors.empty?
30
+
31
+ result.to_h
32
+ end
33
+ end
34
+ end
@@ -52,7 +52,7 @@ module Mortymer
52
52
  container ||= Mortymer.config&.container || Container.new
53
53
  self.class.dependencies.each do |dep|
54
54
  value = if overrides.key?(dep[:var_name].to_sym)
55
- overrides[dep[:var_name].to_sym]
55
+ overrides.delete(dep[:var_name].to_sym)
56
56
  else
57
57
  container.resolve_constant(dep[:constant])
58
58
  end
@@ -1,15 +1,30 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "dry_struct_parser/struct_schema_parser"
4
+ require "dry_validation_parser/validation_schema_parser"
5
+ require "dry/swagger/documentation_generator"
6
+ require "dry/swagger/errors/missing_hash_schema_error"
7
+ require "dry/swagger/errors/missing_type_error"
8
+ require "dry/swagger/config/configuration"
9
+ require "dry/swagger/config/swagger_configuration"
10
+ require "dry/swagger/railtie" if defined?(Rails)
4
11
 
5
12
  # Need to monkey patch the nominal visitor for dry struct parser
6
13
  # as it currently does nothing with this field
7
14
  module DryStructParser
15
+ # Just to monkey patch it
8
16
  class StructSchemaParser
9
- def visit_constructor(node, opts)
17
+ def visit_constructor(node, opts) # rubocop:disable Metrics/AbcSize,Metrics/MethodLength
10
18
  # Handle coercible types which have the form:
11
19
  # [:constructor, [[:nominal, [Type, {}]], [:method, Kernel, :Type]]]
12
20
  if node[0].is_a?(Array) && node[0][0] == :nominal
21
+ if node[0][1][0] == Mortymer::Types::RackFile
22
+ keys[opts[:key]] = node[0][1][1][:swagger].merge(
23
+ required: opts.fetch(:required, true),
24
+ nullable: opts.fetch(:nullable, false)
25
+ )
26
+ return
27
+ end
13
28
  required = opts.fetch(:required, true)
14
29
  nullable = opts.fetch(:nullable, false)
15
30
  type = node[0][1][0] # Get the type from nominal node
@@ -30,11 +45,3 @@ module DryStructParser
30
45
  end
31
46
  end
32
47
  end
33
-
34
- require "dry_validation_parser/validation_schema_parser"
35
- require "dry/swagger/documentation_generator"
36
- require "dry/swagger/errors/missing_hash_schema_error"
37
- require "dry/swagger/errors/missing_type_error"
38
- require "dry/swagger/config/configuration"
39
- require "dry/swagger/config/swagger_configuration"
40
- require "dry/swagger/railtie" if defined?(Rails)
@@ -1,8 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative "generator"
4
+
3
5
  module Mortymer
4
6
  # Represents an endpoint in a given system
5
- class Endpoint
7
+ class Endpoint # rubocop:disable Metrics/ClassLength
6
8
  attr_reader :http_method, :path, :input_class, :output_class, :controller_class, :action, :name
7
9
 
8
10
  def initialize(opts = {})
@@ -15,6 +17,7 @@ module Mortymer
15
17
  @action = opts[:action]
16
18
  @security = opts[:security]
17
19
  @tags = opts[:tags]
20
+ @exception_handlers = opts[:exception_handlers]
18
21
  end
19
22
 
20
23
  def routeable?
@@ -36,20 +39,11 @@ module Mortymer
36
39
  end.join("/")
37
40
  end
38
41
 
39
- def generate_openapi_schema # rubocop:disable Metrics/MethodLength
42
+ def generate_openapi_schema # rubocop:disable Metrics/MethodLength,Metrics/AbcSize
40
43
  return unless defined?(@input_class) && defined?(@output_class)
41
44
 
42
- input_schema = @input_class.respond_to?(:json_schema) ? @input_class.json_schema : Dry::Swagger::DocumentationGenerator.new.from_struct(@input_class)
43
- responses = {
44
- "200" => {
45
- description: "Successful response",
46
- content: {
47
- "application/json" => {
48
- schema: class_ref(@output_class)
49
- }
50
- }
51
- }
52
- }
45
+ input_schema = @input_class.respond_to?(:json_schema) ? @input_class.json_schema : Generator.new.from_struct(@input_class)
46
+ responses = generate_responses
53
47
 
54
48
  # Add 422 response if there are required properties or non-string types that need coercion
55
49
  if validations?(input_schema)
@@ -70,6 +64,7 @@ module Mortymer
70
64
  responses: responses,
71
65
  tags: @tags
72
66
  }
67
+
73
68
  operation[:security] = security if @security
74
69
  {
75
70
  path.to_s => {
@@ -80,6 +75,49 @@ module Mortymer
80
75
 
81
76
  private
82
77
 
78
+ def generate_responses
79
+ responses = {
80
+ "200" => {
81
+ description: "Successful response",
82
+ content: {
83
+ "application/json" => {
84
+ schema: class_ref(@output_class)
85
+ }
86
+ }
87
+ }
88
+ }
89
+
90
+ @exception_handlers&.each do |handler|
91
+ status_code = if handler[:status].is_a?(Symbol)
92
+ Rack::Utils::SYMBOL_TO_STATUS_CODE[handler[:status]].to_s
93
+ else
94
+ handler[:status].to_s
95
+ end
96
+
97
+ responses[status_code] = {
98
+ description: handler[:exception].name,
99
+ content: {
100
+ "application/json" => {
101
+ schema: if handler[:output]
102
+ class_ref(handler[:output])
103
+ else
104
+ {
105
+ type: "object",
106
+ properties: {
107
+ error: {
108
+ type: "string"
109
+ }
110
+ }
111
+ }
112
+ end
113
+ }
114
+ }
115
+ }
116
+ end
117
+
118
+ responses
119
+ end
120
+
83
121
  def validations?(schema)
84
122
  return false unless schema
85
123
 
@@ -111,7 +149,7 @@ module Mortymer
111
149
  schema = if @input_class.respond_to?(:json_schema)
112
150
  @input_class.json_schema
113
151
  else
114
- Dry::Swagger::DocumentationGenerator.new.from_struct(@input_class)
152
+ Generator.new.from_struct(@input_class)
115
153
  end
116
154
  schema[:properties]&.map do |name, property|
117
155
  {
@@ -126,10 +164,22 @@ module Mortymer
126
164
  def generate_request_body
127
165
  return unless @input_class && %i[post put].include?(@http_method)
128
166
 
167
+ schema = if @input_class.respond_to?(:json_schema)
168
+ @input_class.json_schema
169
+ else
170
+ Generator.new.from_struct(@input_class)
171
+ end
172
+
173
+ # Check if any property is a File type
174
+ has_file = schema[:properties]&.any? do |_, property|
175
+ property[:format] == :binary
176
+ end
177
+
178
+ content_type = has_file ? "multipart/form-data" : "application/json"
129
179
  {
130
180
  required: true,
131
181
  content: {
132
- "application/json" => {
182
+ content_type => {
133
183
  schema: class_ref(@input_class)
134
184
  }
135
185
  }
@@ -0,0 +1,115 @@
1
+ require "dry/swagger"
2
+
3
+ module Mortymer
4
+ class Generator < Dry::Swagger::DocumentationGenerator
5
+ SWAGGER_FIELD_TYPE_DEFINITIONS = {
6
+ "string" => { type: :string },
7
+ "integer" => { type: :integer },
8
+ "boolean" => { type: :boolean },
9
+ "float" => { type: :float },
10
+ "decimal" => { type: :string, format: :decimal },
11
+ "datetime" => { type: :string, format: :datetime },
12
+ "date" => { type: :string, format: :date },
13
+ "time" => { type: :string, format: :time },
14
+ "uuid" => { type: :string, format: :uuid },
15
+ "file" => { type: :string, format: :binary }
16
+ }.freeze
17
+
18
+ def from_struct(struct)
19
+ generate_documentation(::DryStructParser::StructSchemaParser.new.call(struct).keys)
20
+ end
21
+
22
+ def from_validation(validation)
23
+ generate_documentation(::DryValidationParser::ValidationSchemaParser.new.call(validation).keys)
24
+ end
25
+
26
+ def generate_documentation(fields)
27
+ documentation = { properties: {}, required: [] }
28
+ fields.each do |field_name, definition|
29
+ documentation[:properties][field_name] = generate_field_properties(definition)
30
+ if definition.is_a?(Hash)
31
+ documentation[:required] << field_name if definition.fetch(:required,
32
+ true) && @config.enable_required_validation
33
+ elsif definition[0].fetch(:required, true) && @config.enable_required_validation
34
+ documentation[:required] << field_name
35
+ end
36
+ end
37
+
38
+ { type: :object, properties: documentation[:properties], required: documentation[:required] }
39
+ end
40
+
41
+ def generate_field_properties(definition)
42
+ return generate_for_sti_type(definition) if definition.is_a?(Array)
43
+
44
+ documentation = if definition[:type] == "array" || definition[:array]
45
+ generate_for_array(definition)
46
+ elsif definition[:type] == "hash"
47
+ generate_for_hash(definition)
48
+ else
49
+ generate_for_primitive_type(definition)
50
+ end
51
+ if @config.enable_nullable_validation
52
+ documentation.merge(@config.nullable_type => definition.fetch(:nullable, false))
53
+ else
54
+ documentation.merge(@config.nullable_type => true)
55
+ end
56
+ rescue KeyError
57
+ raise Errors::MissingTypeError
58
+ end
59
+
60
+ def generate_for_sti_type(definition)
61
+ properties = {}
62
+
63
+ definition.each_with_index do |_, index|
64
+ properties["definition_#{index + 1}"] = generate_field_properties(definition[index])
65
+ end
66
+
67
+ documentation = {
68
+ type: :object,
69
+ properties: properties,
70
+ example: "Dynamic Field. See Model Definitions"
71
+ }
72
+
73
+ if definition[0][:type] == "array"
74
+ definition.each { |it| it[:type] = "hash" }
75
+ documentation[:oneOf] = definition.map { |it| generate_field_properties(it) }
76
+ { type: :array, items: documentation }
77
+ else
78
+ documentation[:oneOf] = definition.map { |it| generate_field_properties(it) }
79
+ documentation
80
+ end
81
+ end
82
+
83
+ def generate_for_array(definition)
84
+ items = if array_of_primitive_type?(definition)
85
+ self.class::SWAGGER_FIELD_TYPE_DEFINITIONS.fetch(definition.fetch(:type))
86
+ else
87
+ generate_documentation(definition.fetch(:keys))
88
+ end
89
+ items = if @config.enable_nullable_validation
90
+ items.merge(@config.nullable_type => definition.fetch(:nullable, false))
91
+ else
92
+ items.merge(@config.nullable_type => true)
93
+ end
94
+ { type: :array, items: items }
95
+ end
96
+
97
+ def generate_for_hash(definition)
98
+ raise Errors::MissingHashSchemaError unless definition[:keys]
99
+
100
+ generate_documentation(definition.fetch(:keys))
101
+ end
102
+
103
+ def generate_for_primitive_type(definition)
104
+ documentation = self.class::SWAGGER_FIELD_TYPE_DEFINITIONS.fetch(definition.fetch(:type))
105
+ documentation = documentation.merge(enum: definition.fetch(:enum)) if definition[:enum] && @config.enable_enums
106
+ documentation = documentation.merge(description: definition.fetch(:description)) if definition[:description] &&
107
+ @config.enable_descriptions
108
+ documentation
109
+ end
110
+
111
+ def array_of_primitive_type?(definition)
112
+ definition[:array] && definition.fetch(:type) != "array"
113
+ end
114
+ end
115
+ end
@@ -1,8 +1,22 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "dry/swagger/documentation_generator"
4
+ require_relative "moldeable"
5
+ require_relative "types"
6
+ require_relative "generator"
7
+
3
8
  module Mortymer
4
9
  # A base model for defining schemas
5
10
  class Model < Dry::Struct
11
+ include Mortymer::Moldeable
6
12
  include Dry.Types()
13
+
14
+ def self.json_schema
15
+ Generator.new.from_struct(self)
16
+ end
17
+
18
+ def self.structify(params)
19
+ new(params)
20
+ end
7
21
  end
8
22
  end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Mortymer
4
+ # Interface for models to be able to be documentable
5
+ # and buildable from request inputs
6
+ module Moldeable
7
+ def self.json_schema
8
+ raise NotImplementedError
9
+ end
10
+
11
+ def self.structify(params = {})
12
+ raise NotImplementedError
13
+ end
14
+ end
15
+ end
@@ -2,13 +2,14 @@
2
2
 
3
3
  require_relative "endpoint_registry"
4
4
  require_relative "utils/string_transformations"
5
+ require_relative "generator"
5
6
 
6
7
  module Mortymer
7
8
  # Generate an openapi doc based on the registered endpoints
8
9
  class OpenapiGenerator
9
10
  include Utils::StringTransformations
10
11
 
11
- def initialize(prefix: "", title: "Rick on Rails API", version: "v1", description: "", registry: [],
12
+ def initialize(prefix: "", title: "Rick on Rails API", version: "v1", description: "", registry: [], # rubocop:disable Metrics/ParameterLists
12
13
  security_schemes: {})
13
14
  @prefix = prefix
14
15
  @title = title
@@ -73,7 +74,7 @@ module Mortymer
73
74
  if endpoint.input_class.respond_to?(:json_schema)
74
75
  endpoint.input_class.json_schema
75
76
  else
76
- Dry::Swagger::DocumentationGenerator.new.from_struct(endpoint.input_class)
77
+ Generator.new.from_struct(endpoint.input_class)
77
78
  end
78
79
  end
79
80
 
@@ -83,7 +84,7 @@ module Mortymer
83
84
  if endpoint.output_class.respond_to?(:json_schema)
84
85
  endpoint.output_class.json_schema
85
86
  else
86
- Dry::Swagger::DocumentationGenerator.new.from_struct(endpoint.output_class)
87
+ Generator.new.from_struct(endpoint.output_class)
87
88
  end
88
89
  end
89
90
  schemas
@@ -28,7 +28,7 @@ module Mortymer
28
28
 
29
29
  @drawer.send(
30
30
  endpoint.http_method,
31
- endpoint.path,
31
+ "#{Mortymer.config.api_prefix}#{endpoint.path}",
32
32
  to: "#{endpoint.controller_name.gsub(/_controller$/, "")}##{endpoint.action}",
33
33
  as: "#{endpoint.http_method}_#{endpoint.api_name}"
34
34
  )
@@ -27,7 +27,8 @@ module Mortymer
27
27
  title: Mortymer.config.swagger_title,
28
28
  version: Mortymer.config.api_version,
29
29
  description: Mortymer.config.api_description,
30
- security_schemes: Mortymer.config.security_schemes
30
+ security_schemes: Mortymer.config.security_schemes,
31
+ prefix: Mortymer.config.api_prefix
31
32
  )
32
33
 
33
34
  # Save OpenAPI spec to public directory
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "dry-types"
4
+
5
+ module Mortymer
6
+ module Types
7
+ include Dry.Types()
8
+
9
+ class RackFile
10
+ attr_reader :tempfile, :original_filename, :content_type
11
+
12
+ def initialize(tempfile:, original_filename:, content_type:)
13
+ @tempfile = tempfile
14
+ @original_filename = original_filename
15
+ @content_type = content_type
16
+ end
17
+
18
+ def self.new_from_rack_file(file)
19
+ return nil if file.nil?
20
+
21
+ new(
22
+ tempfile: file.respond_to?(:tempfile) ? file.tempfile : file[:tempfile],
23
+ original_filename: file.respond_to?(:original_filename) ? file.original_filename : file[:original_filename],
24
+ content_type: file.respond_to?(:content_type) ? file.content_type : file[:content_type]
25
+ )
26
+ end
27
+ end
28
+
29
+ # Define a custom type for handling file uploads
30
+ UploadedFile = Types.Constructor(RackFile) do |value|
31
+ case value
32
+ when RackFile
33
+ value
34
+ when Hash
35
+ RackFile.new_from_rack_file(value)
36
+ when ActionDispatch::Http::UploadedFile
37
+ RackFile.new_from_rack_file(value)
38
+ when NilClass
39
+ nil
40
+ else
41
+ raise Dry::Types::CoercionError, "#{value.inspect} cannot be coerced to UploadedFile"
42
+ end
43
+ end.meta(
44
+ swagger: {
45
+ type: "file"
46
+ }
47
+ )
48
+
49
+ # Array of files
50
+ UploadedFiles = Types::Array.of(File)
51
+ end
52
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "types"
4
+
5
+ UploadedFile = Mortymer::Types::UploadedFile
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "types"
4
+
5
+ UploadedFiles = Mortymer::Types::UploadedFiles
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Mortymer
4
- VERSION = "0.0.7"
4
+ VERSION = "0.0.8"
5
5
  end
data/lib/mortymer.rb CHANGED
@@ -2,8 +2,13 @@
2
2
  # typed: true
3
3
 
4
4
  require "dry/struct"
5
+ require "mortymer/types"
6
+ require "mortymer/uploaded_file"
7
+ require "mortymer/uploaded_files"
5
8
  require "mortymer/configuration"
9
+ require "mortymer/moldeable"
6
10
  require "mortymer/model"
11
+ require "mortymer/contract"
7
12
  require "mortymer/endpoint"
8
13
  require "mortymer/dry_swagger"
9
14
  require "mortymer/endpoint_registry"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mortymer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.7
4
+ version: 0.0.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Adrian Gonzalez
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2025-03-11 00:00:00.000000000 Z
11
+ date: 2025-03-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: dry-monads
@@ -126,11 +126,14 @@ files:
126
126
  - lib/mortymer/api_metadata.rb
127
127
  - lib/mortymer/configuration.rb
128
128
  - lib/mortymer/container.rb
129
+ - lib/mortymer/contract.rb
129
130
  - lib/mortymer/dependencies_dsl.rb
130
131
  - lib/mortymer/dry_swagger.rb
131
132
  - lib/mortymer/endpoint.rb
132
133
  - lib/mortymer/endpoint_registry.rb
134
+ - lib/mortymer/generator.rb
133
135
  - lib/mortymer/model.rb
136
+ - lib/mortymer/moldeable.rb
134
137
  - lib/mortymer/openapi_generator.rb
135
138
  - lib/mortymer/rails.rb
136
139
  - lib/mortymer/rails/configuration.rb
@@ -138,9 +141,11 @@ files:
138
141
  - lib/mortymer/rails/routes.rb
139
142
  - lib/mortymer/railtie.rb
140
143
  - lib/mortymer/security_schemes.rb
144
+ - lib/mortymer/types.rb
145
+ - lib/mortymer/uploaded_file.rb
146
+ - lib/mortymer/uploaded_files.rb
141
147
  - lib/mortymer/utils/string_transformations.rb
142
148
  - lib/mortymer/version.rb
143
- - lib/mortymermer.rb
144
149
  - mortymer.gemspec
145
150
  - package-lock.json
146
151
  - package.json
data/lib/mortymermer.rb DELETED
@@ -1,15 +0,0 @@
1
- # frozen_string_literal: true
2
- # typed: true
3
-
4
- require "dry/struct"
5
- require "mortymer/model"
6
- require "mortymer/endpoint"
7
- require "mortymer/dry_swagger"
8
- require "mortymer/endpoint_registry"
9
- require "mortymer/utils/string_transformations"
10
- require "mortymer/api_metadata"
11
- require "mortymer/openapi_generator"
12
- require "mortymer/container"
13
- require "mortymer/dependencies_dsl"
14
- require "mortymer/rails" if defined?(Rails)
15
- require "mortymer/railtie" if defined?(Rails::Railtie)