From a4a55cf8830acc25afec7ce9c40c53437de8a530 Mon Sep 17 00:00:00 2001 From: Nick Shirokov Date: Sun, 26 Jul 2026 12:05:08 +0300 Subject: [PATCH] =?UTF-8?q?feat(xdto-info):=20=D1=81=D1=82=D1=80=D1=83?= =?UTF-8?q?=D0=BA=D1=82=D1=83=D1=80=D0=B0=20=D0=BF=D0=B0=D0=BA=D0=B5=D1=82?= =?UTF-8?q?=D0=B0=20=D0=B8=20=D1=82=D0=B8=D0=BF=D0=B0=20=D0=B2=20=D1=82?= =?UTF-8?q?=D0=B5=D1=80=D0=BC=D0=B8=D0=BD=D0=B0=D1=85=201=D0=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Навык отвечает на вопрос «что присвоить и что обязательно», а не показывает модель как есть. Типы переведены в нотацию 1С с учётом ограничений (xs:decimal + totalDigits → Число(18,2)), псевдонимы развёрнуты со стрелкой на исходное имя, кратность вынесена во флаги, для перечислимых типов выводятся допустимые литералы. Различие атрибут/элемент в таблице свойств не показывается: в коде 1С обращение одинаковое. Флаг ставится на обязательные, хотя в модели XDTO умолчание обратное. Причина — соседний meta-info, где непомеченный реквизит необязательный: один значок, означающий в двух навыках противоположное, сам по себе источник ошибок. Режимы: список пакетов конфигурации, состав пакета с точками входа, структура типа с разузлованием на -Depth и used-by. Разузлование идёт через границы пакетов с пометкой источника, анонимные типы раскрываются всегда, циклы обрываются. Пакет адресуется путём, именем или namespace — последнее потому, что модель приходит к задаче от строки ФабрикаXDTO.Тип(ns, имя), а не от имени пакета в конфигурации. Попутно закрыт баг паритета во всех четырёх py-портах: платформа допускает в targetNamespace произвольную строку (в БП есть пакет с кириллическим «ДопФайлУниверсальный»), .NET такое принимает, а libxml2 отвергает как невалидный URI. Добавлено узкое отступление на восстанавливающий разбор — только для этой ошибки, чтобы валидатор не перестал замечать битый XML. Обнаружено это только потому, что корпус впервые прогнан на Python: раньше все 760 гонялись лишь на PowerShell. Теперь 760/760 на обоих рантаймах. Сортировка в PS переведена на ординальную: Sort-Object сортирует по культуре, sorted() в Python — по кодам, и на смешанных латиница/кириллица имена расходились бы. Co-Authored-By: Claude Opus 5 (1M context) --- .../xdto-compile/scripts/xdto-compile.py | 23 +- .../xdto-decompile/scripts/xdto-decompile.py | 21 +- .claude/skills/xdto-info/SKILL.md | 99 +++ .../skills/xdto-info/scripts/xdto-info.ps1 | 614 +++++++++++++++++ .claude/skills/xdto-info/scripts/xdto-info.py | 615 ++++++++++++++++++ .../xdto-validate/scripts/xdto-validate.py | 25 +- tests/skills/cases/xdto-info/_skill.json | 12 + .../skills/cases/xdto-info/by-namespace.json | 8 + tests/skills/cases/xdto-info/common.xsd | 8 + .../skills/cases/xdto-info/cross-package.json | 8 + .../cases/xdto-info/depth-anon-text.json | 8 + tests/skills/cases/xdto-info/nested.xsd | 20 + .../skills/cases/xdto-info/package-list.json | 8 + .../cases/xdto-info/package-overview.json | 8 + .../snapshots/by-namespace/Configuration.xml | 253 +++++++ .../Ext/ClientApplicationInterface.xml | 18 + .../by-namespace/Languages/Русский.xml | 16 + .../by-namespace/XDTOPackages/common.xml | 16 + .../XDTOPackages/common/Ext/Package.bin | 6 + .../by-namespace/XDTOPackages/uses_common.xml | 16 + .../XDTOPackages/uses_common/Ext/Package.bin | 9 + .../snapshots/by-namespace/by-namespace.txt | 10 + .../snapshots/by-namespace/common.xsd | 8 + .../snapshots/by-namespace/uses-common.xsd | 12 + .../snapshots/cross-package/Configuration.xml | 253 +++++++ .../Ext/ClientApplicationInterface.xml | 18 + .../cross-package/Languages/Русский.xml | 16 + .../cross-package/XDTOPackages/common.xml | 16 + .../XDTOPackages/common/Ext/Package.bin | 6 + .../XDTOPackages/uses_common.xml | 16 + .../XDTOPackages/uses_common/Ext/Package.bin | 9 + .../snapshots/cross-package/common.xsd | 8 + .../snapshots/cross-package/cross-package.txt | 12 + .../snapshots/cross-package/uses-common.xsd | 12 + .../depth-anon-text/Configuration.xml | 252 +++++++ .../Ext/ClientApplicationInterface.xml | 18 + .../depth-anon-text/Languages/Русский.xml | 16 + .../depth-anon-text/XDTOPackages/nested.xml | 16 + .../XDTOPackages/nested/Ext/Package.bin | 15 + .../depth-anon-text/depth-anon-text.txt | 15 + .../snapshots/depth-anon-text/nested.xsd | 20 + .../snapshots/package-list/Configuration.xml | 253 +++++++ .../Ext/ClientApplicationInterface.xml | 18 + .../package-list/Languages/Русский.xml | 16 + .../package-list/XDTOPackages/common.xml | 16 + .../XDTOPackages/common/Ext/Package.bin | 6 + .../package-list/XDTOPackages/uses_common.xml | 16 + .../XDTOPackages/uses_common/Ext/Package.bin | 9 + .../snapshots/package-list/common.xsd | 8 + .../snapshots/package-list/package-list.txt | 7 + .../snapshots/package-list/uses-common.xsd | 12 + .../package-overview/Configuration.xml | 253 +++++++ .../Ext/ClientApplicationInterface.xml | 18 + .../package-overview/Languages/Русский.xml | 16 + .../package-overview/XDTOPackages/common.xml | 16 + .../XDTOPackages/common/Ext/Package.bin | 6 + .../XDTOPackages/uses_common.xml | 16 + .../XDTOPackages/uses_common/Ext/Package.bin | 9 + .../snapshots/package-overview/common.xsd | 8 + .../package-overview/package-overview.txt | 14 + .../package-overview/uses-common.xsd | 12 + .../snapshots/type-notation/Configuration.xml | 252 +++++++ .../Ext/ClientApplicationInterface.xml | 18 + .../type-notation/Languages/Русский.xml | 16 + .../type-notation/XDTOPackages/types.xml | 16 + .../XDTOPackages/types/Ext/Package.bin | 26 + .../snapshots/type-notation/type-notation.txt | 22 + .../snapshots/type-notation/types.xsd | 35 + .../snapshots/used-by/Configuration.xml | 253 +++++++ .../Ext/ClientApplicationInterface.xml | 18 + .../snapshots/used-by/Languages/Русский.xml | 16 + .../snapshots/used-by/XDTOPackages/common.xml | 16 + .../XDTOPackages/common/Ext/Package.bin | 6 + .../used-by/XDTOPackages/uses_common.xml | 16 + .../XDTOPackages/uses_common/Ext/Package.bin | 9 + .../xdto-info/snapshots/used-by/common.xsd | 8 + .../xdto-info/snapshots/used-by/used-by.txt | 5 + .../snapshots/used-by/uses-common.xsd | 12 + .../snapshots/value-type/Configuration.xml | 252 +++++++ .../Ext/ClientApplicationInterface.xml | 18 + .../value-type/Languages/Русский.xml | 16 + .../value-type/XDTOPackages/types.xml | 16 + .../XDTOPackages/types/Ext/Package.bin | 26 + .../xdto-info/snapshots/value-type/types.xsd | 35 + .../snapshots/value-type/value-type.txt | 8 + .../skills/cases/xdto-info/type-notation.json | 8 + tests/skills/cases/xdto-info/types.xsd | 35 + tests/skills/cases/xdto-info/used-by.json | 8 + tests/skills/cases/xdto-info/uses-common.xsd | 12 + tests/skills/cases/xdto-info/value-type.json | 8 + 90 files changed, 4465 insertions(+), 9 deletions(-) create mode 100644 .claude/skills/xdto-info/SKILL.md create mode 100644 .claude/skills/xdto-info/scripts/xdto-info.ps1 create mode 100644 .claude/skills/xdto-info/scripts/xdto-info.py create mode 100644 tests/skills/cases/xdto-info/_skill.json create mode 100644 tests/skills/cases/xdto-info/by-namespace.json create mode 100644 tests/skills/cases/xdto-info/common.xsd create mode 100644 tests/skills/cases/xdto-info/cross-package.json create mode 100644 tests/skills/cases/xdto-info/depth-anon-text.json create mode 100644 tests/skills/cases/xdto-info/nested.xsd create mode 100644 tests/skills/cases/xdto-info/package-list.json create mode 100644 tests/skills/cases/xdto-info/package-overview.json create mode 100644 tests/skills/cases/xdto-info/snapshots/by-namespace/Configuration.xml create mode 100644 tests/skills/cases/xdto-info/snapshots/by-namespace/Ext/ClientApplicationInterface.xml create mode 100644 tests/skills/cases/xdto-info/snapshots/by-namespace/Languages/Русский.xml create mode 100644 tests/skills/cases/xdto-info/snapshots/by-namespace/XDTOPackages/common.xml create mode 100644 tests/skills/cases/xdto-info/snapshots/by-namespace/XDTOPackages/common/Ext/Package.bin create mode 100644 tests/skills/cases/xdto-info/snapshots/by-namespace/XDTOPackages/uses_common.xml create mode 100644 tests/skills/cases/xdto-info/snapshots/by-namespace/XDTOPackages/uses_common/Ext/Package.bin create mode 100644 tests/skills/cases/xdto-info/snapshots/by-namespace/by-namespace.txt create mode 100644 tests/skills/cases/xdto-info/snapshots/by-namespace/common.xsd create mode 100644 tests/skills/cases/xdto-info/snapshots/by-namespace/uses-common.xsd create mode 100644 tests/skills/cases/xdto-info/snapshots/cross-package/Configuration.xml create mode 100644 tests/skills/cases/xdto-info/snapshots/cross-package/Ext/ClientApplicationInterface.xml create mode 100644 tests/skills/cases/xdto-info/snapshots/cross-package/Languages/Русский.xml create mode 100644 tests/skills/cases/xdto-info/snapshots/cross-package/XDTOPackages/common.xml create mode 100644 tests/skills/cases/xdto-info/snapshots/cross-package/XDTOPackages/common/Ext/Package.bin create mode 100644 tests/skills/cases/xdto-info/snapshots/cross-package/XDTOPackages/uses_common.xml create mode 100644 tests/skills/cases/xdto-info/snapshots/cross-package/XDTOPackages/uses_common/Ext/Package.bin create mode 100644 tests/skills/cases/xdto-info/snapshots/cross-package/common.xsd create mode 100644 tests/skills/cases/xdto-info/snapshots/cross-package/cross-package.txt create mode 100644 tests/skills/cases/xdto-info/snapshots/cross-package/uses-common.xsd create mode 100644 tests/skills/cases/xdto-info/snapshots/depth-anon-text/Configuration.xml create mode 100644 tests/skills/cases/xdto-info/snapshots/depth-anon-text/Ext/ClientApplicationInterface.xml create mode 100644 tests/skills/cases/xdto-info/snapshots/depth-anon-text/Languages/Русский.xml create mode 100644 tests/skills/cases/xdto-info/snapshots/depth-anon-text/XDTOPackages/nested.xml create mode 100644 tests/skills/cases/xdto-info/snapshots/depth-anon-text/XDTOPackages/nested/Ext/Package.bin create mode 100644 tests/skills/cases/xdto-info/snapshots/depth-anon-text/depth-anon-text.txt create mode 100644 tests/skills/cases/xdto-info/snapshots/depth-anon-text/nested.xsd create mode 100644 tests/skills/cases/xdto-info/snapshots/package-list/Configuration.xml create mode 100644 tests/skills/cases/xdto-info/snapshots/package-list/Ext/ClientApplicationInterface.xml create mode 100644 tests/skills/cases/xdto-info/snapshots/package-list/Languages/Русский.xml create mode 100644 tests/skills/cases/xdto-info/snapshots/package-list/XDTOPackages/common.xml create mode 100644 tests/skills/cases/xdto-info/snapshots/package-list/XDTOPackages/common/Ext/Package.bin create mode 100644 tests/skills/cases/xdto-info/snapshots/package-list/XDTOPackages/uses_common.xml create mode 100644 tests/skills/cases/xdto-info/snapshots/package-list/XDTOPackages/uses_common/Ext/Package.bin create mode 100644 tests/skills/cases/xdto-info/snapshots/package-list/common.xsd create mode 100644 tests/skills/cases/xdto-info/snapshots/package-list/package-list.txt create mode 100644 tests/skills/cases/xdto-info/snapshots/package-list/uses-common.xsd create mode 100644 tests/skills/cases/xdto-info/snapshots/package-overview/Configuration.xml create mode 100644 tests/skills/cases/xdto-info/snapshots/package-overview/Ext/ClientApplicationInterface.xml create mode 100644 tests/skills/cases/xdto-info/snapshots/package-overview/Languages/Русский.xml create mode 100644 tests/skills/cases/xdto-info/snapshots/package-overview/XDTOPackages/common.xml create mode 100644 tests/skills/cases/xdto-info/snapshots/package-overview/XDTOPackages/common/Ext/Package.bin create mode 100644 tests/skills/cases/xdto-info/snapshots/package-overview/XDTOPackages/uses_common.xml create mode 100644 tests/skills/cases/xdto-info/snapshots/package-overview/XDTOPackages/uses_common/Ext/Package.bin create mode 100644 tests/skills/cases/xdto-info/snapshots/package-overview/common.xsd create mode 100644 tests/skills/cases/xdto-info/snapshots/package-overview/package-overview.txt create mode 100644 tests/skills/cases/xdto-info/snapshots/package-overview/uses-common.xsd create mode 100644 tests/skills/cases/xdto-info/snapshots/type-notation/Configuration.xml create mode 100644 tests/skills/cases/xdto-info/snapshots/type-notation/Ext/ClientApplicationInterface.xml create mode 100644 tests/skills/cases/xdto-info/snapshots/type-notation/Languages/Русский.xml create mode 100644 tests/skills/cases/xdto-info/snapshots/type-notation/XDTOPackages/types.xml create mode 100644 tests/skills/cases/xdto-info/snapshots/type-notation/XDTOPackages/types/Ext/Package.bin create mode 100644 tests/skills/cases/xdto-info/snapshots/type-notation/type-notation.txt create mode 100644 tests/skills/cases/xdto-info/snapshots/type-notation/types.xsd create mode 100644 tests/skills/cases/xdto-info/snapshots/used-by/Configuration.xml create mode 100644 tests/skills/cases/xdto-info/snapshots/used-by/Ext/ClientApplicationInterface.xml create mode 100644 tests/skills/cases/xdto-info/snapshots/used-by/Languages/Русский.xml create mode 100644 tests/skills/cases/xdto-info/snapshots/used-by/XDTOPackages/common.xml create mode 100644 tests/skills/cases/xdto-info/snapshots/used-by/XDTOPackages/common/Ext/Package.bin create mode 100644 tests/skills/cases/xdto-info/snapshots/used-by/XDTOPackages/uses_common.xml create mode 100644 tests/skills/cases/xdto-info/snapshots/used-by/XDTOPackages/uses_common/Ext/Package.bin create mode 100644 tests/skills/cases/xdto-info/snapshots/used-by/common.xsd create mode 100644 tests/skills/cases/xdto-info/snapshots/used-by/used-by.txt create mode 100644 tests/skills/cases/xdto-info/snapshots/used-by/uses-common.xsd create mode 100644 tests/skills/cases/xdto-info/snapshots/value-type/Configuration.xml create mode 100644 tests/skills/cases/xdto-info/snapshots/value-type/Ext/ClientApplicationInterface.xml create mode 100644 tests/skills/cases/xdto-info/snapshots/value-type/Languages/Русский.xml create mode 100644 tests/skills/cases/xdto-info/snapshots/value-type/XDTOPackages/types.xml create mode 100644 tests/skills/cases/xdto-info/snapshots/value-type/XDTOPackages/types/Ext/Package.bin create mode 100644 tests/skills/cases/xdto-info/snapshots/value-type/types.xsd create mode 100644 tests/skills/cases/xdto-info/snapshots/value-type/value-type.txt create mode 100644 tests/skills/cases/xdto-info/type-notation.json create mode 100644 tests/skills/cases/xdto-info/types.xsd create mode 100644 tests/skills/cases/xdto-info/used-by.json create mode 100644 tests/skills/cases/xdto-info/uses-common.xsd create mode 100644 tests/skills/cases/xdto-info/value-type.json diff --git a/.claude/skills/xdto-compile/scripts/xdto-compile.py b/.claude/skills/xdto-compile/scripts/xdto-compile.py index 5d7e420d..3a6bc0bf 100644 --- a/.claude/skills/xdto-compile/scripts/xdto-compile.py +++ b/.claude/skills/xdto-compile/scripts/xdto-compile.py @@ -27,6 +27,23 @@ parser.add_argument("-Comment", default="") parser.add_argument("-Force", action="store_true") args = parser.parse_args() + +def _parse_xml(source, from_string=False): + """Разбор с узким отступлением для не-URI пространств имён. + + Платформа допускает в targetNamespace произвольную строку (в выгрузке БП есть + пакет с кириллическим «ДопФайлУниверсальный»), .NET такое принимает, а libxml2 + отвергает. Откатываемся на восстанавливающий разбор ТОЛЬКО на этой ошибке, + иначе по-настоящему битый XML перестал бы отличаться от корректного. + """ + try: + return (etree.fromstring(source) if from_string else etree.parse(source)) + except etree.XMLSyntaxError as e: + if "is not a valid URI" not in str(e): + raise + p = etree.XMLParser(recover=True) + return (etree.fromstring(source, p) if from_string else etree.parse(source, p)) + # ── support guard (Ext/ParentConfigurations.bin) ───────────── # См. docs/1c-support-state-spec.md. Блокирует правку объектов поставщика # «на замке». Триггер — наличие bin; реакция из .v8-project.json @@ -60,7 +77,7 @@ def get_edit_mode(cfg_dir): def is_external_object_root(xml_path): try: - root = etree.parse(xml_path).getroot() + root = _parse_xml(xml_path).getroot() for el in root: if isinstance(el.tag, str): return etree.QName(el).localname in ("ExternalDataProcessor", "ExternalReport") @@ -118,7 +135,7 @@ else: sys.exit(1) try: - schema = etree.fromstring(xsd_bytes) + schema = _parse_xml(xsd_bytes, from_string=True) except Exception as e: # noqa: BLE001 print(f"Не удалось разобрать XSD: {e}", file=sys.stderr) sys.exit(1) @@ -848,7 +865,7 @@ if os.path.exists(config_xml): with open(config_xml, "rb") as f: raw = f.read() had_bom = raw.startswith(b"\xef\xbb\xbf") - cfg_doc = etree.parse(config_xml) + cfg_doc = _parse_xml(config_xml) child_objects = cfg_doc.find(f".//{{{MD_NS}}}Configuration/{{{MD_NS}}}ChildObjects") if child_objects is not None: existing = child_objects.findall(f"{{{MD_NS}}}XDTOPackage") diff --git a/.claude/skills/xdto-decompile/scripts/xdto-decompile.py b/.claude/skills/xdto-decompile/scripts/xdto-decompile.py index 133e68b8..249a43bb 100644 --- a/.claude/skills/xdto-decompile/scripts/xdto-decompile.py +++ b/.claude/skills/xdto-decompile/scripts/xdto-decompile.py @@ -22,6 +22,23 @@ parser.add_argument("-PackagePath", "-Path", required=True) parser.add_argument("-OutFile", default="") args = parser.parse_args() + +def _parse_xml(source, from_string=False): + """Разбор с узким отступлением для не-URI пространств имён. + + Платформа допускает в targetNamespace произвольную строку (в выгрузке БП есть + пакет с кириллическим «ДопФайлУниверсальный»), .NET такое принимает, а libxml2 + отвергает. Откатываемся на восстанавливающий разбор ТОЛЬКО на этой ошибке, + иначе по-настоящему битый XML перестал бы отличаться от корректного. + """ + try: + return (etree.fromstring(source) if from_string else etree.parse(source)) + except etree.XMLSyntaxError as e: + if "is not a valid URI" not in str(e): + raise + p = etree.XMLParser(recover=True) + return (etree.fromstring(source, p) if from_string else etree.parse(source, p)) + # ── resolve paths ──────────────────────────────────────────── package_path = args.PackagePath @@ -53,7 +70,7 @@ if not bin_path: print(f"Не найден Ext/Package.bin для пути: {package_path}", file=sys.stderr) sys.exit(1) -doc = etree.parse(bin_path) +doc = _parse_xml(bin_path) pkg = doc.getroot() @@ -460,7 +477,7 @@ def complex_type_attrs(el): meta = None if md_path and os.path.exists(md_path): - md = etree.parse(md_path) + md = _parse_xml(md_path) props_el = md.find(f".//{{{MD_NS}}}XDTOPackage/{{{MD_NS}}}Properties") if props_el is not None: meta = {"Name": None, "Comment": None, "Synonym": []} diff --git a/.claude/skills/xdto-info/SKILL.md b/.claude/skills/xdto-info/SKILL.md new file mode 100644 index 00000000..46411930 --- /dev/null +++ b/.claude/skills/xdto-info/SKILL.md @@ -0,0 +1,99 @@ +--- +name: xdto-info +description: Анализ структуры пакета XDTO 1С — типы, свойства, точки входа. Используй для написания кода, создающего и заполняющего объект XDTO, для разбора входящего XML и чтобы понять, какие пакеты есть в конфигурации +argument-hint: [-Namespace |-Package <имя>] [-Name <Тип>] [-Depth N] [-Mode used-by] [-Limit N] [-Offset N] [-OutFile <файл>] +allowed-tools: + - Bash + - Read + - Glob +--- + +# /xdto-info — Анализ структуры пакета XDTO + +Показывает структуру типа в терминах 1С: какой тип значения присваивать, что обязательно, +где нужен вложенный объект, какие значения допустимы. Заменяет чтение `Package.bin` +или XSD с ручным переводом `xs:decimal` → `Число` и `lowerBound="0"` → необязательный. + +## Параметры + +| Параметр | Обязательный | Описание | +|----------|--------------|----------| +| `PackagePath` | да | Каталог пакета либо корень исходников конфигурации. Псевдоним — `-Path` | +| `Namespace` | нет | Выбрать пакет по пространству имён (когда путь — корень исходников) | +| `Package` | нет | Выбрать пакет по имени объекта метаданных | +| `Name` | нет | Имя типа. Без выбранного пакета ищется по всей конфигурации | +| `Depth` | нет | Глубина разузлования вложенных объектов. По умолчанию 1 | +| `Mode` | нет | `used-by` — кто ссылается на тип. По умолчанию `auto` | +| `Limit` / `Offset` | нет | Пагинация. По умолчанию 150 строк | +| `OutFile` | нет | Записать результат в файл (UTF-8 BOM) | + +```powershell +powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/xdto-info.ps1" -PackagePath "<путь>" +``` + +## Что показывает + +Точка входа определяется по пути: корень исходников — список пакетов, каталог пакета — +его состав. + +| Вызов | Результат | +|---|---| +| `-PackagePath src` | все пакеты конфигурации: имя, число типов, namespace | +| `-PackagePath src/XDTOPackages/ОбменСБанком` | импорты, точки входа, списки типов | +| `... -Name ПлатежныйДокумент` | структура типа для заполнения | +| `... -Name ПлатежныйДокумент -Depth 3` | то же с раскрытием вложенных объектов | +| `... -Mode used-by -Name СуммаТип` | кто ссылается на тип, включая соседние пакеты | + +## Когда известны namespace и тип, но не имя пакета + +Так бывает чаще всего: namespace и имя типа видны в коде или в образце XML, +а как называется пакет — нет. Вызов повторяет строку, от которой отталкиваешься: + +```powershell +# ФабрикаXDTO.Тип("urn:1C.ru:ClientBankExchange", "ПлатежныйДокумент") +... -PackagePath src -Namespace "urn:1C.ru:ClientBankExchange" -Name ПлатежныйДокумент +``` + +Если известно только имя типа — укажи `-Name` и корень исходников: тип найдётся +по всем пакетам. При нескольких совпадениях навык покажет, где именно, чтобы уточнить. + +## Как читать вывод + +``` +=== Тип XDTO: ПлатежныйДокумент === +Пакет: ClientBankExchange · urn:1C.ru:ClientBankExchange + +Свойства (11): + ИдДокумента Строка шаблон [a-fA-F0-9]{8}-… + Номер Строка(6) [обязательный] + Сумма Число(18,2) [обязательный] ← СуммаТип + Квитанция объект Квитанция + РеквизитыПлательщика объект РеквизитыПлательщика [обязательный] + +Создание: + Тип = ФабрикаXDTO.Тип("urn:1C.ru:ClientBankExchange", "ПлатежныйДокумент"); + Объект = ФабрикаXDTO.Создать(Тип); +``` + +- **Тип значения** — уже в нотации 1С, с учётом ограничений: `Строка(6)`, `Число(18,2)`. +- **`объект X`** — свойству нужно присвоить вложенный объект XDTO, а не значение. + Раскрыть его состав — `-Depth 2` и больше. +- **`[обязательный]`** — без заполнения запись XML не пройдёт. Непомеченное свойство + необязательно. `[список]` — коллекция, заполняется через `.Добавить()`. +- **`← СуммаТип`** — исходное имя типа из схемы; слева от стрелки уже развёрнутое значение. +- **`[значение элемента]`** — свойство хранит собственное значение элемента, + остальные свойства такого типа лежат в атрибутах XML. +- Для перечислимых типов выводится список допустимых значений. + +При разузловании вложенные объекты раскрываются отступом; тип из другого пакета +подписывается его именем (`· FSS_Common_01`), повторное вхождение обрывается +пометкой `(раскрыт выше)`. + +## Типичный workflow + +1. `/xdto-info src` — какие пакеты есть +2. `/xdto-info src -Namespace ""` — точки входа и типы пакета +3. `/xdto-info src -Namespace "" -Name <Тип> -Depth 2` — структура для кода +4. Перед правкой типа: `-Mode used-by -Name <Тип>` — кого затронет + +Нужна сама XML-схема, а не сводка, — это `/xdto-decompile`. diff --git a/.claude/skills/xdto-info/scripts/xdto-info.ps1 b/.claude/skills/xdto-info/scripts/xdto-info.ps1 new file mode 100644 index 00000000..12965c20 --- /dev/null +++ b/.claude/skills/xdto-info/scripts/xdto-info.ps1 @@ -0,0 +1,614 @@ +# xdto-info v1.0 — Analyze 1C XDTO package structure +# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills +param( + [Parameter(Mandatory=$true)] + [Alias('Path')] + [string]$PackagePath, + [string]$Package, + [string]$Namespace, + [string]$Name, + [ValidateSet("auto", "used-by")] + [string]$Mode = "auto", + [int]$Depth = 1, + [int]$Limit = 150, + [int]$Offset = 0, + [string]$OutFile +) + +$ErrorActionPreference = "Stop" +[Console]::OutputEncoding = [System.Text.Encoding]::UTF8 + +$XS_NS = "http://www.w3.org/2001/XMLSchema" +$XSI_NS = "http://www.w3.org/2001/XMLSchema-instance" +$MD_NS = "http://v8.1c.ru/8.3/MDClasses" + +# --- Output --- + +$sb = New-Object System.Text.StringBuilder +function O([string]$line = "") { [void]$sb.AppendLine($line) } + +function Flush-Output { + $text = $sb.ToString().TrimEnd() + if ($OutFile) { + $dir = [System.IO.Path]::GetDirectoryName($OutFile) + if ($dir -and -not (Test-Path $dir)) { New-Item -ItemType Directory -Path $dir -Force | Out-Null } + [System.IO.File]::WriteAllText($OutFile, $text + "`r`n", (New-Object System.Text.UTF8Encoding($true))) + Write-Host "✓ Записано: $OutFile" + } else { + Write-Host $text + } +} + +# --- Path resolution ----------------------------------------------------------- +# Путь может указывать на корень конфигурации (тогда работаем со всеми пакетами) +# либо на конкретный пакет. + +if (-not [System.IO.Path]::IsPathRooted($PackagePath)) { + $PackagePath = Join-Path (Get-Location).Path $PackagePath +} +if (-not (Test-Path $PackagePath)) { throw "Путь не найден: $PackagePath" } + +$configRoot = $null +$directPkgDir = $null + +if (Test-Path (Join-Path $PackagePath "Configuration.xml")) { + $configRoot = $PackagePath +} elseif ((Split-Path $PackagePath -Leaf) -eq "XDTOPackages") { + $configRoot = Split-Path $PackagePath -Parent +} elseif (Test-Path (Join-Path (Join-Path $PackagePath "Ext") "Package.bin")) { + $directPkgDir = $PackagePath + $pkgRoot = Split-Path $PackagePath -Parent + $configRoot = Split-Path $pkgRoot -Parent +} elseif ((Test-Path $PackagePath -PathType Leaf) -and ([System.IO.Path]::GetFileName($PackagePath) -eq "Package.bin")) { + $directPkgDir = Split-Path (Split-Path $PackagePath -Parent) -Parent + $configRoot = Split-Path (Split-Path $directPkgDir -Parent) -Parent +} elseif ($PackagePath.EndsWith(".xml")) { + $stem = [System.IO.Path]::Combine([System.IO.Path]::GetDirectoryName($PackagePath), + [System.IO.Path]::GetFileNameWithoutExtension($PackagePath)) + if (Test-Path (Join-Path (Join-Path $stem "Ext") "Package.bin")) { + $directPkgDir = $stem + $configRoot = Split-Path (Split-Path $stem -Parent) -Parent + } +} +if (-not $configRoot -and -not $directPkgDir) { throw "Не удалось определить пакет или конфигурацию по пути: $PackagePath" } + +# Sort-Object в PowerShell сортирует по культуре, sorted() в Python — по кодам. +# Для паритета портов сортируем ординально в обоих. +function Sort-Ordinal($items) { + $arr = [string[]]@($items) + [array]::Sort($arr, [StringComparer]::Ordinal) + return ,$arr +} + +# --- Package index ------------------------------------------------------------- + +function Read-Package([string]$pkgDir) { + $bin = Join-Path (Join-Path $pkgDir "Ext") "Package.bin" + if (-not (Test-Path $bin)) { return $null } + try { + $doc = New-Object System.Xml.XmlDocument + $doc.PreserveWhitespace = $false + $doc.Load($bin) + } catch { return $null } + $root = $doc.DocumentElement + if ($root.get_LocalName() -ne "package") { return $null } + + $info = [pscustomobject]@{ + Name = [System.IO.Path]::GetFileName($pkgDir) + Dir = $pkgDir + Namespace = $root.GetAttribute("targetNamespace") + Root = $root + Imports = (New-Object System.Collections.ArrayList) + Types = @{} + GlobalProps= (New-Object System.Collections.ArrayList) + } + foreach ($n in $root.ChildNodes) { + if ($n.NodeType -ne [System.Xml.XmlNodeType]::Element) { continue } + switch ($n.get_LocalName()) { + "import" { [void]$info.Imports.Add($n.GetAttribute("namespace")) } + "objectType" { $info.Types[$n.GetAttribute("name")] = $n } + "valueType" { $info.Types[$n.GetAttribute("name")] = $n } + "property" { [void]$info.GlobalProps.Add($n) } + } + } + return $info +} + +$packages = New-Object System.Collections.ArrayList +$byNamespace = @{} + +if ($configRoot -and (Test-Path (Join-Path $configRoot "XDTOPackages"))) { + foreach ($dn in (Sort-Ordinal ((Get-ChildItem (Join-Path $configRoot "XDTOPackages") -Directory -ErrorAction SilentlyContinue).Name))) { + $p = Read-Package (Join-Path (Join-Path $configRoot "XDTOPackages") $dn) + if ($p) { + [void]$packages.Add($p) + if (-not $byNamespace.ContainsKey($p.Namespace)) { $byNamespace[$p.Namespace] = $p } + } + } +} +if ($directPkgDir -and $packages.Count -eq 0) { + $p = Read-Package $directPkgDir + if ($p) { [void]$packages.Add($p); $byNamespace[$p.Namespace] = $p } +} +if ($packages.Count -eq 0) { throw "Пакеты XDTO не найдены: $PackagePath" } + +# --- Type notation: XSD -> 1С --------------------------------------------------- + +$XS_TO_1C = @{ + "string" = "Строка"; "normalizedString" = "Строка"; "token" = "Строка"; "NCName" = "Строка" + "Name" = "Строка"; "QName" = "Строка"; "anyURI" = "Строка"; "language" = "Строка" + "ID" = "Строка"; "IDREF" = "Строка"; "NMTOKEN" = "Строка" + "decimal" = "Число"; "integer" = "Число"; "int" = "Число"; "long" = "Число"; "short" = "Число" + "byte" = "Число"; "float" = "Число"; "double" = "Число" + "nonNegativeInteger" = "Число"; "positiveInteger" = "Число"; "nonPositiveInteger" = "Число" + "negativeInteger" = "Число"; "unsignedInt" = "Число"; "unsignedLong" = "Число" + "unsignedShort" = "Число"; "unsignedByte" = "Число" + "date" = "Дата"; "dateTime" = "Дата"; "time" = "Дата" + "boolean" = "Булево" + "base64Binary" = "ДвоичныеДанные"; "hexBinary" = "ДвоичныеДанные" + "anyType" = "произвольный"; "anySimpleType" = "произвольный" +} + +function Split-Ref([System.Xml.XmlElement]$el, [string]$raw) { + if (-not $raw) { return $null } + if ($raw.StartsWith("{")) { + $close = $raw.IndexOf("}") + if ($close -lt 0) { return $null } + return [pscustomobject]@{ Ns = $raw.Substring(1, $close - 1); Local = $raw.Substring($close + 1) } + } + $parts = $raw.Split(":") + if ($parts.Count -eq 2) { + return [pscustomobject]@{ Ns = $el.GetNamespaceOfPrefix($parts[0]); Local = $parts[1] } + } + return [pscustomobject]@{ Ns = $null; Local = $parts[0] } +} + +function Get-Facets([System.Xml.XmlElement]$t) { + $res = @{} + foreach ($f in @("length", "minLength", "maxLength", "totalDigits", "fractionDigits", + "minInclusive", "maxInclusive", "minExclusive", "maxExclusive")) { + $v = $t.GetAttribute($f) + if ($v) { $res[$f] = $v } + } + $pat = $null + foreach ($c in $t.ChildNodes) { + if ($c.NodeType -eq [System.Xml.XmlNodeType]::Element -and $c.get_LocalName() -eq "pattern") { $pat = $c.InnerText; break } + } + if ($pat) { $res["pattern"] = $pat } + return $res +} + +function Get-Enumerations([System.Xml.XmlElement]$t) { + $vals = @() + foreach ($c in $t.ChildNodes) { + if ($c.NodeType -eq [System.Xml.XmlNodeType]::Element -and $c.get_LocalName() -eq "enumeration") { $vals += $c.InnerText } + } + return $vals +} + +# Разворачивает цепочку псевдонимов до примитива, собирая фасеты по пути. +# Возвращает @{ Base1C; Facets; Alias; Enum; Kind } +function Resolve-Scalar([System.Xml.XmlElement]$t, $pkg, [int]$guard = 0) { + $acc = @{ Base1C = $null; Facets = @{}; Alias = $null; Enum = @(); Kind = "scalar" } + if ($guard -gt 10 -or -not $t) { return $acc } + + $variety = $t.GetAttribute("variety") + if ($variety -eq "List") { + $it = Split-Ref $t $t.GetAttribute("itemType") + $acc.Kind = "list" + $acc.Base1C = "список " + $(if ($it) { Format-RefName $it $pkg } else { "значений" }) + return $acc + } + if ($variety -eq "Union" -or $t.GetAttribute("memberTypes")) { + $members = @() + foreach ($m in (($t.GetAttribute("memberTypes") -split "\s+") | Where-Object { $_ })) { + $q = Split-Ref $t $m + if ($q) { $members += (Format-RefName $q $pkg) } + } + foreach ($c in $t.ChildNodes) { + if ($c.NodeType -eq [System.Xml.XmlNodeType]::Element -and $c.get_LocalName() -eq "typeDef") { + $inner = Resolve-Scalar $c $pkg ($guard + 1) + $members += $inner.Base1C + } + } + $acc.Kind = "union" + $acc.Base1C = "одно из (" + (($members | Where-Object { $_ }) -join " | ") + ")" + return $acc + } + + $acc.Facets = Get-Facets $t + $acc.Enum = Get-Enumerations $t + + # базовый тип: атрибут base или вложенный анонимный typeDef + $baseQ = Split-Ref $t $t.GetAttribute("base") + $anonBase = $null + foreach ($c in $t.ChildNodes) { + if ($c.NodeType -eq [System.Xml.XmlNodeType]::Element -and $c.get_LocalName() -eq "typeDef") { $anonBase = $c; break } + } + if (-not $baseQ -and $anonBase) { + $inner = Resolve-Scalar $anonBase $pkg ($guard + 1) + $acc.Base1C = $inner.Base1C + foreach ($k in $inner.Facets.Keys) { if (-not $acc.Facets.ContainsKey($k)) { $acc.Facets[$k] = $inner.Facets[$k] } } + if ($inner.Enum.Count -gt 0 -and $acc.Enum.Count -eq 0) { $acc.Enum = $inner.Enum } + return $acc + } + if (-not $baseQ) { $acc.Base1C = "произвольный"; return $acc } + + if ($baseQ.Ns -eq $XS_NS) { + $acc.Base1C = $(if ($XS_TO_1C.ContainsKey($baseQ.Local)) { $XS_TO_1C[$baseQ.Local] } else { "xs:$($baseQ.Local)" }) + return $acc + } + + # база — именованный тип значения: разворачиваем дальше + $target = Find-Type $baseQ $pkg + if ($target -and $target.Element.get_LocalName() -eq "valueType") { + $inner = Resolve-Scalar $target.Element $target.Package ($guard + 1) + $acc.Base1C = $inner.Base1C + foreach ($k in $inner.Facets.Keys) { if (-not $acc.Facets.ContainsKey($k)) { $acc.Facets[$k] = $inner.Facets[$k] } } + if ($inner.Enum.Count -gt 0 -and $acc.Enum.Count -eq 0) { $acc.Enum = $inner.Enum } + if (-not $acc.Alias) { $acc.Alias = $baseQ.Local } + return $acc + } + $acc.Base1C = $baseQ.Local + return $acc +} + +function Find-Type($q, $pkg) { + if (-not $q) { return $null } + $targetPkg = $null + if (-not $q.Ns -or ($pkg -and $q.Ns -eq $pkg.Namespace)) { $targetPkg = $pkg } + elseif ($byNamespace.ContainsKey($q.Ns)) { $targetPkg = $byNamespace[$q.Ns] } + if (-not $targetPkg) { return $null } + if (-not $targetPkg.Types.ContainsKey($q.Local)) { return $null } + return [pscustomobject]@{ Element = $targetPkg.Types[$q.Local]; Package = $targetPkg } +} + +function Format-RefName($q, $pkg) { + if (-not $q) { return "" } + if ($q.Ns -eq $XS_NS) { + return $(if ($XS_TO_1C.ContainsKey($q.Local)) { $XS_TO_1C[$q.Local] } else { "xs:$($q.Local)" }) + } + return $q.Local +} + +function Format-Scalar($res) { + $t = $res.Base1C + $f = $res.Facets + if ($t -eq "Строка") { + if ($f.ContainsKey("length")) { $t = "Строка($($f['length']))" } + elseif ($f.ContainsKey("maxLength")) { $t = "Строка($($f['maxLength']))" } + } elseif ($t -eq "Число") { + if ($f.ContainsKey("totalDigits")) { + $frac = $(if ($f.ContainsKey("fractionDigits")) { $f["fractionDigits"] } else { "0" }) + $t = "Число($($f['totalDigits']),$frac)" + } + } + return $t +} + +function Format-Notes($res) { + $notes = @() + if ($res.Alias) { $notes += "← $($res.Alias)" } + if ($res.Facets.ContainsKey("pattern")) { + $p = $res.Facets["pattern"] + if ($p.Length -gt 40) { $p = $p.Substring(0, 40) + "…" } + $notes += "шаблон $p" + } + foreach ($k in @("minInclusive", "maxInclusive", "minExclusive", "maxExclusive")) { + if ($res.Facets.ContainsKey($k)) { $notes += "$k $($res.Facets[$k])" } + } + return $notes +} + +# --- Property rendering --------------------------------------------------------- + +function Get-PropRows([System.Xml.XmlElement]$type, $pkg, [int]$depth, [int]$indent, $seen) { + $rows = New-Object System.Collections.ArrayList + foreach ($p in $type.ChildNodes) { + if ($p.NodeType -ne [System.Xml.XmlNodeType]::Element -or $p.get_LocalName() -ne "property") { continue } + + $pname = $p.GetAttribute("name") + if (-not $pname) { + $refQ = Split-Ref $p $p.GetAttribute("ref") + $pname = $(if ($refQ) { $refQ.Local } else { "(без имени)" }) + } + $lower = $p.GetAttribute("lowerBound") + $upper = $p.GetAttribute("upperBound") + $flags = @() + # В модели умолчание lowerBound = 1; помечаем обязательные, как в meta-info + if ($lower -ne "0") { $flags += "обязательный" } + if ($upper -eq "-1") { $flags += "список" } + elseif ($upper -and $upper -ne "1") { $flags += "до $upper" } + if ($p.GetAttribute("form") -eq "Text") { $flags += "значение элемента" } + + $notes = @() + $typeText = "" + $children = $null + $childPkg = $pkg + + $anon = $null + foreach ($c in $p.ChildNodes) { + if ($c.NodeType -eq [System.Xml.XmlNodeType]::Element -and $c.get_LocalName() -eq "typeDef") { $anon = $c; break } + } + + if ($anon) { + if ($anon.GetAttribute("type", $XSI_NS) -eq "ObjectType") { + $typeText = "объект (анонимный)" + $children = $anon # анонимные раскрываем всегда: смотреть отдельно негде + } else { + $res = Resolve-Scalar $anon $pkg + $typeText = Format-Scalar $res + $notes += (Format-Notes $res) + if ($res.Enum.Count -gt 0) { $notes += "значения: " + (($res.Enum | Select-Object -First 8) -join ", ") } + } + } else { + $q = Split-Ref $p $p.GetAttribute("type") + if (-not $q) { + $typeText = "произвольный" + } elseif ($q.Ns -eq $XS_NS) { + $typeText = $(if ($XS_TO_1C.ContainsKey($q.Local)) { $XS_TO_1C[$q.Local] } else { "xs:$($q.Local)" }) + } else { + $target = Find-Type $q $pkg + if (-not $target) { + $typeText = "объект $($q.Local)" + $notes += "(пакет не найден: $($q.Ns))" + } elseif ($target.Element.get_LocalName() -eq "objectType") { + $typeText = "объект $($q.Local)" + if ($target.Package.Namespace -ne $pkg.Namespace) { $typeText += " · $($target.Package.Name)" } + $children = $target.Element + $childPkg = $target.Package + } else { + $res = Resolve-Scalar $target.Element $target.Package + $typeText = Format-Scalar $res + $notes += "← $($q.Local)" + $n2 = Format-Notes $res | Where-Object { -not $_.StartsWith("←") } + $notes += $n2 + if ($res.Enum.Count -gt 0) { $notes += "значения: " + (($res.Enum | Select-Object -First 8) -join ", ") } + } + } + } + + [void]$rows.Add([pscustomobject]@{ + Indent = $indent; Name = $pname; Type = $typeText + Flags = $flags; Notes = ($notes | Where-Object { $_ }) + }) + + if ($children) { + $key = "$($childPkg.Namespace)#$($children.GetAttribute('name'))" + $isAnon = -not $children.GetAttribute("name") + if (-not $isAnon -and $seen.Contains($key)) { + [void]$rows.Add([pscustomobject]@{ Indent = $indent + 1; Name = "(раскрыт выше)"; Type = ""; Flags = @(); Notes = @() }) + } elseif ($isAnon -or $depth -gt 1) { + $nextSeen = New-Object System.Collections.Generic.HashSet[string] (,[string[]]$seen) + if (-not $isAnon) { [void]$nextSeen.Add($key) } + $nextDepth = $(if ($isAnon) { $depth } else { $depth - 1 }) + foreach ($r in (Get-PropRows $children $childPkg $nextDepth ($indent + 1) $nextSeen)) { [void]$rows.Add($r) } + } + } + } + return ,$rows +} + +function Write-Rows($rows) { + if ($rows.Count -eq 0) { O " (нет свойств)"; return } + $shown = $rows + if ($Offset -gt 0 -or $rows.Count -gt $Limit) { + $end = [Math]::Min($Offset + $Limit, $rows.Count) - 1 + if ($Offset -le $end) { $shown = $rows[$Offset..$end] } else { $shown = @() } + } + $wName = 0; $wType = 0 + foreach ($r in $shown) { + $n = (" " * $r.Indent) + $r.Name + if ($n.Length -gt $wName) { $wName = $n.Length } + if ($r.Type.Length -gt $wType) { $wType = $r.Type.Length } + } + foreach ($r in $shown) { + $n = (" " * $r.Indent) + $r.Name + $line = " " + $n.PadRight($wName + 2) + $r.Type.PadRight($wType + 2) + if ($r.Flags.Count -gt 0) { $line += "[" + ($r.Flags -join ", ") + "] " } + if ($r.Notes.Count -gt 0) { $line += ($r.Notes -join ", ") } + O $line.TrimEnd() + } + if ($rows.Count -gt $shown.Count) { + O " … показано $($shown.Count) из $($rows.Count); листать через -Offset/-Limit" + } +} + +# --- Modes ---------------------------------------------------------------------- + +function Show-PackageList { + O "=== Пакеты XDTO: $($packages.Count) ===" + O "" + $shown = $packages + if ($Offset -gt 0 -or $packages.Count -gt $Limit) { + $end = [Math]::Min($Offset + $Limit, $packages.Count) - 1 + if ($Offset -le $end) { $shown = $packages[$Offset..$end] } else { $shown = @() } + } + $wn = 0 + foreach ($p in $shown) { if ($p.Name.Length -gt $wn) { $wn = $p.Name.Length } } + foreach ($p in $shown) { + $cnt = $p.Types.Count + O (" " + $p.Name.PadRight($wn + 2) + "$cnt".PadLeft(4) + " " + $p.Namespace) + } + if ($packages.Count -gt $shown.Count) { + O "" + O " … показано $($shown.Count) из $($packages.Count); листать через -Offset/-Limit" + } + O "" + O "Колонки: имя пакета, число типов, namespace." + O "Следующий шаг: -Package <имя> или -Namespace — состав пакета; -Name <Тип> — поиск типа по всем пакетам" +} + +function Show-PackageOverview($pkg) { + O "=== Пакет XDTO: $($pkg.Name) ===" + O "Namespace: $($pkg.Namespace)" + if ($pkg.Imports.Count -gt 0) { + O "" + O "Импорты ($($pkg.Imports.Count)):" + foreach ($i in $pkg.Imports) { + $dep = $(if ($byNamespace.ContainsKey($i)) { $byNamespace[$i].Name } else { "(пакет не найден)" }) + O " $i → $dep" + } + } + if ($pkg.GlobalProps.Count -gt 0) { + O "" + O "Точки входа ($($pkg.GlobalProps.Count)) — корневые элементы документа:" + foreach ($gp in $pkg.GlobalProps) { + $q = Split-Ref $gp $gp.GetAttribute("type") + $tn = $(if ($q) { Format-RefName $q $pkg } else { "произвольный" }) + $form = $(if ($gp.GetAttribute("form") -eq "Attribute") { " (атрибут)" } else { "" }) + O (" <" + $gp.GetAttribute("name") + "> → " + $tn + $form) + } + } + $objs = @(); $vals = @() + foreach ($k in (Sort-Ordinal $pkg.Types.Keys)) { + if ($pkg.Types[$k].get_LocalName() -eq "objectType") { $objs += $k } else { $vals += $k } + } + if ($objs.Count -gt 0) { + O "" + O "Объектные типы ($($objs.Count)):" + foreach ($n in $objs) { + $cnt = 0 + foreach ($c in $pkg.Types[$n].ChildNodes) { + if ($c.NodeType -eq [System.Xml.XmlNodeType]::Element -and $c.get_LocalName() -eq "property") { $cnt++ } + } + $base = Split-Ref $pkg.Types[$n] $pkg.Types[$n].GetAttribute("base") + $suffix = $(if ($base) { " ← $($base.Local)" } else { "" }) + O (" " + $n.PadRight(40) + "свойств: $cnt" + $suffix) + } + } + if ($vals.Count -gt 0) { + O "" + O "Типы значений ($($vals.Count)):" + foreach ($n in $vals) { + $res = Resolve-Scalar $pkg.Types[$n] $pkg + $line = " " + $n.PadRight(40) + (Format-Scalar $res) + if ($res.Enum.Count -gt 0) { $line += " значения: " + (($res.Enum | Select-Object -First 6) -join ", ") } + O $line + } + } + O "" + O "Следующий шаг: -Name <Тип> — структура типа для заполнения" +} + +function Show-Type($pkg, [string]$typeName) { + $el = $pkg.Types[$typeName] + $kind = $el.get_LocalName() + if ($kind -eq "valueType") { + $res = Resolve-Scalar $el $pkg + O "=== Тип значения XDTO: $typeName ===" + O "Пакет: $($pkg.Name) · $($pkg.Namespace)" + O "" + O "Значение: $(Format-Scalar $res)" + foreach ($n in (Format-Notes $res)) { O " $n" } + if ($res.Enum.Count -gt 0) { + O "" + O "Допустимые значения ($($res.Enum.Count)):" + foreach ($v in $res.Enum) { O " $v" } + } + return + } + + $hdr = "=== Тип XDTO: $typeName ===" + if ($Depth -gt 1) { $hdr += " (глубина $Depth)" } + O $hdr + O "Пакет: $($pkg.Name) · $($pkg.Namespace)" + $base = Split-Ref $el $el.GetAttribute("base") + if ($base) { O "Наследует: $($base.Local)" } + if ($el.GetAttribute("abstract") -eq "true") { O "Абстрактный — создаётся только тип-наследник" } + if ($el.GetAttribute("open") -eq "true") { O "Открытый — допускает произвольные элементы и атрибуты" } + O "" + + $seen = New-Object System.Collections.Generic.HashSet[string] + [void]$seen.Add("$($pkg.Namespace)#$typeName") + $rows = Get-PropRows $el $pkg $Depth 0 $seen + $own = @($rows | Where-Object { $_.Indent -eq 0 }) + O "Свойства ($($own.Count)):" + Write-Rows $rows + O "" + O "Создание:" + O " Тип = ФабрикаXDTO.Тип(`"$($pkg.Namespace)`", `"$typeName`");" + O " Объект = ФабрикаXDTO.Создать(Тип);" +} + +function Show-UsedBy([string]$typeName, $ownerPkg) { + O "=== Ссылки на тип: $typeName ===" + if ($ownerPkg) { O "Объявлен в: $($ownerPkg.Name) · $($ownerPkg.Namespace)" } + O "" + $hits = New-Object System.Collections.ArrayList + foreach ($p in $packages) { + foreach ($node in $p.Root.SelectNodes("//*")) { + if ($node.NodeType -ne [System.Xml.XmlNodeType]::Element) { continue } + foreach ($a in @("type", "base", "itemType", "memberTypes")) { + $raw = $node.GetAttribute($a) + if (-not $raw) { continue } + foreach ($one in ($raw -split "\s+")) { + $q = Split-Ref $node $one + if (-not $q -or $q.Local -ne $typeName) { continue } + if ($ownerPkg -and $q.Ns -and $q.Ns -ne $ownerPkg.Namespace) { continue } + $owner = $node + while ($owner -and @("objectType", "valueType") -notcontains $owner.get_LocalName()) { $owner = $owner.ParentNode } + $where = $(if ($owner -and $owner.GetAttribute("name")) { $owner.GetAttribute("name") } else { "(верхний уровень)" }) + $what = $(if ($node.GetAttribute("name")) { $node.GetAttribute("name") } else { $node.get_LocalName() }) + [void]$hits.Add(" $($p.Name).$where.$what ($a)") + } + } + } + } + if ($hits.Count -eq 0) { O " Ссылок не найдено"; return } + O "Найдено ($($hits.Count)):" + foreach ($h in (Sort-Ordinal ($hits | Select-Object -Unique))) { O $h } +} + +# --- Dispatch ------------------------------------------------------------------- + +# Выбор пакета: явный путь, затем -Namespace / -Package, затем поиск типа по всем +$selected = $null +if ($directPkgDir) { + $leaf = [System.IO.Path]::GetFileName($directPkgDir) + $selected = $packages | Where-Object { $_.Name -eq $leaf } | Select-Object -First 1 +} +if (-not $selected -and $Namespace) { + $selected = $packages | Where-Object { $_.Namespace -eq $Namespace } | Select-Object -First 1 + if (-not $selected) { throw "Пакет с namespace `"$Namespace`" не найден. Список: -PackagePath <корень> без параметров" } +} +if (-not $selected -and $Package) { + $selected = $packages | Where-Object { $_.Name -eq $Package } | Select-Object -First 1 + if (-not $selected) { throw "Пакет `"$Package`" не найден. Список: -PackagePath <корень> без параметров" } +} + +if ($Mode -eq "used-by") { + if (-not $Name) { throw "Режим used-by требует -Name <Тип>" } + $ownerPkg = $selected + if (-not $ownerPkg) { $ownerPkg = ($packages | Where-Object { $_.Types.ContainsKey($Name) } | Select-Object -First 1) } + Show-UsedBy $Name $ownerPkg + Flush-Output + exit 0 +} + +if ($Name) { + if (-not $selected) { + # Тип известен, пакет — нет: ищем по всей конфигурации + $found = @($packages | Where-Object { $_.Types.ContainsKey($Name) }) + if ($found.Count -eq 0) { throw "Тип `"$Name`" не найден ни в одном пакете конфигурации" } + if ($found.Count -gt 1) { + O "=== Тип `"$Name`" найден в нескольких пакетах ($($found.Count)) ===" + O "Уточните через -Namespace или -Package:" + O "" + foreach ($f in $found) { O " $($f.Name) · $($f.Namespace)" } + Flush-Output + exit 0 + } + $selected = $found[0] + } + if (-not $selected.Types.ContainsKey($Name)) { + throw "В пакете $($selected.Name) нет типа `"$Name`". Список типов: тот же вызов без -Name" + } + Show-Type $selected $Name + Flush-Output + exit 0 +} + +if ($selected) { Show-PackageOverview $selected } else { Show-PackageList } +Flush-Output +exit 0 diff --git a/.claude/skills/xdto-info/scripts/xdto-info.py b/.claude/skills/xdto-info/scripts/xdto-info.py new file mode 100644 index 00000000..d62588a3 --- /dev/null +++ b/.claude/skills/xdto-info/scripts/xdto-info.py @@ -0,0 +1,615 @@ +# xdto-info v1.0 — Analyze 1C XDTO package structure (Python port) +# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills +import argparse +import os +import sys + +from lxml import etree + +sys.stdout.reconfigure(encoding="utf-8") +sys.stderr.reconfigure(encoding="utf-8") + +XS_NS = "http://www.w3.org/2001/XMLSchema" +XSI_NS = "http://www.w3.org/2001/XMLSchema-instance" + +parser = argparse.ArgumentParser(allow_abbrev=False) +parser.add_argument("-PackagePath", "-Path", required=True) +parser.add_argument("-Package", default="") +parser.add_argument("-Namespace", default="") +parser.add_argument("-Name", default="") +parser.add_argument("-Mode", default="auto", choices=["auto", "used-by"]) +parser.add_argument("-Depth", type=int, default=1) +parser.add_argument("-Limit", type=int, default=150) +parser.add_argument("-Offset", type=int, default=0) +parser.add_argument("-OutFile", default="") +args = parser.parse_args() + +LIMIT, OFFSET, DEPTH = args.Limit, args.Offset, args.Depth + +lines = [] + + +def O(line=""): + lines.append(line) + + +def flush_output(): + text = "\n".join(lines).rstrip() + if args.OutFile: + d = os.path.dirname(args.OutFile) + if d and not os.path.isdir(d): + os.makedirs(d, exist_ok=True) + with open(args.OutFile, "wb") as f: + f.write(b"\xef\xbb\xbf" + (text + "\r\n").encode("utf-8")) + print(f"✓ Записано: {args.OutFile}") + else: + print(text) + + +def die(msg): + print(msg, file=sys.stderr) + sys.exit(1) + + +def _parse_xml(source, from_string=False): + """Разбор с узким отступлением для не-URI пространств имён. + + Платформа допускает в targetNamespace произвольную строку (в выгрузке БП есть + пакет с кириллическим «ДопФайлУниверсальный»), .NET такое принимает, а libxml2 + отвергает. Откатываемся на восстанавливающий разбор ТОЛЬКО на этой ошибке, + иначе по-настоящему битый XML перестал бы отличаться от корректного. + """ + try: + return (etree.fromstring(source) if from_string else etree.parse(source)) + except etree.XMLSyntaxError as e: + if "is not a valid URI" not in str(e): + raise + p = etree.XMLParser(recover=True) + return (etree.fromstring(source, p) if from_string else etree.parse(source, p)) + + +def local(el): + return etree.QName(el).localname + + +# ── resolve path ───────────────────────────────────────────── + +package_path = os.path.abspath(args.PackagePath) +if not os.path.exists(package_path): + die(f"Путь не найден: {package_path}") + +config_root = None +direct_pkg_dir = None + +if os.path.exists(os.path.join(package_path, "Configuration.xml")): + config_root = package_path +elif os.path.basename(package_path.rstrip("\\/")) == "XDTOPackages": + config_root = os.path.dirname(package_path.rstrip("\\/")) +elif os.path.exists(os.path.join(package_path, "Ext", "Package.bin")): + direct_pkg_dir = package_path + config_root = os.path.dirname(os.path.dirname(package_path)) +elif os.path.isfile(package_path) and os.path.basename(package_path) == "Package.bin": + direct_pkg_dir = os.path.dirname(os.path.dirname(package_path)) + config_root = os.path.dirname(os.path.dirname(direct_pkg_dir)) +elif package_path.endswith(".xml"): + stem = os.path.join(os.path.dirname(package_path), + os.path.splitext(os.path.basename(package_path))[0]) + if os.path.exists(os.path.join(stem, "Ext", "Package.bin")): + direct_pkg_dir = stem + config_root = os.path.dirname(os.path.dirname(stem)) + +if not config_root and not direct_pkg_dir: + die(f"Не удалось определить пакет или конфигурацию по пути: {package_path}") + + +# ── package index ──────────────────────────────────────────── + +class Pkg: + __slots__ = ("Name", "Dir", "Namespace", "Root", "Imports", "Types", "GlobalProps") + + +def read_package(pkg_dir): + b = os.path.join(pkg_dir, "Ext", "Package.bin") + if not os.path.exists(b): + return None + try: + root = _parse_xml(b).getroot() + except Exception: # noqa: BLE001 + return None + if local(root) != "package": + return None + p = Pkg() + p.Name = os.path.basename(pkg_dir.rstrip("\\/")) + p.Dir = pkg_dir + p.Namespace = root.get("targetNamespace") + p.Root = root + p.Imports = [] + p.Types = {} + p.GlobalProps = [] + for n in root: + if not isinstance(n.tag, str): + continue + ln = local(n) + if ln == "import": + p.Imports.append(n.get("namespace")) + elif ln in ("objectType", "valueType"): + p.Types[n.get("name")] = n + elif ln == "property": + p.GlobalProps.append(n) + return p + + +packages = [] +by_namespace = {} + +if config_root and os.path.isdir(os.path.join(config_root, "XDTOPackages")): + base = os.path.join(config_root, "XDTOPackages") + for dn in sorted(d for d in os.listdir(base) if os.path.isdir(os.path.join(base, d))): + p = read_package(os.path.join(base, dn)) + if p: + packages.append(p) + by_namespace.setdefault(p.Namespace, p) +if direct_pkg_dir and not packages: + p = read_package(direct_pkg_dir) + if p: + packages.append(p) + by_namespace[p.Namespace] = p +if not packages: + die(f"Пакеты XDTO не найдены: {package_path}") + +# ── type notation: XSD -> 1С ───────────────────────────────── + +XS_TO_1C = { + "string": "Строка", "normalizedString": "Строка", "token": "Строка", "NCName": "Строка", + "Name": "Строка", "QName": "Строка", "anyURI": "Строка", "language": "Строка", + "ID": "Строка", "IDREF": "Строка", "NMTOKEN": "Строка", + "decimal": "Число", "integer": "Число", "int": "Число", "long": "Число", "short": "Число", + "byte": "Число", "float": "Число", "double": "Число", + "nonNegativeInteger": "Число", "positiveInteger": "Число", "nonPositiveInteger": "Число", + "negativeInteger": "Число", "unsignedInt": "Число", "unsignedLong": "Число", + "unsignedShort": "Число", "unsignedByte": "Число", + "date": "Дата", "dateTime": "Дата", "time": "Дата", + "boolean": "Булево", + "base64Binary": "ДвоичныеДанные", "hexBinary": "ДвоичныеДанные", + "anyType": "произвольный", "anySimpleType": "произвольный", +} + +FACET_NAMES = ["length", "minLength", "maxLength", "totalDigits", "fractionDigits", + "minInclusive", "maxInclusive", "minExclusive", "maxExclusive"] + + +def split_ref(el, raw): + if not raw: + return None + if raw.startswith("{"): + close = raw.find("}") + if close < 0: + return None + return (raw[1:close], raw[close + 1:]) + parts = raw.split(":") + if len(parts) == 2: + return (el.nsmap.get(parts[0]), parts[1]) + return (None, parts[0]) + + +def get_facets(t): + res = {} + for f in FACET_NAMES: + v = t.get(f) + if v: + res[f] = v + for c in t: + if isinstance(c.tag, str) and local(c) == "pattern": + res["pattern"] = c.text or "" + break + return res + + +def get_enumerations(t): + return [(c.text or "") for c in t if isinstance(c.tag, str) and local(c) == "enumeration"] + + +def find_type(q, pkg): + if not q: + return None + ns, loc = q + target = None + if not ns or (pkg and ns == pkg.Namespace): + target = pkg + elif ns in by_namespace: + target = by_namespace[ns] + if not target or loc not in target.Types: + return None + return (target.Types[loc], target) + + +def format_ref_name(q, pkg): + if not q: + return "" + ns, loc = q + if ns == XS_NS: + return XS_TO_1C.get(loc, f"xs:{loc}") + return loc + + +def resolve_scalar(t, pkg, guard=0): + acc = {"Base1C": None, "Facets": {}, "Alias": None, "Enum": [], "Kind": "scalar"} + if guard > 10 or t is None: + return acc + + variety = t.get("variety") + if variety == "List": + it = split_ref(t, t.get("itemType")) + acc["Kind"] = "list" + acc["Base1C"] = "список " + (format_ref_name(it, pkg) if it else "значений") + return acc + if variety == "Union" or t.get("memberTypes"): + members = [] + for m in (t.get("memberTypes") or "").split(): + q = split_ref(t, m) + if q: + members.append(format_ref_name(q, pkg)) + for c in t: + if isinstance(c.tag, str) and local(c) == "typeDef": + members.append(resolve_scalar(c, pkg, guard + 1)["Base1C"]) + acc["Kind"] = "union" + acc["Base1C"] = "одно из (" + " | ".join(m for m in members if m) + ")" + return acc + + acc["Facets"] = get_facets(t) + acc["Enum"] = get_enumerations(t) + + base_q = split_ref(t, t.get("base")) + anon_base = next((c for c in t if isinstance(c.tag, str) and local(c) == "typeDef"), None) + if not base_q and anon_base is not None: + inner = resolve_scalar(anon_base, pkg, guard + 1) + acc["Base1C"] = inner["Base1C"] + for k, v in inner["Facets"].items(): + acc["Facets"].setdefault(k, v) + if inner["Enum"] and not acc["Enum"]: + acc["Enum"] = inner["Enum"] + return acc + if not base_q: + acc["Base1C"] = "произвольный" + return acc + + if base_q[0] == XS_NS: + acc["Base1C"] = XS_TO_1C.get(base_q[1], f"xs:{base_q[1]}") + return acc + + target = find_type(base_q, pkg) + if target and local(target[0]) == "valueType": + inner = resolve_scalar(target[0], target[1], guard + 1) + acc["Base1C"] = inner["Base1C"] + for k, v in inner["Facets"].items(): + acc["Facets"].setdefault(k, v) + if inner["Enum"] and not acc["Enum"]: + acc["Enum"] = inner["Enum"] + if not acc["Alias"]: + acc["Alias"] = base_q[1] + return acc + acc["Base1C"] = base_q[1] + return acc + + +def format_scalar(res): + t, f = res["Base1C"], res["Facets"] + if t == "Строка": + if "length" in f: + t = f'Строка({f["length"]})' + elif "maxLength" in f: + t = f'Строка({f["maxLength"]})' + elif t == "Число": + if "totalDigits" in f: + t = f'Число({f["totalDigits"]},{f.get("fractionDigits", "0")})' + return t + + +def format_notes(res): + notes = [] + if res["Alias"]: + notes.append("← " + res["Alias"]) + if "pattern" in res["Facets"]: + p = res["Facets"]["pattern"] + if len(p) > 40: + p = p[:40] + "…" + notes.append("шаблон " + p) + for k in ("minInclusive", "maxInclusive", "minExclusive", "maxExclusive"): + if k in res["Facets"]: + notes.append(f'{k} {res["Facets"][k]}') + return notes + + +# ── property rendering ─────────────────────────────────────── + +def get_prop_rows(type_el, pkg, depth, indent, seen): + rows = [] + for p in type_el: + if not isinstance(p.tag, str) or local(p) != "property": + continue + + pname = p.get("name") + if not pname: + ref_q = split_ref(p, p.get("ref")) + pname = ref_q[1] if ref_q else "(без имени)" + lower, upper = p.get("lowerBound"), p.get("upperBound") + flags = [] + # В модели умолчание lowerBound = 1; помечаем обязательные, как в meta-info + if lower != "0": + flags.append("обязательный") + if upper == "-1": + flags.append("список") + elif upper and upper != "1": + flags.append("до " + upper) + if p.get("form") == "Text": + flags.append("значение элемента") + + notes = [] + type_text = "" + children = None + child_pkg = pkg + + anon = next((c for c in p if isinstance(c.tag, str) and local(c) == "typeDef"), None) + + if anon is not None: + if anon.get(f"{{{XSI_NS}}}type") == "ObjectType": + type_text = "объект (анонимный)" + children = anon # анонимные раскрываем всегда: смотреть отдельно негде + else: + res = resolve_scalar(anon, pkg) + type_text = format_scalar(res) + notes += format_notes(res) + if res["Enum"]: + notes.append("значения: " + ", ".join(res["Enum"][:8])) + else: + q = split_ref(p, p.get("type")) + if not q: + type_text = "произвольный" + elif q[0] == XS_NS: + type_text = XS_TO_1C.get(q[1], f"xs:{q[1]}") + else: + target = find_type(q, pkg) + if not target: + type_text = "объект " + q[1] + notes.append(f"(пакет не найден: {q[0]})") + elif local(target[0]) == "objectType": + type_text = "объект " + q[1] + if target[1].Namespace != pkg.Namespace: + type_text += " · " + target[1].Name + children = target[0] + child_pkg = target[1] + else: + res = resolve_scalar(target[0], target[1]) + type_text = format_scalar(res) + notes.append("← " + q[1]) + notes += [n for n in format_notes(res) if not n.startswith("←")] + if res["Enum"]: + notes.append("значения: " + ", ".join(res["Enum"][:8])) + + rows.append({"Indent": indent, "Name": pname, "Type": type_text, + "Flags": flags, "Notes": [n for n in notes if n]}) + + if children is not None: + cname = children.get("name") + key = f"{child_pkg.Namespace}#{cname}" + is_anon = not cname + if not is_anon and key in seen: + rows.append({"Indent": indent + 1, "Name": "(раскрыт выше)", "Type": "", + "Flags": [], "Notes": []}) + elif is_anon or depth > 1: + next_seen = set(seen) + if not is_anon: + next_seen.add(key) + next_depth = depth if is_anon else depth - 1 + rows += get_prop_rows(children, child_pkg, next_depth, indent + 1, next_seen) + return rows + + +def write_rows(rows): + if not rows: + O(" (нет свойств)") + return + shown = rows + if OFFSET > 0 or len(rows) > LIMIT: + shown = rows[OFFSET:OFFSET + LIMIT] + w_name = max((len(" " * r["Indent"] + r["Name"]) for r in shown), default=0) + w_type = max((len(r["Type"]) for r in shown), default=0) + for r in shown: + n = " " * r["Indent"] + r["Name"] + line = " " + n.ljust(w_name + 2) + r["Type"].ljust(w_type + 2) + if r["Flags"]: + line += "[" + ", ".join(r["Flags"]) + "] " + if r["Notes"]: + line += ", ".join(r["Notes"]) + O(line.rstrip()) + if len(rows) > len(shown): + O(f" … показано {len(shown)} из {len(rows)}; листать через -Offset/-Limit") + + +# ── modes ──────────────────────────────────────────────────── + +def show_package_list(): + O(f"=== Пакеты XDTO: {len(packages)} ===") + O("") + shown = packages + if OFFSET > 0 or len(packages) > LIMIT: + shown = packages[OFFSET:OFFSET + LIMIT] + wn = max((len(p.Name) for p in shown), default=0) + for p in shown: + O(" " + p.Name.ljust(wn + 2) + str(len(p.Types)).rjust(4) + " " + p.Namespace) + if len(packages) > len(shown): + O("") + O(f" … показано {len(shown)} из {len(packages)}; листать через -Offset/-Limit") + O("") + O("Колонки: имя пакета, число типов, namespace.") + O("Следующий шаг: -Package <имя> или -Namespace — состав пакета; " + "-Name <Тип> — поиск типа по всем пакетам") + + +def show_package_overview(pkg): + O(f"=== Пакет XDTO: {pkg.Name} ===") + O(f"Namespace: {pkg.Namespace}") + if pkg.Imports: + O("") + O(f"Импорты ({len(pkg.Imports)}):") + for i in pkg.Imports: + dep = by_namespace[i].Name if i in by_namespace else "(пакет не найден)" + O(f" {i} → {dep}") + if pkg.GlobalProps: + O("") + O(f"Точки входа ({len(pkg.GlobalProps)}) — корневые элементы документа:") + for gp in pkg.GlobalProps: + q = split_ref(gp, gp.get("type")) + tn = format_ref_name(q, pkg) if q else "произвольный" + form = " (атрибут)" if gp.get("form") == "Attribute" else "" + O(f' <{gp.get("name")}> → {tn}{form}') + objs = [k for k in sorted(pkg.Types) if local(pkg.Types[k]) == "objectType"] + vals = [k for k in sorted(pkg.Types) if local(pkg.Types[k]) == "valueType"] + if objs: + O("") + O(f"Объектные типы ({len(objs)}):") + for n in objs: + cnt = sum(1 for c in pkg.Types[n] if isinstance(c.tag, str) and local(c) == "property") + base = split_ref(pkg.Types[n], pkg.Types[n].get("base")) + suffix = f" ← {base[1]}" if base else "" + O(" " + n.ljust(40) + f"свойств: {cnt}" + suffix) + if vals: + O("") + O(f"Типы значений ({len(vals)}):") + for n in vals: + res = resolve_scalar(pkg.Types[n], pkg) + line = " " + n.ljust(40) + format_scalar(res) + if res["Enum"]: + line += " значения: " + ", ".join(res["Enum"][:6]) + O(line) + O("") + O("Следующий шаг: -Name <Тип> — структура типа для заполнения") + + +def show_type(pkg, type_name): + el = pkg.Types[type_name] + if local(el) == "valueType": + res = resolve_scalar(el, pkg) + O(f"=== Тип значения XDTO: {type_name} ===") + O(f"Пакет: {pkg.Name} · {pkg.Namespace}") + O("") + O("Значение: " + format_scalar(res)) + for n in format_notes(res): + O(" " + n) + if res["Enum"]: + O("") + O(f'Допустимые значения ({len(res["Enum"])}):') + for v in res["Enum"]: + O(" " + v) + return + + hdr = f"=== Тип XDTO: {type_name} ===" + if DEPTH > 1: + hdr += f" (глубина {DEPTH})" + O(hdr) + O(f"Пакет: {pkg.Name} · {pkg.Namespace}") + base = split_ref(el, el.get("base")) + if base: + O("Наследует: " + base[1]) + if el.get("abstract") == "true": + O("Абстрактный — создаётся только тип-наследник") + if el.get("open") == "true": + O("Открытый — допускает произвольные элементы и атрибуты") + O("") + + seen = {f"{pkg.Namespace}#{type_name}"} + rows = get_prop_rows(el, pkg, DEPTH, 0, seen) + own = [r for r in rows if r["Indent"] == 0] + O(f"Свойства ({len(own)}):") + write_rows(rows) + O("") + O("Создание:") + O(f' Тип = ФабрикаXDTO.Тип("{pkg.Namespace}", "{type_name}");') + O(" Объект = ФабрикаXDTO.Создать(Тип);") + + +def show_used_by(type_name, owner_pkg): + O(f"=== Ссылки на тип: {type_name} ===") + if owner_pkg: + O(f"Объявлен в: {owner_pkg.Name} · {owner_pkg.Namespace}") + O("") + hits = [] + for p in packages: + for node in p.Root.iter(): + if not isinstance(node.tag, str): + continue + for a in ("type", "base", "itemType", "memberTypes"): + raw = node.get(a) + if not raw: + continue + for one in raw.split(): + q = split_ref(node, one) + if not q or q[1] != type_name: + continue + if owner_pkg and q[0] and q[0] != owner_pkg.Namespace: + continue + owner = node + while owner is not None and local(owner) not in ("objectType", "valueType"): + owner = owner.getparent() + where = owner.get("name") if (owner is not None and owner.get("name")) else "(верхний уровень)" + what = node.get("name") or local(node) + hits.append(f" {p.Name}.{where}.{what} ({a})") + if not hits: + O(" Ссылок не найдено") + return + O(f"Найдено ({len(hits)}):") + for h in sorted(set(hits)): + O(h) + + +# ── dispatch ───────────────────────────────────────────────── + +selected = None +if direct_pkg_dir: + leaf = os.path.basename(direct_pkg_dir.rstrip("\\/")) + selected = next((p for p in packages if p.Name == leaf), None) +if not selected and args.Namespace: + selected = next((p for p in packages if p.Namespace == args.Namespace), None) + if not selected: + die(f'Пакет с namespace "{args.Namespace}" не найден. ' + "Список: -PackagePath <корень> без параметров") +if not selected and args.Package: + selected = next((p for p in packages if p.Name == args.Package), None) + if not selected: + die(f'Пакет "{args.Package}" не найден. Список: -PackagePath <корень> без параметров') + +if args.Mode == "used-by": + if not args.Name: + die("Режим used-by требует -Name <Тип>") + owner = selected or next((p for p in packages if args.Name in p.Types), None) + show_used_by(args.Name, owner) + flush_output() + sys.exit(0) + +if args.Name: + if not selected: + # Тип известен, пакет — нет: ищем по всей конфигурации + found = [p for p in packages if args.Name in p.Types] + if not found: + die(f'Тип "{args.Name}" не найден ни в одном пакете конфигурации') + if len(found) > 1: + O(f'=== Тип "{args.Name}" найден в нескольких пакетах ({len(found)}) ===') + O("Уточните через -Namespace или -Package:") + O("") + for f in found: + O(f" {f.Name} · {f.Namespace}") + flush_output() + sys.exit(0) + selected = found[0] + if args.Name not in selected.Types: + die(f'В пакете {selected.Name} нет типа "{args.Name}". Список типов: тот же вызов без -Name') + show_type(selected, args.Name) + flush_output() + sys.exit(0) + +if selected: + show_package_overview(selected) +else: + show_package_list() +flush_output() +sys.exit(0) diff --git a/.claude/skills/xdto-validate/scripts/xdto-validate.py b/.claude/skills/xdto-validate/scripts/xdto-validate.py index 5a49e5d1..f275f59a 100644 --- a/.claude/skills/xdto-validate/scripts/xdto-validate.py +++ b/.claude/skills/xdto-validate/scripts/xdto-validate.py @@ -106,6 +106,23 @@ def finalize(): f.write("\n".join(output)) +def _parse_xml(source, from_string=False): + """Разбор с узким отступлением для не-URI пространств имён. + + Платформа допускает в targetNamespace произвольную строку (в выгрузке БП есть + пакет с кириллическим «ДопФайлУниверсальный»), .NET такое принимает, а libxml2 + отвергает. Откатываемся на восстанавливающий разбор ТОЛЬКО на этой ошибке, + иначе по-настоящему битый XML перестал бы отличаться от корректного. + """ + try: + return (etree.fromstring(source) if from_string else etree.parse(source)) + except etree.XMLSyntaxError as e: + if "is not a valid URI" not in str(e): + raise + p = etree.XMLParser(recover=True) + return (etree.fromstring(source, p) if from_string else etree.parse(source, p)) + + def local(el): return etree.QName(el).localname @@ -113,7 +130,7 @@ def local(el): # ── 1. well-formedness ─────────────────────────────────────── try: - doc = etree.parse(bin_path) + doc = _parse_xml(bin_path) except Exception as e: # noqa: BLE001 report_error(f"Package.bin не является корректным XML: {e}") finalize() @@ -450,7 +467,7 @@ if state["stopped"]: # ── 11. metadata object ────────────────────────────────────── if md_path: - md = etree.parse(md_path) + md = _parse_xml(md_path) md_name = md.find(f".//{{{MD_NS}}}XDTOPackage/{{{MD_NS}}}Properties/{{{MD_NS}}}Name") md_ns = md.find(f".//{{{MD_NS}}}XDTOPackage/{{{MD_NS}}}Properties/{{{MD_NS}}}Namespace") if md_name is None: @@ -470,7 +487,7 @@ else: config_xml = os.path.join(config_dir, "Configuration.xml") if os.path.exists(config_xml): - cfg = etree.parse(config_xml) + cfg = _parse_xml(config_xml) registered = any((e.text or "") == file_name for e in cfg.iterfind(f".//{{{MD_NS}}}Configuration/{{{MD_NS}}}ChildObjects/{{{MD_NS}}}XDTOPackage")) if registered: @@ -489,7 +506,7 @@ if os.path.exists(config_xml): if not os.path.exists(ob): continue try: - if etree.parse(ob).getroot().get("targetNamespace") == target_ns: + if _parse_xml(ob).getroot().get("targetNamespace") == target_ns: clash.append(other) except Exception: # noqa: BLE001 pass diff --git a/tests/skills/cases/xdto-info/_skill.json b/tests/skills/cases/xdto-info/_skill.json new file mode 100644 index 00000000..d9069f71 --- /dev/null +++ b/tests/skills/cases/xdto-info/_skill.json @@ -0,0 +1,12 @@ +{ + "script": "xdto-info/scripts/xdto-info", + "setup": "empty-config", + "args": [ + { "flag": "-PackagePath", "from": "workPath", "field": "packagePath" }, + { "flag": "-OutFile", "from": "workPath", "field": "outFile" } + ], + "snapshot": { + "root": "workDir", + "normalizeUuids": true + } +} diff --git a/tests/skills/cases/xdto-info/by-namespace.json b/tests/skills/cases/xdto-info/by-namespace.json new file mode 100644 index 00000000..148c7921 --- /dev/null +++ b/tests/skills/cases/xdto-info/by-namespace.json @@ -0,0 +1,8 @@ +{ + "name": "адресация пакета по namespace от корня исходников", + "caseFiles": ["common.xsd", "uses-common.xsd"], + "preRun": [{ "script": "xdto-compile/scripts/xdto-compile", "args": { "-XsdPath": "{workDir}/common.xsd", "-OutputDir": "{workDir}" } }, { "script": "xdto-compile/scripts/xdto-compile", "args": { "-XsdPath": "{workDir}/uses-common.xsd", "-OutputDir": "{workDir}" } }], + "params": { "packagePath": ".", "outFile": "by-namespace.txt" }, + "args_extra": ["-Namespace", "urn:test:common", "-Name", "Справочник"], + "expect": { "files": ["by-namespace.txt"] } +} diff --git a/tests/skills/cases/xdto-info/common.xsd b/tests/skills/cases/xdto-info/common.xsd new file mode 100644 index 00000000..927c85dd --- /dev/null +++ b/tests/skills/cases/xdto-info/common.xsd @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/tests/skills/cases/xdto-info/cross-package.json b/tests/skills/cases/xdto-info/cross-package.json new file mode 100644 index 00000000..0f3c4f18 --- /dev/null +++ b/tests/skills/cases/xdto-info/cross-package.json @@ -0,0 +1,8 @@ +{ + "name": "раскрытие через границу пакета и отсутствующая зависимость", + "caseFiles": ["common.xsd", "uses-common.xsd"], + "preRun": [{ "script": "xdto-compile/scripts/xdto-compile", "args": { "-XsdPath": "{workDir}/common.xsd", "-OutputDir": "{workDir}" } }, { "script": "xdto-compile/scripts/xdto-compile", "args": { "-XsdPath": "{workDir}/uses-common.xsd", "-OutputDir": "{workDir}" } }], + "params": { "packagePath": "XDTOPackages/uses_common", "outFile": "cross-package.txt" }, + "args_extra": ["-Name", "Заявка", "-Depth", "2"], + "expect": { "files": ["cross-package.txt"] } +} diff --git a/tests/skills/cases/xdto-info/depth-anon-text.json b/tests/skills/cases/xdto-info/depth-anon-text.json new file mode 100644 index 00000000..bd98c42f --- /dev/null +++ b/tests/skills/cases/xdto-info/depth-anon-text.json @@ -0,0 +1,8 @@ +{ + "name": "разузлование: анонимный тип, значение элемента, обрыв цикла", + "caseFiles": ["nested.xsd"], + "preRun": [{ "script": "xdto-compile/scripts/xdto-compile", "args": { "-XsdPath": "{workDir}/nested.xsd", "-OutputDir": "{workDir}" } }], + "params": { "packagePath": "XDTOPackages/nested", "outFile": "depth-anon-text.txt" }, + "args_extra": ["-Name", "Документ", "-Depth", "4"], + "expect": { "files": ["depth-anon-text.txt"] } +} diff --git a/tests/skills/cases/xdto-info/nested.xsd b/tests/skills/cases/xdto-info/nested.xsd new file mode 100644 index 00000000..b5b6d8fb --- /dev/null +++ b/tests/skills/cases/xdto-info/nested.xsd @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/tests/skills/cases/xdto-info/package-list.json b/tests/skills/cases/xdto-info/package-list.json new file mode 100644 index 00000000..6e13f3b5 --- /dev/null +++ b/tests/skills/cases/xdto-info/package-list.json @@ -0,0 +1,8 @@ +{ + "name": "список пакетов конфигурации", + "caseFiles": ["common.xsd", "uses-common.xsd"], + "preRun": [{ "script": "xdto-compile/scripts/xdto-compile", "args": { "-XsdPath": "{workDir}/common.xsd", "-OutputDir": "{workDir}" } }, { "script": "xdto-compile/scripts/xdto-compile", "args": { "-XsdPath": "{workDir}/uses-common.xsd", "-OutputDir": "{workDir}" } }], + "params": { "packagePath": ".", "outFile": "package-list.txt" }, + "args_extra": [], + "expect": { "files": ["package-list.txt"] } +} diff --git a/tests/skills/cases/xdto-info/package-overview.json b/tests/skills/cases/xdto-info/package-overview.json new file mode 100644 index 00000000..9776a8e1 --- /dev/null +++ b/tests/skills/cases/xdto-info/package-overview.json @@ -0,0 +1,8 @@ +{ + "name": "сводка пакета: точки входа, импорты, списки типов", + "caseFiles": ["common.xsd", "uses-common.xsd"], + "preRun": [{ "script": "xdto-compile/scripts/xdto-compile", "args": { "-XsdPath": "{workDir}/common.xsd", "-OutputDir": "{workDir}" } }, { "script": "xdto-compile/scripts/xdto-compile", "args": { "-XsdPath": "{workDir}/uses-common.xsd", "-OutputDir": "{workDir}" } }], + "params": { "packagePath": "XDTOPackages/uses_common", "outFile": "package-overview.txt" }, + "args_extra": [], + "expect": { "files": ["package-overview.txt"] } +} diff --git a/tests/skills/cases/xdto-info/snapshots/by-namespace/Configuration.xml b/tests/skills/cases/xdto-info/snapshots/by-namespace/Configuration.xml new file mode 100644 index 00000000..05a1dd19 --- /dev/null +++ b/tests/skills/cases/xdto-info/snapshots/by-namespace/Configuration.xml @@ -0,0 +1,253 @@ + + + + + + UUID-002 + UUID-003 + + + UUID-004 + UUID-005 + + + UUID-006 + UUID-007 + + + UUID-008 + UUID-009 + + + UUID-010 + UUID-011 + + + UUID-012 + UUID-013 + + + UUID-014 + UUID-015 + + + + TestConfig + + + ru + TestConfig + + + + + Version8_3_24 + ManagedApplication + + PlatformApplication + + Russian + + + + + false + false + false + + + + + + + + + + + + + + + + + + + + + + Biometrics + true + + + Location + false + + + BackgroundLocation + false + + + BluetoothPrinters + false + + + WiFiPrinters + false + + + Contacts + false + + + Calendars + false + + + PushNotifications + false + + + LocalNotifications + false + + + InAppPurchases + false + + + PersonalComputerFileExchange + false + + + Ads + false + + + NumberDialing + false + + + CallProcessing + false + + + CallLog + false + + + AutoSendSMS + false + + + ReceiveSMS + false + + + SMSLog + false + + + Camera + false + + + Microphone + false + + + MusicLibrary + false + + + PictureAndVideoLibraries + false + + + AudioPlaybackAndVibration + false + + + BackgroundAudioPlaybackAndVibration + false + + + InstallPackages + false + + + OSBackup + true + + + ApplicationUsageStatistics + false + + + BarcodeScanning + false + + + BackgroundAudioRecording + false + + + AllFilesAccess + false + + + Videoconferences + false + + + NFC + false + + + DocumentScanning + false + + + SpeechToText + false + + + Geofences + false + + + IncomingShareRequests + false + + + AllIncomingShareRequestsTypesProcessing + false + + + + + + Normal + + + Language.Русский + + + + + + Managed + NotAutoFree + DontUse + DontUse + TaxiEnableVersion8_2 + DontUse + Version8_3_24 + + + + Русский + common + uses_common + + + \ No newline at end of file diff --git a/tests/skills/cases/xdto-info/snapshots/by-namespace/Ext/ClientApplicationInterface.xml b/tests/skills/cases/xdto-info/snapshots/by-namespace/Ext/ClientApplicationInterface.xml new file mode 100644 index 00000000..3c1161b2 --- /dev/null +++ b/tests/skills/cases/xdto-info/snapshots/by-namespace/Ext/ClientApplicationInterface.xml @@ -0,0 +1,18 @@ + + + + + UUID-002 + + + + + UUID-004 + + + + + + + + \ No newline at end of file diff --git a/tests/skills/cases/xdto-info/snapshots/by-namespace/Languages/Русский.xml b/tests/skills/cases/xdto-info/snapshots/by-namespace/Languages/Русский.xml new file mode 100644 index 00000000..37c60d78 --- /dev/null +++ b/tests/skills/cases/xdto-info/snapshots/by-namespace/Languages/Русский.xml @@ -0,0 +1,16 @@ + + + + + Русский + + + ru + Русский + + + + ru + + + \ No newline at end of file diff --git a/tests/skills/cases/xdto-info/snapshots/by-namespace/XDTOPackages/common.xml b/tests/skills/cases/xdto-info/snapshots/by-namespace/XDTOPackages/common.xml new file mode 100644 index 00000000..32189b9d --- /dev/null +++ b/tests/skills/cases/xdto-info/snapshots/by-namespace/XDTOPackages/common.xml @@ -0,0 +1,16 @@ + + + + + common + + + ru + common + + + + urn:test:common + + + \ No newline at end of file diff --git a/tests/skills/cases/xdto-info/snapshots/by-namespace/XDTOPackages/common/Ext/Package.bin b/tests/skills/cases/xdto-info/snapshots/by-namespace/XDTOPackages/common/Ext/Package.bin new file mode 100644 index 00000000..9e6187bb --- /dev/null +++ b/tests/skills/cases/xdto-info/snapshots/by-namespace/XDTOPackages/common/Ext/Package.bin @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/tests/skills/cases/xdto-info/snapshots/by-namespace/XDTOPackages/uses_common.xml b/tests/skills/cases/xdto-info/snapshots/by-namespace/XDTOPackages/uses_common.xml new file mode 100644 index 00000000..93f6d93c --- /dev/null +++ b/tests/skills/cases/xdto-info/snapshots/by-namespace/XDTOPackages/uses_common.xml @@ -0,0 +1,16 @@ + + + + + uses_common + + + ru + uses_common + + + + urn:test:uses + + + \ No newline at end of file diff --git a/tests/skills/cases/xdto-info/snapshots/by-namespace/XDTOPackages/uses_common/Ext/Package.bin b/tests/skills/cases/xdto-info/snapshots/by-namespace/XDTOPackages/uses_common/Ext/Package.bin new file mode 100644 index 00000000..a0be6645 --- /dev/null +++ b/tests/skills/cases/xdto-info/snapshots/by-namespace/XDTOPackages/uses_common/Ext/Package.bin @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/tests/skills/cases/xdto-info/snapshots/by-namespace/by-namespace.txt b/tests/skills/cases/xdto-info/snapshots/by-namespace/by-namespace.txt new file mode 100644 index 00000000..ce7a628f --- /dev/null +++ b/tests/skills/cases/xdto-info/snapshots/by-namespace/by-namespace.txt @@ -0,0 +1,10 @@ +=== Тип XDTO: Справочник === +Пакет: common · urn:test:common + +Свойства (2): + Код Строка [обязательный] + Наименование Строка [обязательный] + +Создание: + Тип = ФабрикаXDTO.Тип("urn:test:common", "Справочник"); + Объект = ФабрикаXDTO.Создать(Тип); diff --git a/tests/skills/cases/xdto-info/snapshots/by-namespace/common.xsd b/tests/skills/cases/xdto-info/snapshots/by-namespace/common.xsd new file mode 100644 index 00000000..927c85dd --- /dev/null +++ b/tests/skills/cases/xdto-info/snapshots/by-namespace/common.xsd @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/tests/skills/cases/xdto-info/snapshots/by-namespace/uses-common.xsd b/tests/skills/cases/xdto-info/snapshots/by-namespace/uses-common.xsd new file mode 100644 index 00000000..2de94e0f --- /dev/null +++ b/tests/skills/cases/xdto-info/snapshots/by-namespace/uses-common.xsd @@ -0,0 +1,12 @@ + + + + + + + + + + + diff --git a/tests/skills/cases/xdto-info/snapshots/cross-package/Configuration.xml b/tests/skills/cases/xdto-info/snapshots/cross-package/Configuration.xml new file mode 100644 index 00000000..05a1dd19 --- /dev/null +++ b/tests/skills/cases/xdto-info/snapshots/cross-package/Configuration.xml @@ -0,0 +1,253 @@ + + + + + + UUID-002 + UUID-003 + + + UUID-004 + UUID-005 + + + UUID-006 + UUID-007 + + + UUID-008 + UUID-009 + + + UUID-010 + UUID-011 + + + UUID-012 + UUID-013 + + + UUID-014 + UUID-015 + + + + TestConfig + + + ru + TestConfig + + + + + Version8_3_24 + ManagedApplication + + PlatformApplication + + Russian + + + + + false + false + false + + + + + + + + + + + + + + + + + + + + + + Biometrics + true + + + Location + false + + + BackgroundLocation + false + + + BluetoothPrinters + false + + + WiFiPrinters + false + + + Contacts + false + + + Calendars + false + + + PushNotifications + false + + + LocalNotifications + false + + + InAppPurchases + false + + + PersonalComputerFileExchange + false + + + Ads + false + + + NumberDialing + false + + + CallProcessing + false + + + CallLog + false + + + AutoSendSMS + false + + + ReceiveSMS + false + + + SMSLog + false + + + Camera + false + + + Microphone + false + + + MusicLibrary + false + + + PictureAndVideoLibraries + false + + + AudioPlaybackAndVibration + false + + + BackgroundAudioPlaybackAndVibration + false + + + InstallPackages + false + + + OSBackup + true + + + ApplicationUsageStatistics + false + + + BarcodeScanning + false + + + BackgroundAudioRecording + false + + + AllFilesAccess + false + + + Videoconferences + false + + + NFC + false + + + DocumentScanning + false + + + SpeechToText + false + + + Geofences + false + + + IncomingShareRequests + false + + + AllIncomingShareRequestsTypesProcessing + false + + + + + + Normal + + + Language.Русский + + + + + + Managed + NotAutoFree + DontUse + DontUse + TaxiEnableVersion8_2 + DontUse + Version8_3_24 + + + + Русский + common + uses_common + + + \ No newline at end of file diff --git a/tests/skills/cases/xdto-info/snapshots/cross-package/Ext/ClientApplicationInterface.xml b/tests/skills/cases/xdto-info/snapshots/cross-package/Ext/ClientApplicationInterface.xml new file mode 100644 index 00000000..3c1161b2 --- /dev/null +++ b/tests/skills/cases/xdto-info/snapshots/cross-package/Ext/ClientApplicationInterface.xml @@ -0,0 +1,18 @@ + + + + + UUID-002 + + + + + UUID-004 + + + + + + + + \ No newline at end of file diff --git a/tests/skills/cases/xdto-info/snapshots/cross-package/Languages/Русский.xml b/tests/skills/cases/xdto-info/snapshots/cross-package/Languages/Русский.xml new file mode 100644 index 00000000..37c60d78 --- /dev/null +++ b/tests/skills/cases/xdto-info/snapshots/cross-package/Languages/Русский.xml @@ -0,0 +1,16 @@ + + + + + Русский + + + ru + Русский + + + + ru + + + \ No newline at end of file diff --git a/tests/skills/cases/xdto-info/snapshots/cross-package/XDTOPackages/common.xml b/tests/skills/cases/xdto-info/snapshots/cross-package/XDTOPackages/common.xml new file mode 100644 index 00000000..32189b9d --- /dev/null +++ b/tests/skills/cases/xdto-info/snapshots/cross-package/XDTOPackages/common.xml @@ -0,0 +1,16 @@ + + + + + common + + + ru + common + + + + urn:test:common + + + \ No newline at end of file diff --git a/tests/skills/cases/xdto-info/snapshots/cross-package/XDTOPackages/common/Ext/Package.bin b/tests/skills/cases/xdto-info/snapshots/cross-package/XDTOPackages/common/Ext/Package.bin new file mode 100644 index 00000000..9e6187bb --- /dev/null +++ b/tests/skills/cases/xdto-info/snapshots/cross-package/XDTOPackages/common/Ext/Package.bin @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/tests/skills/cases/xdto-info/snapshots/cross-package/XDTOPackages/uses_common.xml b/tests/skills/cases/xdto-info/snapshots/cross-package/XDTOPackages/uses_common.xml new file mode 100644 index 00000000..93f6d93c --- /dev/null +++ b/tests/skills/cases/xdto-info/snapshots/cross-package/XDTOPackages/uses_common.xml @@ -0,0 +1,16 @@ + + + + + uses_common + + + ru + uses_common + + + + urn:test:uses + + + \ No newline at end of file diff --git a/tests/skills/cases/xdto-info/snapshots/cross-package/XDTOPackages/uses_common/Ext/Package.bin b/tests/skills/cases/xdto-info/snapshots/cross-package/XDTOPackages/uses_common/Ext/Package.bin new file mode 100644 index 00000000..a0be6645 --- /dev/null +++ b/tests/skills/cases/xdto-info/snapshots/cross-package/XDTOPackages/uses_common/Ext/Package.bin @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/tests/skills/cases/xdto-info/snapshots/cross-package/common.xsd b/tests/skills/cases/xdto-info/snapshots/cross-package/common.xsd new file mode 100644 index 00000000..927c85dd --- /dev/null +++ b/tests/skills/cases/xdto-info/snapshots/cross-package/common.xsd @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/tests/skills/cases/xdto-info/snapshots/cross-package/cross-package.txt b/tests/skills/cases/xdto-info/snapshots/cross-package/cross-package.txt new file mode 100644 index 00000000..aa7883c5 --- /dev/null +++ b/tests/skills/cases/xdto-info/snapshots/cross-package/cross-package.txt @@ -0,0 +1,12 @@ +=== Тип XDTO: Заявка === (глубина 2) +Пакет: uses_common · urn:test:uses + +Свойства (2): + Вид объект Справочник · common [обязательный] + Код Строка [обязательный] + Наименование Строка [обязательный] + Потерянный объект НетТакого (пакет не найден: urn:test:отсутствует) + +Создание: + Тип = ФабрикаXDTO.Тип("urn:test:uses", "Заявка"); + Объект = ФабрикаXDTO.Создать(Тип); diff --git a/tests/skills/cases/xdto-info/snapshots/cross-package/uses-common.xsd b/tests/skills/cases/xdto-info/snapshots/cross-package/uses-common.xsd new file mode 100644 index 00000000..2de94e0f --- /dev/null +++ b/tests/skills/cases/xdto-info/snapshots/cross-package/uses-common.xsd @@ -0,0 +1,12 @@ + + + + + + + + + + + diff --git a/tests/skills/cases/xdto-info/snapshots/depth-anon-text/Configuration.xml b/tests/skills/cases/xdto-info/snapshots/depth-anon-text/Configuration.xml new file mode 100644 index 00000000..4a727d54 --- /dev/null +++ b/tests/skills/cases/xdto-info/snapshots/depth-anon-text/Configuration.xml @@ -0,0 +1,252 @@ + + + + + + UUID-002 + UUID-003 + + + UUID-004 + UUID-005 + + + UUID-006 + UUID-007 + + + UUID-008 + UUID-009 + + + UUID-010 + UUID-011 + + + UUID-012 + UUID-013 + + + UUID-014 + UUID-015 + + + + TestConfig + + + ru + TestConfig + + + + + Version8_3_24 + ManagedApplication + + PlatformApplication + + Russian + + + + + false + false + false + + + + + + + + + + + + + + + + + + + + + + Biometrics + true + + + Location + false + + + BackgroundLocation + false + + + BluetoothPrinters + false + + + WiFiPrinters + false + + + Contacts + false + + + Calendars + false + + + PushNotifications + false + + + LocalNotifications + false + + + InAppPurchases + false + + + PersonalComputerFileExchange + false + + + Ads + false + + + NumberDialing + false + + + CallProcessing + false + + + CallLog + false + + + AutoSendSMS + false + + + ReceiveSMS + false + + + SMSLog + false + + + Camera + false + + + Microphone + false + + + MusicLibrary + false + + + PictureAndVideoLibraries + false + + + AudioPlaybackAndVibration + false + + + BackgroundAudioPlaybackAndVibration + false + + + InstallPackages + false + + + OSBackup + true + + + ApplicationUsageStatistics + false + + + BarcodeScanning + false + + + BackgroundAudioRecording + false + + + AllFilesAccess + false + + + Videoconferences + false + + + NFC + false + + + DocumentScanning + false + + + SpeechToText + false + + + Geofences + false + + + IncomingShareRequests + false + + + AllIncomingShareRequestsTypesProcessing + false + + + + + + Normal + + + Language.Русский + + + + + + Managed + NotAutoFree + DontUse + DontUse + TaxiEnableVersion8_2 + DontUse + Version8_3_24 + + + + Русский + nested + + + \ No newline at end of file diff --git a/tests/skills/cases/xdto-info/snapshots/depth-anon-text/Ext/ClientApplicationInterface.xml b/tests/skills/cases/xdto-info/snapshots/depth-anon-text/Ext/ClientApplicationInterface.xml new file mode 100644 index 00000000..3c1161b2 --- /dev/null +++ b/tests/skills/cases/xdto-info/snapshots/depth-anon-text/Ext/ClientApplicationInterface.xml @@ -0,0 +1,18 @@ + + + + + UUID-002 + + + + + UUID-004 + + + + + + + + \ No newline at end of file diff --git a/tests/skills/cases/xdto-info/snapshots/depth-anon-text/Languages/Русский.xml b/tests/skills/cases/xdto-info/snapshots/depth-anon-text/Languages/Русский.xml new file mode 100644 index 00000000..37c60d78 --- /dev/null +++ b/tests/skills/cases/xdto-info/snapshots/depth-anon-text/Languages/Русский.xml @@ -0,0 +1,16 @@ + + + + + Русский + + + ru + Русский + + + + ru + + + \ No newline at end of file diff --git a/tests/skills/cases/xdto-info/snapshots/depth-anon-text/XDTOPackages/nested.xml b/tests/skills/cases/xdto-info/snapshots/depth-anon-text/XDTOPackages/nested.xml new file mode 100644 index 00000000..c84668ba --- /dev/null +++ b/tests/skills/cases/xdto-info/snapshots/depth-anon-text/XDTOPackages/nested.xml @@ -0,0 +1,16 @@ + + + + + nested + + + ru + nested + + + + urn:test:nested + + + \ No newline at end of file diff --git a/tests/skills/cases/xdto-info/snapshots/depth-anon-text/XDTOPackages/nested/Ext/Package.bin b/tests/skills/cases/xdto-info/snapshots/depth-anon-text/XDTOPackages/nested/Ext/Package.bin new file mode 100644 index 00000000..0e2da7d0 --- /dev/null +++ b/tests/skills/cases/xdto-info/snapshots/depth-anon-text/XDTOPackages/nested/Ext/Package.bin @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/tests/skills/cases/xdto-info/snapshots/depth-anon-text/depth-anon-text.txt b/tests/skills/cases/xdto-info/snapshots/depth-anon-text/depth-anon-text.txt new file mode 100644 index 00000000..8119d784 --- /dev/null +++ b/tests/skills/cases/xdto-info/snapshots/depth-anon-text/depth-anon-text.txt @@ -0,0 +1,15 @@ +=== Тип XDTO: Документ === (глубина 4) +Пакет: nested · urn:test:nested + +Свойства (3): + Реквизиты объект Реквизиты [обязательный] + Наименование Строка [обязательный] + Дочерний объект Документ [список] + (раскрыт выше) + Встроенный объект (анонимный) [обязательный] + Ид Строка [обязательный] + __content Дата [обязательный, значение элемента] + +Создание: + Тип = ФабрикаXDTO.Тип("urn:test:nested", "Документ"); + Объект = ФабрикаXDTO.Создать(Тип); diff --git a/tests/skills/cases/xdto-info/snapshots/depth-anon-text/nested.xsd b/tests/skills/cases/xdto-info/snapshots/depth-anon-text/nested.xsd new file mode 100644 index 00000000..b5b6d8fb --- /dev/null +++ b/tests/skills/cases/xdto-info/snapshots/depth-anon-text/nested.xsd @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/tests/skills/cases/xdto-info/snapshots/package-list/Configuration.xml b/tests/skills/cases/xdto-info/snapshots/package-list/Configuration.xml new file mode 100644 index 00000000..05a1dd19 --- /dev/null +++ b/tests/skills/cases/xdto-info/snapshots/package-list/Configuration.xml @@ -0,0 +1,253 @@ + + + + + + UUID-002 + UUID-003 + + + UUID-004 + UUID-005 + + + UUID-006 + UUID-007 + + + UUID-008 + UUID-009 + + + UUID-010 + UUID-011 + + + UUID-012 + UUID-013 + + + UUID-014 + UUID-015 + + + + TestConfig + + + ru + TestConfig + + + + + Version8_3_24 + ManagedApplication + + PlatformApplication + + Russian + + + + + false + false + false + + + + + + + + + + + + + + + + + + + + + + Biometrics + true + + + Location + false + + + BackgroundLocation + false + + + BluetoothPrinters + false + + + WiFiPrinters + false + + + Contacts + false + + + Calendars + false + + + PushNotifications + false + + + LocalNotifications + false + + + InAppPurchases + false + + + PersonalComputerFileExchange + false + + + Ads + false + + + NumberDialing + false + + + CallProcessing + false + + + CallLog + false + + + AutoSendSMS + false + + + ReceiveSMS + false + + + SMSLog + false + + + Camera + false + + + Microphone + false + + + MusicLibrary + false + + + PictureAndVideoLibraries + false + + + AudioPlaybackAndVibration + false + + + BackgroundAudioPlaybackAndVibration + false + + + InstallPackages + false + + + OSBackup + true + + + ApplicationUsageStatistics + false + + + BarcodeScanning + false + + + BackgroundAudioRecording + false + + + AllFilesAccess + false + + + Videoconferences + false + + + NFC + false + + + DocumentScanning + false + + + SpeechToText + false + + + Geofences + false + + + IncomingShareRequests + false + + + AllIncomingShareRequestsTypesProcessing + false + + + + + + Normal + + + Language.Русский + + + + + + Managed + NotAutoFree + DontUse + DontUse + TaxiEnableVersion8_2 + DontUse + Version8_3_24 + + + + Русский + common + uses_common + + + \ No newline at end of file diff --git a/tests/skills/cases/xdto-info/snapshots/package-list/Ext/ClientApplicationInterface.xml b/tests/skills/cases/xdto-info/snapshots/package-list/Ext/ClientApplicationInterface.xml new file mode 100644 index 00000000..3c1161b2 --- /dev/null +++ b/tests/skills/cases/xdto-info/snapshots/package-list/Ext/ClientApplicationInterface.xml @@ -0,0 +1,18 @@ + + + + + UUID-002 + + + + + UUID-004 + + + + + + + + \ No newline at end of file diff --git a/tests/skills/cases/xdto-info/snapshots/package-list/Languages/Русский.xml b/tests/skills/cases/xdto-info/snapshots/package-list/Languages/Русский.xml new file mode 100644 index 00000000..37c60d78 --- /dev/null +++ b/tests/skills/cases/xdto-info/snapshots/package-list/Languages/Русский.xml @@ -0,0 +1,16 @@ + + + + + Русский + + + ru + Русский + + + + ru + + + \ No newline at end of file diff --git a/tests/skills/cases/xdto-info/snapshots/package-list/XDTOPackages/common.xml b/tests/skills/cases/xdto-info/snapshots/package-list/XDTOPackages/common.xml new file mode 100644 index 00000000..32189b9d --- /dev/null +++ b/tests/skills/cases/xdto-info/snapshots/package-list/XDTOPackages/common.xml @@ -0,0 +1,16 @@ + + + + + common + + + ru + common + + + + urn:test:common + + + \ No newline at end of file diff --git a/tests/skills/cases/xdto-info/snapshots/package-list/XDTOPackages/common/Ext/Package.bin b/tests/skills/cases/xdto-info/snapshots/package-list/XDTOPackages/common/Ext/Package.bin new file mode 100644 index 00000000..9e6187bb --- /dev/null +++ b/tests/skills/cases/xdto-info/snapshots/package-list/XDTOPackages/common/Ext/Package.bin @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/tests/skills/cases/xdto-info/snapshots/package-list/XDTOPackages/uses_common.xml b/tests/skills/cases/xdto-info/snapshots/package-list/XDTOPackages/uses_common.xml new file mode 100644 index 00000000..93f6d93c --- /dev/null +++ b/tests/skills/cases/xdto-info/snapshots/package-list/XDTOPackages/uses_common.xml @@ -0,0 +1,16 @@ + + + + + uses_common + + + ru + uses_common + + + + urn:test:uses + + + \ No newline at end of file diff --git a/tests/skills/cases/xdto-info/snapshots/package-list/XDTOPackages/uses_common/Ext/Package.bin b/tests/skills/cases/xdto-info/snapshots/package-list/XDTOPackages/uses_common/Ext/Package.bin new file mode 100644 index 00000000..a0be6645 --- /dev/null +++ b/tests/skills/cases/xdto-info/snapshots/package-list/XDTOPackages/uses_common/Ext/Package.bin @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/tests/skills/cases/xdto-info/snapshots/package-list/common.xsd b/tests/skills/cases/xdto-info/snapshots/package-list/common.xsd new file mode 100644 index 00000000..927c85dd --- /dev/null +++ b/tests/skills/cases/xdto-info/snapshots/package-list/common.xsd @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/tests/skills/cases/xdto-info/snapshots/package-list/package-list.txt b/tests/skills/cases/xdto-info/snapshots/package-list/package-list.txt new file mode 100644 index 00000000..8c8ec885 --- /dev/null +++ b/tests/skills/cases/xdto-info/snapshots/package-list/package-list.txt @@ -0,0 +1,7 @@ +=== Пакеты XDTO: 2 === + + common 1 urn:test:common + uses_common 1 urn:test:uses + +Колонки: имя пакета, число типов, namespace. +Следующий шаг: -Package <имя> или -Namespace — состав пакета; -Name <Тип> — поиск типа по всем пакетам diff --git a/tests/skills/cases/xdto-info/snapshots/package-list/uses-common.xsd b/tests/skills/cases/xdto-info/snapshots/package-list/uses-common.xsd new file mode 100644 index 00000000..2de94e0f --- /dev/null +++ b/tests/skills/cases/xdto-info/snapshots/package-list/uses-common.xsd @@ -0,0 +1,12 @@ + + + + + + + + + + + diff --git a/tests/skills/cases/xdto-info/snapshots/package-overview/Configuration.xml b/tests/skills/cases/xdto-info/snapshots/package-overview/Configuration.xml new file mode 100644 index 00000000..05a1dd19 --- /dev/null +++ b/tests/skills/cases/xdto-info/snapshots/package-overview/Configuration.xml @@ -0,0 +1,253 @@ + + + + + + UUID-002 + UUID-003 + + + UUID-004 + UUID-005 + + + UUID-006 + UUID-007 + + + UUID-008 + UUID-009 + + + UUID-010 + UUID-011 + + + UUID-012 + UUID-013 + + + UUID-014 + UUID-015 + + + + TestConfig + + + ru + TestConfig + + + + + Version8_3_24 + ManagedApplication + + PlatformApplication + + Russian + + + + + false + false + false + + + + + + + + + + + + + + + + + + + + + + Biometrics + true + + + Location + false + + + BackgroundLocation + false + + + BluetoothPrinters + false + + + WiFiPrinters + false + + + Contacts + false + + + Calendars + false + + + PushNotifications + false + + + LocalNotifications + false + + + InAppPurchases + false + + + PersonalComputerFileExchange + false + + + Ads + false + + + NumberDialing + false + + + CallProcessing + false + + + CallLog + false + + + AutoSendSMS + false + + + ReceiveSMS + false + + + SMSLog + false + + + Camera + false + + + Microphone + false + + + MusicLibrary + false + + + PictureAndVideoLibraries + false + + + AudioPlaybackAndVibration + false + + + BackgroundAudioPlaybackAndVibration + false + + + InstallPackages + false + + + OSBackup + true + + + ApplicationUsageStatistics + false + + + BarcodeScanning + false + + + BackgroundAudioRecording + false + + + AllFilesAccess + false + + + Videoconferences + false + + + NFC + false + + + DocumentScanning + false + + + SpeechToText + false + + + Geofences + false + + + IncomingShareRequests + false + + + AllIncomingShareRequestsTypesProcessing + false + + + + + + Normal + + + Language.Русский + + + + + + Managed + NotAutoFree + DontUse + DontUse + TaxiEnableVersion8_2 + DontUse + Version8_3_24 + + + + Русский + common + uses_common + + + \ No newline at end of file diff --git a/tests/skills/cases/xdto-info/snapshots/package-overview/Ext/ClientApplicationInterface.xml b/tests/skills/cases/xdto-info/snapshots/package-overview/Ext/ClientApplicationInterface.xml new file mode 100644 index 00000000..3c1161b2 --- /dev/null +++ b/tests/skills/cases/xdto-info/snapshots/package-overview/Ext/ClientApplicationInterface.xml @@ -0,0 +1,18 @@ + + + + + UUID-002 + + + + + UUID-004 + + + + + + + + \ No newline at end of file diff --git a/tests/skills/cases/xdto-info/snapshots/package-overview/Languages/Русский.xml b/tests/skills/cases/xdto-info/snapshots/package-overview/Languages/Русский.xml new file mode 100644 index 00000000..37c60d78 --- /dev/null +++ b/tests/skills/cases/xdto-info/snapshots/package-overview/Languages/Русский.xml @@ -0,0 +1,16 @@ + + + + + Русский + + + ru + Русский + + + + ru + + + \ No newline at end of file diff --git a/tests/skills/cases/xdto-info/snapshots/package-overview/XDTOPackages/common.xml b/tests/skills/cases/xdto-info/snapshots/package-overview/XDTOPackages/common.xml new file mode 100644 index 00000000..32189b9d --- /dev/null +++ b/tests/skills/cases/xdto-info/snapshots/package-overview/XDTOPackages/common.xml @@ -0,0 +1,16 @@ + + + + + common + + + ru + common + + + + urn:test:common + + + \ No newline at end of file diff --git a/tests/skills/cases/xdto-info/snapshots/package-overview/XDTOPackages/common/Ext/Package.bin b/tests/skills/cases/xdto-info/snapshots/package-overview/XDTOPackages/common/Ext/Package.bin new file mode 100644 index 00000000..9e6187bb --- /dev/null +++ b/tests/skills/cases/xdto-info/snapshots/package-overview/XDTOPackages/common/Ext/Package.bin @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/tests/skills/cases/xdto-info/snapshots/package-overview/XDTOPackages/uses_common.xml b/tests/skills/cases/xdto-info/snapshots/package-overview/XDTOPackages/uses_common.xml new file mode 100644 index 00000000..93f6d93c --- /dev/null +++ b/tests/skills/cases/xdto-info/snapshots/package-overview/XDTOPackages/uses_common.xml @@ -0,0 +1,16 @@ + + + + + uses_common + + + ru + uses_common + + + + urn:test:uses + + + \ No newline at end of file diff --git a/tests/skills/cases/xdto-info/snapshots/package-overview/XDTOPackages/uses_common/Ext/Package.bin b/tests/skills/cases/xdto-info/snapshots/package-overview/XDTOPackages/uses_common/Ext/Package.bin new file mode 100644 index 00000000..a0be6645 --- /dev/null +++ b/tests/skills/cases/xdto-info/snapshots/package-overview/XDTOPackages/uses_common/Ext/Package.bin @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/tests/skills/cases/xdto-info/snapshots/package-overview/common.xsd b/tests/skills/cases/xdto-info/snapshots/package-overview/common.xsd new file mode 100644 index 00000000..927c85dd --- /dev/null +++ b/tests/skills/cases/xdto-info/snapshots/package-overview/common.xsd @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/tests/skills/cases/xdto-info/snapshots/package-overview/package-overview.txt b/tests/skills/cases/xdto-info/snapshots/package-overview/package-overview.txt new file mode 100644 index 00000000..3d82285e --- /dev/null +++ b/tests/skills/cases/xdto-info/snapshots/package-overview/package-overview.txt @@ -0,0 +1,14 @@ +=== Пакет XDTO: uses_common === +Namespace: urn:test:uses + +Импорты (2): + urn:test:common → common + urn:test:отсутствует → (пакет не найден) + +Точки входа (1) — корневые элементы документа: + <Корень> → Заявка + +Объектные типы (1): + Заявка свойств: 2 + +Следующий шаг: -Name <Тип> — структура типа для заполнения diff --git a/tests/skills/cases/xdto-info/snapshots/package-overview/uses-common.xsd b/tests/skills/cases/xdto-info/snapshots/package-overview/uses-common.xsd new file mode 100644 index 00000000..2de94e0f --- /dev/null +++ b/tests/skills/cases/xdto-info/snapshots/package-overview/uses-common.xsd @@ -0,0 +1,12 @@ + + + + + + + + + + + diff --git a/tests/skills/cases/xdto-info/snapshots/type-notation/Configuration.xml b/tests/skills/cases/xdto-info/snapshots/type-notation/Configuration.xml new file mode 100644 index 00000000..389a4b4c --- /dev/null +++ b/tests/skills/cases/xdto-info/snapshots/type-notation/Configuration.xml @@ -0,0 +1,252 @@ + + + + + + UUID-002 + UUID-003 + + + UUID-004 + UUID-005 + + + UUID-006 + UUID-007 + + + UUID-008 + UUID-009 + + + UUID-010 + UUID-011 + + + UUID-012 + UUID-013 + + + UUID-014 + UUID-015 + + + + TestConfig + + + ru + TestConfig + + + + + Version8_3_24 + ManagedApplication + + PlatformApplication + + Russian + + + + + false + false + false + + + + + + + + + + + + + + + + + + + + + + Biometrics + true + + + Location + false + + + BackgroundLocation + false + + + BluetoothPrinters + false + + + WiFiPrinters + false + + + Contacts + false + + + Calendars + false + + + PushNotifications + false + + + LocalNotifications + false + + + InAppPurchases + false + + + PersonalComputerFileExchange + false + + + Ads + false + + + NumberDialing + false + + + CallProcessing + false + + + CallLog + false + + + AutoSendSMS + false + + + ReceiveSMS + false + + + SMSLog + false + + + Camera + false + + + Microphone + false + + + MusicLibrary + false + + + PictureAndVideoLibraries + false + + + AudioPlaybackAndVibration + false + + + BackgroundAudioPlaybackAndVibration + false + + + InstallPackages + false + + + OSBackup + true + + + ApplicationUsageStatistics + false + + + BarcodeScanning + false + + + BackgroundAudioRecording + false + + + AllFilesAccess + false + + + Videoconferences + false + + + NFC + false + + + DocumentScanning + false + + + SpeechToText + false + + + Geofences + false + + + IncomingShareRequests + false + + + AllIncomingShareRequestsTypesProcessing + false + + + + + + Normal + + + Language.Русский + + + + + + Managed + NotAutoFree + DontUse + DontUse + TaxiEnableVersion8_2 + DontUse + Version8_3_24 + + + + Русский + types + + + \ No newline at end of file diff --git a/tests/skills/cases/xdto-info/snapshots/type-notation/Ext/ClientApplicationInterface.xml b/tests/skills/cases/xdto-info/snapshots/type-notation/Ext/ClientApplicationInterface.xml new file mode 100644 index 00000000..3c1161b2 --- /dev/null +++ b/tests/skills/cases/xdto-info/snapshots/type-notation/Ext/ClientApplicationInterface.xml @@ -0,0 +1,18 @@ + + + + + UUID-002 + + + + + UUID-004 + + + + + + + + \ No newline at end of file diff --git a/tests/skills/cases/xdto-info/snapshots/type-notation/Languages/Русский.xml b/tests/skills/cases/xdto-info/snapshots/type-notation/Languages/Русский.xml new file mode 100644 index 00000000..37c60d78 --- /dev/null +++ b/tests/skills/cases/xdto-info/snapshots/type-notation/Languages/Русский.xml @@ -0,0 +1,16 @@ + + + + + Русский + + + ru + Русский + + + + ru + + + \ No newline at end of file diff --git a/tests/skills/cases/xdto-info/snapshots/type-notation/XDTOPackages/types.xml b/tests/skills/cases/xdto-info/snapshots/type-notation/XDTOPackages/types.xml new file mode 100644 index 00000000..13992fd8 --- /dev/null +++ b/tests/skills/cases/xdto-info/snapshots/type-notation/XDTOPackages/types.xml @@ -0,0 +1,16 @@ + + + + + types + + + ru + types + + + + urn:test:types + + + \ No newline at end of file diff --git a/tests/skills/cases/xdto-info/snapshots/type-notation/XDTOPackages/types/Ext/Package.bin b/tests/skills/cases/xdto-info/snapshots/type-notation/XDTOPackages/types/Ext/Package.bin new file mode 100644 index 00000000..4031d43f --- /dev/null +++ b/tests/skills/cases/xdto-info/snapshots/type-notation/XDTOPackages/types/Ext/Package.bin @@ -0,0 +1,26 @@ + + + + [0-9]{20} + + + Поручение + Требование + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/tests/skills/cases/xdto-info/snapshots/type-notation/type-notation.txt b/tests/skills/cases/xdto-info/snapshots/type-notation/type-notation.txt new file mode 100644 index 00000000..5d256190 --- /dev/null +++ b/tests/skills/cases/xdto-info/snapshots/type-notation/type-notation.txt @@ -0,0 +1,22 @@ +=== Тип XDTO: Платёж === +Пакет: types · urn:test:types + +Свойства (14): + Атрибутом Строка [обязательный] + Строкой Строка [обязательный] + Целым Число [обязательный] + Дробным Число [обязательный] + Датой Дата [обязательный] + Флагом Булево [обязательный] + Двоичным ДвоичныеДанные [обязательный] + Произвольным произвольный [обязательный] + Сумма Число(18,2) [обязательный] ← СуммаТип + Счёт Строка(20) [обязательный] ← СчётТип, шаблон [0-9]{20} + Вид Строка [обязательный] ← ВидДокумента, значения: Поручение, Требование + Необязательное Строка + Коллекция Строка [список] + ДоТрёх Строка [обязательный, до 3] + +Создание: + Тип = ФабрикаXDTO.Тип("urn:test:types", "Платёж"); + Объект = ФабрикаXDTO.Создать(Тип); diff --git a/tests/skills/cases/xdto-info/snapshots/type-notation/types.xsd b/tests/skills/cases/xdto-info/snapshots/type-notation/types.xsd new file mode 100644 index 00000000..4f4c3507 --- /dev/null +++ b/tests/skills/cases/xdto-info/snapshots/type-notation/types.xsd @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/skills/cases/xdto-info/snapshots/used-by/Configuration.xml b/tests/skills/cases/xdto-info/snapshots/used-by/Configuration.xml new file mode 100644 index 00000000..05a1dd19 --- /dev/null +++ b/tests/skills/cases/xdto-info/snapshots/used-by/Configuration.xml @@ -0,0 +1,253 @@ + + + + + + UUID-002 + UUID-003 + + + UUID-004 + UUID-005 + + + UUID-006 + UUID-007 + + + UUID-008 + UUID-009 + + + UUID-010 + UUID-011 + + + UUID-012 + UUID-013 + + + UUID-014 + UUID-015 + + + + TestConfig + + + ru + TestConfig + + + + + Version8_3_24 + ManagedApplication + + PlatformApplication + + Russian + + + + + false + false + false + + + + + + + + + + + + + + + + + + + + + + Biometrics + true + + + Location + false + + + BackgroundLocation + false + + + BluetoothPrinters + false + + + WiFiPrinters + false + + + Contacts + false + + + Calendars + false + + + PushNotifications + false + + + LocalNotifications + false + + + InAppPurchases + false + + + PersonalComputerFileExchange + false + + + Ads + false + + + NumberDialing + false + + + CallProcessing + false + + + CallLog + false + + + AutoSendSMS + false + + + ReceiveSMS + false + + + SMSLog + false + + + Camera + false + + + Microphone + false + + + MusicLibrary + false + + + PictureAndVideoLibraries + false + + + AudioPlaybackAndVibration + false + + + BackgroundAudioPlaybackAndVibration + false + + + InstallPackages + false + + + OSBackup + true + + + ApplicationUsageStatistics + false + + + BarcodeScanning + false + + + BackgroundAudioRecording + false + + + AllFilesAccess + false + + + Videoconferences + false + + + NFC + false + + + DocumentScanning + false + + + SpeechToText + false + + + Geofences + false + + + IncomingShareRequests + false + + + AllIncomingShareRequestsTypesProcessing + false + + + + + + Normal + + + Language.Русский + + + + + + Managed + NotAutoFree + DontUse + DontUse + TaxiEnableVersion8_2 + DontUse + Version8_3_24 + + + + Русский + common + uses_common + + + \ No newline at end of file diff --git a/tests/skills/cases/xdto-info/snapshots/used-by/Ext/ClientApplicationInterface.xml b/tests/skills/cases/xdto-info/snapshots/used-by/Ext/ClientApplicationInterface.xml new file mode 100644 index 00000000..3c1161b2 --- /dev/null +++ b/tests/skills/cases/xdto-info/snapshots/used-by/Ext/ClientApplicationInterface.xml @@ -0,0 +1,18 @@ + + + + + UUID-002 + + + + + UUID-004 + + + + + + + + \ No newline at end of file diff --git a/tests/skills/cases/xdto-info/snapshots/used-by/Languages/Русский.xml b/tests/skills/cases/xdto-info/snapshots/used-by/Languages/Русский.xml new file mode 100644 index 00000000..37c60d78 --- /dev/null +++ b/tests/skills/cases/xdto-info/snapshots/used-by/Languages/Русский.xml @@ -0,0 +1,16 @@ + + + + + Русский + + + ru + Русский + + + + ru + + + \ No newline at end of file diff --git a/tests/skills/cases/xdto-info/snapshots/used-by/XDTOPackages/common.xml b/tests/skills/cases/xdto-info/snapshots/used-by/XDTOPackages/common.xml new file mode 100644 index 00000000..32189b9d --- /dev/null +++ b/tests/skills/cases/xdto-info/snapshots/used-by/XDTOPackages/common.xml @@ -0,0 +1,16 @@ + + + + + common + + + ru + common + + + + urn:test:common + + + \ No newline at end of file diff --git a/tests/skills/cases/xdto-info/snapshots/used-by/XDTOPackages/common/Ext/Package.bin b/tests/skills/cases/xdto-info/snapshots/used-by/XDTOPackages/common/Ext/Package.bin new file mode 100644 index 00000000..9e6187bb --- /dev/null +++ b/tests/skills/cases/xdto-info/snapshots/used-by/XDTOPackages/common/Ext/Package.bin @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/tests/skills/cases/xdto-info/snapshots/used-by/XDTOPackages/uses_common.xml b/tests/skills/cases/xdto-info/snapshots/used-by/XDTOPackages/uses_common.xml new file mode 100644 index 00000000..93f6d93c --- /dev/null +++ b/tests/skills/cases/xdto-info/snapshots/used-by/XDTOPackages/uses_common.xml @@ -0,0 +1,16 @@ + + + + + uses_common + + + ru + uses_common + + + + urn:test:uses + + + \ No newline at end of file diff --git a/tests/skills/cases/xdto-info/snapshots/used-by/XDTOPackages/uses_common/Ext/Package.bin b/tests/skills/cases/xdto-info/snapshots/used-by/XDTOPackages/uses_common/Ext/Package.bin new file mode 100644 index 00000000..a0be6645 --- /dev/null +++ b/tests/skills/cases/xdto-info/snapshots/used-by/XDTOPackages/uses_common/Ext/Package.bin @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/tests/skills/cases/xdto-info/snapshots/used-by/common.xsd b/tests/skills/cases/xdto-info/snapshots/used-by/common.xsd new file mode 100644 index 00000000..927c85dd --- /dev/null +++ b/tests/skills/cases/xdto-info/snapshots/used-by/common.xsd @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/tests/skills/cases/xdto-info/snapshots/used-by/used-by.txt b/tests/skills/cases/xdto-info/snapshots/used-by/used-by.txt new file mode 100644 index 00000000..48c54578 --- /dev/null +++ b/tests/skills/cases/xdto-info/snapshots/used-by/used-by.txt @@ -0,0 +1,5 @@ +=== Ссылки на тип: Справочник === +Объявлен в: common · urn:test:common + +Найдено (1): + uses_common.Заявка.Вид (type) diff --git a/tests/skills/cases/xdto-info/snapshots/used-by/uses-common.xsd b/tests/skills/cases/xdto-info/snapshots/used-by/uses-common.xsd new file mode 100644 index 00000000..2de94e0f --- /dev/null +++ b/tests/skills/cases/xdto-info/snapshots/used-by/uses-common.xsd @@ -0,0 +1,12 @@ + + + + + + + + + + + diff --git a/tests/skills/cases/xdto-info/snapshots/value-type/Configuration.xml b/tests/skills/cases/xdto-info/snapshots/value-type/Configuration.xml new file mode 100644 index 00000000..389a4b4c --- /dev/null +++ b/tests/skills/cases/xdto-info/snapshots/value-type/Configuration.xml @@ -0,0 +1,252 @@ + + + + + + UUID-002 + UUID-003 + + + UUID-004 + UUID-005 + + + UUID-006 + UUID-007 + + + UUID-008 + UUID-009 + + + UUID-010 + UUID-011 + + + UUID-012 + UUID-013 + + + UUID-014 + UUID-015 + + + + TestConfig + + + ru + TestConfig + + + + + Version8_3_24 + ManagedApplication + + PlatformApplication + + Russian + + + + + false + false + false + + + + + + + + + + + + + + + + + + + + + + Biometrics + true + + + Location + false + + + BackgroundLocation + false + + + BluetoothPrinters + false + + + WiFiPrinters + false + + + Contacts + false + + + Calendars + false + + + PushNotifications + false + + + LocalNotifications + false + + + InAppPurchases + false + + + PersonalComputerFileExchange + false + + + Ads + false + + + NumberDialing + false + + + CallProcessing + false + + + CallLog + false + + + AutoSendSMS + false + + + ReceiveSMS + false + + + SMSLog + false + + + Camera + false + + + Microphone + false + + + MusicLibrary + false + + + PictureAndVideoLibraries + false + + + AudioPlaybackAndVibration + false + + + BackgroundAudioPlaybackAndVibration + false + + + InstallPackages + false + + + OSBackup + true + + + ApplicationUsageStatistics + false + + + BarcodeScanning + false + + + BackgroundAudioRecording + false + + + AllFilesAccess + false + + + Videoconferences + false + + + NFC + false + + + DocumentScanning + false + + + SpeechToText + false + + + Geofences + false + + + IncomingShareRequests + false + + + AllIncomingShareRequestsTypesProcessing + false + + + + + + Normal + + + Language.Русский + + + + + + Managed + NotAutoFree + DontUse + DontUse + TaxiEnableVersion8_2 + DontUse + Version8_3_24 + + + + Русский + types + + + \ No newline at end of file diff --git a/tests/skills/cases/xdto-info/snapshots/value-type/Ext/ClientApplicationInterface.xml b/tests/skills/cases/xdto-info/snapshots/value-type/Ext/ClientApplicationInterface.xml new file mode 100644 index 00000000..3c1161b2 --- /dev/null +++ b/tests/skills/cases/xdto-info/snapshots/value-type/Ext/ClientApplicationInterface.xml @@ -0,0 +1,18 @@ + + + + + UUID-002 + + + + + UUID-004 + + + + + + + + \ No newline at end of file diff --git a/tests/skills/cases/xdto-info/snapshots/value-type/Languages/Русский.xml b/tests/skills/cases/xdto-info/snapshots/value-type/Languages/Русский.xml new file mode 100644 index 00000000..37c60d78 --- /dev/null +++ b/tests/skills/cases/xdto-info/snapshots/value-type/Languages/Русский.xml @@ -0,0 +1,16 @@ + + + + + Русский + + + ru + Русский + + + + ru + + + \ No newline at end of file diff --git a/tests/skills/cases/xdto-info/snapshots/value-type/XDTOPackages/types.xml b/tests/skills/cases/xdto-info/snapshots/value-type/XDTOPackages/types.xml new file mode 100644 index 00000000..13992fd8 --- /dev/null +++ b/tests/skills/cases/xdto-info/snapshots/value-type/XDTOPackages/types.xml @@ -0,0 +1,16 @@ + + + + + types + + + ru + types + + + + urn:test:types + + + \ No newline at end of file diff --git a/tests/skills/cases/xdto-info/snapshots/value-type/XDTOPackages/types/Ext/Package.bin b/tests/skills/cases/xdto-info/snapshots/value-type/XDTOPackages/types/Ext/Package.bin new file mode 100644 index 00000000..4031d43f --- /dev/null +++ b/tests/skills/cases/xdto-info/snapshots/value-type/XDTOPackages/types/Ext/Package.bin @@ -0,0 +1,26 @@ + + + + [0-9]{20} + + + Поручение + Требование + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/tests/skills/cases/xdto-info/snapshots/value-type/types.xsd b/tests/skills/cases/xdto-info/snapshots/value-type/types.xsd new file mode 100644 index 00000000..4f4c3507 --- /dev/null +++ b/tests/skills/cases/xdto-info/snapshots/value-type/types.xsd @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/skills/cases/xdto-info/snapshots/value-type/value-type.txt b/tests/skills/cases/xdto-info/snapshots/value-type/value-type.txt new file mode 100644 index 00000000..b74da03c --- /dev/null +++ b/tests/skills/cases/xdto-info/snapshots/value-type/value-type.txt @@ -0,0 +1,8 @@ +=== Тип значения XDTO: ВидДокумента === +Пакет: types · urn:test:types + +Значение: Строка + +Допустимые значения (2): + Поручение + Требование diff --git a/tests/skills/cases/xdto-info/type-notation.json b/tests/skills/cases/xdto-info/type-notation.json new file mode 100644 index 00000000..00b3ae09 --- /dev/null +++ b/tests/skills/cases/xdto-info/type-notation.json @@ -0,0 +1,8 @@ +{ + "name": "перевод типов в нотацию 1С, фасеты, перечисление, флаги кратности", + "caseFiles": ["types.xsd"], + "preRun": [{ "script": "xdto-compile/scripts/xdto-compile", "args": { "-XsdPath": "{workDir}/types.xsd", "-OutputDir": "{workDir}" } }], + "params": { "packagePath": "XDTOPackages/types", "outFile": "type-notation.txt" }, + "args_extra": ["-Name", "Платёж"], + "expect": { "files": ["type-notation.txt"] } +} diff --git a/tests/skills/cases/xdto-info/types.xsd b/tests/skills/cases/xdto-info/types.xsd new file mode 100644 index 00000000..4f4c3507 --- /dev/null +++ b/tests/skills/cases/xdto-info/types.xsd @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/skills/cases/xdto-info/used-by.json b/tests/skills/cases/xdto-info/used-by.json new file mode 100644 index 00000000..ea94bdce --- /dev/null +++ b/tests/skills/cases/xdto-info/used-by.json @@ -0,0 +1,8 @@ +{ + "name": "кто ссылается на тип, включая соседний пакет", + "caseFiles": ["common.xsd", "uses-common.xsd"], + "preRun": [{ "script": "xdto-compile/scripts/xdto-compile", "args": { "-XsdPath": "{workDir}/common.xsd", "-OutputDir": "{workDir}" } }, { "script": "xdto-compile/scripts/xdto-compile", "args": { "-XsdPath": "{workDir}/uses-common.xsd", "-OutputDir": "{workDir}" } }], + "params": { "packagePath": ".", "outFile": "used-by.txt" }, + "args_extra": ["-Mode", "used-by", "-Name", "Справочник"], + "expect": { "files": ["used-by.txt"] } +} diff --git a/tests/skills/cases/xdto-info/uses-common.xsd b/tests/skills/cases/xdto-info/uses-common.xsd new file mode 100644 index 00000000..2de94e0f --- /dev/null +++ b/tests/skills/cases/xdto-info/uses-common.xsd @@ -0,0 +1,12 @@ + + + + + + + + + + + diff --git a/tests/skills/cases/xdto-info/value-type.json b/tests/skills/cases/xdto-info/value-type.json new file mode 100644 index 00000000..81437806 --- /dev/null +++ b/tests/skills/cases/xdto-info/value-type.json @@ -0,0 +1,8 @@ +{ + "name": "тип значения: развёрнутое значение и список допустимых литералов", + "caseFiles": ["types.xsd"], + "preRun": [{ "script": "xdto-compile/scripts/xdto-compile", "args": { "-XsdPath": "{workDir}/types.xsd", "-OutputDir": "{workDir}" } }], + "params": { "packagePath": "XDTOPackages/types", "outFile": "value-type.txt" }, + "args_extra": ["-Name", "ВидДокумента"], + "expect": { "files": ["value-type.txt"] } +}