name: flask
language: python
description: "Flask routes (explicit methods=, @app.<verb> shorthand, and bare @app.route default-GET)"

detection:
  file_patterns:
    - "**/*.py"
  markers:
    - pattern: "from flask import"
      type: import
    - pattern: "import flask"
      type: import
    - pattern: "Flask(__name__)"
      type: instantiation

# Three patterns, in priority order. The bare-route pattern is anchored
# with `\)` after the path so it does not match the explicit-methods=
# form. Capture order is path then method because that's how Flask
# writes them.
endpoint_extraction:
  patterns:
    - regex: "@(?:app|bp|blueprint)\\.route\\s*\\(\\s*['\"]([^'\"]+)['\"]\\s*,\\s*methods\\s*=\\s*\\[\\s*['\"](GET|POST|PUT|DELETE|PATCH|OPTIONS|HEAD)['\"]"
      method_group: 2
      path_group: 1
    # @app.get("/x"), @app.post("/x") — Flask 2+ shorthand
    - regex: "@(?:app|bp|blueprint)\\.(get|post|put|delete|patch|options|head)\\s*\\(\\s*['\"]([^'\"]+)['\"]"
      method_group: 1
      path_group: 2
    # @app.route("/x") — bare form, defaults to GET. The `\)` anchor
    # keeps this from double-matching lines that also have methods=.
    - regex: "@(?:app|bp|blueprint)\\.route\\s*\\(\\s*['\"]([^'\"]+)['\"]\\s*\\)"
      method_group: 0
      path_group: 1
      default_method: GET
