diff --git a/.claude/skills/meta-compile/scripts/meta-compile.ps1 b/.claude/skills/meta-compile/scripts/meta-compile.ps1
index 08e6f3bb..d9572024 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.20 — Compile 1C metadata object from JSON
+# meta-compile v1.21 — Compile 1C metadata object from JSON
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
param(
[Parameter(Mandatory)]
@@ -561,10 +561,9 @@ function Emit-TypeContent {
return
}
- # DefinedType
- if ($typeStr -match '^DefinedType\.(.+)$') {
- $dtName = $Matches[1]
- X "$indentcfg:DefinedType.$dtName"
+ # TypeSet — тип-множество: ОпределяемыйТип (DefinedType) ИЛИ Характеристика ПВХ (Characteristic).
+ if ($typeStr -match '^(DefinedType|Characteristic)\.(.+)$') {
+ X "$indentcfg:$typeStr"
return
}
@@ -826,6 +825,7 @@ function Parse-AttributeShorthand {
mask = if ($val.mask) { "$($val.mask)" } else { "" }
hasFillValue = ($val.PSObject -and $val.PSObject.Properties -and ($val.PSObject.Properties.Name -contains 'fillValue'))
fillValue = $val.fillValue
+ linkByType = $val.linkByType
}
}
@@ -1136,6 +1136,24 @@ $script:reservedByContext = @{
"document" = @("Ref","DeletionMark","Date","Number","Posted")
}
+# (связь по типу — тип значения реквизита-Характеристики определяется другим реквизитом).
+# Структура как формы: DataPath + LinkItem. DSL `linkByType`: {dataPath, linkItem?} ИЛИ строка-путь.
+# Нет ключа → (пусто).
+function Emit-LinkByType {
+ param([string]$indent, $spec)
+ if (-not $spec) { X "$indent"; return }
+ if ($spec -is [string]) { $dp = "$spec"; $li = 0 }
+ else {
+ $dp = if ($spec.dataPath) { "$($spec.dataPath)" } elseif ($spec.path) { "$($spec.path)" } elseif ($spec.путь) { "$($spec.путь)" } else { "" }
+ $li = if ($null -ne $spec.linkItem) { $spec.linkItem } elseif ($null -ne $spec.элементСвязи) { $spec.элементСвязи } else { 0 }
+ }
+ if (-not $dp) { X "$indent"; return }
+ X "$indent"
+ X "$indent`t$(Esc-Xml "$dp")"
+ X "$indent`t$li"
+ X "$indent"
+}
+
function Emit-Attribute {
param([string]$indent, $parsed, [string]$context)
# $context: "catalog", "document", "object", "processor", "tabular", "processor-tabular", "register"
@@ -1210,7 +1228,7 @@ function Emit-Attribute {
$coi = if ($parsed.createOnInput) { $parsed.createOnInput } else { "Auto" }
X "$indent`t`t$coi"
X "$indent`t`t"
- X "$indent`t`t"
+ Emit-LinkByType "$indent`t`t" $parsed.linkByType
$chi = if ($parsed.choiceHistoryOnInput) { $parsed.choiceHistoryOnInput } else { "Auto" }
X "$indent`t`t$chi"
diff --git a/.claude/skills/meta-compile/scripts/meta-compile.py b/.claude/skills/meta-compile/scripts/meta-compile.py
index 5163c8de..f107c98a 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.20 — Compile 1C metadata object from JSON
+# meta-compile v1.21 — Compile 1C metadata object from JSON
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
import argparse
@@ -596,11 +596,9 @@ def emit_type_content(indent, type_str):
X(f'{indent}\tDateTime')
X(f'{indent}')
return
- # DefinedType
- m = re.match(r'^DefinedType\.(.+)$', type_str)
- if m:
- dt_name = m.group(1)
- X(f'{indent}cfg:DefinedType.{dt_name}')
+ # TypeSet — тип-множество: ОпределяемыйТип (DefinedType) ИЛИ Характеристика ПВХ (Characteristic).
+ if re.match(r'^(DefinedType|Characteristic)\.(.+)$', type_str):
+ X(f'{indent}cfg:{type_str}')
return
# ValueStorage (ХранилищеЗначения) — канон v8:ValueStorage (не xs:base64Binary).
if type_str == 'ValueStorage':
@@ -851,6 +849,7 @@ def parse_attribute_shorthand(val):
'mask': str(val['mask']) if val.get('mask') else '',
'hasFillValue': ('fillValue' in val),
'fillValue': val.get('fillValue'),
+ 'linkByType': val.get('linkByType'),
}
def parse_enum_value_shorthand(val):
@@ -1179,6 +1178,28 @@ RESERVED_BY_CONTEXT = {
},
}
+def emit_link_by_type(indent, spec):
+ """ (связь по типу): DataPath + LinkItem. spec — {dataPath, linkItem?} или строка-путь; нет → ."""
+ if not spec:
+ X(f'{indent}')
+ return
+ if isinstance(spec, str):
+ dp, li = spec, 0
+ else:
+ dp = str(spec.get('dataPath') or spec.get('path') or spec.get('путь') or '')
+ li = spec.get('linkItem')
+ if li is None:
+ li = spec.get('элементСвязи')
+ if li is None:
+ li = 0
+ if not dp:
+ X(f'{indent}')
+ return
+ X(f'{indent}')
+ X(f'{indent}\t{esc_xml(str(dp))}')
+ X(f'{indent}\t{li}')
+ X(f'{indent}')
+
def emit_attribute(indent, parsed, context):
attr_name = parsed['name']
ctx_reserved = RESERVED_BY_CONTEXT.get(context)
@@ -1238,7 +1259,7 @@ def emit_attribute(indent, parsed, context):
X(f'{indent}\t\t{parsed.get("quickChoice") or "Auto"}')
X(f'{indent}\t\t{parsed.get("createOnInput") or "Auto"}')
X(f'{indent}\t\t')
- X(f'{indent}\t\t')
+ emit_link_by_type(f'{indent}\t\t', parsed.get('linkByType'))
chi = parsed.get('choiceHistoryOnInput') or 'Auto'
X(f'{indent}\t\t{chi}')
if context == 'catalog':
diff --git a/.claude/skills/meta-decompile/scripts/meta-decompile.ps1 b/.claude/skills/meta-decompile/scripts/meta-decompile.ps1
index fd82de41..1e914635 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.13 — XML объекта метаданных 1С → JSON-черновик формата meta-compile
+# meta-decompile v0.14 — XML объекта метаданных 1С → JSON-черновик формата meta-compile
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
#
# Пилот: только Catalog. Инверс meta-compile (omit-on-default: ключ эмитим только
@@ -251,6 +251,18 @@ function Attr-ToDsl {
}
}
+ # LinkByType (связь по типу): DataPath + LinkItem. Пусто → пропускаем. linkItem=0 → компактно строкой.
+ $lbtNode = $ap.SelectSingleNode('md:LinkByType', $nsm)
+ if ($lbtNode) {
+ $dpN = $lbtNode.SelectSingleNode('xr:DataPath', $nsm)
+ if ($dpN -and $dpN.InnerText) {
+ $liN = $lbtNode.SelectSingleNode('xr:LinkItem', $nsm)
+ $li = if ($liN -and $liN.InnerText) { [int]$liN.InnerText } else { 0 }
+ if ($li -eq 0) { $extra['linkByType'] = $dpN.InnerText }
+ else { $extra['linkByType'] = [ordered]@{ dataPath = $dpN.InnerText; linkItem = $li } }
+ }
+ }
+
if ($synCustom -or ($null -ne $ttVal) -or $extra.Count -gt 0) {
$o = [ordered]@{ name = $nm }
if ($ts) { $o['type'] = $ts }
diff --git a/docs/meta-dsl-spec.md b/docs/meta-dsl-spec.md
index 6fdc0372..5aa67482 100644
--- a/docs/meta-dsl-spec.md
+++ b/docs/meta-dsl-spec.md
@@ -82,6 +82,11 @@ JSON DSL для описания объектов метаданных конф
| `BusinessProcessRef.Xxx` | `cfg:BusinessProcessRef.Xxx` |
| `TaskRef.Xxx` | `cfg:TaskRef.Xxx` |
| `DefinedType.Xxx` | `cfg:DefinedType.Xxx` (через `v8:TypeSet`) |
+| `Characteristic.Xxx` | `cfg:Characteristic.Xxx` (через `v8:TypeSet`) |
+
+**Тип-множество (`v8:TypeSet`)** — тип, подразумевающий набор типов: `DefinedType.Xxx` (Определяемый тип) и
+`Characteristic.Xxx` (значение Характеристики из ПВХ — «Вид субконто»/доп.реквизит). У реквизита-значения
+Характеристики тип значения обычно определяется другим реквизитом-Видом — см. `linkByType` (§4.2).
### 3.3 Русские синонимы типов
@@ -145,6 +150,7 @@ JSON DSL для описания объектов метаданных конф
| `fullTextSearch` | FullTextSearch | Use | Use/DontUse |
| `fillFromFillingValue` | FillFromFillingValue | false | bool |
| `fillValue` | FillValue | по типу (см. ниже) | значение заполнения — bool/число/строка/дата/DTR-путь; `null` → nil |
+| `linkByType` | LinkByType | пусто | связь по типу: `{dataPath, linkItem?}` ИЛИ строка-путь (linkItem=0). Тип значения реквизита-Характеристики берётся из реквизита по `dataPath` |
| `createOnInput` | CreateOnInput | Auto | Auto/Use/DontUse |
| `quickChoice` | QuickChoice | Auto | Auto/Use/DontUse. Прощаем bool (форм-стиль): `true`→Use, `false`→DontUse |
| `dataHistory` | DataHistory | Use | Use/DontUse |
diff --git a/tests/skills/cases/meta-compile/catalog-attr-typeset-linkbytype.json b/tests/skills/cases/meta-compile/catalog-attr-typeset-linkbytype.json
new file mode 100644
index 00000000..aa893268
--- /dev/null
+++ b/tests/skills/cases/meta-compile/catalog-attr-typeset-linkbytype.json
@@ -0,0 +1,19 @@
+{
+ "name": "Реквизит-Характеристика: TypeSet + LinkByType (связь по типу)",
+ "input": {
+ "type": "Catalog",
+ "name": "ТестХарактеристик",
+ "attributes": [
+ { "name": "Свойство", "type": "ChartOfCharacteristicTypesRef.ДополнительныеРеквизиты" },
+ { "name": "Значение", "type": "Characteristic.ДополнительныеРеквизиты",
+ "linkByType": { "dataPath": "Catalog.ТестХарактеристик.Attribute.Свойство", "linkItem": 1 } },
+ { "name": "ЗначениеОпредТип", "type": "DefinedType.Сумма" },
+ { "name": "СвязьСтрокой", "type": "Characteristic.ВидыСубконто",
+ "linkByType": "Catalog.ТестХарактеристик.Attribute.Свойство" }
+ ]
+ },
+ "validatePath": "Catalogs/ТестХарактеристик",
+ "expect": {
+ "files": ["Catalogs/ТестХарактеристик.xml"]
+ }
+}
diff --git a/tests/skills/cases/meta-compile/snapshots/catalog-attr-typeset-linkbytype/Catalogs/ТестХарактеристик.xml b/tests/skills/cases/meta-compile/snapshots/catalog-attr-typeset-linkbytype/Catalogs/ТестХарактеристик.xml
new file mode 100644
index 00000000..56ca92db
--- /dev/null
+++ b/tests/skills/cases/meta-compile/snapshots/catalog-attr-typeset-linkbytype/Catalogs/ТестХарактеристик.xml
@@ -0,0 +1,258 @@
+
+
+
+
+
+ UUID-002
+ UUID-003
+
+
+ UUID-004
+ UUID-005
+
+
+ UUID-006
+ UUID-007
+
+
+ UUID-008
+ UUID-009
+
+
+ UUID-010
+ UUID-011
+
+
+
+ ТестХарактеристик
+
+
+ ru
+ Тест характеристик
+
+
+
+ false
+ HierarchyFoldersAndItems
+ false
+ 2
+ true
+ true
+
+ ToItems
+ 9
+ 25
+ String
+ Variable
+ WholeCatalog
+ false
+ true
+ AsDescription
+
+ Auto
+ InDialog
+ false
+ BothWays
+
+ Catalog.ТестХарактеристик.StandardAttribute.Description
+ Catalog.ТестХарактеристик.StandardAttribute.Code
+
+ Begin
+ DontUse
+ Directly
+
+
+
+
+
+
+
+
+
+
+ false
+
+
+ Automatic
+ Use
+
+
+
+
+
+ Use
+ Auto
+ DontUse
+ false
+ false
+
+
+
+
+ Свойство
+
+
+ ru
+ Свойство
+
+
+
+
+ d5p1:ChartOfCharacteristicTypesRef.ДополнительныеРеквизиты
+
+ false
+
+
+
+ false
+
+ false
+ false
+
+
+ false
+
+ DontCheck
+ Items
+
+
+ Auto
+ Auto
+
+
+ Auto
+
+ DontIndex
+ Use
+ Use
+
+
+
+
+ Значение
+
+
+ ru
+ Значение
+
+
+
+
+ cfg:Characteristic.ДополнительныеРеквизиты
+
+ false
+
+
+
+ false
+
+ false
+ false
+
+
+ false
+
+ DontCheck
+ Items
+
+
+ Auto
+ Auto
+
+
+ Catalog.ТестХарактеристик.Attribute.Свойство
+ 1
+
+ Auto
+
+ DontIndex
+ Use
+ Use
+
+
+
+
+ ЗначениеОпредТип
+
+
+ ru
+ Значение опред тип
+
+
+
+
+ cfg:DefinedType.Сумма
+
+ false
+
+
+
+ false
+
+ false
+ false
+
+
+ false
+
+ DontCheck
+ Items
+
+
+ Auto
+ Auto
+
+
+ Auto
+
+ DontIndex
+ Use
+ Use
+
+
+
+
+ СвязьСтрокой
+
+
+ ru
+ Связь строкой
+
+
+
+
+ cfg:Characteristic.ВидыСубконто
+
+ false
+
+
+
+ false
+
+ false
+ false
+
+
+ false
+
+ DontCheck
+ Items
+
+
+ Auto
+ Auto
+
+
+ Catalog.ТестХарактеристик.Attribute.Свойство
+ 0
+
+ Auto
+
+ DontIndex
+ Use
+ Use
+
+
+
+
+
diff --git a/tests/skills/cases/meta-compile/snapshots/catalog-attr-typeset-linkbytype/Catalogs/ТестХарактеристик/Ext/ObjectModule.bsl b/tests/skills/cases/meta-compile/snapshots/catalog-attr-typeset-linkbytype/Catalogs/ТестХарактеристик/Ext/ObjectModule.bsl
new file mode 100644
index 00000000..e69de29b
diff --git a/tests/skills/cases/meta-compile/snapshots/catalog-attr-typeset-linkbytype/Configuration.xml b/tests/skills/cases/meta-compile/snapshots/catalog-attr-typeset-linkbytype/Configuration.xml
new file mode 100644
index 00000000..837231e9
--- /dev/null
+++ b/tests/skills/cases/meta-compile/snapshots/catalog-attr-typeset-linkbytype/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/catalog-attr-typeset-linkbytype/Ext/ClientApplicationInterface.xml b/tests/skills/cases/meta-compile/snapshots/catalog-attr-typeset-linkbytype/Ext/ClientApplicationInterface.xml
new file mode 100644
index 00000000..3c1161b2
--- /dev/null
+++ b/tests/skills/cases/meta-compile/snapshots/catalog-attr-typeset-linkbytype/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/catalog-attr-typeset-linkbytype/Languages/Русский.xml b/tests/skills/cases/meta-compile/snapshots/catalog-attr-typeset-linkbytype/Languages/Русский.xml
new file mode 100644
index 00000000..37c60d78
--- /dev/null
+++ b/tests/skills/cases/meta-compile/snapshots/catalog-attr-typeset-linkbytype/Languages/Русский.xml
@@ -0,0 +1,16 @@
+
+
+
+
+ Русский
+
+
+ ru
+ Русский
+
+
+
+ ru
+
+
+
\ No newline at end of file