SignalWire
view release on metacpan or search on metacpan
porting-sdk/scripts/extract_relay_schemas.py view on Meta::CPAN
inner = m_list.group(1).strip()
return {
"type": "array",
"items": _csharp_type_to_schema(inner, classes, seen),
}
# Container: Dictionary<K, V>
m_dict = re.match(r"^Dictionary<\s*\w+\s*,\s*(.+)>$", t)
if m_dict:
return {
"type": "object",
"additionalProperties": _csharp_type_to_schema(m_dict.group(1).strip(), classes, seen),
}
# Array T[]
if t.endswith("[]"):
inner = t[:-2].strip()
return {
"type": "array",
"items": _csharp_type_to_schema(inner, classes, seen),
}
# Primitive
if t in _PRIMITIVE_TYPE_TO_SCHEMA:
return dict(_PRIMITIVE_TYPE_TO_SCHEMA[t])
# Newtonsoft enum-as-string converters: any enum type becomes string.
if t.endswith("DeviceType") or t.endswith("PlayType") or "DetectType" in t or "AudioDirection" in t or "RecordType" in t:
return {"type": "string"}
# Local class lookup (custom DTO, possibly nested)
if t in classes:
if t in seen:
return {"type": "object"} # break cycle
return _class_to_schema(classes[t], classes, seen | {t})
# Unknown â permissive
return {}
def _class_to_schema(
cls: CSharpClass,
classes: dict[str, CSharpClass],
seen: set[str] | None = None,
) -> dict[str, Any]:
"""Build a JSON-Schema object schema from a parsed C# class."""
seen = seen or set()
properties: dict[str, Any] = {}
required: list[str] = []
for field in cls.fields:
sub = _csharp_type_to_schema(field.csharp_type, classes, seen)
# Mark nullable types explicitly.
if field.nullable:
# JSON-Schema 2020-12: type can be array including "null"
if isinstance(sub.get("type"), str):
sub = dict(sub)
sub["type"] = [sub["type"], "null"]
properties[field.json_name] = sub
if field.required_always:
required.append(field.json_name)
schema: dict[str, Any] = {"type": "object", "properties": properties}
if required:
schema["required"] = required
# We allow additional fields â many params are forward-compat.
schema["additionalProperties"] = True
return schema
def _root_schema(
title: str,
description: str,
payload_schema: dict[str, Any],
extra_meta: dict[str, Any] | None = None,
) -> dict[str, Any]:
"""Wrap an inner payload schema in a top-level JSON-Schema document."""
out: dict[str, Any] = {
"$schema": JSON_SCHEMA_VERSION,
"title": title,
"description": description,
}
if extra_meta:
out.update(extra_meta)
# Fold the payload into the root schema.
for k, v in payload_schema.items():
out[k] = v
return out
# ---------------------------------------------------------------------------
# Method-name mapping (CSharp class basename â RELAY method)
# ---------------------------------------------------------------------------
# Sub-command suffixes that produce dotted method names (e.g.
# ``PublicCallPlayPause`` â ``calling.play.pause``). Listed longest-first so
# ``StartInputTimers`` beats ``Stop``.
_SUBCOMMAND_SUFFIXES: tuple[str, ...] = (
"StartInputTimers",
"Resume",
"Pause",
"Stop",
"Volume",
)
# Hard-coded base names for dotted methods where the base is itself a
# multi-word camel chunk (e.g. ``PublicCallPlayAndCollect`` â ``play_and_collect``,
# whose stop becomes ``play_and_collect.stop``).
_KNOWN_BASE_METHODS: tuple[str, ...] = (
"PlayAndCollect",
"Play",
"Record",
"Detect",
"Collect",
"Pay",
"SendFax",
"ReceiveFax",
"Tap",
"Stream",
"Transcribe",
"Ai",
"Denoise",
"Queue",
)
( run in 0.796 second using v1.01-cache-2.11-cpan-71847e10f99 )