From 339c70b457fcb2624f8dabee7e0a5f9316e998a7 Mon Sep 17 00:00:00 2001 From: Nick Shirokov Date: Sun, 7 Jun 2026 22:11:34 +0300 Subject: [PATCH] =?UTF-8?q?feat(form-compile):=20xs:dateTime=20=D0=B2=20?= =?UTF-8?q?=D0=B7=D0=BD=D0=B0=D1=87=D0=B5=D0=BD=D0=B8=D1=8F=D1=85=20=D0=BF?= =?UTF-8?q?=D0=B0=D1=80=D0=B0=D0=BC=D0=B5=D1=82=D1=80=D0=BE=D0=B2=20=D0=B2?= =?UTF-8?q?=D1=8B=D0=B1=D0=BE=D1=80=D0=B0=20/=20choiceList?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Авто-детект 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) --- .claude/skills/form-compile/scripts/form-compile.ps1 | 7 ++++++- .claude/skills/form-compile/scripts/form-compile.py | 6 +++++- docs/form-dsl-spec.md | 2 +- tests/skills/cases/form-compile/input-fields.json | 3 ++- .../ПоляВвода/Forms/Форма/Ext/Form.xml | 12 ++++++++++++ 5 files changed, 26 insertions(+), 4 deletions(-) diff --git a/.claude/skills/form-compile/scripts/form-compile.ps1 b/.claude/skills/form-compile/scripts/form-compile.ps1 index 7479b479..3dc23c8e 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.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: ".[..]" $parts = $s -split '\.' if ($parts.Count -ge 2) { diff --git a/.claude/skills/form-compile/scripts/form-compile.py b/.claude/skills/form-compile/scripts/form-compile.py index 80ab3ef6..f1e11265 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.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] diff --git a/docs/form-dsl-spec.md b/docs/form-dsl-spec.md index 386738b8..6d9f20f2 100644 --- a/docs/form-dsl-spec.md +++ b/docs/form-dsl-spec.md @@ -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`). Синонимы: `путь`/`элементСвязи`. diff --git a/tests/skills/cases/form-compile/input-fields.json b/tests/skills/cases/form-compile/input-fields.json index ddc30d0c..f7b169d8 100644 --- a/tests/skills/cases/form-compile/input-fields.json +++ b/tests/skills/cases/form-compile/input-fields.json @@ -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": "ПолеПодсказка" }, diff --git a/tests/skills/cases/form-compile/snapshots/input-fields/DataProcessors/ПоляВвода/Forms/Форма/Ext/Form.xml b/tests/skills/cases/form-compile/snapshots/input-fields/DataProcessors/ПоляВвода/Forms/Форма/Ext/Form.xml index 17da78fe..c0764df1 100644 --- a/tests/skills/cases/form-compile/snapshots/input-fields/DataProcessors/ПоляВвода/Forms/Форма/Ext/Form.xml +++ b/tests/skills/cases/form-compile/snapshots/input-fields/DataProcessors/ПоляВвода/Forms/Форма/Ext/Form.xml @@ -175,6 +175,12 @@ Основной + + + + 2020-01-01T00:00:00 + + @@ -231,6 +237,12 @@ Основной + + + + 2020-01-01T00:00:00 + +