mirror of
https://github.com/dalbodeule/sh0rt.kr-pdns.git
synced 2026-11-05 22:29:34 +09:00
feat: Add script to refresh README from OpenAPI document
refactor: Improve error handling in PowerDNSAPIClient and streamline response processing fix: Update RecordController to directly return records without unnecessary mapping refactor: Update DomainRepository and RecordRepository to remove nullable types for IDs fix: Change User domains fetch strategy to lazy loading for performance improvement fix: Enhance user authentication handling in UserFilter to ensure authenticated user presence refactor: Improve DomainService to enforce ownership checks before domain deletion refactor: Update RecordService to streamline record retrieval and ensure proper domain association test: Add OpenAPI generation test to validate API documentation endpoint test: Implement PowerDNSAPIClient tests to verify HTTP method usage and error handling test: Create DomainService tests to validate domain ownership and deletion logic test: Add application-test.properties for in-memory database configuration during tests
This commit is contained in:
24 files changed
+920
-1329
No files matched your search
@@ -0,0 +1,99 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Refresh the generated README section from the root OpenAPI document."""
|
||||
|
||||
import json
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
START = "<!-- BEGIN GENERATED API -->"
|
||||
END = "<!-- END GENERATED API -->"
|
||||
METHODS = ("get", "post", "put", "patch", "delete")
|
||||
|
||||
|
||||
def schema_type(schema):
|
||||
if not schema:
|
||||
return "—"
|
||||
if "$ref" in schema:
|
||||
name = schema["$ref"].rsplit("/", 1)[-1]
|
||||
return f"[{name}](#{name.lower()})"
|
||||
if "oneOf" in schema:
|
||||
return " or ".join(schema_type(part) for part in schema["oneOf"])
|
||||
kind = schema.get("type", "object")
|
||||
if isinstance(kind, list):
|
||||
return " or ".join(
|
||||
f"array of {schema_type(schema.get('items'))}" if part == "array" else part
|
||||
for part in kind
|
||||
)
|
||||
if kind == "array":
|
||||
return f"array of {schema_type(schema.get('items'))}"
|
||||
return kind
|
||||
|
||||
|
||||
def media_schema(content):
|
||||
return schema_type(content.get("application/json", {}).get("schema"))
|
||||
|
||||
|
||||
def cell(value):
|
||||
return str(value or "—").replace("|", "\\|").replace("\n", " ")
|
||||
|
||||
|
||||
def generate(spec):
|
||||
lines = [
|
||||
"Generated from [openapi.json](openapi.json). Do not edit this section by hand.",
|
||||
"",
|
||||
"### Endpoints",
|
||||
"",
|
||||
"| Method | Path | Summary | Request body | Success response |",
|
||||
"| --- | --- | --- | --- | --- |",
|
||||
]
|
||||
|
||||
for path, operations in sorted(spec["paths"].items()):
|
||||
for method in METHODS:
|
||||
operation = operations.get(method)
|
||||
if not operation:
|
||||
continue
|
||||
request = media_schema(operation.get("requestBody", {}).get("content", {}))
|
||||
responses = operation.get("responses", {})
|
||||
success_code = next((code for code in sorted(responses) if code.startswith("2")), None)
|
||||
response = responses.get(success_code, {})
|
||||
result = media_schema(response.get("content", {}))
|
||||
lines.append(
|
||||
f"| `{method.upper()}` | `{path}` | {cell(operation.get('summary'))} | "
|
||||
f"{cell(request)} | {cell(success_code)}: {cell(result)} |"
|
||||
)
|
||||
|
||||
lines.extend(["", "### Schemas", ""])
|
||||
for name, schema in sorted(spec.get("components", {}).get("schemas", {}).items()):
|
||||
lines.extend([f"#### {name}", ""])
|
||||
if schema.get("description"):
|
||||
lines.extend([schema["description"], ""])
|
||||
properties = schema.get("properties", {})
|
||||
if not properties:
|
||||
lines.extend([f"Type: {schema_type(schema)}", ""])
|
||||
continue
|
||||
required = set(schema.get("required", []))
|
||||
lines.extend(["| Field | Type | Required | Description |", "| --- | --- | --- | --- |"])
|
||||
for field, definition in properties.items():
|
||||
lines.append(
|
||||
f"| `{field}` | {cell(schema_type(definition))} | "
|
||||
f"{'Yes' if field in required else 'No'} | {cell(definition.get('description'))} |"
|
||||
)
|
||||
lines.append("")
|
||||
|
||||
return "\n".join(lines).rstrip() + "\n"
|
||||
|
||||
|
||||
def main():
|
||||
spec = json.loads((ROOT / "openapi.json").read_text(encoding="utf-8"))
|
||||
readme_path = ROOT / "README.md"
|
||||
readme = readme_path.read_text(encoding="utf-8")
|
||||
if readme.count(START) != 1 or readme.count(END) != 1:
|
||||
raise ValueError("README.md must contain one pair of generated API markers")
|
||||
before, remainder = readme.split(START, 1)
|
||||
_, after = remainder.split(END, 1)
|
||||
readme_path.write_text(before + START + "\n" + generate(spec) + END + after, encoding="utf-8")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in new issue
Block a user