feat(form-compile): xs:dateTime в значениях параметров выбора / choiceList

Авто-детект ISO-datetime (^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}$) в
Normalize-ChoiceValue → xs:dateTime вместо xs:string. Без изменения DSL:
декомпилятор уже отдаёт строку, компилятор распознаёт формат. Заодно
исправляет choiceList со значениями-датами (та же FormChoiceListDesTimeValue).

Round-trip бит-в-бит на 3 формах с датами в параметрах выбора. Кейс
input-fields: Отбор.Дата в объектной и короткой формах; снэпшот
сертифицирован загрузкой в 1С. Закрывает микро-хвост кластера ChoiceParameters.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Nick Shirokov
2026-06-07 22:11:34 +03:00
co-authored by Claude Opus 4.8
parent 65f63fbc48
commit 339c70b457
5 changed files with 26 additions and 4 deletions
@@ -1,4 +1,4 @@
# form-compile v1.69 — Compile 1C managed form from JSON or object metadata
# form-compile v1.70 — Compile 1C managed form from JSON or object metadata
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
param(
[string]$JsonPath,
@@ -3049,6 +3049,11 @@ function Normalize-ChoiceValue {
return @{ XsiType = "xs:string"; Text = "" }
}
# ISO datetime ("2020-01-01T00:00:00") → xs:dateTime
if ($s -match '^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}$') {
return @{ XsiType = "xs:dateTime"; Text = $s }
}
# Try to detect typed reference path: "<Root>.<Type>[.<Member>.<Value>]"
$parts = $s -split '\.'
if ($parts.Count -ge 2) {
@@ -1,5 +1,5 @@
#!/usr/bin/env python3
# form-compile v1.69 — Compile 1C managed form from JSON or object metadata
# form-compile v1.70 — Compile 1C managed form from JSON or object metadata
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
import argparse
import copy
@@ -1911,6 +1911,10 @@ def normalize_choice_value(value):
if not s:
return {"xsi_type": "xs:string", "text": ""}
# ISO datetime ("2020-01-01T00:00:00") → xs:dateTime
if re.fullmatch(r'\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}', s):
return {"xsi_type": "xs:dateTime", "text": s}
parts = s.split(".")
if len(parts) >= 2:
root = parts[0]
+1 -1
View File
@@ -386,7 +386,7 @@ companion-панели с собственным контентом. Оба не
}
```
- **`choiceParameters`** — `[{ name, value }]`. `value` через ту же нормализацию, что `choiceList`: bool / число / строка / ссылка-путь (`Enum.X.Y`, `Catalog.X` и синонимы `Перечисление.`/`Справочник.`). **Массив** значений → фиксированный массив (`FixedArray`). Синонимы ключей: `имя`/`значение`.
- **`choiceParameters`** — `[{ name, value }]`. `value` через ту же нормализацию, что `choiceList`: bool / число / строка / ISO-дата (`2020-01-01T00:00:00``xs:dateTime`) / ссылка-путь (`Enum.X.Y`, `Catalog.X` и синонимы `Перечисление.`/`Справочник.`). **Массив** значений → фиксированный массив (`FixedArray`). Синонимы ключей: `имя`/`значение`.
- **`choiceParameterLinks`** — `[{ name, dataPath, valueChange? }]`. `valueChange`: `Clear` (дефолт, опускается) / `DontChange`; forgiving `очистить`/`неизменять`. Синонимы: `имя`/`путь`/`режимИзменения`.
- **`typeLink`** — `{ dataPath, linkItem }`. `linkItem` — индекс (дефолт `0`). Синонимы: `путь`/`элементСвязи`.
@@ -30,6 +30,7 @@
"choiceParameters": [
{ "name": "Отбор.Активный", "value": true },
{ "name": "Отбор.Вид", "value": "Основной" },
{ "name": "Отбор.Дата", "value": "2020-01-01T00:00:00" },
{ "name": "Отбор.Список", "value": ["Один", "Два"] }
],
"choiceParameterLinks": [
@@ -39,7 +40,7 @@
"typeLink": { "dataPath": "ПолеПодсказка", "linkItem": 0 }
},
{ "input": "ПолеСвязиКратко", "path": "ПолеСвязиКратко", "title": "Связи (короткая форма)",
"choiceParameters": [ "Отбор.Активный=true", "Отбор.Вид=Основной", "Отбор.Список=Один, Два" ],
"choiceParameters": [ "Отбор.Активный=true", "Отбор.Вид=Основной", "Отбор.Дата=2020-01-01T00:00:00", "Отбор.Список=Один, Два" ],
"choiceParameterLinks": [ "Отбор.Организация=ОбычноеПоле", "Отбор.Тип=ПолеСписокВыбора:DontChange" ],
"typeLink": "ПолеПодсказка"
},
@@ -175,6 +175,12 @@
<Value xsi:type="xs:string">Основной</Value>
</app:value>
</app:item>
<app:item name="Отбор.Дата">
<app:value xsi:type="FormChoiceListDesTimeValue">
<Presentation/>
<Value xsi:type="xs:dateTime">2020-01-01T00:00:00</Value>
</app:value>
</app:item>
<app:item name="Отбор.Список">
<app:value xsi:type="FormChoiceListDesTimeValue">
<Presentation/>
@@ -231,6 +237,12 @@
<Value xsi:type="xs:string">Основной</Value>
</app:value>
</app:item>
<app:item name="Отбор.Дата">
<app:value xsi:type="FormChoiceListDesTimeValue">
<Presentation/>
<Value xsi:type="xs:dateTime">2020-01-01T00:00:00</Value>
</app:value>
</app:item>
<app:item name="Отбор.Список">
<app:value xsi:type="FormChoiceListDesTimeValue">
<Presentation/>