Module: Archsight::Web::API::JsonHelpers
- Defined in:
- lib/archsight/web/api/json_helpers.rb
Overview
Shared helpers for JSON API responses
Constant Summary collapse
- DEFAULT_LIMIT =
50- MAX_LIMIT =
500- MARKDOWN_ANNOTATION_KEYS =
Set["architecture/description"].freeze
Instance Method Summary collapse
- #build_analysis_result(result) ⇒ Object
- #build_count_response(query, results, query_time_ms) ⇒ Object
- #build_filters_response(kind) ⇒ Object
- #build_instance_response(kind, instance) ⇒ Object
- #build_kinds_list ⇒ Object
- #build_list_response(kind, pagination, instances) ⇒ Object
- #build_search_response(query, results, _parsed_query, query_time_ms) ⇒ Object
- #extract_references(instance) ⇒ Object
- #extract_relations(instance) ⇒ Object
- #json_error(message, status:, error_type: "Error", query: nil) ⇒ Object
- #json_response(data, status: 200) ⇒ Object
- #paginate(collection, limit:, offset:) ⇒ Object
- #parse_output_param ⇒ Object
- #parse_pagination_params ⇒ Object
- #render_annotations(annotations) ⇒ Object
- #resource_summary(resource, output:, omit_kind: false) ⇒ Object
- #serialize_analysis_section(section) ⇒ Object
- #serialize_spec(spec) ⇒ Object
Instance Method Details
#build_analysis_result(result) ⇒ Object
179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 |
# File 'lib/archsight/web/api/json_helpers.rb', line 179 def build_analysis_result(result) data = { name: result.name, success: result.success?, has_findings: result.has_findings?, duration: result.duration, sections: result.sections.map { |s| serialize_analysis_section(s) } } if result.failed? data[:error] = result.error data[:error_backtrace] = result.error_backtrace if result.error_backtrace&.any? end data end |
#build_count_response(query, results, query_time_ms) ⇒ Object
121 122 123 124 125 126 127 128 129 130 |
# File 'lib/archsight/web/api/json_helpers.rb', line 121 def build_count_response(query, results, query_time_ms) by_kind = results.group_by { |r| r.class.to_s.split("::").last } .transform_values(&:length) { query: query, total: results.length, query_time_ms: query_time_ms, by_kind: by_kind } end |
#build_filters_response(kind) ⇒ Object
167 168 169 170 171 172 173 174 175 176 177 |
# File 'lib/archsight/web/api/json_helpers.rb', line 167 def build_filters_response(kind) db.filters_for_kind(kind).map do |annotation, values| { key: annotation.key, title: annotation.title, description: annotation.description, filter_type: annotation.filter.to_s, values: values } end end |
#build_instance_response(kind, instance) ⇒ Object
88 89 90 91 92 93 94 95 96 97 |
# File 'lib/archsight/web/api/json_helpers.rb', line 88 def build_instance_response(kind, instance) { kind: kind, name: instance.name, metadata: { annotations: render_annotations(instance.annotations) }, spec: serialize_spec(instance.spec), relations: extract_relations(instance), references: extract_references(instance) } end |
#build_kinds_list ⇒ Object
61 62 63 64 65 66 67 68 69 70 71 72 73 |
# File 'lib/archsight/web/api/json_helpers.rb', line 61 def build_kinds_list kinds = Archsight::Resources.resource_classes.map do |kind_name, klass| count = db.instances_by_kind(kind_name).length { kind: kind_name, description: klass.description, layer: klass.layer, icon: klass.icon, instance_count: count } end kinds.sort_by { |k| k[:kind] } end |
#build_list_response(kind, pagination, instances) ⇒ Object
75 76 77 78 79 80 81 82 83 84 |
# File 'lib/archsight/web/api/json_helpers.rb', line 75 def build_list_response(kind, pagination, instances) { kind: kind, total: pagination[:total], limit: pagination[:limit], offset: pagination[:offset], count: instances.length, instances: instances } end |
#build_search_response(query, results, _parsed_query, query_time_ms) ⇒ Object
132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 |
# File 'lib/archsight/web/api/json_helpers.rb', line 132 def build_search_response(query, results, _parsed_query, query_time_ms) limit, offset = parse_pagination_params output = parse_output_param sorted = results.sort_by(&:name) pagination = paginate(sorted, limit: limit, offset: offset) instances = pagination[:items].map do |r| resource_summary(r, output: output, omit_kind: false) end { query: query, total: pagination[:total], limit: pagination[:limit], offset: pagination[:offset], count: instances.length, query_time_ms: query_time_ms, instances: instances } end |
#extract_references(instance) ⇒ Object
215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 |
# File 'lib/archsight/web/api/json_helpers.rb', line 215 def extract_references(instance) references = {} instance.references.each do |ref| inst = ref[:instance] verb = ref[:verb] kind = inst.klass references[kind] ||= {} references[kind][verb] ||= [] references[kind][verb] << inst.name end references end |
#extract_relations(instance) ⇒ Object
153 154 155 156 157 158 159 160 161 162 163 164 165 |
# File 'lib/archsight/web/api/json_helpers.rb', line 153 def extract_relations(instance) relations = {} instance.class.relations.each do |verb, spec_key, kind| rels = instance.relations(verb, spec_key).map(&:name) next if rels.empty? relations[verb] ||= {} relations[verb][kind] = rels end relations end |
#json_error(message, status:, error_type: "Error", query: nil) ⇒ Object
17 18 19 20 21 22 |
# File 'lib/archsight/web/api/json_helpers.rb', line 17 def json_error(, status:, error_type: "Error", query: nil) content_type :json error = { error: error_type, message: } error[:query] = query if query halt status, JSON.pretty_generate(error) end |
#json_response(data, status: 200) ⇒ Object
12 13 14 15 |
# File 'lib/archsight/web/api/json_helpers.rb', line 12 def json_response(data, status: 200) content_type :json halt status, JSON.pretty_generate(data) end |
#paginate(collection, limit:, offset:) ⇒ Object
40 41 42 43 44 45 46 47 48 49 |
# File 'lib/archsight/web/api/json_helpers.rb', line 40 def paginate(collection, limit:, offset:) limit = [[limit.to_i, 1].max, MAX_LIMIT].min offset = [offset.to_i, 0].max { items: collection.drop(offset).take(limit), limit: limit, offset: offset, total: collection.length } end |
#parse_output_param ⇒ Object
57 58 59 |
# File 'lib/archsight/web/api/json_helpers.rb', line 57 def parse_output_param params[:output] || "complete" end |
#parse_pagination_params ⇒ Object
51 52 53 54 55 |
# File 'lib/archsight/web/api/json_helpers.rb', line 51 def parse_pagination_params limit = (params[:limit] || DEFAULT_LIMIT).to_i offset = (params[:offset] || 0).to_i [limit, offset] end |
#render_annotations(annotations) ⇒ Object
99 100 101 102 103 104 105 106 107 |
# File 'lib/archsight/web/api/json_helpers.rb', line 99 def render_annotations(annotations) annotations.each_with_object({}) do |(key, value), result| result[key] = if MARKDOWN_ANNOTATION_KEYS.include?(key) && value.is_a?(String) markdown(value) else value end end end |
#resource_summary(resource, output:, omit_kind: false) ⇒ Object
24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
# File 'lib/archsight/web/api/json_helpers.rb', line 24 def resource_summary(resource, output:, omit_kind: false) result = case output when "brief" Archsight::MCP.brief_summary(resource, omit_kind: omit_kind) when "annotations" Archsight::MCP.annotations_summary(resource, omit_kind: omit_kind) else # "complete" summary = Archsight::MCP.complete_summary(resource, omit_kind: omit_kind) summary[:spec] = serialize_spec(summary[:spec]) if summary[:spec] summary end result[:icon] = resource.class.icon result[:layer] = resource.class.layer result end |
#serialize_analysis_section(section) ⇒ Object
196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 |
# File 'lib/archsight/web/api/json_helpers.rb', line 196 def serialize_analysis_section(section) case section[:type] when :heading { type: "heading", level: section[:level], text: section[:text] } when :text { type: "text", content: section[:content] } when :message { type: "message", level: section[:level].to_s, message: section[:message] } when :table { type: "table", headers: section[:headers], rows: section[:rows] } when :list { type: "list", items: section[:items] } when :code { type: "code", lang: section[:lang], content: section[:content] } else { type: section[:type].to_s } end end |
#serialize_spec(spec) ⇒ Object
109 110 111 112 113 114 115 116 117 118 119 |
# File 'lib/archsight/web/api/json_helpers.rb', line 109 def serialize_spec(spec) spec.transform_values do |kinds| next kinds unless kinds.is_a?(Hash) kinds.transform_values do |instances| next instances unless instances.is_a?(Array) instances.map { |i| i.is_a?(Archsight::Resources::Base) ? i.name : i } end end end |