Class: Async::Discord::Api::PathTree

Inherits:
Matrix::Api::PathTree show all
Defined in:
lib/async/discord/api/path_tree.rb

Overview

Loads the Discord HTTP API OpenAPI spec and builds a PathTree trie of all valid endpoints. Reuses the core Node/insert/match logic from Async::Matrix::Api::PathTree.

The Discord spec is a single JSON file (OpenAPI 3.1.0) with the server URL discord.com/api/v10, yielding prefix segments [“api”, “v10”].

tree = PathTree.load
tree.match(%w[api v10 channels 123 messages], "POST")
# => { valid: true, operation_id: "create_message", methods: ["post"] }

Constant Summary collapse

SCHEMA_PATH =
Pathname.new(File.expand_path("../../../../data/discord-api-spec/openapi.json", __dir__)).freeze

Constants inherited from Matrix::Api::PathTree

Matrix::Api::PathTree::SCHEMA_DIR

Instance Attribute Summary

Attributes inherited from Matrix::Api::PathTree

#root

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Matrix::Api::PathTree

#initialize, #insert, #load_schema, #match

Constructor Details

This class inherits a constructor from Async::Matrix::Api::PathTree

Class Method Details

.load(schema_path: SCHEMA_PATH) ⇒ Object



30
31
32
33
34
# File 'lib/async/discord/api/path_tree.rb', line 30

def self.load(schema_path: SCHEMA_PATH)
  tree = new
  tree.load_json_schema(schema_path)
  tree
end

Instance Method Details

#load_json_schema(path) ⇒ Object

Parse the Discord OpenAPI JSON file and insert all paths into the trie.



37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/async/discord/api/path_tree.rb', line 37

def load_json_schema(path)
  doc = JSON.parse(File.read(path))

  base_path = extract_json_base_path(doc)
  paths = doc["paths"]
  return unless paths.is_a?(Hash)

  paths.each do |path_template, methods_hash|
    next unless methods_hash.is_a?(Hash)

    full_path = "#{base_path}#{path_template.strip}"
    segments = full_path.split("/").reject(&:empty?)

    methods_hash.each do |method, operation|
      # Skip path-level parameters (Discord spec puts these alongside methods)
      next if method == "parameters"
      next unless %w[get post put delete patch head].include?(method)
      operation_id = operation.is_a?(Hash) ? operation["operationId"] : nil
      insert(segments, method, operation_id)
    end
  end
end