feat(meta-compile): создание внешних источников данных

Вид ExternalDataSource навыки meta-* не поддерживали вовсе: в корпусе выгрузок его нет
ни одного, формат был неизвестен. Разведан на стенде (PostgreSQL в Docker + база 8.3.24)
и по реальной выгрузке рабочего проекта.

meta-compile собирает источник целиком одним JSON: сам источник, его таблицы с полями
и функции. Единственный вид, у которого объект складывается более чем из одного XML —
файл источника плюс по файлу на таблицу в <Источник>/Tables/.

DSL без новых конвенций: tables — dict имя → массив полей ЛИБО объект (как tabularSections),
поле — обычный реквизит плюс три своих ключа (nameInDataSource/readOnly/allowNull),
ссылки на поля короткими именами (как inputByString у справочника), functions — dict
имя → строка ИЛИ объект (как urlTemplates). Параметры функций не объекты метаданных:
они живут в самом выражении как &1, &2.

Инструкция под каскадом: в SKILL.md строка индекса, вся специфика — в
reference/external-data-source.md.

meta-validate принимает ExternalDataSource и Table, знает их наборы GeneratedType,
состав ChildObjects и шестичастную ссылку на форму таблицы. Проверено на выгрузке
платформы и на чужой рабочей выгрузке из другого проекта — обе проходят чисто.

Раундтрип на платформе 8.3.24.1691: наш эмит → загрузка → выгрузка даёт файлы,
идентичные поданным (с точностью до uuid). Два поведения платформы пришлось воспроизвести
явно, оба измерены: ввод по строке выводится из поля представления, а заданное значение
незаполненного родителя платформа при загрузке XML сбрасывает в пустую строку — задать
его можно только интерактивно.

Спека: раздел «Внешние источники данных» в 1c-config-objects-spec.md, формат ссылок,
наборы GeneratedType, строка в индексе спек.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NBsZA5cr2WFThtgp7i5WVi
This commit is contained in:
Nick Shirokov
2026-09-05 20:53:37 +03:00
co-authored by Claude Opus 5
parent c1f07f96ad
commit 6dde36a690
20 changed files with 2071 additions and 39 deletions
@@ -1,4 +1,4 @@
# meta-validate v1.25 — Validate 1C metadata object structure
# meta-validate v1.26 — Validate 1C metadata object structure
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
[CmdletBinding(PositionalBinding=$false)]
param(
@@ -179,7 +179,9 @@ $validTypes = @(
"BusinessProcess","Task","ExchangePlan","DocumentJournal",
"Report","DataProcessor",
"CommonModule","ScheduledJob","EventSubscription",
"HTTPService","WebService","DefinedType"
"HTTPService","WebService","DefinedType",
# Внешний источник данных и его таблица (корень файла таблицы — <Table>).
"ExternalDataSource","Table"
)
# Валидные типы метаданных без глубоких правил валидации — раньше падали как "Unrecognized"
@@ -213,6 +215,9 @@ $generatedTypeCategories = @{
"DataProcessor" = @("Object","Manager")
"DefinedType" = @("DefinedType")
"ExternalDataSource" = @("Manager","TablesManager","CubesManager")
# Таблица внешнего источника: имя элемента трёхчастное (Префикс.Источник.Таблица),
# но проверка «имя оканчивается на .ИмяОбъекта» на нём работает как есть.
"Table" = @("Manager","Object","Ref","List","Record","RecordSet","RecordKey","RecordManager")
}
# Types that have NO InternalInfo / GeneratedType
@@ -274,6 +279,9 @@ $childObjectRules = @{
"DocumentJournal" = @("Column","Form","Template","Command")
"HTTPService" = @("URLTemplate")
"WebService" = @("Operation")
# Внешний источник: таблицы перечислены именами, функции лежат полными узлами.
"ExternalDataSource" = @("Table","Function","Cube")
"Table" = @("Field","Form","Template","Command")
"Constant" = @("Form")
"DefinedType" = @()
"CommonModule" = @()
@@ -296,7 +304,8 @@ $validPropertyValues = @{
"RealTimePosting" = @("Allow","Deny")
"RegisterRecordsDeletion" = @("AutoDelete","AutoDeleteOnUnpost","AutoDeleteOff")
"RegisterRecordsWritingOnPost" = @("WriteModified","WriteSelected","WriteAll")
"DataLockControlMode" = @("Automatic","Managed")
# AutomaticAndManaged — только у внешнего источника данных и его таблиц.
"DataLockControlMode" = @("Automatic","Managed","AutomaticAndManaged")
"FullTextSearch" = @("Use","DontUse")
"DefaultPresentation" = @("AsDescription","AsCode")
"HierarchyType" = @("HierarchyFoldersAndItems","HierarchyOfItems")
@@ -1762,6 +1771,13 @@ if (-not $isAdopted) {
continue
}
# Ссылка на форму таблицы внешнего источника — шестичастная:
# ExternalDataSource.<Источник>.Table.<Таблица>.Form.<Форма>. Сводим её к четырём частям
# (вид = Table, объект = имя таблицы), дальше проверка общая.
if ($parts.Count -eq 6 -and $parts[0] -eq "ExternalDataSource" -and $parts[2] -eq "Table" -and $parts[4] -eq "Form") {
$parts = @("Table", $parts[3], "Form", $parts[5])
}
if ($parts.Count -ne 4 -or $parts[2] -ne "Form") {
Report-Warn "20. $tag '$ref' — неожиданный вид ссылки на форму (ожидается 'CommonForm.Имя' или '<Вид>.<Объект>.Form.<Форма>')"
continue