feat: param_value context — enum/allowed completions for principalType, environmentType etc.
- Add _KNOWN_ENUMS dict (principalType, principalObjectType, environmentType fallbacks) - Add param_value_completion_items() to BicepModuleCatalog - Detect 'param_value' context in _detect_context() (cursor after 'param: ' inside params block) - Wire param_value into _inject_completions() - 9 new unit tests (context detection, catalog allowed, known enum fallback, injection) - Fix modules.py edit regression (param_completion_items was orphaned) - All 35 tests pass
This commit is contained in:
@@ -17,6 +17,11 @@ from typing import Any
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
# Known Azure enum values not always captured in the catalog schema
|
||||
_KNOWN_ENUMS: dict[str, list[str]] = {
|
||||
"principalType": ["User", "Group", "ServicePrincipal", "Device", "ForeignGroup"],
|
||||
}
|
||||
|
||||
# Catalog is baked into the image root at /bicep_modules_catalog.json
|
||||
_CATALOG_PATHS = [
|
||||
pathlib.Path("/data/bicep_modules_catalog.json"), # volume-mount (freshest)
|
||||
@@ -133,6 +138,56 @@ class BicepModuleCatalog:
|
||||
})
|
||||
return items
|
||||
|
||||
@classmethod
|
||||
def param_value_completion_items(
|
||||
cls,
|
||||
module_name: str,
|
||||
version: str,
|
||||
param_name: str,
|
||||
has_open_quote: bool = False,
|
||||
) -> list[dict[str, Any]]:
|
||||
"""Enum/allowed-value completions for a specific param (e.g. principalType, environmentType)."""
|
||||
mod = cls.get_module_by_name(module_name)
|
||||
allowed: list[str] = []
|
||||
|
||||
if mod:
|
||||
schema = mod.get("schema", {})
|
||||
ver_params = schema.get(version, {}).get("parameters", {})
|
||||
if not ver_params:
|
||||
for v in reversed(list(schema.keys())):
|
||||
candidate = schema[v].get("parameters", {})
|
||||
if candidate:
|
||||
ver_params = candidate
|
||||
break
|
||||
param_info = ver_params.get(param_name, {})
|
||||
ptype = param_info.get("type", "")
|
||||
allowed = [str(a) for a in param_info.get("allowed", [])]
|
||||
if not allowed and ptype == "bool":
|
||||
allowed = ["true", "false"]
|
||||
|
||||
# Fallback: known Azure enums not captured in catalog
|
||||
if not allowed:
|
||||
allowed = _KNOWN_ENUMS.get(param_name, [])
|
||||
|
||||
if not allowed:
|
||||
return []
|
||||
|
||||
items = []
|
||||
for i, val in enumerate(allowed):
|
||||
insert = f"{val}'" if has_open_quote else f"'{val}'"
|
||||
items.append({
|
||||
"label": val,
|
||||
"kind": 12, # Value
|
||||
"detail": f"{param_name} value",
|
||||
"insertText": insert,
|
||||
"sortText": f"0_lru_val_{i:03d}_{val}",
|
||||
"documentation": {
|
||||
"kind": "markdown",
|
||||
"value": f"**{val}**\n\nAllowed value for `{param_name}`",
|
||||
},
|
||||
})
|
||||
return items
|
||||
|
||||
@classmethod
|
||||
def param_completion_items(cls, module_name: str, version: str) -> list[dict[str, Any]]:
|
||||
"""Param completions for a specific module+version combination."""
|
||||
|
||||
@@ -127,10 +127,25 @@ class _ProxySession:
|
||||
if params_m:
|
||||
text_in_params = text_after_mod[params_m.start():]
|
||||
if text_in_params.count("{") > text_in_params.count("}"):
|
||||
mod_name = last_mod.group(1)
|
||||
mod_ver = last_mod.group(2)
|
||||
|
||||
# Check if cursor is after 'paramname: ' on the current line
|
||||
# (value context — inject enum/allowed values)
|
||||
value_m = re.search(r"^\s*(\w+):\s*('?)([^'{}]*)$", current)
|
||||
if value_m and value_m.group(1) not in {"params", "name", "module", "resource"}:
|
||||
return {
|
||||
"type": "param_value",
|
||||
"module": mod_name,
|
||||
"version": mod_ver,
|
||||
"param": value_m.group(1),
|
||||
"has_open_quote": bool(value_m.group(2)),
|
||||
}
|
||||
|
||||
return {
|
||||
"type": "param",
|
||||
"module": last_mod.group(1),
|
||||
"version": last_mod.group(2),
|
||||
"module": mod_name,
|
||||
"version": mod_ver,
|
||||
}
|
||||
|
||||
return {"type": "unknown"}
|
||||
@@ -175,6 +190,13 @@ def _inject_completions(msg: dict[str, Any], context: dict | None = None) -> byt
|
||||
lru_items = BicepModuleCatalog.param_completion_items(
|
||||
context["module"], context["version"]
|
||||
)
|
||||
elif ctx_type == "param_value":
|
||||
lru_items = BicepModuleCatalog.param_value_completion_items(
|
||||
context["module"],
|
||||
context["version"],
|
||||
context["param"],
|
||||
context.get("has_open_quote", False),
|
||||
)
|
||||
else:
|
||||
# Default: module name completions
|
||||
lru_items = BicepModuleCatalog.as_completion_items()
|
||||
|
||||
Reference in New Issue
Block a user