model_driven_api 3.1.10 → 3.1.11

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: 0afb3dc1dca5b7277c7ea2bfd601669765d5227fe68ede17fa6fbfc3de19d36f
4
- data.tar.gz: 02c3ece69e6237b42f8f04de6660469d528c81a84cf392a34a743360b765d832
3
+ metadata.gz: bbaf42c9a62f9ebdc9cdf60633aeeb47ad39b11e9ebb9d20a94af73fea6c7213
4
+ data.tar.gz: c56851d1ae81777a20cc1d7ea26c0a31fb2f349933df72e41f303b8194cc8da6
5
5
  SHA512:
6
- metadata.gz: 92c3d537101cb23123ce34564eaac4fe1d767770628dddcd1cc94487253bb82c880e07721a78c2be3dc571c370020b12e13ab30e9981d035c7766634dccdeb7b
7
- data.tar.gz: 69385bf1c20fe26e8168be63da529edb847002984084e133e431aef6b07815bb88edf1f42ed43d65dc0ef5194a28ede011c29f05aca3de0176dd11a119da3a8a
6
+ metadata.gz: 67ff210a1024a027db62fdaad0091b52229b36d61753ee95c128930a3e4ea8bd127bc1bf8e61209a7aac9938b0c32fd768cdd8b72548adf7f8cc1336b41c95e6
7
+ data.tar.gz: fc5a82329178979b349055efb02840708ee1d2df4a3ea37d19f9b317403a5d583a584c25f712e3a72c83d438d344d46fbcfb8762bfa573d40909f991e8716fc6
@@ -515,49 +515,17 @@ class Api::V2::InfoController < Api::V2::ApplicationController
515
515
  }
516
516
  }
517
517
  # Non CRUD or Search, but custom, usually bulk operations endpoints
518
- custom_actions = d.methods(false).select do |m| m.to_s.starts_with?("custom_action_") end
519
- # Add also custom actions created using th enew Endpoints Interface
520
- custom_actions += "Endpoints::#{d.model_name.name}".constantize.methods(false) rescue []
521
- custom_actions.each do |action|
522
- custom_action_name = action.to_s.gsub("custom_action_", "")
523
- pivot["/#{model}/custom_action/#{custom_action_name}"] = {
524
- "get": {
525
- "summary": "Custom Action #{custom_action_name.titleize}",
526
- "description": "This is just an example of a custom action, they can accept a wide range of payloads and response with a wide range of responses, also all verbs are valid. Please refer to the documentation for more information.",
527
- "tags": [model.classify],
528
- "security": [
529
- "bearerAuth": []
530
- ],
531
- "responses": {
532
- "200": {
533
- "description": "Custom Action",
534
- "content": {
535
- "application/json": {
536
- "schema": {
537
- "type": "object",
538
- "properties": {
539
- "id": {
540
- "type": "integer"
541
- },
542
- "created_at": {
543
- "type": "string",
544
- "format": "date-time"
545
- },
546
- "updated_at": {
547
- "type": "string",
548
- "format": "date-time"
549
- }
550
- }
551
- }
552
- }
553
- }
554
- },
555
- "404": {
556
- "description": "No #{model} found"
557
- }
558
- }
559
- }
560
- }
518
+ new_custom_actions = ("Endpoints::#{d.model_name.name}".constantize.instance_methods(false) rescue [])
519
+ # Rails.logger.debug "New Custom Actions (#{d.model_name.name}): #{new_custom_actions}"
520
+ new_custom_actions.each do |action|
521
+ openapi_definition = "Endpoints::#{d.model_name.name}".constantize.definitions[action.to_sym] rescue false
522
+
523
+ # Add the tag to the openapi definition
524
+ openapi_definition.each do |k, v|
525
+ v[:tags] = [ d.model_name.name ]
526
+ end
527
+
528
+ pivot["/#{model}/custom_action/#{action}"] = openapi_definition if openapi_definition
561
529
  end
562
530
  pivot["/#{model}/search"] = {
563
531
  # Complex queries are made using ranskac search via a post endpoint
@@ -1,56 +1,78 @@
1
1
  class Endpoints::TestApi < NonCrudEndpoints
2
- def test(params)
3
- # Define an explain var to be used to validate and document the action behavior when using ?explain=true in query string
4
- explain = {
5
- verbs: ["GET", "POST"],
6
- body: {
7
- messages: {
8
- type: :array,
9
- optional: true,
10
- items: {
11
- type: :string,
12
- optional: false
2
+ self.desc :test, {
3
+ # Define the action name using openapi swagger format
4
+ get: {
5
+ summary: "Test API Custom Action",
6
+ description: "This is a test API custom action",
7
+ operationId: "test",
8
+ tags: ["Test"],
9
+ parameters: [
10
+ {
11
+ name: "explain",
12
+ in: "query",
13
+ description: "Explain the action by returning this openapi schema",
14
+ required: true,
15
+ schema: {
16
+ type: "boolean"
13
17
  }
14
- },
15
- is_connected: {
16
- type: :boolean,
17
- optional: false
18
- },
19
- user: {
20
- type: :object,
21
- optional: true,
22
- properties: {
23
- name: {
24
- type: :string,
25
- optional: false
26
- },
27
- age: {
28
- type: :integer,
29
- optional: true
18
+ }
19
+ ],
20
+ responses: {
21
+ 200 => {
22
+ description: "The openAPI json schema for this action",
23
+ content: {
24
+ "application/json": {
25
+ schema: {
26
+ type: "object",
27
+ additionalProperties: true
28
+ }
30
29
  }
31
30
  }
31
+ },
32
+ 501 => {
33
+ error: :string,
32
34
  }
33
- },
34
- query: {
35
- explain: {
36
- type: :boolean,
37
- optional: true
35
+ }
36
+ },
37
+ post: {
38
+ summary: "Test API Custom Action",
39
+ description: "This is a test API custom action",
40
+ operationId: "test",
41
+ tags: ["Test"],
42
+ requestBody: {
43
+ required: true,
44
+ content: {
45
+ "application/json": {}
38
46
  }
39
47
  },
40
48
  responses: {
41
49
  200 => {
42
- message: :string,
43
- params: {},
50
+ description: "The openAPI json schema for this action",
51
+ # This will return the object with a message string and a params object
52
+ content: {
53
+ "application/json": {
54
+ schema: {
55
+ type: "object",
56
+ properties: {
57
+ message: {
58
+ type: "string"
59
+ },
60
+ params: {
61
+ type: "object",
62
+ additionalProperties: true
63
+ }
64
+ }
65
+ }
66
+ }
67
+ }
44
68
  },
45
69
  501 => {
46
70
  error: :string,
47
- },
48
- },
71
+ }
72
+ }
49
73
  }
50
- return explain, 200 if params[:explain].to_s == "true" && !explain.blank?
51
-
52
-
74
+ }
75
+ def test(params)
53
76
  return { message: "Hello World From Test API Custom Action called test", params: params }, 200
54
77
  end
55
78
  end
56
- # end
@@ -1,3 +1,3 @@
1
1
  module ModelDrivenApi
2
- VERSION = "3.1.10".freeze
2
+ VERSION = "3.1.11".freeze
3
3
  end
@@ -1,37 +1,45 @@
1
1
  class NonCrudEndpoints
2
2
  attr_accessor :result
3
+ cattr_accessor :definitions
4
+ self.definitions = {}
3
5
  # Add a validation method which will be inherited by all the instances, and automatically run before any method call
4
6
  def initialize(m, params)
5
7
  # Check if self hase the m method, if not, raise a NoMethodError
6
- raise NoMethodError, "The method #{m} does not exist in #{self.class}" unless self.respond_to? m
7
- definition = self.send(m, { explain: true }) rescue []
8
- validate_request(definition.first.presence || {}, params)
8
+ raise NoMethodError, "The method #{m} does not exist in #{self.class.name}" unless self.respond_to? m
9
+ @definition = self.definitions[m.to_sym].with_indifferent_access
10
+
11
+ # self.send(m, { explain: true }) rescue []
12
+ validate_request(params)
9
13
  @result = self.send(m, params)
10
14
  end
11
15
 
12
- def validate_request(definition, params)
16
+ def validate_request(params)
13
17
  # If there is no definition, return
14
- return if definition.blank?
18
+ return if @definition.blank?
15
19
  # puts "Called Class is: #{self.class}"
16
20
  # puts "Which is son of: #{self.class.superclass}"
17
- body_mandatory_keys = definition[:body].select { |k, v| v[:optional] == false }.keys
18
- query_mandatory_keys = definition[:query].select { |k, v| v[:optional] == false }.keys
19
- # Raise a ValidationError if the request does not match the definition
20
- raise EndpointValidationError, "The verb \"#{params[:request_verb].presence || "No Verb Provided"}\" is not present in #{definition[:verbs].join(", ")}." if definition[:verbs].exclude? params[:request_verb]
21
- # Raise an exception if the verb is put or post and the body keys in definition are not all present as params keys, both params and definition[:body] can have nested objects
22
- raise EndpointValidationError, "The request body does not match the definition: in #{params[:request_verb]} requests all of the params must be present in definition. The body definition is #{definition[:body]}." if params[:request_verb] != "GET" && (body_mandatory_keys & params.keys) != body_mandatory_keys
23
- # Raise an exception if the verb is put or post and the body keys in definition are not all present as params keys, both params and definition[:body] can have nested objects
24
- raise EndpointValidationError, "The request query does not match the definition. The query definition is: #{definition[:query]}." if (query_mandatory_keys & params.keys) != query_mandatory_keys
25
- # Rais if the type of the param is not the same as the definition
26
- definition[:body].each do |k, v|
27
- next if params[k].nil?
28
- computed_type = get_type(params[k])
29
- raise EndpointValidationError, "The type of the param #{k} is not the same as the definition. The definition is #{v[:type]} and the param is #{computed_type}." if v[:type] != computed_type
30
- end
21
+ # body_mandatory_keys = definition[:body].select { |k, v| v[:optional] == false }.keys
22
+ # query_mandatory_keys = definition[:query].select { |k, v| v[:optional] == false }.keys
23
+ # # Raise a ValidationError if the request does not match the definition
24
+ # raise EndpointValidationError, "The verb \"#{params[:request_verb].presence || "No Verb Provided"}\" is not present in #{definition.keys.join(", ")}." if definition.keys.exclude? params[:request_verb]
25
+ # # Raise an exception if the verb is put or post and the body keys in definition are not all present as params keys, both params and definition[:body] can have nested objects
26
+ # raise EndpointValidationError, "The request body does not match the definition: in #{params[:request_verb]} requests all of the params must be present in definition. The body definition is #{definition[:body]}." if params[:request_verb] != "GET" && (body_mandatory_keys & params.keys) != body_mandatory_keys
27
+ # # Raise an exception if the verb is put or post and the body keys in definition are not all present as params keys, both params and definition[:body] can have nested objects
28
+ # raise EndpointValidationError, "The request query does not match the definition. The query definition is: #{definition[:query]}." if (query_mandatory_keys & params.keys) != query_mandatory_keys
29
+ # # Rais if the type of the param is not the same as the definition
30
+ # definition[:body].each do |k, v|
31
+ # next if params[k].nil?
32
+ # computed_type = get_type(params[k])
33
+ # raise EndpointValidationError, "The type of the param #{k} is not the same as the definition. The definition is #{v[:type]} and the param is #{computed_type}." if v[:type] != computed_type
34
+ # end
31
35
  end
32
36
 
33
37
  private
34
38
 
39
+ def self.desc(key, definition)
40
+ self.definitions[key] = definition
41
+ end
42
+
35
43
  def get_type(type)
36
44
  case type
37
45
  when String
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: model_driven_api
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.1.10
4
+ version: 3.1.11
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gabriele Tassoni
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-03-18 00:00:00.000000000 Z
11
+ date: 2024-03-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: thecore_backend_commons