diff --git a/.claude/skills/form-compile/scripts/form-compile.ps1 b/.claude/skills/form-compile/scripts/form-compile.ps1 index f928f611..ecbc6a28 100644 --- a/.claude/skills/form-compile/scripts/form-compile.ps1 +++ b/.claude/skills/form-compile/scripts/form-compile.ps1 @@ -1,4 +1,4 @@ -# form-compile v1.77 — Compile 1C managed form from JSON or object metadata +# form-compile v1.78 — Compile 1C managed form from JSON or object metadata # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills param( [string]$JsonPath, @@ -2019,10 +2019,12 @@ function Resolve-TypeStr { } function Emit-Type { - param($typeStr, [string]$indent) + # $tag/$tagAttrs — обёртка (по умолчанию ); для уточнения типа значений ValueList + # вызывается с tag="Settings", tagAttrs=' xsi:type="v8:TypeDescription"'. + param($typeStr, [string]$indent, [string]$tag = "Type", [string]$tagAttrs = "") if (-not $typeStr) { - X "$indent" + X "$indent<$tag$tagAttrs/>" return } @@ -2031,12 +2033,12 @@ function Emit-Type { # Composite type: "Type1 | Type2" or "Type1 + Type2" $parts = $typeString -split '\s*[|+]\s*' - X "$indent" + X "$indent<$tag$tagAttrs>" foreach ($part in $parts) { $part = $part.Trim() Emit-SingleType -typeStr $part -indent "$indent`t" } - X "$indent" + X "$indent" } function Emit-SingleType { @@ -4394,6 +4396,15 @@ function Emit-Attributes { } else { X "$inner" } + # valueType: уточнение типа значений ValueList → + # (та же грамматика типа, что и Type, включая составной "A | B"). Forgiving-синонимы. + $vtSpec = $null + foreach ($k in @('valueType','typeDescription','описаниеТипов','типЗначений')) { + if ($attr.PSObject.Properties[$k] -and $attr.$k) { $vtSpec = $attr.$k; break } + } + if ($vtSpec) { + Emit-Type -typeStr "$vtSpec" -indent $inner -tag "Settings" -tagAttrs ' xsi:type="v8:TypeDescription"' + } if ($attr.main -eq $true) { X "$innertrue" diff --git a/.claude/skills/form-compile/scripts/form-compile.py b/.claude/skills/form-compile/scripts/form-compile.py index eca6251f..6a976c30 100644 --- a/.claude/skills/form-compile/scripts/form-compile.py +++ b/.claude/skills/form-compile/scripts/form-compile.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# form-compile v1.77 — Compile 1C managed form from JSON or object metadata +# form-compile v1.78 — Compile 1C managed form from JSON or object metadata # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills import argparse import copy @@ -2894,18 +2894,20 @@ def emit_single_type(lines, type_str, indent): lines.append(f'{indent}{type_str}') -def emit_type(lines, type_str, indent): +def emit_type(lines, type_str, indent, tag="Type", tag_attrs=""): + # tag/tag_attrs — обёртка (по умолчанию ); для valueType ValueList вызывается с + # tag="Settings", tag_attrs=' xsi:type="v8:TypeDescription"'. if not type_str: - lines.append(f'{indent}') + lines.append(f'{indent}<{tag}{tag_attrs}/>') return type_string = str(type_str) parts = [p.strip() for p in re.split(r'[|+]', type_string)] - lines.append(f'{indent}') + lines.append(f'{indent}<{tag}{tag_attrs}>') for part in parts: emit_single_type(lines, part, f'{indent}\t') - lines.append(f'{indent}') + lines.append(f'{indent}') # --- Element emitters --- @@ -4118,6 +4120,15 @@ def emit_attributes(lines, attrs, indent): emit_type(lines, str(attr['type']), inner) else: lines.append(f'{inner}') + # valueType: ОписаниеТипов значений ValueList → + # (та же грамматика типа, включая составной "A | B"). Forgiving-синонимы. + vt_spec = None + for k in ('valueType', 'typeDescription', 'описаниеТипов', 'типЗначений'): + if attr.get(k): + vt_spec = attr[k] + break + if vt_spec: + emit_type(lines, str(vt_spec), inner, tag="Settings", tag_attrs=' xsi:type="v8:TypeDescription"') if attr.get('main') is True: lines.append(f'{inner}true') diff --git a/.claude/skills/form-decompile/scripts/form-decompile.ps1 b/.claude/skills/form-decompile/scripts/form-decompile.ps1 index 1c03e0fe..a3d2aa28 100644 --- a/.claude/skills/form-decompile/scripts/form-decompile.ps1 +++ b/.claude/skills/form-decompile/scripts/form-decompile.ps1 @@ -1,4 +1,4 @@ -# form-decompile v0.53 — Decompile 1C managed Form.xml to JSON DSL (draft) +# form-decompile v0.54 — Decompile 1C managed Form.xml to JSON DSL (draft) # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills # ВНИМАНИЕ: раундтрип не гарантируется. Навык исключён из авто-использования моделью. param( @@ -1672,6 +1672,12 @@ if ($attrsNode) { $ao = [ordered]@{} $ao['name'] = $a.GetAttribute("name") $ty = Decompile-Type ($a.SelectSingleNode("lf:Type", $ns)); if ($ty) { $ao['type'] = $ty } + # valueType: — уточнение типа значений ValueList + # (та же грамматика типа). Дин-список Settings (xsi:type="DynamicList") обрабатывается отдельно. + $setNode = $a.SelectSingleNode("lf:Settings", $ns) + if ($setNode -and $setNode.GetAttribute("type", $NS_XSI) -match 'TypeDescription$') { + $vt = Decompile-Type $setNode; if ($vt) { $ao['valueType'] = $vt } + } if ((Get-Child $a 'MainAttribute') -eq 'true') { $ao['main'] = $true } $vw = Decompile-XrFlag $a 'View'; if ($null -ne $vw) { $ao['view'] = $vw } $ed = Decompile-XrFlag $a 'Edit'; if ($null -ne $ed) { $ao['edit'] = $ed } diff --git a/docs/form-dsl-spec.md b/docs/form-dsl-spec.md index d322c49d..38e52e18 100644 --- a/docs/form-dsl-spec.md +++ b/docs/form-dsl-spec.md @@ -740,6 +740,7 @@ Pages поддерживает `pagesRepresentation`: `None`, `TabsOnTop`, `Tabs | `edit` | bool/object | Редактирование по ролям (``). См. §4.1c | | `functionalOptions` | array | Функциональные опции (`FunctionalOption.X…`). Массив имён; forgiving: `"X"`/`"FunctionalOption.X"`. Также у колонок (`columns[*]`) и команд (§7) | | `useAlways` | array | Поля, всегда читаемые (`Имя.Поле…`). Массив коротких имён полей (forgiving: с/без префикса `Имя.`). **Две формы**: этот массив на реквизите ИЛИ `useAlways: true` на колонке (`columns[*]`) — компилятор сливает. Для дин-списка — только массив (колонки не эмитятся, но формируют ``) | +| `valueType` | string | Тип значений у реквизита типа `ValueList` (``). Грамматика — как у `type`, включая составной `A \| B`. Forgiving-синонимы: `typeDescription` (≈1С «ОписаниеТипов» / XML), `описаниеТипов`, `типЗначений`. Пример: `"valueType": "CatalogRef.Контрагенты"` | | `savedData` | bool | Сохраняемые данные (``) | | `save` | bool/string/array | Сохранение значения в пользовательских настройках (`…`). `true` → `имя`; строка/массив строк → под-поля с авто-префиксом `имя.` (путь с точкой / UUID `1/0:…` / совпадающее с именем — берётся как есть). Нет ключа или `false` → не эмитится. Пример периода: `["Период","EndDate","StartDate","Variant"]` | | `fillChecking` | string | `Show`, `DontShow` | diff --git a/tests/skills/cases/form-compile/attributes-types.json b/tests/skills/cases/form-compile/attributes-types.json index ac1e5cc2..8ea29a99 100644 --- a/tests/skills/cases/form-compile/attributes-types.json +++ b/tests/skills/cases/form-compile/attributes-types.json @@ -28,7 +28,7 @@ { "name": "Дата", "type": "dateTime", "title": "" }, { "name": "Булево", "type": "boolean" }, { "name": "Период", "type": "СтандартныйПериод", "save": ["Период", "EndDate", "StartDate", "Variant"] }, - { "name": "СписокЗначений", "type": "ValueList" }, + { "name": "СписокЗначений", "type": "ValueList", "valueType": "string(50) | decimal(10,2)" }, { "name": "Идентификатор", "type": "v8:UUID" } ] } diff --git a/tests/skills/cases/form-compile/snapshots/attributes-types/DataProcessors/Типы/Forms/Форма/Ext/Form.xml b/tests/skills/cases/form-compile/snapshots/attributes-types/DataProcessors/Типы/Forms/Форма/Ext/Form.xml index 7e1dd215..30bdade6 100644 --- a/tests/skills/cases/form-compile/snapshots/attributes-types/DataProcessors/Типы/Forms/Форма/Ext/Form.xml +++ b/tests/skills/cases/form-compile/snapshots/attributes-types/DataProcessors/Типы/Forms/Форма/Ext/Form.xml @@ -126,6 +126,19 @@ v8:ValueListType + + xs:string + + 50 + Variable + + xs:decimal + + 10 + 2 + Any + +