From 11e7abfc3fcae71b7792b22797cf212851205db7 Mon Sep 17 00:00:00 2001 From: Nick Shirokov Date: Mon, 6 Jul 2026 12:55:08 +0300 Subject: [PATCH] =?UTF-8?q?feat(meta-compile,meta-decompile):=20=D1=81?= =?UTF-8?q?=D0=BE=D1=81=D1=82=D0=B0=D0=B2=20=D0=BF=D0=BB=D0=B0=D0=BD=D0=B0?= =?UTF-8?q?=20=D0=BE=D0=B1=D0=BC=D0=B5=D0=BD=D0=B0=20=E2=80=94=20Content.x?= =?UTF-8?q?ml=20(v1.42/v0.31)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Соседний Ext/Content.xml (состав плана обмена: объекты-участники + признак авторегистрации) был вне скоупа раундтрипа → при декомпиляции→компиляции состав терялся (компилятор писал пустой , декомпилятор не захватывал). DSL content/Состав: массив MDObjectRef — строка "Type.Name" (AutoRecord=Deny, дефолт) / "Type.Name: autoRecord" (Allow; токен-признак autoRecord/АвтоРегистрация, регистронезав.; прощающе : Allow/: Разрешить) ЛИБО объект {metadata, autoRecord: bool|Allow/Deny/Разрешить/Запретить} (синонимы Метаданные/объект, АвтоРегистрация). Декомпилятор пишет короткую строковую форму. Class-2 фикс заголовка: пустой писался с 2 namespace, реальный 1С — с 4 (+xmlns:xs/xsi); чинил и пустой шаблон. Роундтрип 42 ЭП (acc+erp): match 39/42, TOTAL 146 без новых диффов (остаток — известный хвост TS-LineNumber/FillValue-пробелы). Регресс 48/48 ps1+py, ps1↔py identical. 1С-cert ✓ (пустой 4-ns корень + непустой состав); verify-snapshots расширен: getStructuralDeps стабит объекты состава ЭП по MDObjectRef + стаб Constant. spec §7.2a, кейс exchange-plan-content. Co-Authored-By: Claude Opus 4.8 (1M context) --- .../meta-compile/scripts/meta-compile.ps1 | 46 +++- .../meta-compile/scripts/meta-compile.py | 57 +++- .../meta-decompile/scripts/meta-decompile.ps1 | 23 +- docs/meta-dsl-spec.md | 16 +- .../meta-compile/exchange-plan-content.json | 23 ++ .../exchange-plan-content/Configuration.xml | 252 ++++++++++++++++++ .../ExchangePlans/ОбменСФилиаламиСоставом.xml | 78 ++++++ .../ОбменСФилиаламиСоставом/Ext/Content.xml | 27 ++ .../Ext/ObjectModule.bsl | 0 .../Ext/ClientApplicationInterface.xml | 18 ++ .../Languages/Русский.xml | 16 ++ .../ОбменСФилиалами/Ext/Content.xml | 2 +- tests/skills/verify-snapshots.mjs | 18 ++ 13 files changed, 567 insertions(+), 9 deletions(-) create mode 100644 tests/skills/cases/meta-compile/exchange-plan-content.json create mode 100644 tests/skills/cases/meta-compile/snapshots/exchange-plan-content/Configuration.xml create mode 100644 tests/skills/cases/meta-compile/snapshots/exchange-plan-content/ExchangePlans/ОбменСФилиаламиСоставом.xml create mode 100644 tests/skills/cases/meta-compile/snapshots/exchange-plan-content/ExchangePlans/ОбменСФилиаламиСоставом/Ext/Content.xml create mode 100644 tests/skills/cases/meta-compile/snapshots/exchange-plan-content/ExchangePlans/ОбменСФилиаламиСоставом/Ext/ObjectModule.bsl create mode 100644 tests/skills/cases/meta-compile/snapshots/exchange-plan-content/Ext/ClientApplicationInterface.xml create mode 100644 tests/skills/cases/meta-compile/snapshots/exchange-plan-content/Languages/Русский.xml diff --git a/.claude/skills/meta-compile/scripts/meta-compile.ps1 b/.claude/skills/meta-compile/scripts/meta-compile.ps1 index 1fff40a8..7c43c405 100644 --- a/.claude/skills/meta-compile/scripts/meta-compile.ps1 +++ b/.claude/skills/meta-compile/scripts/meta-compile.ps1 @@ -1,4 +1,4 @@ -# meta-compile v1.41 — Compile 1C metadata object from JSON +# meta-compile v1.42 — Compile 1C metadata object from JSON # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills param( [Parameter(Mandatory)] @@ -4037,11 +4037,51 @@ if ($objType -in $typesWithModule) { } # Special files +# --- Состав плана обмена (ExchangePlan, Ext/Content.xml). Ключ `content`/`Состав`: +# [ "MDRef" (AutoRecord=Deny, дефолт) | "MDRef: autoRecord" (Allow) | {metadata, autoRecord} ]. +# Токен-признак autoRecord/АвтоРегистрация (или Allow/Разрешить) → авторегистрация вкл. Метаданные — MDObjectRef verbatim. --- +function Parse-ExchangeContentItem($entry) { + if ($entry -is [string]) { + $s = "$entry"; $ref = $s; $ar = 'Deny' + $ci = $s.LastIndexOf(':') + if ($ci -ge 0) { + $ref = $s.Substring(0, $ci).Trim() + $flag = $s.Substring($ci + 1).Trim() + if ($flag -match '^(autoRecord|АвтоРегистрация|Allow|Разрешить)$') { $ar = 'Allow' } + elseif ($flag -match '^(Deny|Запретить)$') { $ar = 'Deny' } + } + return @{ metadata = $ref.Trim(); autoRecord = $ar } + } + $ref = if ($null -ne $entry.metadata) { "$($entry.metadata)" } elseif ($null -ne $entry.Метаданные) { "$($entry.Метаданные)" } elseif ($null -ne $entry.объект) { "$($entry.объект)" } else { '' } + $rawAr = if ($null -ne $entry.autoRecord) { $entry.autoRecord } elseif ($null -ne $entry.АвтоРегистрация) { $entry.АвтоРегистрация } else { $false } + $ar = 'Deny' + if ($rawAr -is [bool]) { if ($rawAr) { $ar = 'Allow' } } + elseif ("$rawAr" -match '^(Allow|Разрешить|true|autoRecord|АвтоРегистрация)$') { $ar = 'Allow' } + return @{ metadata = $ref.Trim(); autoRecord = $ar } +} if ($objType -eq "ExchangePlan") { $contentPath = Join-Path $extDir "Content.xml" - if (-not (Test-Path $contentPath)) { + $xepNs = 'xmlns="http://v8.1c.ru/8.3/xcf/extrnprops" xmlns:xr="http://v8.1c.ru/8.3/xcf/readable" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"' + $cItems = @() + $cSrc = if ($null -ne $def.content) { $def.content } elseif ($null -ne $def.Состав) { $def.Состав } else { $null } + if ($cSrc) { foreach ($e in @($cSrc)) { $it = Parse-ExchangeContentItem $e; if ($it.metadata) { $cItems += $it } } } + if ($cItems.Count -gt 0) { Ensure-ExtDir - $contentXml = "`r`n`r`n" + $sbC = New-Object System.Text.StringBuilder + [void]$sbC.Append("`r`n") + [void]$sbC.Append("`r`n") + foreach ($it in $cItems) { + [void]$sbC.Append("`t`r`n") + [void]$sbC.Append("`t`t$(Esc-Xml $it.metadata)`r`n") + [void]$sbC.Append("`t`t$($it.autoRecord)`r`n") + [void]$sbC.Append("`t`r`n") + } + [void]$sbC.Append("`r`n") + [System.IO.File]::WriteAllText($contentPath, $sbC.ToString(), $enc) + $modulesCreated += $contentPath + } elseif (-not (Test-Path $contentPath)) { + Ensure-ExtDir + $contentXml = "`r`n`r`n" [System.IO.File]::WriteAllText($contentPath, $contentXml, $enc) $modulesCreated += $contentPath } diff --git a/.claude/skills/meta-compile/scripts/meta-compile.py b/.claude/skills/meta-compile/scripts/meta-compile.py index d7338c45..d42417e6 100644 --- a/.claude/skills/meta-compile/scripts/meta-compile.py +++ b/.claude/skills/meta-compile/scripts/meta-compile.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# meta-compile v1.41 — Compile 1C metadata object from JSON +# meta-compile v1.42 — Compile 1C metadata object from JSON # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills import argparse @@ -3810,11 +3810,62 @@ def build_predefined_calc_type_xml(items): return '\n'.join(out) + '\n' # Special files +# --- Состав плана обмена (ExchangePlan, Ext/Content.xml). Ключ `content`/`Состав`: +# [ "MDRef" (AutoRecord=Deny, дефолт) | "MDRef: autoRecord" (Allow) | {metadata, autoRecord} ]. --- +def parse_exchange_content_item(entry): + if isinstance(entry, str): + ref, ar = entry, 'Deny' + ci = entry.rfind(':') + if ci >= 0: + ref = entry[:ci].strip() + flag = entry[ci + 1:].strip() + if re.match(r'^(autoRecord|АвтоРегистрация|Allow|Разрешить)$', flag, re.I): + ar = 'Allow' + elif re.match(r'^(Deny|Запретить)$', flag, re.I): + ar = 'Deny' + return {'metadata': ref.strip(), 'autoRecord': ar} + ref = '' + for k in ('metadata', 'Метаданные', 'объект'): + if entry.get(k) is not None: + ref = str(entry[k]); break + raw_ar = entry.get('autoRecord') + if raw_ar is None: + raw_ar = entry.get('АвтоРегистрация') + ar = 'Deny' + if isinstance(raw_ar, bool): + if raw_ar: + ar = 'Allow' + elif raw_ar is not None and re.match(r'^(Allow|Разрешить|true|autoRecord|АвтоРегистрация)$', str(raw_ar), re.I): + ar = 'Allow' + return {'metadata': ref.strip(), 'autoRecord': ar} + if obj_type == 'ExchangePlan': content_path = os.path.join(ext_dir, 'Content.xml') - if not os.path.isfile(content_path): + xep_ns = 'xmlns="http://v8.1c.ru/8.3/xcf/extrnprops" xmlns:xr="http://v8.1c.ru/8.3/xcf/readable" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"' + c_src = defn.get('content') + if c_src is None: + c_src = defn.get('Состав') + c_items = [] + if c_src: + for e in (c_src if isinstance(c_src, list) else [c_src]): + it = parse_exchange_content_item(e) + if it['metadata']: + c_items.append(it) + if c_items: ensure_ext_dir() - content_xml = f'\r\n\r\n' + parts = ['\r\n', + f'\r\n'] + for it in c_items: + parts.append('\t\r\n') + parts.append(f'\t\t{esc_xml(it["metadata"])}\r\n') + parts.append(f'\t\t{it["autoRecord"]}\r\n') + parts.append('\t\r\n') + parts.append('\r\n') + write_utf8_bom(content_path, ''.join(parts)) + modules_created.append(content_path) + elif not os.path.isfile(content_path): + ensure_ext_dir() + content_xml = f'\r\n\r\n' write_utf8_bom(content_path, content_xml) modules_created.append(content_path) diff --git a/.claude/skills/meta-decompile/scripts/meta-decompile.ps1 b/.claude/skills/meta-decompile/scripts/meta-decompile.ps1 index eac519dd..64c1199a 100644 --- a/.claude/skills/meta-decompile/scripts/meta-decompile.ps1 +++ b/.claude/skills/meta-decompile/scripts/meta-decompile.ps1 @@ -1,4 +1,4 @@ -# meta-decompile v0.30 — XML объекта метаданных 1С → JSON-черновик формата meta-compile +# meta-decompile v0.31 — XML объекта метаданных 1С → JSON-черновик формата meta-compile # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills # # Поддержаны: Catalog, ExchangePlan, ChartOfCharacteristicTypes, ChartOfAccounts. Инверс meta-compile (omit-on-default: ключ эмитим только @@ -898,6 +898,27 @@ if (Test-Path -LiteralPath $predefPath) { if ($rootItems.Count -gt 0) { $dsl['predefined'] = $rootItems } } +# --- Состав плана обмена (соседний Ext/Content.xml) → DSL content (ExchangePlan). +# Каждый {MDRefDeny|Allow}. +# Deny (дефолт) → строка "MDRef"; Allow → "MDRef: autoRecord". --- +if ($objType -eq 'ExchangePlan') { + $contentPath = Join-Path (Join-Path (Join-Path $objDir $objName) 'Ext') 'Content.xml' + if (Test-Path -LiteralPath $contentPath) { + $cdoc = New-Object System.Xml.XmlDocument + $cdoc.Load($contentPath) + $contentItems = [System.Collections.ArrayList]@() + foreach ($it in @($cdoc.DocumentElement.SelectNodes("*[local-name()='Item']"))) { + $mdEl = $it.SelectSingleNode("*[local-name()='Metadata']") + if (-not $mdEl -or -not $mdEl.InnerText) { continue } + $ref = $mdEl.InnerText + $arEl = $it.SelectSingleNode("*[local-name()='AutoRecord']") + $ar = if ($arEl) { $arEl.InnerText } else { 'Deny' } + if ($ar -eq 'Allow') { [void]$contentItems.Add("${ref}: autoRecord") } else { [void]$contentItems.Add($ref) } + } + if ($contentItems.Count -gt 0) { $dsl['content'] = $contentItems } + } +} + # === Вывод === $json = ConvertTo-CompactJson $dsl 0 if ($OutputPath) { diff --git a/docs/meta-dsl-spec.md b/docs/meta-dsl-spec.md index 1291444b..692cd71c 100644 --- a/docs/meta-dsl-spec.md +++ b/docs/meta-dsl-spec.md @@ -619,6 +619,20 @@ omit-on-empty. Поля пишутся частичной формой (`Standar ключ `standardAttributes`. Опциональный легаси-реквизит `ExchangeDate` (часть планов) поддержан как «доп.» член `standardAttributes` (эмитится по факту наличия ключа, вне фикс-списка). +**Состав плана обмена** (`content`, синоним `Состав`) — соседний `Ext/Content.xml`: список объектов-участников обмена, +у каждого признак авторегистрации изменений на узле (AutoRecord: `Deny`=запрещена, дефолт; `Allow`=разрешена). Элемент — +MDObjectRef (`Catalog.X`/`Document.Y`/`InformationRegister.Z`/`Constant.W`/…), пишется verbatim. + +| Форма записи | Смысл | +|--------------|-------| +| `"Catalog.Организации"` | AutoRecord=Deny (авторегистрация выкл — дефолт) | +| `"InformationRegister.Курсы: autoRecord"` | AutoRecord=Allow — токен-признак `autoRecord`/`АвтоРегистрация` (регистронезависимо; принимается и `: Allow`/`: Разрешить`) | +| `{ "metadata": "Document.РеализацияТоваров", "autoRecord": true }` | объектная форма: `autoRecord` — boolean (`true`=Allow) ИЛИ строка `Allow`/`Deny`/`Разрешить`/`Запретить` | + +Синонимы ключей объектной формы: `metadata` → `Метаданные`/`объект`, `autoRecord` → `АвтоРегистрация`. Дефолт `Deny` в +строке опускается. Пустой/отсутствующий `content` → пустой ``. Декомпилятор пишет короткую строковую +форму (`"Ref"` для Deny, `"Ref: autoRecord"` для Allow). Порядок элементов платформенно-произвольный (1С толерантна). + ### 7.2b ChartOfCharacteristicTypes (План видов характеристик) Иерархический ссылочный тип (папки+элементы, без уровней/подчинения). Общий с Catalog слой: `synonym`, `comment`, @@ -924,7 +938,7 @@ Split-CamelCase имени. | `tabularSections` | `{}` | → TabularSection в ChildObjects | Модули: `Ext/ObjectModule.bsl` (пустой). -Дополнительно: `Ext/Content.xml` (пустой шаблон). +Дополнительно: `Ext/Content.xml` — состав плана обмена (ключ `content`/`Состав`, см. §7.2a; пустой, если не задан). ```json { "type": "ExchangePlan", "name": "ОбменССайтом", "attributes": ["АдресСервера: String(200)"] } diff --git a/tests/skills/cases/meta-compile/exchange-plan-content.json b/tests/skills/cases/meta-compile/exchange-plan-content.json new file mode 100644 index 00000000..1d8ef3a4 --- /dev/null +++ b/tests/skills/cases/meta-compile/exchange-plan-content.json @@ -0,0 +1,23 @@ +{ + "name": "План обмена с составом (content)", + "input": { + "type": "ExchangePlan", + "name": "ОбменСФилиаламиСоставом", + "comment": "обмен с явным составом", + "content": [ + "Catalog.Организации", + "InformationRegister.Курсы: autoRecord", + "Document.РеализацияТоваров: АвтоРегистрация", + { "metadata": "Catalog.Номенклатура", "autoRecord": true }, + { "Метаданные": "Constant.ВалютаУчета", "АвтоРегистрация": "Разрешить" }, + { "metadata": "InformationRegister.ЦеныНоменклатуры", "autoRecord": false } + ] + }, + "validatePath": "ExchangePlans/ОбменСФилиаламиСоставом", + "expect": { + "files": [ + "ExchangePlans/ОбменСФилиаламиСоставом.xml", + "ExchangePlans/ОбменСФилиаламиСоставом/Ext/Content.xml" + ] + } +} diff --git a/tests/skills/cases/meta-compile/snapshots/exchange-plan-content/Configuration.xml b/tests/skills/cases/meta-compile/snapshots/exchange-plan-content/Configuration.xml new file mode 100644 index 00000000..314d82b6 --- /dev/null +++ b/tests/skills/cases/meta-compile/snapshots/exchange-plan-content/Configuration.xml @@ -0,0 +1,252 @@ + + + + + + UUID-002 + UUID-003 + + + UUID-004 + UUID-005 + + + UUID-006 + UUID-007 + + + UUID-008 + UUID-009 + + + UUID-010 + UUID-011 + + + UUID-012 + UUID-013 + + + UUID-014 + UUID-015 + + + + TestConfig + + + ru + TestConfig + + + + + Version8_3_24 + ManagedApplication + + PlatformApplication + + Russian + + + + + false + false + false + + + + + + + + + + + + + + + + + + + + + + Biometrics + true + + + Location + false + + + BackgroundLocation + false + + + BluetoothPrinters + false + + + WiFiPrinters + false + + + Contacts + false + + + Calendars + false + + + PushNotifications + false + + + LocalNotifications + false + + + InAppPurchases + false + + + PersonalComputerFileExchange + false + + + Ads + false + + + NumberDialing + false + + + CallProcessing + false + + + CallLog + false + + + AutoSendSMS + false + + + ReceiveSMS + false + + + SMSLog + false + + + Camera + false + + + Microphone + false + + + MusicLibrary + false + + + PictureAndVideoLibraries + false + + + AudioPlaybackAndVibration + false + + + BackgroundAudioPlaybackAndVibration + false + + + InstallPackages + false + + + OSBackup + true + + + ApplicationUsageStatistics + false + + + BarcodeScanning + false + + + BackgroundAudioRecording + false + + + AllFilesAccess + false + + + Videoconferences + false + + + NFC + false + + + DocumentScanning + false + + + SpeechToText + false + + + Geofences + false + + + IncomingShareRequests + false + + + AllIncomingShareRequestsTypesProcessing + false + + + + + + Normal + + + Language.Русский + + + + + + Managed + NotAutoFree + DontUse + DontUse + TaxiEnableVersion8_2 + DontUse + Version8_3_24 + + + + Русский + ОбменСФилиаламиСоставом + + + \ No newline at end of file diff --git a/tests/skills/cases/meta-compile/snapshots/exchange-plan-content/ExchangePlans/ОбменСФилиаламиСоставом.xml b/tests/skills/cases/meta-compile/snapshots/exchange-plan-content/ExchangePlans/ОбменСФилиаламиСоставом.xml new file mode 100644 index 00000000..2b87c866 --- /dev/null +++ b/tests/skills/cases/meta-compile/snapshots/exchange-plan-content/ExchangePlans/ОбменСФилиаламиСоставом.xml @@ -0,0 +1,78 @@ + + + + + UUID-002 + + UUID-003 + UUID-004 + + + UUID-005 + UUID-006 + + + UUID-007 + UUID-008 + + + UUID-009 + UUID-010 + + + UUID-011 + UUID-012 + + + + ОбменСФилиаламиСоставом + + + ru + Обмен сфилиалами составом + + + обмен с явным составом + true + 9 + Variable + 150 + AsDescription + InDialog + false + BothWays + + ExchangePlan.ОбменСФилиаламиСоставом.StandardAttribute.Description + ExchangePlan.ОбменСФилиаламиСоставом.StandardAttribute.Code + + Begin + DontUse + Directly + + + + + + + + + false + false + DontUse + Auto + false + + Managed + Use + + + + + + DontUse + false + false + + + + diff --git a/tests/skills/cases/meta-compile/snapshots/exchange-plan-content/ExchangePlans/ОбменСФилиаламиСоставом/Ext/Content.xml b/tests/skills/cases/meta-compile/snapshots/exchange-plan-content/ExchangePlans/ОбменСФилиаламиСоставом/Ext/Content.xml new file mode 100644 index 00000000..1853dcdf --- /dev/null +++ b/tests/skills/cases/meta-compile/snapshots/exchange-plan-content/ExchangePlans/ОбменСФилиаламиСоставом/Ext/Content.xml @@ -0,0 +1,27 @@ + + + + Catalog.Организации + Deny + + + InformationRegister.Курсы + Allow + + + Document.РеализацияТоваров + Allow + + + Catalog.Номенклатура + Allow + + + Constant.ВалютаУчета + Allow + + + InformationRegister.ЦеныНоменклатуры + Deny + + diff --git a/tests/skills/cases/meta-compile/snapshots/exchange-plan-content/ExchangePlans/ОбменСФилиаламиСоставом/Ext/ObjectModule.bsl b/tests/skills/cases/meta-compile/snapshots/exchange-plan-content/ExchangePlans/ОбменСФилиаламиСоставом/Ext/ObjectModule.bsl new file mode 100644 index 00000000..e69de29b diff --git a/tests/skills/cases/meta-compile/snapshots/exchange-plan-content/Ext/ClientApplicationInterface.xml b/tests/skills/cases/meta-compile/snapshots/exchange-plan-content/Ext/ClientApplicationInterface.xml new file mode 100644 index 00000000..3c1161b2 --- /dev/null +++ b/tests/skills/cases/meta-compile/snapshots/exchange-plan-content/Ext/ClientApplicationInterface.xml @@ -0,0 +1,18 @@ + + + + + UUID-002 + + + + + UUID-004 + + + + + + + + \ No newline at end of file diff --git a/tests/skills/cases/meta-compile/snapshots/exchange-plan-content/Languages/Русский.xml b/tests/skills/cases/meta-compile/snapshots/exchange-plan-content/Languages/Русский.xml new file mode 100644 index 00000000..37c60d78 --- /dev/null +++ b/tests/skills/cases/meta-compile/snapshots/exchange-plan-content/Languages/Русский.xml @@ -0,0 +1,16 @@ + + + + + Русский + + + ru + Русский + + + + ru + + + \ No newline at end of file diff --git a/tests/skills/cases/meta-compile/snapshots/exchange-plan/ExchangePlans/ОбменСФилиалами/Ext/Content.xml b/tests/skills/cases/meta-compile/snapshots/exchange-plan/ExchangePlans/ОбменСФилиалами/Ext/Content.xml index 2da0f71a..7b07428d 100644 --- a/tests/skills/cases/meta-compile/snapshots/exchange-plan/ExchangePlans/ОбменСФилиалами/Ext/Content.xml +++ b/tests/skills/cases/meta-compile/snapshots/exchange-plan/ExchangePlans/ОбменСФилиалами/Ext/Content.xml @@ -1,2 +1,2 @@ - + diff --git a/tests/skills/verify-snapshots.mjs b/tests/skills/verify-snapshots.mjs index dd13b7e5..38c5c0ab 100644 --- a/tests/skills/verify-snapshots.mjs +++ b/tests/skills/verify-snapshots.mjs @@ -177,6 +177,23 @@ function getStructuralDeps(input) { } } break; + case 'ExchangePlan': + // Состав плана обмена (Content.xml) ссылается на объекты по MDObjectRef "Type.Name" — + // 1С требует их существования при загрузке. Стабим каждый. + if (inp.content) { + const entries = Array.isArray(inp.content) ? inp.content : [inp.content]; + for (const e of entries) { + let ref = typeof e === 'string' ? e : (e.metadata || e['Метаданные'] || e['объект'] || ''); + ref = String(ref).split(':')[0].trim(); // отбросить ": autoRecord"/флаг + const dot = ref.indexOf('.'); + if (dot < 0) continue; + const t = ref.substring(0, dot); + const n = ref.substring(dot + 1); + const dsl = makeStubDSL(t, n); + if (dsl) deps.push({ type: t, name: n, dsl }); + } + } + break; } } return deps; @@ -189,6 +206,7 @@ function makeStubDSL(type, name) { case 'Catalog': return { type: 'Catalog', name }; case 'Document': return { type: 'Document', name }; case 'Enum': return { type: 'Enum', name, values: ['Значение1'] }; + case 'Constant': return { type: 'Constant', name, valueType: 'Boolean' }; case 'InformationRegister': return { type: 'InformationRegister', name, dimensions: ['Ключ: String(10)'] }; case 'AccumulationRegister': return { type: 'AccumulationRegister', name, dimensions: ['Ключ: String(10)'], resources: ['Значение: Number(15,2)'] }; case 'ChartOfAccounts': return { type: 'ChartOfAccounts', name, codeLength: 4, descriptionLength: 100, maxExtDimensionCount: 0 };