fix(support-guard): не блокировать автономные внешние обработки/отчёты (#39)

При поиске корня конфигурации guard поднимался по дереву вверх и «проскакивал»
собственный корень автономной внешней обработки/отчёта (ExternalDataProcessor /
ExternalReport), лежащей внутри дерева выгрузки конфигурации. Если у охватывающей
конфигурации выключена возможность изменения (G=1), внешний объект ложно
блокировался как «объект типовой конфигурации на поддержке», а info-навыки
выводили нерелевантную строку «Поддержка: конфигурация read-only».

Теперь climb останавливается на границе автономного объекта: если целевой файл или
встреченный по пути <каталог>.xml имеет корень ExternalDataProcessor/ExternalReport,
подъём прекращается и объект не привязывается к конфигурации. Корень внешнего объекта
всегда глубже Configuration.xml, поэтому встречается первым — регрессии для обычных
объектов конфигурации нет.

Синхронно во всех копиях guard-а (навыки автономны): хук support-state.mjs
(decideSupport + findConfigRoot), 16 мутаторов (Assert-EditAllowed), 5 info-навыков
и meta-info (Get-SupportStatusForPath / Get-ObjectSupportStatus) — ps1 и py. Для
info-навыков строка «Поддержка:» для внешнего объекта опускается.

Тесты: hooks/test/run.mjs — секция внешней границы (G=1 + встроенная EPF);
tests/skills — кейсы mxl-compile (guard пропускает) и mxl-info (строка опущена).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Nick Shirokov
2026-07-17 19:46:54 +03:00
parent e7b5df4d50
commit ddc1641176
64 changed files with 1400 additions and 58 deletions
+14 -1
View File
@@ -1,4 +1,4 @@
# cf-edit v1.8 — Edit 1C configuration root (Configuration.xml)
# cf-edit v1.9 — Edit 1C configuration root (Configuration.xml)
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
param(
[Parameter(Mandatory)][Alias('Path')][string]$ConfigPath,
@@ -44,6 +44,16 @@ function Get-RootUuid([string]$xmlPath) {
} catch {}
return $null
}
function Test-ExternalObjectRoot([string]$xmlPath) {
if (-not (Test-Path $xmlPath)) { return $false }
try {
[xml]$mx = Get-Content -Path $xmlPath -Encoding UTF8
$el = $mx.DocumentElement.FirstChild
while ($el -and $el.NodeType -ne 'Element') { $el = $el.NextSibling }
if ($el) { return @('ExternalDataProcessor','ExternalReport') -contains $el.LocalName }
} catch {}
return $false
}
function Find-V8Project([string]$startDir) {
$d = $startDir
for ($i = 0; $i -lt 20 -and $d; $i++) {
@@ -80,10 +90,13 @@ function Assert-EditAllowed([string]$targetPath, [string]$require) {
try {
$rp = $targetPath
try { $rp = (Resolve-Path $targetPath -ErrorAction Stop).Path } catch {}
# Autonomous external object (EPF/ERF): never part of a config on support (issue #39).
if (Test-ExternalObjectRoot $rp) { return }
$elemUuid = Get-RootUuid $rp
$cfgDir = $null; $binPath = $null
$d = if (Test-Path $rp -PathType Container) { $rp } else { [System.IO.Path]::GetDirectoryName($rp) }
for ($i = 0; $i -lt 12 -and $d; $i++) {
if (Test-ExternalObjectRoot "$d.xml") { return }
if (-not $elemUuid) { $elemUuid = Get-RootUuid "$d.xml" }
if (-not $cfgDir) {
$cand = Join-Path (Join-Path $d "Ext") "ParentConfigurations.bin"
+18 -1
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env python3
# cf-edit v1.8 — Edit 1C configuration root (Configuration.xml)
# cf-edit v1.9 — Edit 1C configuration root (Configuration.xml)
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
import argparse
@@ -33,6 +33,18 @@ def _sg_root_uuid(xml_path):
return None
def _sg_is_external_root(xml_path):
if not os.path.isfile(xml_path):
return False
try:
mx = etree.parse(xml_path).getroot()
for child in mx:
if isinstance(child.tag, str):
return child.tag.split("}")[-1] in ("ExternalDataProcessor", "ExternalReport")
except Exception:
return False
return False
def _sg_find_v8project(start_dir):
d = start_dir
for _ in range(20):
@@ -72,6 +84,9 @@ def _sg_get_edit_mode(cfg_dir):
def assert_edit_allowed(target_path, require):
try:
rp = os.path.abspath(target_path)
# Autonomous external object (EPF/ERF): never part of a config on support (issue #39).
if _sg_is_external_root(rp):
return
elem_uuid = _sg_root_uuid(rp)
cfg_dir = None
bin_path = None
@@ -79,6 +94,8 @@ def assert_edit_allowed(target_path, require):
for _ in range(12):
if not d:
break
if _sg_is_external_root(d + ".xml"):
return
if not elem_uuid:
elem_uuid = _sg_root_uuid(d + ".xml")
if not cfg_dir:
+14 -1
View File
@@ -1,4 +1,4 @@
# form-add v1.8 — Add managed form to 1C config object
# form-add v1.9 — Add managed form to 1C config object
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
param(
[Parameter(Mandatory)]
@@ -33,6 +33,16 @@ function Get-RootUuid([string]$xmlPath) {
} catch {}
return $null
}
function Test-ExternalObjectRoot([string]$xmlPath) {
if (-not (Test-Path $xmlPath)) { return $false }
try {
[xml]$mx = Get-Content -Path $xmlPath -Encoding UTF8
$el = $mx.DocumentElement.FirstChild
while ($el -and $el.NodeType -ne 'Element') { $el = $el.NextSibling }
if ($el) { return @('ExternalDataProcessor','ExternalReport') -contains $el.LocalName }
} catch {}
return $false
}
function Find-V8Project([string]$startDir) {
$d = $startDir
for ($i = 0; $i -lt 20 -and $d; $i++) {
@@ -69,10 +79,13 @@ function Assert-EditAllowed([string]$targetPath, [string]$require) {
try {
$rp = $targetPath
try { $rp = (Resolve-Path $targetPath -ErrorAction Stop).Path } catch {}
# Autonomous external object (EPF/ERF): never part of a config on support (issue #39).
if (Test-ExternalObjectRoot $rp) { return }
$elemUuid = Get-RootUuid $rp
$cfgDir = $null; $binPath = $null
$d = if (Test-Path $rp -PathType Container) { $rp } else { [System.IO.Path]::GetDirectoryName($rp) }
for ($i = 0; $i -lt 12 -and $d; $i++) {
if (Test-ExternalObjectRoot "$d.xml") { return }
if (-not $elemUuid) { $elemUuid = Get-RootUuid "$d.xml" }
if (-not $cfgDir) {
$cand = Join-Path (Join-Path $d "Ext") "ParentConfigurations.bin"
+18 -1
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env python3
# form-add v1.8 — Add managed form to 1C config object
# form-add v1.9 — Add managed form to 1C config object
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
import argparse
@@ -32,6 +32,18 @@ def _sg_root_uuid(xml_path):
return None
def _sg_is_external_root(xml_path):
if not os.path.isfile(xml_path):
return False
try:
mx = etree.parse(xml_path).getroot()
for child in mx:
if isinstance(child.tag, str):
return child.tag.split("}")[-1] in ("ExternalDataProcessor", "ExternalReport")
except Exception:
return False
return False
def _sg_find_v8project(start_dir):
d = start_dir
for _ in range(20):
@@ -71,6 +83,9 @@ def _sg_get_edit_mode(cfg_dir):
def assert_edit_allowed(target_path, require):
try:
rp = os.path.abspath(target_path)
# Autonomous external object (EPF/ERF): never part of a config on support (issue #39).
if _sg_is_external_root(rp):
return
elem_uuid = _sg_root_uuid(rp)
cfg_dir = None
bin_path = None
@@ -78,6 +93,8 @@ def assert_edit_allowed(target_path, require):
for _ in range(12):
if not d:
break
if _sg_is_external_root(d + ".xml"):
return
if not elem_uuid:
elem_uuid = _sg_root_uuid(d + ".xml")
if not cfg_dir:
@@ -1,4 +1,4 @@
# form-compile v1.174 — Compile 1C managed form from JSON or object metadata
# form-compile v1.175 — Compile 1C managed form from JSON or object metadata
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
param(
[string]$JsonPath,
@@ -1362,6 +1362,16 @@ function Get-RootUuid([string]$xmlPath) {
} catch {}
return $null
}
function Test-ExternalObjectRoot([string]$xmlPath) {
if (-not (Test-Path $xmlPath)) { return $false }
try {
[xml]$mx = Get-Content -Path $xmlPath -Encoding UTF8
$el = $mx.DocumentElement.FirstChild
while ($el -and $el.NodeType -ne 'Element') { $el = $el.NextSibling }
if ($el) { return @('ExternalDataProcessor','ExternalReport') -contains $el.LocalName }
} catch {}
return $false
}
function Find-V8Project([string]$startDir) {
$d = $startDir
for ($i = 0; $i -lt 20 -and $d; $i++) {
@@ -1398,10 +1408,13 @@ function Assert-EditAllowed([string]$targetPath, [string]$require) {
try {
$rp = $targetPath
try { $rp = (Resolve-Path $targetPath -ErrorAction Stop).Path } catch {}
# Autonomous external object (EPF/ERF): never part of a config on support (issue #39).
if (Test-ExternalObjectRoot $rp) { return }
$elemUuid = Get-RootUuid $rp
$cfgDir = $null; $binPath = $null
$d = if (Test-Path $rp -PathType Container) { $rp } else { [System.IO.Path]::GetDirectoryName($rp) }
for ($i = 0; $i -lt 12 -and $d; $i++) {
if (Test-ExternalObjectRoot "$d.xml") { return }
if (-not $elemUuid) { $elemUuid = Get-RootUuid "$d.xml" }
if (-not $cfgDir) {
$cand = Join-Path (Join-Path $d "Ext") "ParentConfigurations.bin"
@@ -1,5 +1,5 @@
#!/usr/bin/env python3
# form-compile v1.174 — Compile 1C managed form from JSON or object metadata
# form-compile v1.175 — Compile 1C managed form from JSON or object metadata
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
import argparse
import copy
@@ -34,6 +34,18 @@ def _sg_root_uuid(xml_path):
return None
def _sg_is_external_root(xml_path):
if not os.path.isfile(xml_path):
return False
try:
mx = etree.parse(xml_path).getroot()
for child in mx:
if isinstance(child.tag, str):
return child.tag.split("}")[-1] in ("ExternalDataProcessor", "ExternalReport")
except Exception:
return False
return False
def _sg_find_v8project(start_dir):
d = start_dir
for _ in range(20):
@@ -73,6 +85,9 @@ def _sg_get_edit_mode(cfg_dir):
def assert_edit_allowed(target_path, require):
try:
rp = os.path.abspath(target_path)
# Autonomous external object (EPF/ERF): never part of a config on support (issue #39).
if _sg_is_external_root(rp):
return
elem_uuid = _sg_root_uuid(rp)
cfg_dir = None
bin_path = None
@@ -80,6 +95,8 @@ def assert_edit_allowed(target_path, require):
for _ in range(12):
if not d:
break
if _sg_is_external_root(d + ".xml"):
return
if not elem_uuid:
elem_uuid = _sg_root_uuid(d + ".xml")
if not cfg_dir:
+14 -1
View File
@@ -1,4 +1,4 @@
# form-edit v1.3 — Edit 1C managed form elements
# form-edit v1.4 — Edit 1C managed form elements
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
param(
[Parameter(Mandatory)]
@@ -27,6 +27,16 @@ function Get-RootUuid([string]$xmlPath) {
} catch {}
return $null
}
function Test-ExternalObjectRoot([string]$xmlPath) {
if (-not (Test-Path $xmlPath)) { return $false }
try {
[xml]$mx = Get-Content -Path $xmlPath -Encoding UTF8
$el = $mx.DocumentElement.FirstChild
while ($el -and $el.NodeType -ne 'Element') { $el = $el.NextSibling }
if ($el) { return @('ExternalDataProcessor','ExternalReport') -contains $el.LocalName }
} catch {}
return $false
}
function Find-V8Project([string]$startDir) {
$d = $startDir
for ($i = 0; $i -lt 20 -and $d; $i++) {
@@ -63,10 +73,13 @@ function Assert-EditAllowed([string]$targetPath, [string]$require) {
try {
$rp = $targetPath
try { $rp = (Resolve-Path $targetPath -ErrorAction Stop).Path } catch {}
# Autonomous external object (EPF/ERF): never part of a config on support (issue #39).
if (Test-ExternalObjectRoot $rp) { return }
$elemUuid = Get-RootUuid $rp
$cfgDir = $null; $binPath = $null
$d = if (Test-Path $rp -PathType Container) { $rp } else { [System.IO.Path]::GetDirectoryName($rp) }
for ($i = 0; $i -lt 12 -and $d; $i++) {
if (Test-ExternalObjectRoot "$d.xml") { return }
if (-not $elemUuid) { $elemUuid = Get-RootUuid "$d.xml" }
if (-not $cfgDir) {
$cand = Join-Path (Join-Path $d "Ext") "ParentConfigurations.bin"
+18 -1
View File
@@ -1,4 +1,4 @@
# form-edit v1.3 — Edit 1C managed form elements (Python port)
# form-edit v1.4 — Edit 1C managed form elements (Python port)
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
import argparse
import json
@@ -31,6 +31,18 @@ def _sg_root_uuid(xml_path):
return None
def _sg_is_external_root(xml_path):
if not os.path.isfile(xml_path):
return False
try:
mx = etree.parse(xml_path).getroot()
for child in mx:
if isinstance(child.tag, str):
return child.tag.split("}")[-1] in ("ExternalDataProcessor", "ExternalReport")
except Exception:
return False
return False
def _sg_find_v8project(start_dir):
d = start_dir
for _ in range(20):
@@ -70,6 +82,9 @@ def _sg_get_edit_mode(cfg_dir):
def assert_edit_allowed(target_path, require):
try:
rp = os.path.abspath(target_path)
# Autonomous external object (EPF/ERF): never part of a config on support (issue #39).
if _sg_is_external_root(rp):
return
elem_uuid = _sg_root_uuid(rp)
cfg_dir = None
bin_path = None
@@ -77,6 +92,8 @@ def assert_edit_allowed(target_path, require):
for _ in range(12):
if not d:
break
if _sg_is_external_root(d + ".xml"):
return
if not elem_uuid:
elem_uuid = _sg_root_uuid(d + ".xml")
if not cfg_dir:
+15 -2
View File
@@ -1,4 +1,4 @@
# form-info v1.4 — Analyze 1C managed form structure
# form-info v1.5 — Analyze 1C managed form structure
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
param(
[Parameter(Mandatory=$true)]
@@ -372,6 +372,16 @@ if ($formsIdx -ge 0 -and ($formsIdx + 1) -lt $parts.Count) {
# See docs/1c-support-state-spec.md. Walks up from the target path, taking the
# uuid of the nearest element meta-xml (form/template/etc.) and the config root
# bin. Never throws — degrades to "не на поддержке".
function Test-ExternalObjectRoot([string]$xmlPath) {
if (-not (Test-Path $xmlPath)) { return $false }
try {
[xml]$mx = Get-Content -Path $xmlPath -Encoding UTF8
$el = $mx.DocumentElement.FirstChild
while ($el -and $el.NodeType -ne 'Element') { $el = $el.NextSibling }
if ($el) { return @('ExternalDataProcessor','ExternalReport') -contains $el.LocalName }
} catch {}
return $false
}
function Get-SupportStatusForPath([string]$targetPath) {
try {
$rp = (Resolve-Path $targetPath).Path
@@ -390,8 +400,10 @@ function Get-SupportStatusForPath([string]$targetPath) {
}
# The target file itself may be the element meta-xml (e.g. Subsystems/X.xml).
$elemUuid = Get-RootUuid $rp
if (Test-ExternalObjectRoot $rp) { return $null }
$d = [System.IO.Path]::GetDirectoryName($rp)
for ($i = 0; $i -lt 12 -and $d; $i++) {
if (Test-ExternalObjectRoot "$d.xml") { return $null }
if (-not $elemUuid) { $elemUuid = Get-RootUuid "$d.xml" }
if (-not $binPath) {
$cand = Join-Path (Join-Path $d "Ext") "ParentConfigurations.bin"
@@ -448,7 +460,8 @@ if ($formTitle) { $header += " — `"$formTitle`"" }
if ($objectContext) { $header += " ($objectContext)" }
$header += " ==="
$lines += $header
$lines += "Поддержка: $(Get-SupportStatusForPath $FormPath)"
$support = Get-SupportStatusForPath $FormPath
if ($null -ne $support) { $lines += "Поддержка: $support" }
# --- Form properties (Title excluded — shown in header) ---
+19 -2
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env python3
# form-info v1.4 — Analyze 1C managed form structure
# form-info v1.5 — Analyze 1C managed form structure
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
import argparse
@@ -353,14 +353,29 @@ def get_support_status_for_path(target_path):
except Exception:
pass
return None
def is_external_root(xml_path):
if not os.path.isfile(xml_path):
return False
try:
mx = etree.parse(xml_path).getroot()
for child in mx:
if isinstance(child.tag, str):
return child.tag.split("}")[-1] in ("ExternalDataProcessor", "ExternalReport")
except Exception:
return False
return False
rp = os.path.abspath(target_path)
# The target file itself may be the element meta-xml (e.g. Subsystems/X.xml).
elem_uuid = root_uuid(rp)
if is_external_root(rp):
return None
bin_path = None
d = os.path.dirname(rp)
for _ in range(12):
if not d:
break
if is_external_root(d + ".xml"):
return None
if not elem_uuid:
elem_uuid = root_uuid(d + ".xml")
if not bin_path:
@@ -513,7 +528,9 @@ def main():
header += f" ({object_context})"
header += " ==="
lines.append(header)
lines.append(f"Поддержка: {get_support_status_for_path(form_path)}")
_support = get_support_status_for_path(form_path)
if _support is not None:
lines.append(f"Поддержка: {_support}")
# --- Form properties (Title excluded -- shown in header) ---
prop_names = [
+14 -1
View File
@@ -1,4 +1,4 @@
# help-add v1.7 — Add built-in help to 1C object
# help-add v1.8 — Add built-in help to 1C object
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
param(
[Parameter(Mandatory)]
@@ -28,6 +28,16 @@ function Get-RootUuid([string]$xmlPath) {
} catch {}
return $null
}
function Test-ExternalObjectRoot([string]$xmlPath) {
if (-not (Test-Path $xmlPath)) { return $false }
try {
[xml]$mx = Get-Content -Path $xmlPath -Encoding UTF8
$el = $mx.DocumentElement.FirstChild
while ($el -and $el.NodeType -ne 'Element') { $el = $el.NextSibling }
if ($el) { return @('ExternalDataProcessor','ExternalReport') -contains $el.LocalName }
} catch {}
return $false
}
function Find-V8Project([string]$startDir) {
$d = $startDir
for ($i = 0; $i -lt 20 -and $d; $i++) {
@@ -64,10 +74,13 @@ function Assert-EditAllowed([string]$targetPath, [string]$require) {
try {
$rp = $targetPath
try { $rp = (Resolve-Path $targetPath -ErrorAction Stop).Path } catch {}
# Autonomous external object (EPF/ERF): never part of a config on support (issue #39).
if (Test-ExternalObjectRoot $rp) { return }
$elemUuid = Get-RootUuid $rp
$cfgDir = $null; $binPath = $null
$d = if (Test-Path $rp -PathType Container) { $rp } else { [System.IO.Path]::GetDirectoryName($rp) }
for ($i = 0; $i -lt 12 -and $d; $i++) {
if (Test-ExternalObjectRoot "$d.xml") { return }
if (-not $elemUuid) { $elemUuid = Get-RootUuid "$d.xml" }
if (-not $cfgDir) {
$cand = Join-Path (Join-Path $d "Ext") "ParentConfigurations.bin"
+18 -1
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env python3
# add-help v1.7 — Add built-in help to 1C object
# add-help v1.8 — Add built-in help to 1C object
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
import argparse
@@ -33,6 +33,18 @@ def _sg_root_uuid(xml_path):
return None
def _sg_is_external_root(xml_path):
if not os.path.isfile(xml_path):
return False
try:
mx = etree.parse(xml_path).getroot()
for child in mx:
if isinstance(child.tag, str):
return child.tag.split("}")[-1] in ("ExternalDataProcessor", "ExternalReport")
except Exception:
return False
return False
def _sg_find_v8project(start_dir):
d = start_dir
for _ in range(20):
@@ -72,6 +84,9 @@ def _sg_get_edit_mode(cfg_dir):
def assert_edit_allowed(target_path, require):
try:
rp = os.path.abspath(target_path)
# Autonomous external object (EPF/ERF): never part of a config on support (issue #39).
if _sg_is_external_root(rp):
return
elem_uuid = _sg_root_uuid(rp)
cfg_dir = None
bin_path = None
@@ -79,6 +94,8 @@ def assert_edit_allowed(target_path, require):
for _ in range(12):
if not d:
break
if _sg_is_external_root(d + ".xml"):
return
if not elem_uuid:
elem_uuid = _sg_root_uuid(d + ".xml")
if not cfg_dir:
@@ -1,4 +1,4 @@
# interface-edit v1.6 — Edit 1C CommandInterface.xml
# interface-edit v1.7 — Edit 1C CommandInterface.xml
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
param(
[Parameter(Mandatory)][Alias('Path')][string]$CIPath,
@@ -39,6 +39,16 @@ function Get-RootUuid([string]$xmlPath) {
} catch {}
return $null
}
function Test-ExternalObjectRoot([string]$xmlPath) {
if (-not (Test-Path $xmlPath)) { return $false }
try {
[xml]$mx = Get-Content -Path $xmlPath -Encoding UTF8
$el = $mx.DocumentElement.FirstChild
while ($el -and $el.NodeType -ne 'Element') { $el = $el.NextSibling }
if ($el) { return @('ExternalDataProcessor','ExternalReport') -contains $el.LocalName }
} catch {}
return $false
}
function Find-V8Project([string]$startDir) {
$d = $startDir
for ($i = 0; $i -lt 20 -and $d; $i++) {
@@ -75,10 +85,13 @@ function Assert-EditAllowed([string]$targetPath, [string]$require) {
try {
$rp = $targetPath
try { $rp = (Resolve-Path $targetPath -ErrorAction Stop).Path } catch {}
# Autonomous external object (EPF/ERF): never part of a config on support (issue #39).
if (Test-ExternalObjectRoot $rp) { return }
$elemUuid = Get-RootUuid $rp
$cfgDir = $null; $binPath = $null
$d = if (Test-Path $rp -PathType Container) { $rp } else { [System.IO.Path]::GetDirectoryName($rp) }
for ($i = 0; $i -lt 12 -and $d; $i++) {
if (Test-ExternalObjectRoot "$d.xml") { return }
if (-not $elemUuid) { $elemUuid = Get-RootUuid "$d.xml" }
if (-not $cfgDir) {
$cand = Join-Path (Join-Path $d "Ext") "ParentConfigurations.bin"
@@ -1,5 +1,5 @@
#!/usr/bin/env python3
# interface-edit v1.6 — Edit 1C CommandInterface.xml
# interface-edit v1.7 — Edit 1C CommandInterface.xml
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
import argparse
@@ -31,6 +31,18 @@ def _sg_root_uuid(xml_path):
return None
def _sg_is_external_root(xml_path):
if not os.path.isfile(xml_path):
return False
try:
mx = etree.parse(xml_path).getroot()
for child in mx:
if isinstance(child.tag, str):
return child.tag.split("}")[-1] in ("ExternalDataProcessor", "ExternalReport")
except Exception:
return False
return False
def _sg_find_v8project(start_dir):
d = start_dir
for _ in range(20):
@@ -70,6 +82,9 @@ def _sg_get_edit_mode(cfg_dir):
def assert_edit_allowed(target_path, require):
try:
rp = os.path.abspath(target_path)
# Autonomous external object (EPF/ERF): never part of a config on support (issue #39).
if _sg_is_external_root(rp):
return
elem_uuid = _sg_root_uuid(rp)
cfg_dir = None
bin_path = None
@@ -77,6 +92,8 @@ def assert_edit_allowed(target_path, require):
for _ in range(12):
if not d:
break
if _sg_is_external_root(d + ".xml"):
return
if not elem_uuid:
elem_uuid = _sg_root_uuid(d + ".xml")
if not cfg_dir:
@@ -1,4 +1,4 @@
# meta-compile v1.65 — Compile 1C metadata object from JSON
# meta-compile v1.66 — Compile 1C metadata object from JSON
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
param(
[Parameter(Mandatory)]
@@ -36,6 +36,16 @@ function Get-RootUuid([string]$xmlPath) {
} catch {}
return $null
}
function Test-ExternalObjectRoot([string]$xmlPath) {
if (-not (Test-Path $xmlPath)) { return $false }
try {
[xml]$mx = Get-Content -Path $xmlPath -Encoding UTF8
$el = $mx.DocumentElement.FirstChild
while ($el -and $el.NodeType -ne 'Element') { $el = $el.NextSibling }
if ($el) { return @('ExternalDataProcessor','ExternalReport') -contains $el.LocalName }
} catch {}
return $false
}
function Find-V8Project([string]$startDir) {
$d = $startDir
for ($i = 0; $i -lt 20 -and $d; $i++) {
@@ -72,10 +82,13 @@ function Assert-EditAllowed([string]$targetPath, [string]$require) {
try {
$rp = $targetPath
try { $rp = (Resolve-Path $targetPath -ErrorAction Stop).Path } catch {}
# Autonomous external object (EPF/ERF): never part of a config on support (issue #39).
if (Test-ExternalObjectRoot $rp) { return }
$elemUuid = Get-RootUuid $rp
$cfgDir = $null; $binPath = $null
$d = if (Test-Path $rp -PathType Container) { $rp } else { [System.IO.Path]::GetDirectoryName($rp) }
for ($i = 0; $i -lt 12 -and $d; $i++) {
if (Test-ExternalObjectRoot "$d.xml") { return }
if (-not $elemUuid) { $elemUuid = Get-RootUuid "$d.xml" }
if (-not $cfgDir) {
$cand = Join-Path (Join-Path $d "Ext") "ParentConfigurations.bin"
@@ -1,5 +1,5 @@
#!/usr/bin/env python3
# meta-compile v1.65 — Compile 1C metadata object from JSON
# meta-compile v1.66 — Compile 1C metadata object from JSON
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
import argparse
@@ -36,6 +36,18 @@ def _sg_root_uuid(xml_path):
return None
def _sg_is_external_root(xml_path):
if not os.path.isfile(xml_path):
return False
try:
mx = etree.parse(xml_path).getroot()
for child in mx:
if isinstance(child.tag, str):
return child.tag.split("}")[-1] in ("ExternalDataProcessor", "ExternalReport")
except Exception:
return False
return False
def _sg_find_v8project(start_dir):
d = start_dir
for _ in range(20):
@@ -75,6 +87,9 @@ def _sg_get_edit_mode(cfg_dir):
def assert_edit_allowed(target_path, require):
try:
rp = os.path.abspath(target_path)
# Autonomous external object (EPF/ERF): never part of a config on support (issue #39).
if _sg_is_external_root(rp):
return
elem_uuid = _sg_root_uuid(rp)
cfg_dir = None
bin_path = None
@@ -82,6 +97,8 @@ def assert_edit_allowed(target_path, require):
for _ in range(12):
if not d:
break
if _sg_is_external_root(d + ".xml"):
return
if not elem_uuid:
elem_uuid = _sg_root_uuid(d + ".xml")
if not cfg_dir:
+14 -1
View File
@@ -1,4 +1,4 @@
# meta-edit v1.19 — Edit existing 1C metadata object XML (+add-predefined предопределённые Ext/Predefined.xml)
# meta-edit v1.20 — Edit existing 1C metadata object XML (+add-predefined предопределённые Ext/Predefined.xml)
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
param(
[string]$DefinitionFile,
@@ -170,6 +170,16 @@ function Get-RootUuid([string]$xmlPath) {
} catch {}
return $null
}
function Test-ExternalObjectRoot([string]$xmlPath) {
if (-not (Test-Path $xmlPath)) { return $false }
try {
[xml]$mx = Get-Content -Path $xmlPath -Encoding UTF8
$el = $mx.DocumentElement.FirstChild
while ($el -and $el.NodeType -ne 'Element') { $el = $el.NextSibling }
if ($el) { return @('ExternalDataProcessor','ExternalReport') -contains $el.LocalName }
} catch {}
return $false
}
function Find-V8Project([string]$startDir) {
$d = $startDir
for ($i = 0; $i -lt 20 -and $d; $i++) {
@@ -206,10 +216,13 @@ function Assert-EditAllowed([string]$targetPath, [string]$require) {
try {
$rp = $targetPath
try { $rp = (Resolve-Path $targetPath -ErrorAction Stop).Path } catch {}
# Autonomous external object (EPF/ERF): never part of a config on support (issue #39).
if (Test-ExternalObjectRoot $rp) { return }
$elemUuid = Get-RootUuid $rp
$cfgDir = $null; $binPath = $null
$d = if (Test-Path $rp -PathType Container) { $rp } else { [System.IO.Path]::GetDirectoryName($rp) }
for ($i = 0; $i -lt 12 -and $d; $i++) {
if (Test-ExternalObjectRoot "$d.xml") { return }
if (-not $elemUuid) { $elemUuid = Get-RootUuid "$d.xml" }
if (-not $cfgDir) {
$cand = Join-Path (Join-Path $d "Ext") "ParentConfigurations.bin"
+18 -1
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env python3
# meta-edit v1.19 — Edit existing 1C metadata object XML (+add-predefined предопределённые Ext/Predefined.xml)
# meta-edit v1.20 — Edit existing 1C metadata object XML (+add-predefined предопределённые Ext/Predefined.xml)
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
import argparse
@@ -32,6 +32,18 @@ def _sg_root_uuid(xml_path):
return None
def _sg_is_external_root(xml_path):
if not os.path.isfile(xml_path):
return False
try:
mx = etree.parse(xml_path).getroot()
for child in mx:
if isinstance(child.tag, str):
return child.tag.split("}")[-1] in ("ExternalDataProcessor", "ExternalReport")
except Exception:
return False
return False
def _sg_find_v8project(start_dir):
d = start_dir
for _ in range(20):
@@ -71,6 +83,9 @@ def _sg_get_edit_mode(cfg_dir):
def assert_edit_allowed(target_path, require):
try:
rp = os.path.abspath(target_path)
# Autonomous external object (EPF/ERF): never part of a config on support (issue #39).
if _sg_is_external_root(rp):
return
elem_uuid = _sg_root_uuid(rp)
cfg_dir = None
bin_path = None
@@ -78,6 +93,8 @@ def assert_edit_allowed(target_path, require):
for _ in range(12):
if not d:
break
if _sg_is_external_root(d + ".xml"):
return
if not elem_uuid:
elem_uuid = _sg_root_uuid(d + ".xml")
if not cfg_dir:
+14 -2
View File
@@ -1,4 +1,4 @@
# meta-info v1.3 — Compact summary of 1C metadata object
# meta-info v1.4 — Compact summary of 1C metadata object
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
param(
[Parameter(Mandatory=$true)][Alias('Path')][string]$ObjectPath,
@@ -418,8 +418,19 @@ function Get-WSOperations($childObjs) {
# --- Support status of this object (Ext/ParentConfigurations.bin) ---
# See docs/1c-support-state-spec.md. Walks up to the config root, decodes the
# object's support rule. Never throws — degrades to "не на поддержке".
function Test-ExternalObjectRoot([string]$xmlPath) {
if (-not (Test-Path $xmlPath)) { return $false }
try {
[xml]$mx = Get-Content -Path $xmlPath -Encoding UTF8
$el = $mx.DocumentElement.FirstChild
while ($el -and $el.NodeType -ne 'Element') { $el = $el.NextSibling }
if ($el) { return @('ExternalDataProcessor','ExternalReport') -contains $el.LocalName }
} catch {}
return $false
}
function Get-ObjectSupportStatus([string]$objUuid) {
try {
if (Test-ExternalObjectRoot $ObjectPath) { return $null }
# Walk up to the config root (dir with Configuration.xml or Ext/ParentConfigurations.bin).
$d = [System.IO.Path]::GetDirectoryName($ObjectPath)
$binPath = $null
@@ -653,7 +664,8 @@ if (-not $drillDone) {
if ($synonym -and $synonym -ne $objName) { $header += "`"$synonym`"" }
$header += " ==="
Out $header
Out "Поддержка: $(Get-ObjectSupportStatus $typeNode.GetAttribute('uuid'))"
$support = Get-ObjectSupportStatus $typeNode.GetAttribute('uuid')
if ($null -ne $support) { Out "Поддержка: $support" }
# --- Type presentation (ref objects) ---
if ($isRefObject) {
+19 -2
View File
@@ -1,4 +1,4 @@
# meta-info v1.3 — Compact summary of 1C metadata object (Python port)
# meta-info v1.4 — Compact summary of 1C metadata object (Python port)
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
import argparse
import os
@@ -472,8 +472,23 @@ def get_ws_operations(child_objs):
# ── Support status of this object (Ext/ParentConfigurations.bin) ──
# See docs/1c-support-state-spec.md. Walks up to the config root, decodes the
# object's support rule. Never throws — degrades to "не на поддержке".
def _meta_is_external_root(xml_path):
if not os.path.isfile(xml_path):
return False
try:
mx = etree.parse(xml_path).getroot()
for child in mx:
if isinstance(child.tag, str):
return child.tag.split("}")[-1] in ("ExternalDataProcessor", "ExternalReport")
except Exception:
return False
return False
def get_object_support_status(obj_uuid):
try:
if _meta_is_external_root(object_path):
return None
d = os.path.dirname(object_path)
bin_path = None
for _ in range(8):
@@ -703,7 +718,9 @@ if not drill_done:
header += f' \u2014 "{synonym}"'
header += " ==="
out(header)
out(f"Поддержка: {get_object_support_status(type_node.get('uuid', ''))}")
_support = get_object_support_status(type_node.get('uuid', ''))
if _support is not None:
out(f"Поддержка: {_support}")
# Type presentation (ref objects)
if is_ref_object:
@@ -1,4 +1,4 @@
# meta-remove v1.3 — Remove metadata object from 1C configuration dump
# meta-remove v1.4 — Remove metadata object from 1C configuration dump
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
param(
[Parameter(Mandatory)]
@@ -93,6 +93,16 @@ function Get-RootUuid([string]$xmlPath) {
} catch {}
return $null
}
function Test-ExternalObjectRoot([string]$xmlPath) {
if (-not (Test-Path $xmlPath)) { return $false }
try {
[xml]$mx = Get-Content -Path $xmlPath -Encoding UTF8
$el = $mx.DocumentElement.FirstChild
while ($el -and $el.NodeType -ne 'Element') { $el = $el.NextSibling }
if ($el) { return @('ExternalDataProcessor','ExternalReport') -contains $el.LocalName }
} catch {}
return $false
}
function Find-V8Project([string]$startDir) {
$d = $startDir
for ($i = 0; $i -lt 20 -and $d; $i++) {
@@ -129,10 +139,13 @@ function Assert-EditAllowed([string]$targetPath, [string]$require) {
try {
$rp = $targetPath
try { $rp = (Resolve-Path $targetPath -ErrorAction Stop).Path } catch {}
# Autonomous external object (EPF/ERF): never part of a config on support (issue #39).
if (Test-ExternalObjectRoot $rp) { return }
$elemUuid = Get-RootUuid $rp
$cfgDir = $null; $binPath = $null
$d = if (Test-Path $rp -PathType Container) { $rp } else { [System.IO.Path]::GetDirectoryName($rp) }
for ($i = 0; $i -lt 12 -and $d; $i++) {
if (Test-ExternalObjectRoot "$d.xml") { return }
if (-not $elemUuid) { $elemUuid = Get-RootUuid "$d.xml" }
if (-not $cfgDir) {
$cand = Join-Path (Join-Path $d "Ext") "ParentConfigurations.bin"
@@ -1,5 +1,5 @@
#!/usr/bin/env python3
# meta-remove v1.3 — Remove metadata object from 1C configuration dump
# meta-remove v1.4 — Remove metadata object from 1C configuration dump
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
import argparse
@@ -31,6 +31,18 @@ def _sg_root_uuid(xml_path):
return None
def _sg_is_external_root(xml_path):
if not os.path.isfile(xml_path):
return False
try:
mx = etree.parse(xml_path).getroot()
for child in mx:
if isinstance(child.tag, str):
return child.tag.split("}")[-1] in ("ExternalDataProcessor", "ExternalReport")
except Exception:
return False
return False
def _sg_find_v8project(start_dir):
d = start_dir
for _ in range(20):
@@ -70,6 +82,9 @@ def _sg_get_edit_mode(cfg_dir):
def assert_edit_allowed(target_path, require):
try:
rp = os.path.abspath(target_path)
# Autonomous external object (EPF/ERF): never part of a config on support (issue #39).
if _sg_is_external_root(rp):
return
elem_uuid = _sg_root_uuid(rp)
cfg_dir = None
bin_path = None
@@ -77,6 +92,8 @@ def assert_edit_allowed(target_path, require):
for _ in range(12):
if not d:
break
if _sg_is_external_root(d + ".xml"):
return
if not elem_uuid:
elem_uuid = _sg_root_uuid(d + ".xml")
if not cfg_dir:
@@ -1,4 +1,4 @@
# mxl-compile v1.3 — Compile 1C spreadsheet from JSON
# mxl-compile v1.4 — Compile 1C spreadsheet from JSON
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
param(
[Parameter(Mandatory)]
@@ -26,6 +26,16 @@ function Get-RootUuid([string]$xmlPath) {
} catch {}
return $null
}
function Test-ExternalObjectRoot([string]$xmlPath) {
if (-not (Test-Path $xmlPath)) { return $false }
try {
[xml]$mx = Get-Content -Path $xmlPath -Encoding UTF8
$el = $mx.DocumentElement.FirstChild
while ($el -and $el.NodeType -ne 'Element') { $el = $el.NextSibling }
if ($el) { return @('ExternalDataProcessor','ExternalReport') -contains $el.LocalName }
} catch {}
return $false
}
function Find-V8Project([string]$startDir) {
$d = $startDir
for ($i = 0; $i -lt 20 -and $d; $i++) {
@@ -62,10 +72,13 @@ function Assert-EditAllowed([string]$targetPath, [string]$require) {
try {
$rp = $targetPath
try { $rp = (Resolve-Path $targetPath -ErrorAction Stop).Path } catch {}
# Autonomous external object (EPF/ERF): never part of a config on support (issue #39).
if (Test-ExternalObjectRoot $rp) { return }
$elemUuid = Get-RootUuid $rp
$cfgDir = $null; $binPath = $null
$d = if (Test-Path $rp -PathType Container) { $rp } else { [System.IO.Path]::GetDirectoryName($rp) }
for ($i = 0; $i -lt 12 -and $d; $i++) {
if (Test-ExternalObjectRoot "$d.xml") { return }
if (-not $elemUuid) { $elemUuid = Get-RootUuid "$d.xml" }
if (-not $cfgDir) {
$cand = Join-Path (Join-Path $d "Ext") "ParentConfigurations.bin"
@@ -1,5 +1,5 @@
#!/usr/bin/env python3
# mxl-compile v1.3 — Compile 1C spreadsheet from JSON
# mxl-compile v1.4 — Compile 1C spreadsheet from JSON
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
import argparse
import json
@@ -31,6 +31,18 @@ def _sg_root_uuid(xml_path):
return None
def _sg_is_external_root(xml_path):
if not os.path.isfile(xml_path):
return False
try:
mx = etree.parse(xml_path).getroot()
for child in mx:
if isinstance(child.tag, str):
return child.tag.split("}")[-1] in ("ExternalDataProcessor", "ExternalReport")
except Exception:
return False
return False
def _sg_find_v8project(start_dir):
d = start_dir
for _ in range(20):
@@ -70,6 +82,9 @@ def _sg_get_edit_mode(cfg_dir):
def assert_edit_allowed(target_path, require):
try:
rp = os.path.abspath(target_path)
# Autonomous external object (EPF/ERF): never part of a config on support (issue #39).
if _sg_is_external_root(rp):
return
elem_uuid = _sg_root_uuid(rp)
cfg_dir = None
bin_path = None
@@ -77,6 +92,8 @@ def assert_edit_allowed(target_path, require):
for _ in range(12):
if not d:
break
if _sg_is_external_root(d + ".xml"):
return
if not elem_uuid:
elem_uuid = _sg_root_uuid(d + ".xml")
if not cfg_dir:
+15 -2
View File
@@ -1,4 +1,4 @@
# mxl-info v1.1 — Analyze 1C spreadsheet structure
# mxl-info v1.2 — Analyze 1C spreadsheet structure
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
param(
[Alias('Path')]
@@ -321,6 +321,16 @@ if ($Format -eq "json") {
exit 0
}
function Test-ExternalObjectRoot([string]$xmlPath) {
if (-not (Test-Path $xmlPath)) { return $false }
try {
[xml]$mx = Get-Content -Path $xmlPath -Encoding UTF8
$el = $mx.DocumentElement.FirstChild
while ($el -and $el.NodeType -ne 'Element') { $el = $el.NextSibling }
if ($el) { return @('ExternalDataProcessor','ExternalReport') -contains $el.LocalName }
} catch {}
return $false
}
function Get-SupportStatusForPath([string]$targetPath) {
try {
$rp = (Resolve-Path $targetPath).Path
@@ -339,8 +349,10 @@ function Get-SupportStatusForPath([string]$targetPath) {
}
# The target file itself may be the element meta-xml (e.g. Subsystems/X.xml).
$elemUuid = Get-RootUuid $rp
if (Test-ExternalObjectRoot $rp) { return $null }
$d = [System.IO.Path]::GetDirectoryName($rp)
for ($i = 0; $i -lt 12 -and $d; $i++) {
if (Test-ExternalObjectRoot "$d.xml") { return $null }
if (-not $elemUuid) { $elemUuid = Get-RootUuid "$d.xml" }
if (-not $binPath) {
$cand = Join-Path (Join-Path $d "Ext") "ParentConfigurations.bin"
@@ -385,7 +397,8 @@ function Get-SupportStatusForPath([string]$targetPath) {
$lines = @()
$lines += "=== $templateName ==="
$lines += "Поддержка: $(Get-SupportStatusForPath $TemplatePath)"
$support = Get-SupportStatusForPath $TemplatePath
if ($null -ne $support) { $lines += "Поддержка: $support" }
$lines += " Rows: $docHeight, Columns: $defaultColCount"
if ($columnSets.Count -eq 0) {
+19 -2
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env python3
# mxl-info v1.1 — Analyze 1C spreadsheet structure
# mxl-info v1.2 — Analyze 1C spreadsheet structure
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
import argparse
@@ -321,14 +321,29 @@ def get_support_status_for_path(target_path):
except Exception:
pass
return None
def is_external_root(xml_path):
if not os.path.isfile(xml_path):
return False
try:
mx = etree.parse(xml_path).getroot()
for child in mx:
if isinstance(child.tag, str):
return child.tag.split("}")[-1] in ("ExternalDataProcessor", "ExternalReport")
except Exception:
return False
return False
rp = os.path.abspath(target_path)
# The target file itself may be the element meta-xml (e.g. Subsystems/X.xml).
elem_uuid = root_uuid(rp)
if is_external_root(rp):
return None
bin_path = None
d = os.path.dirname(rp)
for _ in range(12):
if not d:
break
if is_external_root(d + ".xml"):
return None
if not elem_uuid:
elem_uuid = root_uuid(d + ".xml")
if not bin_path:
@@ -380,7 +395,9 @@ def get_support_status_for_path(target_path):
lines = []
lines.append(f"=== {template_name} ===")
lines.append(f"Поддержка: {get_support_status_for_path(template_path)}")
_support = get_support_status_for_path(template_path)
if _support is not None:
lines.append(f"Поддержка: {_support}")
lines.append(f" Rows: {doc_height}, Columns: {default_col_count}")
if len(column_sets) == 0:
@@ -1,4 +1,4 @@
# role-compile v1.7 — Compile 1C role from JSON
# role-compile v1.8 — Compile 1C role from JSON
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
param(
[Parameter(Mandatory)]
@@ -26,6 +26,16 @@ function Get-RootUuid([string]$xmlPath) {
} catch {}
return $null
}
function Test-ExternalObjectRoot([string]$xmlPath) {
if (-not (Test-Path $xmlPath)) { return $false }
try {
[xml]$mx = Get-Content -Path $xmlPath -Encoding UTF8
$el = $mx.DocumentElement.FirstChild
while ($el -and $el.NodeType -ne 'Element') { $el = $el.NextSibling }
if ($el) { return @('ExternalDataProcessor','ExternalReport') -contains $el.LocalName }
} catch {}
return $false
}
function Find-V8Project([string]$startDir) {
$d = $startDir
for ($i = 0; $i -lt 20 -and $d; $i++) {
@@ -62,10 +72,13 @@ function Assert-EditAllowed([string]$targetPath, [string]$require) {
try {
$rp = $targetPath
try { $rp = (Resolve-Path $targetPath -ErrorAction Stop).Path } catch {}
# Autonomous external object (EPF/ERF): never part of a config on support (issue #39).
if (Test-ExternalObjectRoot $rp) { return }
$elemUuid = Get-RootUuid $rp
$cfgDir = $null; $binPath = $null
$d = if (Test-Path $rp -PathType Container) { $rp } else { [System.IO.Path]::GetDirectoryName($rp) }
for ($i = 0; $i -lt 12 -and $d; $i++) {
if (Test-ExternalObjectRoot "$d.xml") { return }
if (-not $elemUuid) { $elemUuid = Get-RootUuid "$d.xml" }
if (-not $cfgDir) {
$cand = Join-Path (Join-Path $d "Ext") "ParentConfigurations.bin"
@@ -1,5 +1,5 @@
#!/usr/bin/env python3
# role-compile v1.7 — Compile 1C role from JSON
# role-compile v1.8 — Compile 1C role from JSON
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
import argparse
import json
@@ -31,6 +31,18 @@ def _sg_root_uuid(xml_path):
return None
def _sg_is_external_root(xml_path):
if not os.path.isfile(xml_path):
return False
try:
mx = etree.parse(xml_path).getroot()
for child in mx:
if isinstance(child.tag, str):
return child.tag.split("}")[-1] in ("ExternalDataProcessor", "ExternalReport")
except Exception:
return False
return False
def _sg_find_v8project(start_dir):
d = start_dir
for _ in range(20):
@@ -70,6 +82,9 @@ def _sg_get_edit_mode(cfg_dir):
def assert_edit_allowed(target_path, require):
try:
rp = os.path.abspath(target_path)
# Autonomous external object (EPF/ERF): never part of a config on support (issue #39).
if _sg_is_external_root(rp):
return
elem_uuid = _sg_root_uuid(rp)
cfg_dir = None
bin_path = None
@@ -77,6 +92,8 @@ def assert_edit_allowed(target_path, require):
for _ in range(12):
if not d:
break
if _sg_is_external_root(d + ".xml"):
return
if not elem_uuid:
elem_uuid = _sg_root_uuid(d + ".xml")
if not cfg_dir:
+15 -2
View File
@@ -1,4 +1,4 @@
# role-info v1.1 — Analyze 1C role rights
# role-info v1.2 — Analyze 1C role rights
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
param(
[Parameter(Mandatory=$true)][Alias('Path')][string]$RightsPath,
@@ -145,6 +145,16 @@ foreach ($tpl in $tplNodes) {
}
}
function Test-ExternalObjectRoot([string]$xmlPath) {
if (-not (Test-Path $xmlPath)) { return $false }
try {
[xml]$mx = Get-Content -Path $xmlPath -Encoding UTF8
$el = $mx.DocumentElement.FirstChild
while ($el -and $el.NodeType -ne 'Element') { $el = $el.NextSibling }
if ($el) { return @('ExternalDataProcessor','ExternalReport') -contains $el.LocalName }
} catch {}
return $false
}
function Get-SupportStatusForPath([string]$targetPath) {
try {
$rp = (Resolve-Path $targetPath).Path
@@ -163,8 +173,10 @@ function Get-SupportStatusForPath([string]$targetPath) {
}
# The target file itself may be the element meta-xml (e.g. Subsystems/X.xml).
$elemUuid = Get-RootUuid $rp
if (Test-ExternalObjectRoot $rp) { return $null }
$d = [System.IO.Path]::GetDirectoryName($rp)
for ($i = 0; $i -lt 12 -and $d; $i++) {
if (Test-ExternalObjectRoot "$d.xml") { return $null }
if (-not $elemUuid) { $elemUuid = Get-RootUuid "$d.xml" }
if (-not $binPath) {
$cand = Join-Path (Join-Path $d "Ext") "ParentConfigurations.bin"
@@ -209,7 +221,8 @@ $header = "=== Role: $roleName"
if ($roleSynonym) { $header += " --- `"$roleSynonym`"" }
$header += " ==="
Out $header
Out "Поддержка: $(Get-SupportStatusForPath $RightsPath)"
$support = Get-SupportStatusForPath $RightsPath
if ($null -ne $support) { Out "Поддержка: $support" }
Out ""
Out "Properties: setForNewObjects=$setForNew, setForAttributesByDefault=$setForAttrs, independentRightsOfChildObjects=$independentChild"
+19 -2
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env python3
# role-info v1.1 — Analyze 1C role rights
# role-info v1.2 — Analyze 1C role rights
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
import argparse
@@ -161,14 +161,29 @@ def get_support_status_for_path(target_path):
except Exception:
pass
return None
def is_external_root(xml_path):
if not os.path.isfile(xml_path):
return False
try:
mx = etree.parse(xml_path).getroot()
for child in mx:
if isinstance(child.tag, str):
return child.tag.split("}")[-1] in ("ExternalDataProcessor", "ExternalReport")
except Exception:
return False
return False
rp = os.path.abspath(target_path)
# The target file itself may be the element meta-xml (e.g. Subsystems/X.xml).
elem_uuid = root_uuid(rp)
if is_external_root(rp):
return None
bin_path = None
d = os.path.dirname(rp)
for _ in range(12):
if not d:
break
if is_external_root(d + ".xml"):
return None
if not elem_uuid:
elem_uuid = root_uuid(d + ".xml")
if not bin_path:
@@ -222,7 +237,9 @@ if role_synonym:
header += f' --- "{role_synonym}"'
header += " ==="
out(header)
out(f"Поддержка: {get_support_status_for_path(rights_path)}")
_support = get_support_status_for_path(rights_path)
if _support is not None:
out(f"Поддержка: {_support}")
out()
out(f"Properties: setForNewObjects={set_for_new}, setForAttributesByDefault={set_for_attrs}, independentRightsOfChildObjects={independent_child}")
@@ -1,4 +1,4 @@
# skd-compile v1.107 — Compile 1C DCS from JSON
# skd-compile v1.108 — Compile 1C DCS from JSON
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
param(
[string]$DefinitionFile,
@@ -25,6 +25,16 @@ function Get-RootUuid([string]$xmlPath) {
} catch {}
return $null
}
function Test-ExternalObjectRoot([string]$xmlPath) {
if (-not (Test-Path $xmlPath)) { return $false }
try {
[xml]$mx = Get-Content -Path $xmlPath -Encoding UTF8
$el = $mx.DocumentElement.FirstChild
while ($el -and $el.NodeType -ne 'Element') { $el = $el.NextSibling }
if ($el) { return @('ExternalDataProcessor','ExternalReport') -contains $el.LocalName }
} catch {}
return $false
}
function Find-V8Project([string]$startDir) {
$d = $startDir
for ($i = 0; $i -lt 20 -and $d; $i++) {
@@ -61,10 +71,13 @@ function Assert-EditAllowed([string]$targetPath, [string]$require) {
try {
$rp = $targetPath
try { $rp = (Resolve-Path $targetPath -ErrorAction Stop).Path } catch {}
# Autonomous external object (EPF/ERF): never part of a config on support (issue #39).
if (Test-ExternalObjectRoot $rp) { return }
$elemUuid = Get-RootUuid $rp
$cfgDir = $null; $binPath = $null
$d = if (Test-Path $rp -PathType Container) { $rp } else { [System.IO.Path]::GetDirectoryName($rp) }
for ($i = 0; $i -lt 12 -and $d; $i++) {
if (Test-ExternalObjectRoot "$d.xml") { return }
if (-not $elemUuid) { $elemUuid = Get-RootUuid "$d.xml" }
if (-not $cfgDir) {
$cand = Join-Path (Join-Path $d "Ext") "ParentConfigurations.bin"
@@ -1,5 +1,5 @@
#!/usr/bin/env python3
# skd-compile v1.107 — Compile 1C DCS from JSON
# skd-compile v1.108 — Compile 1C DCS from JSON
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
import argparse
import json
@@ -31,6 +31,18 @@ def _sg_root_uuid(xml_path):
return None
def _sg_is_external_root(xml_path):
if not os.path.isfile(xml_path):
return False
try:
mx = etree.parse(xml_path).getroot()
for child in mx:
if isinstance(child.tag, str):
return child.tag.split("}")[-1] in ("ExternalDataProcessor", "ExternalReport")
except Exception:
return False
return False
def _sg_find_v8project(start_dir):
d = start_dir
for _ in range(20):
@@ -70,6 +82,9 @@ def _sg_get_edit_mode(cfg_dir):
def assert_edit_allowed(target_path, require):
try:
rp = os.path.abspath(target_path)
# Autonomous external object (EPF/ERF): never part of a config on support (issue #39).
if _sg_is_external_root(rp):
return
elem_uuid = _sg_root_uuid(rp)
cfg_dir = None
bin_path = None
@@ -77,6 +92,8 @@ def assert_edit_allowed(target_path, require):
for _ in range(12):
if not d:
break
if _sg_is_external_root(d + ".xml"):
return
if not elem_uuid:
elem_uuid = _sg_root_uuid(d + ".xml")
if not cfg_dir:
+14 -1
View File
@@ -1,4 +1,4 @@
# skd-edit v1.28 — Atomic 1C DCS editor
# skd-edit v1.29 — Atomic 1C DCS editor
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
# NB: парный .py собирает выражения автодат вне f-string ради совместимости с python 3.9 (PEP 701).
param(
@@ -64,6 +64,16 @@ function Get-RootUuid([string]$xmlPath) {
} catch {}
return $null
}
function Test-ExternalObjectRoot([string]$xmlPath) {
if (-not (Test-Path $xmlPath)) { return $false }
try {
[xml]$mx = Get-Content -Path $xmlPath -Encoding UTF8
$el = $mx.DocumentElement.FirstChild
while ($el -and $el.NodeType -ne 'Element') { $el = $el.NextSibling }
if ($el) { return @('ExternalDataProcessor','ExternalReport') -contains $el.LocalName }
} catch {}
return $false
}
function Find-V8Project([string]$startDir) {
$d = $startDir
for ($i = 0; $i -lt 20 -and $d; $i++) {
@@ -100,10 +110,13 @@ function Assert-EditAllowed([string]$targetPath, [string]$require) {
try {
$rp = $targetPath
try { $rp = (Resolve-Path $targetPath -ErrorAction Stop).Path } catch {}
# Autonomous external object (EPF/ERF): never part of a config on support (issue #39).
if (Test-ExternalObjectRoot $rp) { return }
$elemUuid = Get-RootUuid $rp
$cfgDir = $null; $binPath = $null
$d = if (Test-Path $rp -PathType Container) { $rp } else { [System.IO.Path]::GetDirectoryName($rp) }
for ($i = 0; $i -lt 12 -and $d; $i++) {
if (Test-ExternalObjectRoot "$d.xml") { return }
if (-not $elemUuid) { $elemUuid = Get-RootUuid "$d.xml" }
if (-not $cfgDir) {
$cand = Join-Path (Join-Path $d "Ext") "ParentConfigurations.bin"
+18 -1
View File
@@ -1,4 +1,4 @@
# skd-edit v1.28 — Atomic 1C DCS editor (Python port)
# skd-edit v1.29 — Atomic 1C DCS editor (Python port)
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
import argparse
import json
@@ -141,6 +141,18 @@ def _sg_root_uuid(xml_path):
return None
def _sg_is_external_root(xml_path):
if not os.path.isfile(xml_path):
return False
try:
mx = etree.parse(xml_path).getroot()
for child in mx:
if isinstance(child.tag, str):
return child.tag.split("}")[-1] in ("ExternalDataProcessor", "ExternalReport")
except Exception:
return False
return False
def _sg_find_v8project(start_dir):
d = start_dir
for _ in range(20):
@@ -180,6 +192,9 @@ def _sg_get_edit_mode(cfg_dir):
def assert_edit_allowed(target_path, require):
try:
rp = os.path.abspath(target_path)
# Autonomous external object (EPF/ERF): never part of a config on support (issue #39).
if _sg_is_external_root(rp):
return
elem_uuid = _sg_root_uuid(rp)
cfg_dir = None
bin_path = None
@@ -187,6 +202,8 @@ def assert_edit_allowed(target_path, require):
for _ in range(12):
if not d:
break
if _sg_is_external_root(d + ".xml"):
return
if not elem_uuid:
elem_uuid = _sg_root_uuid(d + ".xml")
if not cfg_dir:
+15 -2
View File
@@ -1,4 +1,4 @@
# skd-info v1.7 — Analyze 1C DCS structure
# skd-info v1.8 — Analyze 1C DCS structure
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
param(
[Parameter(Mandatory=$true)]
@@ -334,6 +334,16 @@ for ($i = $pathParts.Count - 1; $i -ge 0; $i--) {
$totalXmlLines = (Get-Content $resolvedPath).Count
function Test-ExternalObjectRoot([string]$xmlPath) {
if (-not (Test-Path $xmlPath)) { return $false }
try {
[xml]$mx = Get-Content -Path $xmlPath -Encoding UTF8
$el = $mx.DocumentElement.FirstChild
while ($el -and $el.NodeType -ne 'Element') { $el = $el.NextSibling }
if ($el) { return @('ExternalDataProcessor','ExternalReport') -contains $el.LocalName }
} catch {}
return $false
}
function Get-SupportStatusForPath([string]$targetPath) {
try {
$rp = (Resolve-Path $targetPath).Path
@@ -352,8 +362,10 @@ function Get-SupportStatusForPath([string]$targetPath) {
}
# The target file itself may be the element meta-xml (e.g. Subsystems/X.xml).
$elemUuid = Get-RootUuid $rp
if (Test-ExternalObjectRoot $rp) { return $null }
$d = [System.IO.Path]::GetDirectoryName($rp)
for ($i = 0; $i -lt 12 -and $d; $i++) {
if (Test-ExternalObjectRoot "$d.xml") { return $null }
if (-not $elemUuid) { $elemUuid = Get-RootUuid "$d.xml" }
if (-not $binPath) {
$cand = Join-Path (Join-Path $d "Ext") "ParentConfigurations.bin"
@@ -395,7 +407,8 @@ function Get-SupportStatusForPath([string]$targetPath) {
function Show-Overview {
$lines.Add("=== DCS: $templateName ($totalXmlLines lines) ===")
$lines.Add("Поддержка: $(Get-SupportStatusForPath $TemplatePath)")
$support = Get-SupportStatusForPath $TemplatePath
if ($null -ne $support) { $lines.Add("Поддержка: $support") }
$lines.Add("")
# Sources
+19 -2
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env python3
# skd-info v1.7 — Analyze 1C DCS structure
# skd-info v1.8 — Analyze 1C DCS structure
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
import argparse
@@ -278,14 +278,29 @@ def get_support_status_for_path(target_path):
except Exception:
pass
return None
def is_external_root(xml_path):
if not os.path.isfile(xml_path):
return False
try:
mx = etree.parse(xml_path).getroot()
for child in mx:
if isinstance(child.tag, str):
return child.tag.split("}")[-1] in ("ExternalDataProcessor", "ExternalReport")
except Exception:
return False
return False
rp = os.path.abspath(target_path)
# The target file itself may be the element meta-xml (e.g. Subsystems/X.xml).
elem_uuid = root_uuid(rp)
if is_external_root(rp):
return None
bin_path = None
d = os.path.dirname(rp)
for _ in range(12):
if not d:
break
if is_external_root(d + ".xml"):
return None
if not elem_uuid:
elem_uuid = root_uuid(d + ".xml")
if not bin_path:
@@ -424,7 +439,9 @@ def main():
def show_overview():
lines.append(f"=== DCS: {template_name} ({total_xml_lines} lines) ===")
lines.append(f"Поддержка: {get_support_status_for_path(template_path)}")
_support = get_support_status_for_path(template_path)
if _support is not None:
lines.append(f"Поддержка: {_support}")
lines.append("")
# Sources
@@ -1,4 +1,4 @@
# subsystem-compile v1.8 — Create 1C subsystem from JSON definition
# subsystem-compile v1.9 — Create 1C subsystem from JSON definition
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
param(
[string]$DefinitionFile,
@@ -63,6 +63,16 @@ function Get-RootUuid([string]$xmlPath) {
} catch {}
return $null
}
function Test-ExternalObjectRoot([string]$xmlPath) {
if (-not (Test-Path $xmlPath)) { return $false }
try {
[xml]$mx = Get-Content -Path $xmlPath -Encoding UTF8
$el = $mx.DocumentElement.FirstChild
while ($el -and $el.NodeType -ne 'Element') { $el = $el.NextSibling }
if ($el) { return @('ExternalDataProcessor','ExternalReport') -contains $el.LocalName }
} catch {}
return $false
}
function Find-V8Project([string]$startDir) {
$d = $startDir
for ($i = 0; $i -lt 20 -and $d; $i++) {
@@ -99,10 +109,13 @@ function Assert-EditAllowed([string]$targetPath, [string]$require) {
try {
$rp = $targetPath
try { $rp = (Resolve-Path $targetPath -ErrorAction Stop).Path } catch {}
# Autonomous external object (EPF/ERF): never part of a config on support (issue #39).
if (Test-ExternalObjectRoot $rp) { return }
$elemUuid = Get-RootUuid $rp
$cfgDir = $null; $binPath = $null
$d = if (Test-Path $rp -PathType Container) { $rp } else { [System.IO.Path]::GetDirectoryName($rp) }
for ($i = 0; $i -lt 12 -and $d; $i++) {
if (Test-ExternalObjectRoot "$d.xml") { return }
if (-not $elemUuid) { $elemUuid = Get-RootUuid "$d.xml" }
if (-not $cfgDir) {
$cand = Join-Path (Join-Path $d "Ext") "ParentConfigurations.bin"
@@ -1,5 +1,5 @@
#!/usr/bin/env python3
# subsystem-compile v1.8 — Create 1C subsystem from JSON definition
# subsystem-compile v1.9 — Create 1C subsystem from JSON definition
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
import argparse
import json
@@ -32,6 +32,18 @@ def _sg_root_uuid(xml_path):
return None
def _sg_is_external_root(xml_path):
if not os.path.isfile(xml_path):
return False
try:
mx = etree.parse(xml_path).getroot()
for child in mx:
if isinstance(child.tag, str):
return child.tag.split("}")[-1] in ("ExternalDataProcessor", "ExternalReport")
except Exception:
return False
return False
def _sg_find_v8project(start_dir):
d = start_dir
for _ in range(20):
@@ -71,6 +83,9 @@ def _sg_get_edit_mode(cfg_dir):
def assert_edit_allowed(target_path, require):
try:
rp = os.path.abspath(target_path)
# Autonomous external object (EPF/ERF): never part of a config on support (issue #39).
if _sg_is_external_root(rp):
return
elem_uuid = _sg_root_uuid(rp)
cfg_dir = None
bin_path = None
@@ -78,6 +93,8 @@ def assert_edit_allowed(target_path, require):
for _ in range(12):
if not d:
break
if _sg_is_external_root(d + ".xml"):
return
if not elem_uuid:
elem_uuid = _sg_root_uuid(d + ".xml")
if not cfg_dir:
@@ -1,4 +1,4 @@
# subsystem-edit v1.5 — Edit existing 1C subsystem XML
# subsystem-edit v1.6 — Edit existing 1C subsystem XML
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
param(
[Parameter(Mandatory)][Alias('Path')][string]$SubsystemPath,
@@ -136,6 +136,16 @@ function Get-RootUuid([string]$xmlPath) {
} catch {}
return $null
}
function Test-ExternalObjectRoot([string]$xmlPath) {
if (-not (Test-Path $xmlPath)) { return $false }
try {
[xml]$mx = Get-Content -Path $xmlPath -Encoding UTF8
$el = $mx.DocumentElement.FirstChild
while ($el -and $el.NodeType -ne 'Element') { $el = $el.NextSibling }
if ($el) { return @('ExternalDataProcessor','ExternalReport') -contains $el.LocalName }
} catch {}
return $false
}
function Find-V8Project([string]$startDir) {
$d = $startDir
for ($i = 0; $i -lt 20 -and $d; $i++) {
@@ -172,10 +182,13 @@ function Assert-EditAllowed([string]$targetPath, [string]$require) {
try {
$rp = $targetPath
try { $rp = (Resolve-Path $targetPath -ErrorAction Stop).Path } catch {}
# Autonomous external object (EPF/ERF): never part of a config on support (issue #39).
if (Test-ExternalObjectRoot $rp) { return }
$elemUuid = Get-RootUuid $rp
$cfgDir = $null; $binPath = $null
$d = if (Test-Path $rp -PathType Container) { $rp } else { [System.IO.Path]::GetDirectoryName($rp) }
for ($i = 0; $i -lt 12 -and $d; $i++) {
if (Test-ExternalObjectRoot "$d.xml") { return }
if (-not $elemUuid) { $elemUuid = Get-RootUuid "$d.xml" }
if (-not $cfgDir) {
$cand = Join-Path (Join-Path $d "Ext") "ParentConfigurations.bin"
@@ -1,5 +1,5 @@
#!/usr/bin/env python3
# subsystem-edit v1.5 — Edit existing 1C subsystem XML
# subsystem-edit v1.6 — Edit existing 1C subsystem XML
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
import argparse
@@ -32,6 +32,18 @@ def _sg_root_uuid(xml_path):
return None
def _sg_is_external_root(xml_path):
if not os.path.isfile(xml_path):
return False
try:
mx = etree.parse(xml_path).getroot()
for child in mx:
if isinstance(child.tag, str):
return child.tag.split("}")[-1] in ("ExternalDataProcessor", "ExternalReport")
except Exception:
return False
return False
def _sg_find_v8project(start_dir):
d = start_dir
for _ in range(20):
@@ -71,6 +83,9 @@ def _sg_get_edit_mode(cfg_dir):
def assert_edit_allowed(target_path, require):
try:
rp = os.path.abspath(target_path)
# Autonomous external object (EPF/ERF): never part of a config on support (issue #39).
if _sg_is_external_root(rp):
return
elem_uuid = _sg_root_uuid(rp)
cfg_dir = None
bin_path = None
@@ -78,6 +93,8 @@ def assert_edit_allowed(target_path, require):
for _ in range(12):
if not d:
break
if _sg_is_external_root(d + ".xml"):
return
if not elem_uuid:
elem_uuid = _sg_root_uuid(d + ".xml")
if not cfg_dir:
@@ -1,4 +1,4 @@
# subsystem-info v1.1 — Compact summary of 1C subsystem structure
# subsystem-info v1.2 — Compact summary of 1C subsystem structure
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
param(
[Parameter(Mandatory=$true)][Alias('Path')][string]$SubsystemPath,
@@ -17,6 +17,16 @@ $ErrorActionPreference = 'Stop'
$script:lines = @()
function Out([string]$text) { $script:lines += $text }
function Test-ExternalObjectRoot([string]$xmlPath) {
if (-not (Test-Path $xmlPath)) { return $false }
try {
[xml]$mx = Get-Content -Path $xmlPath -Encoding UTF8
$el = $mx.DocumentElement.FirstChild
while ($el -and $el.NodeType -ne 'Element') { $el = $el.NextSibling }
if ($el) { return @('ExternalDataProcessor','ExternalReport') -contains $el.LocalName }
} catch {}
return $false
}
function Get-SupportStatusForPath([string]$targetPath) {
try {
$rp = (Resolve-Path $targetPath).Path
@@ -35,8 +45,10 @@ function Get-SupportStatusForPath([string]$targetPath) {
}
# The target file itself may be the element meta-xml (e.g. Subsystems/X.xml).
$elemUuid = Get-RootUuid $rp
if (Test-ExternalObjectRoot $rp) { return $null }
$d = [System.IO.Path]::GetDirectoryName($rp)
for ($i = 0; $i -lt 12 -and $d; $i++) {
if (Test-ExternalObjectRoot "$d.xml") { return $null }
if (-not $elemUuid) { $elemUuid = Get-RootUuid "$d.xml" }
if (-not $binPath) {
$cand = Join-Path (Join-Path $d "Ext") "ParentConfigurations.bin"
@@ -175,7 +187,8 @@ function Get-SubsystemDir([string]$xmlPath) {
# --- Show functions for full mode ---
function Show-Overview {
Out "Подсистема: $subName"
Out "Поддержка: $(Get-SupportStatusForPath $SubsystemPath)"
$support = Get-SupportStatusForPath $SubsystemPath
if ($null -ne $support) { Out "Поддержка: $support" }
if ($synonym -and $synonym -ne $subName) { Out "Синоним: $synonym" }
if ($commentText) { Out "Комментарий: $commentText" }
Out "ВключатьВКомандныйИнтерфейс: $inclCI"
@@ -1,5 +1,5 @@
#!/usr/bin/env python3
# subsystem-info v1.1 — Compact summary of 1C subsystem structure
# subsystem-info v1.2 — Compact summary of 1C subsystem structure
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
import argparse
@@ -150,14 +150,29 @@ def get_support_status_for_path(target_path):
except Exception:
pass
return None
def is_external_root(xml_path):
if not os.path.isfile(xml_path):
return False
try:
mx = etree.parse(xml_path).getroot()
for child in mx:
if isinstance(child.tag, str):
return child.tag.split("}")[-1] in ("ExternalDataProcessor", "ExternalReport")
except Exception:
return False
return False
rp = os.path.abspath(target_path)
# The target file itself may be the element meta-xml (e.g. Subsystems/X.xml).
elem_uuid = root_uuid(rp)
if is_external_root(rp):
return None
bin_path = None
d = os.path.dirname(rp)
for _ in range(12):
if not d:
break
if is_external_root(d + ".xml"):
return None
if not elem_uuid:
elem_uuid = root_uuid(d + ".xml")
if not bin_path:
@@ -208,7 +223,9 @@ def get_support_status_for_path(target_path):
def show_overview(sub_name, synonym, comment_text, incl_ci, use_one_cmd,
explanation, pic_text, content_items, groups, child_names, has_ci):
out(f"Подсистема: {sub_name}")
out(f"Поддержка: {get_support_status_for_path(subsystem_path)}")
_support = get_support_status_for_path(subsystem_path)
if _support is not None:
out(f"Поддержка: {_support}")
if synonym and synonym != sub_name:
out(f"Синоним: {synonym}")
if comment_text:
@@ -1,4 +1,4 @@
# template-add v1.7 — Add template to 1C object
# template-add v1.8 — Add template to 1C object
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
param(
[Parameter(Mandatory)]
@@ -38,6 +38,16 @@ function Get-RootUuid([string]$xmlPath) {
} catch {}
return $null
}
function Test-ExternalObjectRoot([string]$xmlPath) {
if (-not (Test-Path $xmlPath)) { return $false }
try {
[xml]$mx = Get-Content -Path $xmlPath -Encoding UTF8
$el = $mx.DocumentElement.FirstChild
while ($el -and $el.NodeType -ne 'Element') { $el = $el.NextSibling }
if ($el) { return @('ExternalDataProcessor','ExternalReport') -contains $el.LocalName }
} catch {}
return $false
}
function Find-V8Project([string]$startDir) {
$d = $startDir
for ($i = 0; $i -lt 20 -and $d; $i++) {
@@ -74,10 +84,13 @@ function Assert-EditAllowed([string]$targetPath, [string]$require) {
try {
$rp = $targetPath
try { $rp = (Resolve-Path $targetPath -ErrorAction Stop).Path } catch {}
# Autonomous external object (EPF/ERF): never part of a config on support (issue #39).
if (Test-ExternalObjectRoot $rp) { return }
$elemUuid = Get-RootUuid $rp
$cfgDir = $null; $binPath = $null
$d = if (Test-Path $rp -PathType Container) { $rp } else { [System.IO.Path]::GetDirectoryName($rp) }
for ($i = 0; $i -lt 12 -and $d; $i++) {
if (Test-ExternalObjectRoot "$d.xml") { return }
if (-not $elemUuid) { $elemUuid = Get-RootUuid "$d.xml" }
if (-not $cfgDir) {
$cand = Join-Path (Join-Path $d "Ext") "ParentConfigurations.bin"
@@ -1,5 +1,5 @@
#!/usr/bin/env python3
# add-template v1.7 — Add template to 1C object
# add-template v1.8 — Add template to 1C object
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
import argparse
@@ -34,6 +34,18 @@ def _sg_root_uuid(xml_path):
return None
def _sg_is_external_root(xml_path):
if not os.path.isfile(xml_path):
return False
try:
mx = etree.parse(xml_path).getroot()
for child in mx:
if isinstance(child.tag, str):
return child.tag.split("}")[-1] in ("ExternalDataProcessor", "ExternalReport")
except Exception:
return False
return False
def _sg_find_v8project(start_dir):
d = start_dir
for _ in range(20):
@@ -73,6 +85,9 @@ def _sg_get_edit_mode(cfg_dir):
def assert_edit_allowed(target_path, require):
try:
rp = os.path.abspath(target_path)
# Autonomous external object (EPF/ERF): never part of a config on support (issue #39).
if _sg_is_external_root(rp):
return
elem_uuid = _sg_root_uuid(rp)
cfg_dir = None
bin_path = None
@@ -80,6 +95,8 @@ def assert_edit_allowed(target_path, require):
for _ in range(12):
if not d:
break
if _sg_is_external_root(d + ".xml"):
return
if not elem_uuid:
elem_uuid = _sg_root_uuid(d + ".xml")
if not cfg_dir:
+24 -1
View File
@@ -1,4 +1,4 @@
// support-state.mjs v1.0 — decode 1C support state (Ext/ParentConfigurations.bin) for Claude Code hooks
// support-state.mjs v1.1 — decode 1C support state (Ext/ParentConfigurations.bin) for Claude Code hooks
// Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
//
// Canonical port of the in-skill guard Assert-EditAllowed / assert_edit_allowed
@@ -13,6 +13,20 @@ import { readFileSync, existsSync, statSync } from 'node:fs';
import { dirname, join } from 'node:path';
const GUID_RE = /\buuid="([0-9a-fA-F-]{36})"/;
// Root child of an autonomous external object dump (EPF/ERF). Such an object is never
// part of a configuration on support, even when its dump sits inside the config tree —
// the climb must stop at this boundary instead of attributing it to the enclosing config.
const EXT_ROOT_RE = /<MetaDataObject\b[^>]*>\s*<(?:\w+:)?(?:ExternalDataProcessor|ExternalReport)\b/;
// True when xmlPath is the root file of an autonomous ExternalDataProcessor / ExternalReport.
export function isExternalObjectRoot(xmlPath) {
try {
if (!existsSync(xmlPath) || !statSync(xmlPath).isFile()) return false;
return EXT_ROOT_RE.test(readFileSync(xmlPath, 'utf8').slice(0, 1000));
} catch {
return false;
}
}
// First uuid="..." in an object XML == root element uuid (the <MetaDataObject> wrapper
// carries none), matching the reference's "first element child uuid" semantics.
@@ -40,7 +54,11 @@ export function findConfigRoot(startPath) {
} catch {
d = dirname(startPath);
}
// startPath itself may be the external object root file.
if (isExternalObjectRoot(startPath)) return { cfgDir: null, binPath: null, isExtension: false };
for (let i = 0; i < 12 && d; i++) {
// Crossed the boundary of an autonomous external object → not part of any config.
if (isExternalObjectRoot(d + '.xml')) return { cfgDir: null, binPath: null, isExtension: false };
const cand = join(d, 'Ext', 'ParentConfigurations.bin');
const cfgX = join(d, 'Configuration.xml');
if (existsSync(cand) || existsSync(cfgX)) {
@@ -70,6 +88,9 @@ export function findConfigRoot(startPath) {
export function decideSupport(targetPath, require = 'editable') {
const result = { blocked: false, reason: '', code: null, cfgDir: null, targetPath };
try {
// Autonomous external object (EPF/ERF): its root is never part of a configuration on
// support, even when the dump sits inside the config tree — do not attribute it (issue #39).
if (isExternalObjectRoot(targetPath)) return result;
let elemUuid = rootUuid(targetPath);
// Walk up: collect elemUuid (from <dir>.xml of a sub-element) and the config root.
let cfgDir = null, binPath = null;
@@ -80,6 +101,8 @@ export function decideSupport(targetPath, require = 'editable') {
d = dirname(targetPath);
}
for (let i = 0; i < 12 && d; i++) {
// Crossed the boundary of an autonomous external object → allow (not on support).
if (isExternalObjectRoot(d + '.xml')) return result;
if (!elemUuid) elemUuid = rootUuid(d + '.xml');
if (!cfgDir) {
const cand = join(d, 'Ext', 'ParentConfigurations.bin');
+40 -1
View File
@@ -4,7 +4,7 @@
// No live hook registration needed: exercises decideSupport / getEditMode / findConfigRoot
// directly. Run: node hooks/test/run.mjs
import { decideSupport, findConfigRoot, rootUuid } from '../common/support-state.mjs';
import { decideSupport, findConfigRoot, rootUuid, isExternalObjectRoot } from '../common/support-state.mjs';
import { getEditMode, getSuggesterMode } from '../common/project.mjs';
import { processInput as guard } from '../support-guard.mjs';
import { processInput as suggest } from '../skill-suggester.mjs';
@@ -96,6 +96,45 @@ console.log('=== support-state: synthetic per-object f1 (G=0) ===');
check('synth remove removed (f1=2) → NOT blocked', rmRemoved.blocked === false, JSON.stringify(rmRemoved));
}
console.log('=== support-state: external object boundary (issue #39) ===');
{
// Autonomous EPF/ERF parked INSIDE a config tree whose capability is off (G=1). The
// climb must stop at the external object's root and NOT attribute it to the config.
const ROOT = join(REPO, 'test-tmp', 'hooks-ext');
const cat = '66666666-6666-6666-6666-666666666666';
mkdirSync(join(ROOT, 'Ext'), { recursive: true });
mkdirSync(join(ROOT, 'Catalogs'), { recursive: true });
mkdirSync(join(ROOT, 'print-forms', 'Демо', 'Templates', 'Макет', 'Ext'), { recursive: true });
// G=1 (capability off), K=1 — blocks every config object unconditionally.
const binText = `{6,1,1,aaaaaaaa-0000-0000-0000-000000000000,0,bbbbbbbb-0000-0000-0000-000000000000,` +
`"1.0","Vendor","Name",1,0,0,${cat}}`;
writeFileSync(join(ROOT, 'Ext', 'ParentConfigurations.bin'),
Buffer.concat([Buffer.from([0xef, 0xbb, 0xbf]), Buffer.from(binText, 'utf8')]));
writeFileSync(join(ROOT, 'Configuration.xml'),
`<?xml version="1.0" encoding="UTF-8"?>\n<MetaDataObject><Configuration uuid="11111111-1111-1111-1111-111111111111"></Configuration></MetaDataObject>`);
writeFileSync(join(ROOT, 'Catalogs', 'InConfig.xml'),
`<?xml version="1.0" encoding="UTF-8"?>\n<MetaDataObject><Catalog uuid="${cat}"></Catalog></MetaDataObject>`);
writeFileSync(join(ROOT, 'print-forms', 'Демо.xml'),
`<?xml version="1.0" encoding="UTF-8"?>\n<MetaDataObject xmlns="http://v8.1c.ru/8.3/MDClasses">\n\t<ExternalDataProcessor uuid="99999999-9999-9999-9999-999999999999"><Properties><Name>Демо</Name></Properties></ExternalDataProcessor>\n</MetaDataObject>`);
writeFileSync(join(ROOT, 'print-forms', 'Демо', 'Templates', 'Макет', 'Ext', 'Template.xml'),
`<?xml version="1.0"?><document xmlns="http://v8.1c.ru/8.1/data/spreadsheet"></document>`);
const epfRoot = join(ROOT, 'print-forms', 'Демо.xml');
const epfTpl = join(ROOT, 'print-forms', 'Демо', 'Templates', 'Макет', 'Ext', 'Template.xml');
const cfgObj = join(ROOT, 'Catalogs', 'InConfig.xml');
check('isExternalObjectRoot(EPF root) → true', isExternalObjectRoot(epfRoot) === true);
check('isExternalObjectRoot(config Catalog) → false', isExternalObjectRoot(cfgObj) === false);
check('EPF root → NOT blocked (G=1 config ignored)', decideSupport(epfRoot, 'editable').blocked === false, JSON.stringify(decideSupport(epfRoot, 'editable')));
const rTpl = decideSupport(epfTpl, 'editable');
check('EPF template → NOT blocked (climb stops at EPF root)', rTpl.blocked === false, JSON.stringify(rTpl));
const rCfg = decideSupport(cfgObj, 'editable');
check('control: config object under G=1 → blocked', rCfg.blocked === true && rCfg.code === 'capability-off', JSON.stringify(rCfg));
check('findConfigRoot(EPF template) → no cfgDir', findConfigRoot(epfTpl).cfgDir === null, JSON.stringify(findConfigRoot(epfTpl)));
const rGuard = guard({ tool_name: 'Edit', cwd: REPO, tool_input: { file_path: epfTpl } });
check('guard on EPF template → allow (no stdout)', rGuard.stdout === '' && rGuard.exitCode === 0, JSON.stringify(rGuard));
}
console.log('=== project: reaction modes ===');
{
const m = getEditMode(ACC, REPO);
@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<MetaDataObject xmlns="http://v8.1c.ru/8.3/MDClasses"><Configuration uuid="11111111-1111-1111-1111-111111111111"><Properties><Name>ТестКонфа</Name></Properties></Configuration></MetaDataObject>
@@ -0,0 +1 @@
{6,1,1,aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa,0,bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb,"1.0","ТестВендор","ТестКонфа",1,0,0,cccccccc-cccc-cccc-cccc-cccccccccccc}
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<MetaDataObject xmlns="http://v8.1c.ru/8.3/MDClasses">
<ExternalDataProcessor uuid="99999999-9999-9999-9999-999999999999"><Properties><Name>Демо</Name></Properties></ExternalDataProcessor>
</MetaDataObject>
@@ -0,0 +1,54 @@
<?xml version="1.0" encoding="UTF-8"?>
<document xmlns="http://v8.1c.ru/8.2/data/spreadsheet" xmlns:style="http://v8.1c.ru/8.1/data/ui/style" xmlns:v8="http://v8.1c.ru/8.1/data/core" xmlns:v8ui="http://v8.1c.ru/8.1/data/ui" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<languageSettings>
<currentLanguage>ru</currentLanguage>
<defaultLanguage>ru</defaultLanguage>
<languageInfo>
<id>ru</id>
<code>Русский</code>
<description>Русский</description>
</languageInfo>
</languageSettings>
<columns>
<size>1</size>
</columns>
<rowsItem>
<index>0</index>
<row>
<c>
<i>0</i>
<c>
<f>2</f>
<tl>
<v8:item>
<v8:lang>ru</v8:lang>
<v8:content>Значение</v8:content>
</v8:item>
</tl>
</c>
</c>
</row>
</rowsItem>
<templateMode>true</templateMode>
<defaultFormatIndex>1</defaultFormatIndex>
<height>1</height>
<vgRows>1</vgRows>
<namedItem xsi:type="NamedItemCells">
<name>Ячейка</name>
<area>
<type>Rows</type>
<beginRow>0</beginRow>
<endRow>0</endRow>
<beginColumn>-1</beginColumn>
<endColumn>-1</endColumn>
</area>
</namedItem>
<font faceName="Arial" height="10" bold="false" italic="false" underline="false" strikeout="false" kind="Absolute" scale="100"/>
<format>
<width>10</width>
</format>
<format>
<font>0</font>
<fillType>Text</fillType>
</format>
</document>
@@ -0,0 +1,23 @@
{
"name": "Guard #39: автономная EPF внутри конфигурации на поддержке (G=1) НЕ блокируется",
"setup": "fixture:epf-in-locked-config",
"input": {
"columns": 2,
"areas": [
{
"name": "О",
"rows": [
{
"cells": [
{
"col": 1,
"text": "a"
}
]
}
]
}
]
},
"outputPath": "print-forms/Демо/Templates/Макет/Ext/Template.xml"
}
@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<MetaDataObject xmlns="http://v8.1c.ru/8.3/MDClasses"><Configuration uuid="11111111-1111-1111-1111-111111111111"><Properties><Name>ТестКонфа</Name></Properties></Configuration></MetaDataObject>
@@ -0,0 +1 @@
{6,1,1,aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa,0,bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb,"1.0","ТестВендор","ТестКонфа",1,0,0,cccccccc-cccc-cccc-cccc-cccccccccccc}
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<MetaDataObject xmlns="http://v8.1c.ru/8.3/MDClasses">
<ExternalDataProcessor uuid="99999999-9999-9999-9999-999999999999"><Properties><Name>Демо</Name></Properties></ExternalDataProcessor>
</MetaDataObject>
@@ -0,0 +1,54 @@
<?xml version="1.0" encoding="UTF-8"?>
<document xmlns="http://v8.1c.ru/8.2/data/spreadsheet" xmlns:style="http://v8.1c.ru/8.1/data/ui/style" xmlns:v8="http://v8.1c.ru/8.1/data/core" xmlns:v8ui="http://v8.1c.ru/8.1/data/ui" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<languageSettings>
<currentLanguage>ru</currentLanguage>
<defaultLanguage>ru</defaultLanguage>
<languageInfo>
<id>ru</id>
<code>Русский</code>
<description>Русский</description>
</languageInfo>
</languageSettings>
<columns>
<size>2</size>
</columns>
<rowsItem>
<index>0</index>
<row>
<c>
<i>0</i>
<c>
<f>2</f>
<tl>
<v8:item>
<v8:lang>ru</v8:lang>
<v8:content>a</v8:content>
</v8:item>
</tl>
</c>
</c>
</row>
</rowsItem>
<templateMode>true</templateMode>
<defaultFormatIndex>1</defaultFormatIndex>
<height>1</height>
<vgRows>1</vgRows>
<namedItem xsi:type="NamedItemCells">
<name>О</name>
<area>
<type>Rows</type>
<beginRow>0</beginRow>
<endRow>0</endRow>
<beginColumn>-1</beginColumn>
<endColumn>-1</endColumn>
</area>
</namedItem>
<font faceName="Arial" height="10" bold="false" italic="false" underline="false" strikeout="false" kind="Absolute" scale="100"/>
<format>
<width>10</width>
</format>
<format>
<font>0</font>
<fillType>Text</fillType>
</format>
</document>
@@ -0,0 +1,6 @@
{
"name": "Info #39: для автономной EPF строка «Поддержка:» не выводится",
"setup": "fixture:epf-in-locked-config",
"params": { "templatePath": "print-forms/Демо/Templates/Макет/Ext/Template.xml" },
"expect": { "stdoutNotContains": "Поддержка:" }
}
@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<MetaDataObject xmlns="http://v8.1c.ru/8.3/MDClasses"><Configuration uuid="11111111-1111-1111-1111-111111111111"><Properties><Name>ТестКонфа</Name></Properties></Configuration></MetaDataObject>
@@ -0,0 +1 @@
{6,1,1,aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa,0,bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb,"1.0","ТестВендор","ТестКонфа",1,0,0,cccccccc-cccc-cccc-cccc-cccccccccccc}
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<MetaDataObject xmlns="http://v8.1c.ru/8.3/MDClasses">
<ExternalDataProcessor uuid="99999999-9999-9999-9999-999999999999"><Properties><Name>Демо</Name></Properties></ExternalDataProcessor>
</MetaDataObject>
@@ -0,0 +1,228 @@
<?xml version="1.0" encoding="UTF-8"?>
<document xmlns="http://v8.1c.ru/8.2/data/spreadsheet" xmlns:style="http://v8.1c.ru/8.1/data/ui/style" xmlns:v8="http://v8.1c.ru/8.1/data/core" xmlns:v8ui="http://v8.1c.ru/8.1/data/ui" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<languageSettings>
<currentLanguage>ru</currentLanguage>
<defaultLanguage>ru</defaultLanguage>
<languageInfo>
<id>ru</id>
<code>Русский</code>
<description>Русский</description>
</languageInfo>
</languageSettings>
<columns>
<size>5</size>
</columns>
<rowsItem>
<index>0</index>
<row>
<c>
<i>0</i>
<c>
<f>2</f>
<parameter>ТекстЗаголовка</parameter>
</c>
</c>
</row>
</rowsItem>
<rowsItem>
<index>1</index>
<row>
<c>
<i>0</i>
<c>
<f>3</f>
<tl>
<v8:item>
<v8:lang>ru</v8:lang>
<v8:content>Поставщик:</v8:content>
</v8:item>
</tl>
</c>
</c>
<c>
<i>2</i>
<c>
<f>2</f>
<parameter>ПредставлениеПоставщика</parameter>
<detailParameter>Поставщик</detailParameter>
</c>
</c>
</row>
</rowsItem>
<rowsItem>
<index>2</index>
<row>
<c>
<i>0</i>
<c>
<f>5</f>
<parameter>НомерСтроки</parameter>
</c>
</c>
<c>
<i>1</i>
<c>
<f>5</f>
<parameter>Товар</parameter>
<detailParameter>Номенклатура</detailParameter>
</c>
</c>
<c>
<i>2</i>
<c>
<f>6</f>
<parameter>Количество</parameter>
</c>
</c>
<c>
<i>3</i>
<c>
<f>6</f>
<parameter>Цена</parameter>
</c>
</c>
<c>
<i>4</i>
<c>
<f>6</f>
<parameter>Сумма</parameter>
</c>
</c>
</row>
</rowsItem>
<rowsItem>
<index>3</index>
<row>
<c>
<i>3</i>
<c>
<f>7</f>
<tl>
<v8:item>
<v8:lang>ru</v8:lang>
<v8:content>Итого:</v8:content>
</v8:item>
</tl>
</c>
</c>
<c>
<i>4</i>
<c>
<f>8</f>
<parameter>Всего</parameter>
</c>
</c>
</row>
</rowsItem>
<templateMode>true</templateMode>
<defaultFormatIndex>1</defaultFormatIndex>
<height>4</height>
<vgRows>4</vgRows>
<merge>
<r>0</r>
<c>0</c>
<w>4</w>
</merge>
<merge>
<r>1</r>
<c>0</c>
<w>1</w>
</merge>
<merge>
<r>1</r>
<c>2</c>
<w>2</w>
</merge>
<namedItem xsi:type="NamedItemCells">
<name>Заголовок</name>
<area>
<type>Rows</type>
<beginRow>0</beginRow>
<endRow>0</endRow>
<beginColumn>-1</beginColumn>
<endColumn>-1</endColumn>
</area>
</namedItem>
<namedItem xsi:type="NamedItemCells">
<name>Поставщик</name>
<area>
<type>Rows</type>
<beginRow>1</beginRow>
<endRow>1</endRow>
<beginColumn>-1</beginColumn>
<endColumn>-1</endColumn>
</area>
</namedItem>
<namedItem xsi:type="NamedItemCells">
<name>Строка</name>
<area>
<type>Rows</type>
<beginRow>2</beginRow>
<endRow>2</endRow>
<beginColumn>-1</beginColumn>
<endColumn>-1</endColumn>
</area>
</namedItem>
<namedItem xsi:type="NamedItemCells">
<name>Итого</name>
<area>
<type>Rows</type>
<beginRow>3</beginRow>
<endRow>3</endRow>
<beginColumn>-1</beginColumn>
<endColumn>-1</endColumn>
</area>
</namedItem>
<line width="1" gap="false">
<v8ui:style xsi:type="v8ui:SpreadsheetDocumentCellLineType">Solid</v8ui:style>
</line>
<font faceName="Arial" height="10" bold="false" italic="false" underline="false" strikeout="false" kind="Absolute" scale="100"/>
<font faceName="Arial" height="10" bold="true" italic="false" underline="false" strikeout="false" kind="Absolute" scale="100"/>
<format>
<width>10</width>
</format>
<format>
<font>0</font>
<fillType>Parameter</fillType>
</format>
<format>
<font>0</font>
<fillType>Text</fillType>
</format>
<format>
<font>0</font>
<leftBorder>0</leftBorder>
<topBorder>0</topBorder>
<rightBorder>0</rightBorder>
<bottomBorder>0</bottomBorder>
</format>
<format>
<font>0</font>
<leftBorder>0</leftBorder>
<topBorder>0</topBorder>
<rightBorder>0</rightBorder>
<bottomBorder>0</bottomBorder>
<fillType>Parameter</fillType>
</format>
<format>
<font>0</font>
<leftBorder>0</leftBorder>
<topBorder>0</topBorder>
<rightBorder>0</rightBorder>
<bottomBorder>0</bottomBorder>
<horizontalAlignment>Right</horizontalAlignment>
<fillType>Parameter</fillType>
</format>
<format>
<font>1</font>
<topBorder>0</topBorder>
<horizontalAlignment>Right</horizontalAlignment>
<fillType>Text</fillType>
</format>
<format>
<font>1</font>
<topBorder>0</topBorder>
<horizontalAlignment>Right</horizontalAlignment>
<fillType>Parameter</fillType>
</format>
</document>
@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<MetaDataObject xmlns="http://v8.1c.ru/8.3/MDClasses"><Configuration uuid="11111111-1111-1111-1111-111111111111"><Properties><Name>ТестКонфа</Name></Properties></Configuration></MetaDataObject>
@@ -0,0 +1 @@
{6,1,1,aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa,0,bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb,"1.0","ТестВендор","ТестКонфа",1,0,0,cccccccc-cccc-cccc-cccc-cccccccccccc}
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<MetaDataObject xmlns="http://v8.1c.ru/8.3/MDClasses">
<ExternalDataProcessor uuid="99999999-9999-9999-9999-999999999999"><Properties><Name>Демо</Name></Properties></ExternalDataProcessor>
</MetaDataObject>
@@ -0,0 +1,228 @@
<?xml version="1.0" encoding="UTF-8"?>
<document xmlns="http://v8.1c.ru/8.2/data/spreadsheet" xmlns:style="http://v8.1c.ru/8.1/data/ui/style" xmlns:v8="http://v8.1c.ru/8.1/data/core" xmlns:v8ui="http://v8.1c.ru/8.1/data/ui" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<languageSettings>
<currentLanguage>ru</currentLanguage>
<defaultLanguage>ru</defaultLanguage>
<languageInfo>
<id>ru</id>
<code>Русский</code>
<description>Русский</description>
</languageInfo>
</languageSettings>
<columns>
<size>5</size>
</columns>
<rowsItem>
<index>0</index>
<row>
<c>
<i>0</i>
<c>
<f>2</f>
<parameter>ТекстЗаголовка</parameter>
</c>
</c>
</row>
</rowsItem>
<rowsItem>
<index>1</index>
<row>
<c>
<i>0</i>
<c>
<f>3</f>
<tl>
<v8:item>
<v8:lang>ru</v8:lang>
<v8:content>Поставщик:</v8:content>
</v8:item>
</tl>
</c>
</c>
<c>
<i>2</i>
<c>
<f>2</f>
<parameter>ПредставлениеПоставщика</parameter>
<detailParameter>Поставщик</detailParameter>
</c>
</c>
</row>
</rowsItem>
<rowsItem>
<index>2</index>
<row>
<c>
<i>0</i>
<c>
<f>5</f>
<parameter>НомерСтроки</parameter>
</c>
</c>
<c>
<i>1</i>
<c>
<f>5</f>
<parameter>Товар</parameter>
<detailParameter>Номенклатура</detailParameter>
</c>
</c>
<c>
<i>2</i>
<c>
<f>6</f>
<parameter>Количество</parameter>
</c>
</c>
<c>
<i>3</i>
<c>
<f>6</f>
<parameter>Цена</parameter>
</c>
</c>
<c>
<i>4</i>
<c>
<f>6</f>
<parameter>Сумма</parameter>
</c>
</c>
</row>
</rowsItem>
<rowsItem>
<index>3</index>
<row>
<c>
<i>3</i>
<c>
<f>7</f>
<tl>
<v8:item>
<v8:lang>ru</v8:lang>
<v8:content>Итого:</v8:content>
</v8:item>
</tl>
</c>
</c>
<c>
<i>4</i>
<c>
<f>8</f>
<parameter>Всего</parameter>
</c>
</c>
</row>
</rowsItem>
<templateMode>true</templateMode>
<defaultFormatIndex>1</defaultFormatIndex>
<height>4</height>
<vgRows>4</vgRows>
<merge>
<r>0</r>
<c>0</c>
<w>4</w>
</merge>
<merge>
<r>1</r>
<c>0</c>
<w>1</w>
</merge>
<merge>
<r>1</r>
<c>2</c>
<w>2</w>
</merge>
<namedItem xsi:type="NamedItemCells">
<name>Заголовок</name>
<area>
<type>Rows</type>
<beginRow>0</beginRow>
<endRow>0</endRow>
<beginColumn>-1</beginColumn>
<endColumn>-1</endColumn>
</area>
</namedItem>
<namedItem xsi:type="NamedItemCells">
<name>Поставщик</name>
<area>
<type>Rows</type>
<beginRow>1</beginRow>
<endRow>1</endRow>
<beginColumn>-1</beginColumn>
<endColumn>-1</endColumn>
</area>
</namedItem>
<namedItem xsi:type="NamedItemCells">
<name>Строка</name>
<area>
<type>Rows</type>
<beginRow>2</beginRow>
<endRow>2</endRow>
<beginColumn>-1</beginColumn>
<endColumn>-1</endColumn>
</area>
</namedItem>
<namedItem xsi:type="NamedItemCells">
<name>Итого</name>
<area>
<type>Rows</type>
<beginRow>3</beginRow>
<endRow>3</endRow>
<beginColumn>-1</beginColumn>
<endColumn>-1</endColumn>
</area>
</namedItem>
<line width="1" gap="false">
<v8ui:style xsi:type="v8ui:SpreadsheetDocumentCellLineType">Solid</v8ui:style>
</line>
<font faceName="Arial" height="10" bold="false" italic="false" underline="false" strikeout="false" kind="Absolute" scale="100"/>
<font faceName="Arial" height="10" bold="true" italic="false" underline="false" strikeout="false" kind="Absolute" scale="100"/>
<format>
<width>10</width>
</format>
<format>
<font>0</font>
<fillType>Parameter</fillType>
</format>
<format>
<font>0</font>
<fillType>Text</fillType>
</format>
<format>
<font>0</font>
<leftBorder>0</leftBorder>
<topBorder>0</topBorder>
<rightBorder>0</rightBorder>
<bottomBorder>0</bottomBorder>
</format>
<format>
<font>0</font>
<leftBorder>0</leftBorder>
<topBorder>0</topBorder>
<rightBorder>0</rightBorder>
<bottomBorder>0</bottomBorder>
<fillType>Parameter</fillType>
</format>
<format>
<font>0</font>
<leftBorder>0</leftBorder>
<topBorder>0</topBorder>
<rightBorder>0</rightBorder>
<bottomBorder>0</bottomBorder>
<horizontalAlignment>Right</horizontalAlignment>
<fillType>Parameter</fillType>
</format>
<format>
<font>1</font>
<topBorder>0</topBorder>
<horizontalAlignment>Right</horizontalAlignment>
<fillType>Text</fillType>
</format>
<format>
<font>1</font>
<topBorder>0</topBorder>
<horizontalAlignment>Right</horizontalAlignment>
<fillType>Parameter</fillType>
</format>
</document>