mirror of
https://github.com/Nikolay-Shirokov/cc-1c-skills.git
synced 2026-06-11 16:34:57 +03:00
feat(meta-compile): configurable Catalog props, owners, multiLine, fix reservedAttrNames
- Catalog: limitLevelCount, levelCount, foldersOnTop, subordinationUse, codeSeries, quickChoice, choiceMode now read from JSON (were hardcoded) - Catalog owners: new `owners` array property with shorthand normalization - Attribute MultiLine: configurable via `multiLine: true` or `| multiline` flag - reservedAttrNames warning: now skipped for tabular/processor-tabular context - 3 new enum validations: SubordinationUse, CodeSeries, ChoiceMode Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
# meta-compile v1.9 — Compile 1C metadata object from JSON
|
||||
# meta-compile v1.10 — Compile 1C metadata object from JSON
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
param(
|
||||
[Parameter(Mandatory)]
|
||||
@@ -136,6 +136,9 @@ $script:validEnumValues = @{
|
||||
"ReuseSessions" = @("DontUse","AutoUse")
|
||||
"FillChecking" = @("DontCheck","ShowError","ShowWarning")
|
||||
"Indexing" = @("DontIndex","Index","IndexWithAdditionalOrder")
|
||||
"SubordinationUse" = @("ToItems","ToFolders","ToFoldersAndItems")
|
||||
"CodeSeries" = @("WholeCatalog","WithinSubordination")
|
||||
"ChoiceMode" = @("BothWays","QuickChoice","FromForm")
|
||||
}
|
||||
|
||||
function Normalize-EnumValue {
|
||||
@@ -498,6 +501,7 @@ function Parse-AttributeShorthand {
|
||||
flags = @(if ($val.flags) { $val.flags } else { @() })
|
||||
fillChecking = if ($val.fillChecking) { "$($val.fillChecking)" } else { "" }
|
||||
indexing = if ($val.indexing) { "$($val.indexing)" } else { "" }
|
||||
multiLine = if ($val.multiLine -eq $true) { $true } else { $false }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -760,7 +764,8 @@ function Emit-Attribute {
|
||||
param([string]$indent, $parsed, [string]$context)
|
||||
# $context: "catalog", "document", "object", "processor", "tabular", "processor-tabular", "register"
|
||||
$attrName = $parsed.name
|
||||
if ($script:reservedAttrNames.ContainsKey($attrName) -or $script:reservedAttrNames.ContainsValue($attrName)) {
|
||||
if ($context -notin @("tabular", "processor-tabular") -and
|
||||
($script:reservedAttrNames.ContainsKey($attrName) -or $script:reservedAttrNames.ContainsValue($attrName))) {
|
||||
Write-Warning "Attribute '$attrName' conflicts with a standard attribute name. This may cause errors when loading into 1C."
|
||||
}
|
||||
$uuid = New-Guid-String
|
||||
@@ -787,7 +792,8 @@ function Emit-Attribute {
|
||||
X "$indent`t`t<ToolTip/>"
|
||||
X "$indent`t`t<MarkNegatives>false</MarkNegatives>"
|
||||
X "$indent`t`t<Mask/>"
|
||||
X "$indent`t`t<MultiLine>false</MultiLine>"
|
||||
$multiLine = if ($parsed.multiLine -eq $true -or $parsed.flags -contains "multiline") { "true" } else { "false" }
|
||||
X "$indent`t`t<MultiLine>$multiLine</MultiLine>"
|
||||
X "$indent`t`t<ExtendedEdit>false</ExtendedEdit>"
|
||||
X "$indent`t`t<MinValue xsi:nil=`"true`"/>"
|
||||
X "$indent`t`t<MaxValue xsi:nil=`"true`"/>"
|
||||
@@ -931,7 +937,8 @@ function Emit-Dimension {
|
||||
X "$indent`t`t<ToolTip/>"
|
||||
X "$indent`t`t<MarkNegatives>false</MarkNegatives>"
|
||||
X "$indent`t`t<Mask/>"
|
||||
X "$indent`t`t<MultiLine>false</MultiLine>"
|
||||
$multiLine = if ($parsed.multiLine -eq $true -or $parsed.flags -contains "multiline") { "true" } else { "false" }
|
||||
X "$indent`t`t<MultiLine>$multiLine</MultiLine>"
|
||||
X "$indent`t`t<ExtendedEdit>false</ExtendedEdit>"
|
||||
X "$indent`t`t<MinValue xsi:nil=`"true`"/>"
|
||||
X "$indent`t`t<MaxValue xsi:nil=`"true`"/>"
|
||||
@@ -1024,7 +1031,8 @@ function Emit-Resource {
|
||||
X "$indent`t`t<ToolTip/>"
|
||||
X "$indent`t`t<MarkNegatives>false</MarkNegatives>"
|
||||
X "$indent`t`t<Mask/>"
|
||||
X "$indent`t`t<MultiLine>false</MultiLine>"
|
||||
$multiLine = if ($parsed.multiLine -eq $true -or $parsed.flags -contains "multiline") { "true" } else { "false" }
|
||||
X "$indent`t`t<MultiLine>$multiLine</MultiLine>"
|
||||
X "$indent`t`t<ExtendedEdit>false</ExtendedEdit>"
|
||||
X "$indent`t`t<MinValue xsi:nil=`"true`"/>"
|
||||
X "$indent`t`t<MaxValue xsi:nil=`"true`"/>"
|
||||
@@ -1078,12 +1086,25 @@ function Emit-CatalogProperties {
|
||||
$hierarchyType = Get-EnumProp "HierarchyType" "hierarchyType" "HierarchyFoldersAndItems"
|
||||
X "$i<Hierarchical>$hierarchical</Hierarchical>"
|
||||
X "$i<HierarchyType>$hierarchyType</HierarchyType>"
|
||||
X "$i<LimitLevelCount>false</LimitLevelCount>"
|
||||
X "$i<LevelCount>2</LevelCount>"
|
||||
X "$i<FoldersOnTop>true</FoldersOnTop>"
|
||||
$limitLevelCount = if ($def.limitLevelCount -eq $true) { "true" } else { "false" }
|
||||
$levelCount = if ($null -ne $def.levelCount) { "$($def.levelCount)" } else { "2" }
|
||||
$foldersOnTop = if ($def.foldersOnTop -eq $false) { "false" } else { "true" }
|
||||
X "$i<LimitLevelCount>$limitLevelCount</LimitLevelCount>"
|
||||
X "$i<LevelCount>$levelCount</LevelCount>"
|
||||
X "$i<FoldersOnTop>$foldersOnTop</FoldersOnTop>"
|
||||
X "$i<UseStandardCommands>true</UseStandardCommands>"
|
||||
X "$i<Owners/>"
|
||||
X "$i<SubordinationUse>ToItems</SubordinationUse>"
|
||||
if ($def.owners -and $def.owners.Count -gt 0) {
|
||||
X "$i<Owners>"
|
||||
foreach ($ownerRef in $def.owners) {
|
||||
$fullRef = if ("$ownerRef" -match '\.') { "$ownerRef" } else { "Catalog.$ownerRef" }
|
||||
X "$i`t<xr:Item xsi:type=`"xr:MDObjectRef`">$fullRef</xr:Item>"
|
||||
}
|
||||
X "$i</Owners>"
|
||||
} else {
|
||||
X "$i<Owners/>"
|
||||
}
|
||||
$subordinationUse = Get-EnumProp "SubordinationUse" "subordinationUse" "ToItems"
|
||||
X "$i<SubordinationUse>$subordinationUse</SubordinationUse>"
|
||||
|
||||
$codeLength = if ($null -ne $def.codeLength) { "$($def.codeLength)" } else { "9" }
|
||||
$descriptionLength = if ($null -ne $def.descriptionLength) { "$($def.descriptionLength)" } else { "25" }
|
||||
@@ -1096,7 +1117,8 @@ function Emit-CatalogProperties {
|
||||
X "$i<DescriptionLength>$descriptionLength</DescriptionLength>"
|
||||
X "$i<CodeType>$codeType</CodeType>"
|
||||
X "$i<CodeAllowedLength>$codeAllowedLength</CodeAllowedLength>"
|
||||
X "$i<CodeSeries>WholeCatalog</CodeSeries>"
|
||||
$codeSeries = Get-EnumProp "CodeSeries" "codeSeries" "WholeCatalog"
|
||||
X "$i<CodeSeries>$codeSeries</CodeSeries>"
|
||||
X "$i<CheckUnique>$checkUnique</CheckUnique>"
|
||||
X "$i<Autonumbering>$autonumbering</Autonumbering>"
|
||||
|
||||
@@ -1107,8 +1129,10 @@ function Emit-CatalogProperties {
|
||||
X "$i<Characteristics/>"
|
||||
X "$i<PredefinedDataUpdate>Auto</PredefinedDataUpdate>"
|
||||
X "$i<EditType>InDialog</EditType>"
|
||||
X "$i<QuickChoice>true</QuickChoice>"
|
||||
X "$i<ChoiceMode>BothWays</ChoiceMode>"
|
||||
$quickChoice = if ($def.quickChoice -eq $false) { "false" } else { "true" }
|
||||
$choiceMode = Get-EnumProp "ChoiceMode" "choiceMode" "BothWays"
|
||||
X "$i<QuickChoice>$quickChoice</QuickChoice>"
|
||||
X "$i<ChoiceMode>$choiceMode</ChoiceMode>"
|
||||
X "$i<InputByString>"
|
||||
X "$i`t<xr:Field>Catalog.$objName.StandardAttribute.Description</xr:Field>"
|
||||
X "$i`t<xr:Field>Catalog.$objName.StandardAttribute.Code</xr:Field>"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
# meta-compile v1.9 — Compile 1C metadata object from JSON
|
||||
# meta-compile v1.10 — Compile 1C metadata object from JSON
|
||||
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
|
||||
|
||||
import argparse
|
||||
@@ -196,6 +196,9 @@ valid_enum_values = {
|
||||
'ReuseSessions': ['DontUse', 'AutoUse'],
|
||||
'FillChecking': ['DontCheck', 'ShowError', 'ShowWarning'],
|
||||
'Indexing': ['DontIndex', 'Index', 'IndexWithAdditionalOrder'],
|
||||
'SubordinationUse': ['ToItems', 'ToFolders', 'ToFoldersAndItems'],
|
||||
'CodeSeries': ['WholeCatalog', 'WithinSubordination'],
|
||||
'ChoiceMode': ['BothWays', 'QuickChoice', 'FromForm'],
|
||||
}
|
||||
|
||||
def normalize_enum_value(prop_name, value):
|
||||
@@ -461,6 +464,7 @@ def parse_attribute_shorthand(val):
|
||||
'flags': list(val.get('flags', [])),
|
||||
'fillChecking': str(val['fillChecking']) if val.get('fillChecking') else '',
|
||||
'indexing': str(val['indexing']) if val.get('indexing') else '',
|
||||
'multiLine': True if val.get('multiLine') is True else False,
|
||||
}
|
||||
|
||||
def parse_enum_value_shorthand(val):
|
||||
@@ -725,7 +729,7 @@ RESERVED_ATTR_NAMES_RU = {
|
||||
|
||||
def emit_attribute(indent, parsed, context):
|
||||
attr_name = parsed['name']
|
||||
if attr_name in RESERVED_ATTR_NAMES or attr_name in RESERVED_ATTR_NAMES_RU:
|
||||
if context not in ('tabular', 'processor-tabular') and (attr_name in RESERVED_ATTR_NAMES or attr_name in RESERVED_ATTR_NAMES_RU):
|
||||
print(f"WARNING: Attribute '{attr_name}' conflicts with a standard attribute name. This may cause errors when loading into 1C.", file=sys.stderr)
|
||||
uid = new_uuid()
|
||||
X(f'{indent}<Attribute uuid="{uid}">')
|
||||
@@ -746,7 +750,8 @@ def emit_attribute(indent, parsed, context):
|
||||
X(f'{indent}\t\t<ToolTip/>')
|
||||
X(f'{indent}\t\t<MarkNegatives>false</MarkNegatives>')
|
||||
X(f'{indent}\t\t<Mask/>')
|
||||
X(f'{indent}\t\t<MultiLine>false</MultiLine>')
|
||||
multi_line = 'true' if (parsed.get('multiLine') is True or 'multiline' in parsed.get('flags', [])) else 'false'
|
||||
X(f'{indent}\t\t<MultiLine>{multi_line}</MultiLine>')
|
||||
X(f'{indent}\t\t<ExtendedEdit>false</ExtendedEdit>')
|
||||
X(f'{indent}\t\t<MinValue xsi:nil="true"/>')
|
||||
X(f'{indent}\t\t<MaxValue xsi:nil="true"/>')
|
||||
@@ -864,7 +869,8 @@ def emit_dimension(indent, parsed, register_type):
|
||||
X(f'{indent}\t\t<ToolTip/>')
|
||||
X(f'{indent}\t\t<MarkNegatives>false</MarkNegatives>')
|
||||
X(f'{indent}\t\t<Mask/>')
|
||||
X(f'{indent}\t\t<MultiLine>false</MultiLine>')
|
||||
multi_line = 'true' if (parsed.get('multiLine') is True or 'multiline' in parsed.get('flags', [])) else 'false'
|
||||
X(f'{indent}\t\t<MultiLine>{multi_line}</MultiLine>')
|
||||
X(f'{indent}\t\t<ExtendedEdit>false</ExtendedEdit>')
|
||||
X(f'{indent}\t\t<MinValue xsi:nil="true"/>')
|
||||
X(f'{indent}\t\t<MaxValue xsi:nil="true"/>')
|
||||
@@ -937,7 +943,8 @@ def emit_resource(indent, parsed, register_type):
|
||||
X(f'{indent}\t\t<ToolTip/>')
|
||||
X(f'{indent}\t\t<MarkNegatives>false</MarkNegatives>')
|
||||
X(f'{indent}\t\t<Mask/>')
|
||||
X(f'{indent}\t\t<MultiLine>false</MultiLine>')
|
||||
multi_line = 'true' if (parsed.get('multiLine') is True or 'multiline' in parsed.get('flags', [])) else 'false'
|
||||
X(f'{indent}\t\t<MultiLine>{multi_line}</MultiLine>')
|
||||
X(f'{indent}\t\t<ExtendedEdit>false</ExtendedEdit>')
|
||||
X(f'{indent}\t\t<MinValue xsi:nil="true"/>')
|
||||
X(f'{indent}\t\t<MaxValue xsi:nil="true"/>')
|
||||
@@ -979,12 +986,24 @@ def emit_catalog_properties(indent):
|
||||
hierarchy_type = get_enum_prop('HierarchyType', 'hierarchyType', 'HierarchyFoldersAndItems')
|
||||
X(f'{i}<Hierarchical>{hierarchical}</Hierarchical>')
|
||||
X(f'{i}<HierarchyType>{hierarchy_type}</HierarchyType>')
|
||||
X(f'{i}<LimitLevelCount>false</LimitLevelCount>')
|
||||
X(f'{i}<LevelCount>2</LevelCount>')
|
||||
X(f'{i}<FoldersOnTop>true</FoldersOnTop>')
|
||||
limit_level_count = 'true' if defn.get('limitLevelCount') is True else 'false'
|
||||
level_count = str(defn['levelCount']) if defn.get('levelCount') is not None else '2'
|
||||
folders_on_top = 'false' if defn.get('foldersOnTop') is False else 'true'
|
||||
X(f'{i}<LimitLevelCount>{limit_level_count}</LimitLevelCount>')
|
||||
X(f'{i}<LevelCount>{level_count}</LevelCount>')
|
||||
X(f'{i}<FoldersOnTop>{folders_on_top}</FoldersOnTop>')
|
||||
X(f'{i}<UseStandardCommands>true</UseStandardCommands>')
|
||||
X(f'{i}<Owners/>')
|
||||
X(f'{i}<SubordinationUse>ToItems</SubordinationUse>')
|
||||
owners = defn.get('owners', [])
|
||||
if owners:
|
||||
X(f'{i}<Owners>')
|
||||
for owner_ref in owners:
|
||||
full_ref = owner_ref if '.' in str(owner_ref) else f'Catalog.{owner_ref}'
|
||||
X(f'{i}\t<xr:Item xsi:type="xr:MDObjectRef">{full_ref}</xr:Item>')
|
||||
X(f'{i}</Owners>')
|
||||
else:
|
||||
X(f'{i}<Owners/>')
|
||||
subordination_use = get_enum_prop('SubordinationUse', 'subordinationUse', 'ToItems')
|
||||
X(f'{i}<SubordinationUse>{subordination_use}</SubordinationUse>')
|
||||
code_length = str(defn['codeLength']) if defn.get('codeLength') is not None else '9'
|
||||
description_length = str(defn['descriptionLength']) if defn.get('descriptionLength') is not None else '25'
|
||||
code_type = get_enum_prop('CodeType', 'codeType', 'String')
|
||||
@@ -995,7 +1014,8 @@ def emit_catalog_properties(indent):
|
||||
X(f'{i}<DescriptionLength>{description_length}</DescriptionLength>')
|
||||
X(f'{i}<CodeType>{code_type}</CodeType>')
|
||||
X(f'{i}<CodeAllowedLength>{code_allowed_length}</CodeAllowedLength>')
|
||||
X(f'{i}<CodeSeries>WholeCatalog</CodeSeries>')
|
||||
code_series = get_enum_prop('CodeSeries', 'codeSeries', 'WholeCatalog')
|
||||
X(f'{i}<CodeSeries>{code_series}</CodeSeries>')
|
||||
X(f'{i}<CheckUnique>{check_unique}</CheckUnique>')
|
||||
X(f'{i}<Autonumbering>{autonumbering}</Autonumbering>')
|
||||
default_presentation = get_enum_prop('DefaultPresentation', 'defaultPresentation', 'AsDescription')
|
||||
@@ -1004,8 +1024,10 @@ def emit_catalog_properties(indent):
|
||||
X(f'{i}<Characteristics/>')
|
||||
X(f'{i}<PredefinedDataUpdate>Auto</PredefinedDataUpdate>')
|
||||
X(f'{i}<EditType>InDialog</EditType>')
|
||||
X(f'{i}<QuickChoice>true</QuickChoice>')
|
||||
X(f'{i}<ChoiceMode>BothWays</ChoiceMode>')
|
||||
quick_choice = 'false' if defn.get('quickChoice') is False else 'true'
|
||||
choice_mode = get_enum_prop('ChoiceMode', 'choiceMode', 'BothWays')
|
||||
X(f'{i}<QuickChoice>{quick_choice}</QuickChoice>')
|
||||
X(f'{i}<ChoiceMode>{choice_mode}</ChoiceMode>')
|
||||
X(f'{i}<InputByString>')
|
||||
X(f'{i}\t<xr:Field>Catalog.{obj_name}.StandardAttribute.Description</xr:Field>')
|
||||
X(f'{i}\t<xr:Field>Catalog.{obj_name}.StandardAttribute.Code</xr:Field>')
|
||||
|
||||
Reference in New Issue
Block a user