├── .gitignore ├── .vs ├── slnx.sqlite └── VSWorkspaceState.json ├── tests └── fixtures │ ├── cf-edt │ ├── DT-INF │ │ └── PROJECT.PMF │ ├── .settings │ │ └── org.eclipse.core.resources.prefs │ ├── src │ │ ├── Configuration │ │ │ ├── CommandInterface.cmi │ │ │ ├── MainSectionCommandInterface.cmi │ │ │ └── Configuration.mdo │ │ └── HTTPServices │ │ │ └── UserAPI │ │ │ ├── Module.bsl │ │ │ └── UserAPI.mdo │ └── .project │ ├── cf-xml │ ├── Languages │ │ └── Русский.xml │ ├── HTTPServices │ │ ├── UserAPI │ │ │ └── Ext │ │ │ │ └── Module.bsl │ │ └── UserAPI.xml │ └── Configuration.xml │ └── UserAPI.json ├── lib.config ├── packagedef ├── src ├── Модули │ └── ПараметрыПриложения.os ├── main.os └── Классы │ ├── КомандаGenerate.os │ ├── metadataparser.os │ ├── codeparser.os │ └── specgenerator.os ├── simple-ui ├── spec-admin │ ├── web.config │ ├── list.os │ └── spec.os ├── index.html └── upload.os ├── .vscode ├── launch.json └── tasks.json ├── LICENSE ├── examples └── script │ ├── example_metadataparser.os │ ├── example_codeparser.os │ └── example_specgenerator.os ├── features ├── lib │ └── step_definitions │ │ └── РаботаСФайлами.os └── КомандаGenerate.feature ├── tasks └── test.os └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | *.ospx 2 | /build 3 | -------------------------------------------------------------------------------- /.vs/slnx.sqlite: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/botokash/swagger/HEAD/.vs/slnx.sqlite -------------------------------------------------------------------------------- /tests/fixtures/cf-edt/DT-INF/PROJECT.PMF: -------------------------------------------------------------------------------- 1 | Manifest-Version: 1.0 2 | Runtime-Version: 8.3.16 3 | -------------------------------------------------------------------------------- /.vs/VSWorkspaceState.json: -------------------------------------------------------------------------------- 1 | { 2 | "ExpandedNodes": [ 3 | "" 4 | ], 5 | "PreviewInSolutionExplorer": false 6 | } -------------------------------------------------------------------------------- /tests/fixtures/cf-edt/.settings/org.eclipse.core.resources.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | encoding/=UTF-8 3 | -------------------------------------------------------------------------------- /tests/fixtures/cf-edt/src/Configuration/CommandInterface.cmi: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /tests/fixtures/cf-edt/src/Configuration/MainSectionCommandInterface.cmi: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /lib.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /tests/fixtures/cf-edt/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | Конфигурация 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.xtext.ui.shared.xtextBuilder 10 | 11 | 12 | 13 | 14 | 15 | org.eclipse.xtext.ui.shared.xtextNature 16 | com._1c.g5.v8.dt.core.V8ConfigurationNature 17 | 18 | 19 | -------------------------------------------------------------------------------- /packagedef: -------------------------------------------------------------------------------- 1 | ПутьКСценариюПараметров = ОбъединитьПути(ТекущийСценарий().Каталог, "src", "Модули", "ПараметрыПриложения.os"); 2 | ПараметрыПриложения = ЗагрузитьСценарий(ПутьКСценариюПараметров); 3 | 4 | Описание.Имя(ПараметрыПриложения.ИмяПриложения()) 5 | .Версия(ПараметрыПриложения.Версия()) 6 | .Автор("Vladislav Kashin") 7 | .АдресАвтора("botokash@gmail.com") 8 | .Описание("Формирование swagger спецификации на основании метаданных конфигурации 1С") 9 | .ВерсияСреды("1.1.1.44") 10 | .ВключитьФайл("src") 11 | .ВключитьФайл("lib.config") 12 | .ВключитьФайл("README.md") 13 | .ЗависитОт("fs", "1.0.0") 14 | .ЗависитОт("xml-parser", "0.1.1") 15 | .ЗависитОт("json", "1.1.1") 16 | .ЗависитОт("logos", "1.2.1") 17 | .ИсполняемыйФайл("src/main.os"); 18 | ; -------------------------------------------------------------------------------- /src/Модули/ПараметрыПриложения.os: -------------------------------------------------------------------------------- 1 | #Использовать logos 2 | 3 | Перем Лог; 4 | 5 | Функция Лог() Экспорт 6 | 7 | Если Лог = Неопределено Тогда 8 | Лог = Логирование.ПолучитьЛог(ИмяЛогаПриложения()); 9 | КонецЕсли; 10 | 11 | Возврат Лог; 12 | 13 | КонецФункции 14 | 15 | Функция ИмяЛогаПриложения() Экспорт 16 | Возврат "oscript.app." + ИмяПриложения(); 17 | КонецФункции 18 | 19 | Функция ИмяПриложения() Экспорт 20 | 21 | Возврат "swagger"; 22 | 23 | КонецФункции 24 | 25 | Функция Версия() Экспорт 26 | 27 | Возврат "0.5.0"; 28 | 29 | КонецФункции 30 | 31 | Процедура УстановитьРежимОтладкиПриНеобходимости(Знач РежимОтладки) Экспорт 32 | 33 | Если РежимОтладки Тогда 34 | 35 | Лог().УстановитьУровень(УровниЛога.Отладка); 36 | Лог.Отладка("Установлен уровень логов ОТЛАДКА"); 37 | 38 | КонецЕсли; 39 | 40 | КонецПроцедуры 41 | -------------------------------------------------------------------------------- /simple-ui/spec-admin/web.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "name": "Отладка 1Script", 9 | "type": "oscript", 10 | "request": "launch", 11 | "program": "${file}", 12 | "args": [], 13 | "cwd": "${workspaceRoot}", 14 | "runtimeExecutable": null, 15 | "debugPort": 2801, 16 | "protocol": "internal" 17 | }, 18 | { 19 | "name": "generate", 20 | "type": "oscript", 21 | "request": "launch", 22 | "program": "${workspaceRoot}/src/main.os", 23 | "args": ["-v", "generate", "--src-path", "./tests/fixtures/cf-xml", "--out", "./build"], 24 | "cwd": "${workspaceRoot}", 25 | "runtimeExecutable": null, 26 | "debugPort": 2801, 27 | "protocol": "internal" 28 | } 29 | ] 30 | } -------------------------------------------------------------------------------- /src/main.os: -------------------------------------------------------------------------------- 1 | #Использовать "." 2 | #Использовать cli 3 | 4 | Перем Лог; 5 | 6 | Процедура ВыполнитьПриложение() 7 | 8 | Приложение = Новый КонсольноеПриложение(ПараметрыПриложения.ИмяПриложения(), 9 | "Приложение для работы с OpenAPI (Swagger)", 10 | ЭтотОбъект); 11 | Приложение.Версия("version", ПараметрыПриложения.Версия()); 12 | 13 | Приложение.Опция("v verbose", Ложь, "вывод отладочной информация в процессе выполнения") 14 | .Флаговый(); 15 | 16 | Приложение.ДобавитьКоманду("generate", "Генерация спецификаций OpenAPI по исходному коду конфигурации 1С", 17 | Новый КомандаGenerate); 18 | 19 | Приложение.Запустить(АргументыКоманднойСтроки); 20 | 21 | КонецПроцедуры 22 | 23 | Процедура ПередВыполнениемКоманды(Знач Команда) Экспорт 24 | 25 | ВыводДополнительнойИнформации = Команда.ЗначениеОпции("verbose"); 26 | 27 | ПараметрыПриложения.УстановитьРежимОтладкиПриНеобходимости(ВыводДополнительнойИнформации); 28 | 29 | КонецПроцедуры 30 | 31 | Лог = ПараметрыПриложения.Лог(); 32 | 33 | Попытка 34 | 35 | ВыполнитьПриложение(); 36 | 37 | Исключение 38 | 39 | Лог.КритичнаяОшибка(ОписаниеОшибки()); 40 | ЗавершитьРаботу(1); 41 | 42 | КонецПопытки; 43 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | ===================== 3 | 4 | Copyright © `2018` `Vladislav Kashin ` 5 | 6 | Permission is hereby granted, free of charge, to any person 7 | obtaining a copy of this software and associated documentation 8 | files (the “Software”), to deal in the Software without 9 | restriction, including without limitation the rights to use, 10 | copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | copies of the Software, and to permit persons to whom the 12 | Software is furnished to do so, subject to the following 13 | conditions: 14 | 15 | The above copyright notice and this permission notice shall be 16 | included in all copies or substantial portions of the Software. 17 | 18 | THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, 19 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 20 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 21 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 22 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 23 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 24 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 25 | OTHER DEALINGS IN THE SOFTWARE. 26 | -------------------------------------------------------------------------------- /tests/fixtures/cf-xml/Languages/Русский.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Русский 6 | 7 | 8 | ru 9 | Русский 10 | 11 | 12 | 13 | ru 14 | 15 | 16 | -------------------------------------------------------------------------------- /examples/script/example_metadataparser.os: -------------------------------------------------------------------------------- 1 | #Использовать cmdline 2 | #Использовать json 3 | #Использовать swagger 4 | 5 | Перем ПутьКПроекту; 6 | Перем ТипПроекта; 7 | 8 | Процедура ИнициализироватьПараметрыЗапуска() 9 | 10 | Парсер = Новый ПарсерАргументовКоманднойСтроки(); 11 | 12 | Парсер.ДобавитьИменованныйПараметр("-project"); 13 | Парсер.ДобавитьИменованныйПараметр("-type"); 14 | 15 | Параметры = Парсер.Разобрать(АргументыКоманднойСтроки); 16 | 17 | ПутьКПроекту = Параметры["-project"]; 18 | ТипПроекта = Параметры["-type"]; 19 | 20 | КонецПроцедуры 21 | 22 | // работа скрипта 23 | ИнициализироватьПараметрыЗапуска(); 24 | 25 | ПарсерМетаданных = Новый ПарсерМетаданных(); 26 | 27 | Если ПарсерМетаданных.ПодключитьКонфигурацию(ПутьКПроекту, ТипПроекта) Тогда 28 | 29 | ПарсерМетаданных.ВыполнитьПарсингКонфигурации("Broker"); 30 | 31 | ПарсерJSON = Новый ПарсерJSON(); 32 | 33 | //Сообщить(ПарсерJSON.ЗаписатьJSON(ПарсерМетаданных.ВнутренниеОписанияСервисов)); 34 | 35 | //СпецификацииСервисов = ПарсерСервисов.ПолучитьСпецификацииСервисов(); 36 | 37 | Иначе 38 | 39 | Сообщить("Не удалось подключить конфигурацию!", СтатусСообщения.Внимание); 40 | ЗавершитьРаботу(0); 41 | 42 | КонецЕсли; 43 | 44 | //Для Каждого КлючИЗначение Из СпецификацииСервисов Цикл 45 | 46 | //ИмяФайла = КлючИЗначение.Ключ + ".json"; 47 | //Текст = КлючИЗначение.Значение; 48 | 49 | //ЗаписьТекста = Новый ЗаписьТекста(ПутьВыгрузки + "\" + ИмяФайла); 50 | //ЗаписьТекста.Записать(Текст); 51 | 52 | //КонецЦикла; -------------------------------------------------------------------------------- /.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | // See https://go.microsoft.com/fwlink/?LinkId=733558 3 | // for the documentation about the tasks.json format 4 | "version": "2.0.0", 5 | "windows": { 6 | "command": "cmd", 7 | "args": ["/c", "chcp 65001 && "] 8 | }, 9 | "linux": { 10 | "command": "sh", 11 | "args": ["-c"] 12 | }, 13 | "type": "shell", 14 | "tasks": [ 15 | { 16 | "label": "Exec current feature", 17 | "type": "shell", 18 | "args": [ 19 | "oscript", 20 | "C:/Program files/OneScript/lib/1bdd/src/bdd.os", 21 | "exec", 22 | "${file}", 23 | // "-fail-fast", 24 | "-debug", 25 | "off" 26 | ], 27 | "problemMatcher": [] 28 | }, 29 | { 30 | "label": "Exec current feature + debug", 31 | "type": "shell", 32 | "args": [ 33 | "oscript", 34 | "C:/Program files/OneScript/lib/1bdd/src/bdd.os", 35 | "exec", 36 | "${file}", 37 | // "-fail-fast", 38 | "-debug", 39 | "on" 40 | ], 41 | "problemMatcher": [] 42 | }, 43 | { 44 | "label": "Exec current test", 45 | "type": "shell", 46 | "args": [ 47 | "1testrunner", 48 | "-run", 49 | "${file}" 50 | ], 51 | "problemMatcher": [] 52 | } 53 | ] 54 | } 55 | -------------------------------------------------------------------------------- /features/lib/step_definitions/РаботаСФайлами.os: -------------------------------------------------------------------------------- 1 | #Использовать 1bdd 2 | 3 | Перем БДД; //контекст фреймворка 1bdd 4 | 5 | // Метод выдает список шагов, реализованных в данном файле-шагов 6 | Функция ПолучитьСписокШагов(КонтекстФреймворкаBDD) Экспорт 7 | 8 | БДД = КонтекстФреймворкаBDD; 9 | 10 | ВсеШаги = Новый Массив; 11 | ВсеШаги.Добавить("СодержимоеФайлаРавноСодержимомуФайла"); 12 | 13 | Возврат ВсеШаги; 14 | 15 | КонецФункции 16 | 17 | // Реализация шагов 18 | 19 | // содержимое файла "./build/OpenAPI.json" равно содержимому файла "<КаталогПроекта>/tests/fixtures/OpenAPI.json" 20 | Процедура СодержимоеФайлаРавноСодержимомуФайла(Знач РезультатПутьКФайлу, Знач ЭталонПутьКФайлу) Экспорт 21 | 22 | РезультатПутьКФайлу = ЗаменитьШаблоныВПараметрахКоманды(РезультатПутьКФайлу); 23 | ЭталонПутьКФайлу = ЗаменитьШаблоныВПараметрахКоманды(ЭталонПутьКФайлу); 24 | 25 | ЧтениеТекстаРезультат = Новый ЧтениеТекста(РезультатПутьКФайлу, КодировкаТекста.UTF8NoBOM); 26 | СодержимоеФайлаРезультат = ЧтениеТекстаРезультат.Прочитать(); 27 | ЧтениеТекстаРезультат.Закрыть(); 28 | 29 | ЧтениеТекстаЭталон = Новый ЧтениеТекста(ЭталонПутьКФайлу, КодировкаТекста.UTF8NoBOM); 30 | СодержимоеФайлаЭталон = ЧтениеТекстаЭталон.Прочитать(); 31 | ЧтениеТекстаЭталон.Закрыть(); 32 | 33 | Ожидаем.Что(СодержимоеФайлаРезультат).Равно(СодержимоеФайлаЭталон); 34 | 35 | КонецПроцедуры 36 | 37 | Функция ЗаменитьШаблоныВПараметрахКоманды(Знач ПараметрыКоманды) 38 | Рез = СтрЗаменить(ПараметрыКоманды, "<КаталогПроекта>", БДД.КаталогПроверяемогоПроекта()); 39 | Рез = СтрЗаменить(Рез, "<РабочийКаталог>", БДД.ПолучитьИзКонтекста("РабочийКаталог")); 40 | Возврат Рез; 41 | КонецФункции 42 | -------------------------------------------------------------------------------- /examples/script/example_codeparser.os: -------------------------------------------------------------------------------- 1 | #Использовать cmdline 2 | #Использовать swagger 3 | 4 | Перем ПутьКФайлу; 5 | 6 | Процедура ИнициализироватьПараметрыЗапуска() 7 | 8 | Парсер = Новый ПарсерАргументовКоманднойСтроки(); 9 | 10 | Парсер.ДобавитьИменованныйПараметр("-file"); 11 | 12 | Параметры = Парсер.Разобрать(АргументыКоманднойСтроки); 13 | 14 | ПутьКФайлу = Параметры["-file"]; 15 | 16 | КонецПроцедуры 17 | 18 | // работа скрипта 19 | ИнициализироватьПараметрыЗапуска(); 20 | 21 | ПарсерКода = Новый ПарсерКода(ПутьКФайлу); 22 | ПарсерКода.Прочитать(); 23 | 24 | Сообщить("=============================================================="); 25 | 26 | Для Каждого КлючИзначение Из ПарсерКода.КартаМодуля Цикл 27 | 28 | // 29 | ИмяВызова = КлючИзначение.Ключ; 30 | ТипВызова = КлючИзначение.Значение.Тип; 31 | ОписаниеВызова = КлючИзначение.Значение.Описание; 32 | ВходящиеПараметры = КлючИзначение.Значение.ВходящиеПараметры; 33 | 34 | // 35 | СтрокаСообщения = ""; 36 | 37 | СтрокаСообщения = ТипВызова + " " + ИмяВызова + "("; 38 | 39 | Если ВходящиеПараметры <> Неопределено Тогда 40 | 41 | Для Каждого Параметр Из ВходящиеПараметры Цикл 42 | СтрокаСообщения = СтрокаСообщения + Параметр.Имя + ", "; 43 | КонецЦикла; 44 | 45 | СтрокаСообщения = Лев(СтрокаСообщения, СтрДлина(СтрокаСообщения) - 2); 46 | 47 | КонецЕсли; 48 | 49 | СтрокаСообщения = СтрокаСообщения + ")"; 50 | 51 | Если ОписаниеВызова <> Неопределено Тогда 52 | СтрокаСообщения = СтрокаСообщения + Символы.ПС + "Назначение:" + Символы.ПС + ОписаниеВызова; 53 | КонецЕсли; 54 | 55 | Сообщить(СтрокаСообщения); 56 | 57 | Сообщить("=============================================================="); 58 | 59 | КонецЦикла; -------------------------------------------------------------------------------- /examples/script/example_specgenerator.os: -------------------------------------------------------------------------------- 1 | #Использовать cmdline 2 | #Использовать json 3 | #Использовать swagger 4 | 5 | Перем ИмяПроекта; 6 | Перем ПутьКПроекту; 7 | Перем ТипПроекта; 8 | 9 | Процедура ИнициализироватьПараметрыЗапуска() 10 | 11 | Парсер = Новый ПарсерАргументовКоманднойСтроки(); 12 | 13 | Парсер.ДобавитьИменованныйПараметр("-name"); 14 | Парсер.ДобавитьИменованныйПараметр("-path"); 15 | Парсер.ДобавитьИменованныйПараметр("-type"); 16 | 17 | Параметры = Парсер.Разобрать(АргументыКоманднойСтроки); 18 | 19 | ИмяПроекта = Параметры["-name"]; 20 | ПутьКПроекту = Параметры["-path"]; 21 | ТипПроекта = Параметры["-type"]; 22 | 23 | КонецПроцедуры 24 | 25 | // работа скрипта 26 | ИнициализироватьПараметрыЗапуска(); 27 | 28 | ПарсерМетаданных = Новый ПарсерМетаданных(); 29 | 30 | Если ПарсерМетаданных.ПодключитьКонфигурацию(ПутьКПроекту, ТипПроекта) Тогда 31 | 32 | // парсим все сервисы конфигурации 33 | ПарсерМетаданных.ВыполнитьПарсингКонфигурации(); 34 | 35 | Для Каждого КЗ Из ПарсерМетаданных.ВнутренниеОписанияСервисов Цикл 36 | 37 | ИмяСервиса = КЗ.Ключ; 38 | ВнутреннееОписание = КЗ.Значение; 39 | 40 | // получаем OAS 41 | ГенераторСпецификации = Новый ГенераторСпецификации(ВнутреннееОписание); 42 | 43 | ГенераторСпецификации.ПрочитатьОписаниеСервиса(); 44 | 45 | Спецификация = ГенераторСпецификации.ПолучитьСпецификацию(); 46 | 47 | // вывод в консоль 48 | Сообщить("========================================================"); 49 | Сообщить(ИмяПроекта + ", сервис " + ИмяСервиса + ":"); 50 | Сообщить(Спецификация); 51 | 52 | КонецЦикла; 53 | 54 | Иначе 55 | 56 | Сообщить("Не удалось подключить конфигурацию!", СтатусСообщения.Внимание); 57 | ЗавершитьРаботу(0); 58 | 59 | КонецЕсли; -------------------------------------------------------------------------------- /tests/fixtures/cf-edt/src/Configuration/Configuration.mdo: -------------------------------------------------------------------------------- 1 | 2 | 3 | Конфигурация 4 | 5 | 6 | 7 | 8 | 9 | 10 | 8.3.16 11 | ManagedApplication 12 | PersonalComputer 13 | Russian 14 | 15 | AllowOSBackup 16 | true 17 | 18 | Language.Русский 19 | Managed 20 | NotAutoFree 21 | DontUse 22 | DontUse 23 | 8.3.12 24 | 25 | Русский 26 | 27 | ru 28 | Русский 29 | 30 | ru 31 | 32 | HTTPService.UserAPI 33 | 34 | -------------------------------------------------------------------------------- /simple-ui/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Swagger UI 7 | 8 | 9 | 10 | 31 | 32 | 33 | 34 |
35 | 36 | 37 | 38 | 85 | 86 | 87 | 88 | 89 | -------------------------------------------------------------------------------- /tests/fixtures/cf-xml/HTTPServices/UserAPI/Ext/Module.bsl: -------------------------------------------------------------------------------- 1 | 2 | // Возвращает полный список пользователей в базе 1С 3 | // 4 | // Коды ответов: 5 | // 200 - запрос выполнен 6 | // 500 - внутренняя ошибка сервера 7 | // 8 | Функция ПользователиСписокGET(Запрос) 9 | Ответ = Новый HTTPСервисОтвет(200); 10 | Возврат Ответ; 11 | КонецФункции 12 | 13 | // Возвращает все свойства указанного пользователя в базе 1С 14 | // 15 | // Параметры: 16 | // userID - Строка - GUID пользователя ИБ 17 | // 18 | // Коды ответов: 19 | // 200 - запрос выполнен 20 | // 404 - пользователь по userID не найден 21 | // 500 - внутренняя ошибка сервера 22 | // 23 | Функция ПользовательGET(Запрос) 24 | Ответ = Новый HTTPСервисОтвет(200); 25 | Возврат Ответ; 26 | КонецФункции 27 | 28 | // Изменяет одно свойство указанного пользователя в базе 1С 29 | // 30 | // Параметры: 31 | // userID - Строка - GUID пользователя ИБ 32 | // property - Строка - ключ изменяемого свойства 33 | // value - Строка - новое значение 34 | // 35 | // Коды ответов: 36 | // 200 - запрос выполнен 37 | // 404 - пользователь по userID не найден 38 | // 500 - внутренняя ошибка сервера 39 | // 40 | Функция ПользовательPATCH(Запрос) 41 | Ответ = Новый HTTPСервисОтвет(200); 42 | Возврат Ответ; 43 | КонецФункции 44 | 45 | // Изменяет все свойства указанного пользователя в базе 1С 46 | // 47 | // Параметры: 48 | // body - Строка - новые свойства пользователя 49 | // userID - Строка - GUID пользователя ИБ 50 | // 51 | // Коды ответов: 52 | // 200 - запрос выполнен 53 | // 404 - пользователь по userID не найден 54 | // 500 - внутренняя ошибка сервера 55 | // 56 | Функция ПользовательPUT(Запрос) 57 | Ответ = Новый HTTPСервисОтвет(200); 58 | Возврат Ответ; 59 | КонецФункции 60 | 61 | // Удаляет указанного пользователя в базе 1С 62 | // 63 | // Параметры: 64 | // userID - Строка - GUID пользователя ИБ 65 | // 66 | // Коды ответов: 67 | // 200 - запрос выполнен 68 | // 404 - пользователь по userID не найден 69 | // 500 - внутренняя ошибка сервера 70 | // 71 | Функция ПользовательDELETE(Запрос) 72 | Ответ = Новый HTTPСервисОтвет(200); 73 | Возврат Ответ; 74 | КонецФункции 75 | 76 | // Создает нового пользователя в базе 1С 77 | // 78 | // Параметры: 79 | // body - Строка - свойства нового пользователя 80 | // 81 | // Коды ответов: 82 | // 200 - запрос выполнен 83 | // 500 - внутренняя ошибка сервера 84 | // 85 | Функция ПользовательНовыйPOST(Запрос) 86 | Ответ = Новый HTTPСервисОтвет(200); 87 | Возврат Ответ; 88 | КонецФункции 89 | -------------------------------------------------------------------------------- /tests/fixtures/cf-edt/src/HTTPServices/UserAPI/Module.bsl: -------------------------------------------------------------------------------- 1 | 2 | // Возвращает полный список пользователей в базе 1С 3 | // 4 | // Коды ответов: 5 | // 200 - запрос выполнен 6 | // 500 - внутренняя ошибка сервера 7 | // 8 | Функция ПользователиСписокGET(Запрос) 9 | Ответ = Новый HTTPСервисОтвет(200); 10 | Возврат Ответ; 11 | КонецФункции 12 | 13 | // Возвращает все свойства указанного пользователя в базе 1С 14 | // 15 | // Параметры: 16 | // userID - Строка - GUID пользователя ИБ 17 | // 18 | // Коды ответов: 19 | // 200 - запрос выполнен 20 | // 404 - пользователь по userID не найден 21 | // 500 - внутренняя ошибка сервера 22 | // 23 | Функция ПользовательGET(Запрос) 24 | Ответ = Новый HTTPСервисОтвет(200); 25 | Возврат Ответ; 26 | КонецФункции 27 | 28 | // Изменяет одно свойство указанного пользователя в базе 1С 29 | // 30 | // Параметры: 31 | // userID - Строка - GUID пользователя ИБ 32 | // property - Строка - ключ изменяемого свойства 33 | // value - Строка - новое значение 34 | // 35 | // Коды ответов: 36 | // 200 - запрос выполнен 37 | // 404 - пользователь по userID не найден 38 | // 500 - внутренняя ошибка сервера 39 | // 40 | Функция ПользовательPATCH(Запрос) 41 | Ответ = Новый HTTPСервисОтвет(200); 42 | Возврат Ответ; 43 | КонецФункции 44 | 45 | // Изменяет все свойства указанного пользователя в базе 1С 46 | // 47 | // Параметры: 48 | // body - Строка - новые свойства пользователя 49 | // userID - Строка - GUID пользователя ИБ 50 | // 51 | // Коды ответов: 52 | // 200 - запрос выполнен 53 | // 404 - пользователь по userID не найден 54 | // 500 - внутренняя ошибка сервера 55 | // 56 | Функция ПользовательPUT(Запрос) 57 | Ответ = Новый HTTPСервисОтвет(200); 58 | Возврат Ответ; 59 | КонецФункции 60 | 61 | // Удаляет указанного пользователя в базе 1С 62 | // 63 | // Параметры: 64 | // userID - Строка - GUID пользователя ИБ 65 | // 66 | // Коды ответов: 67 | // 200 - запрос выполнен 68 | // 404 - пользователь по userID не найден 69 | // 500 - внутренняя ошибка сервера 70 | // 71 | Функция ПользовательDELETE(Запрос) 72 | Ответ = Новый HTTPСервисОтвет(200); 73 | Возврат Ответ; 74 | КонецФункции 75 | 76 | // Создает нового пользователя в базе 1С 77 | // 78 | // Параметры: 79 | // body - Строка - свойства нового пользователя 80 | // 81 | // Коды ответов: 82 | // 200 - запрос выполнен 83 | // 500 - внутренняя ошибка сервера 84 | // 85 | Функция ПользовательНовыйPOST(Запрос) 86 | Ответ = Новый HTTPСервисОтвет(200); 87 | Возврат Ответ; 88 | КонецФункции 89 | -------------------------------------------------------------------------------- /features/КомандаGenerate.feature: -------------------------------------------------------------------------------- 1 | # language: ru 2 | 3 | Функционал: Проверка работы команды generate 4 | Как Пользователь 5 | Я хочу автоматически проверять работу команды generate 6 | Чтобы гарантировать корректность работы приложения 7 | 8 | Контекст: Работа в каталоге проекта 9 | Допустим Я очищаю параметры команды "oscript" в контексте 10 | 11 | Сценарий: Запуск приложения с командой generate без параметров 12 | Когда Я выполняю команду "oscript" с параметрами "./src/main.os -v generate" 13 | И Я сообщаю вывод команды "oscript" 14 | И код возврата равен 1 15 | 16 | Сценарий: Генерация OpenAPI 2.0 для конфигурации XML в формате JSON 17 | Когда Я создаю временный каталог и сохраняю его в контекст 18 | И Я устанавливаю временный каталог как рабочий каталог 19 | И Я копирую каталог "cf-xml" из каталога "tests/fixtures" проекта в рабочий каталог 20 | И Я установил рабочий каталог как текущий каталог 21 | И Я добавляю параметр "<КаталогПроекта>/src/main.os -v generate" для команды "oscript" 22 | И Я добавляю параметр "--src-path ./cf-xml" для команды "oscript" 23 | И Я добавляю параметр "--out ./build" для команды "oscript" 24 | И Я добавляю параметр "--format JSON" для команды "oscript" 25 | И Я добавляю параметр "--version 2" для команды "oscript" 26 | И Я выполняю команду "oscript" 27 | # oscript ./src/main.os -v generate --src-path ./cf-xml -out ./build --format JSON --version 2 28 | И Я сообщаю вывод команды "oscript" 29 | И Вывод команды "oscript" не содержит "КРИТИЧНАЯОШИБКА" 30 | И код возврата равен 0 31 | И файл "./build/UserAPI.json" существует 32 | И содержимое файла "./build/UserAPI.json" равно содержимому файла "<КаталогПроекта>/tests/fixtures/UserAPI.json" 33 | 34 | Сценарий: Генерация OpenAPI 2.0 для конфигурации EDT в формате JSON 35 | Когда Я создаю временный каталог и сохраняю его в контекст 36 | И Я устанавливаю временный каталог как рабочий каталог 37 | И Я копирую каталог "cf-edt" из каталога "tests/fixtures" проекта в рабочий каталог 38 | И Я установил рабочий каталог как текущий каталог 39 | И Я добавляю параметр "<КаталогПроекта>/src/main.os -v generate" для команды "oscript" 40 | И Я добавляю параметр "--src-path ./cf-edt" для команды "oscript" 41 | И Я добавляю параметр "--out ./build" для команды "oscript" 42 | И Я добавляю параметр "--format JSON" для команды "oscript" 43 | И Я добавляю параметр "--version 2" для команды "oscript" 44 | И Я выполняю команду "oscript" 45 | # oscript ./src/main.os -v generate --src-path ./cf-edt -out ./build --format JSON --version 2 46 | И Я сообщаю вывод команды "oscript" 47 | И Вывод команды "oscript" не содержит "КРИТИЧНАЯОШИБКА" 48 | И код возврата равен 0 49 | И файл "./build/UserAPI.json" существует 50 | И содержимое файла "./build/UserAPI.json" равно содержимому файла "<КаталогПроекта>/tests/fixtures/UserAPI.json" 51 | -------------------------------------------------------------------------------- /src/Классы/КомандаGenerate.os: -------------------------------------------------------------------------------- 1 | #Использовать "../.." 2 | 3 | Перем Лог; 4 | 5 | Перем ПутьКЛогамПрокси; 6 | Перем ПутьКИсходномуКоду; 7 | Перем КаталогВыгрузкиРезультатов; 8 | Перем ФорматФайлаРезультата; 9 | Перем Хост; 10 | Перем База1С; 11 | 12 | Процедура ОписаниеКоманды(Команда) Экспорт 13 | 14 | Команда.Опция("src-path", "", "путь к исходному коду конфигурации") 15 | .ТСтрока(); 16 | Команда.Опция("out", "", "каталог выгрузки результатов") 17 | .ТСтрока(); 18 | Команда.Опция("format", "", "формат файлов (json или yaml)") 19 | .ТСтрока(); 20 | Команда.Опция("version", "", "версия OpenAPI") 21 | .ТСтрока(); 22 | Команда.Опция("host", "", "веб сервер") 23 | .ТСтрока(); 24 | Команда.Опция("onecbase", "", "база 1С") 25 | .ТСтрока(); 26 | 27 | КонецПроцедуры 28 | 29 | Процедура ПередВыполнениемКоманды(Знач Команда) Экспорт 30 | 31 | Лог = ПараметрыПриложения.Лог(); 32 | 33 | ПутьКИсходномуКоду = Команда.ЗначениеОпции("src-path"); 34 | КаталогВыгрузкиРезультатов = Команда.ЗначениеОпции("out"); 35 | ФорматФайлаРезультата = Команда.ЗначениеОпции("format"); 36 | ВерсияСпецификации = Команда.ЗначениеОпции("version"); 37 | 38 | Лог.Предупреждение("Параметр format не реализован и всегда равен JSON"); 39 | ФорматФайлаРезультата = "json"; 40 | 41 | Лог.Предупреждение("Параметр version не реализован и всегда равен 2"); 42 | ВерсияСпецификации = "2"; 43 | 44 | Хост = Команда.ЗначениеОпции("host"); 45 | База1С = Команда.ЗначениеОпции("onecbase"); 46 | 47 | КонецПроцедуры 48 | 49 | Процедура ВыполнитьКоманду(Знач Команда) Экспорт 50 | 51 | ПарсерМетаданных = Новый ПарсерМетаданных(); 52 | 53 | Если Не ПарсерМетаданных.ПодключитьКонфигурацию(ПутьКИсходномуКоду) Тогда 54 | ВызватьИсключение("Не удалось подключить конфигурацию!"); 55 | КонецЕсли; 56 | 57 | ПарсерМетаданных.ВыполнитьПарсингКонфигурации(); 58 | 59 | Для Каждого HTTPСервис Из ПарсерМетаданных.ВнутренниеОписанияСервисов Цикл 60 | 61 | ИмяСервиса = HTTPСервис.Ключ; 62 | ВнутреннееОписаниеСервиса = HTTPСервис.Значение; 63 | 64 | ВнутреннееОписаниеСервиса.Хост = Хост; 65 | ВнутреннееОписаниеСервиса.База1С = База1С; 66 | 67 | ГенераторСпецификации = Новый ГенераторСпецификации(ВнутреннееОписаниеСервиса); 68 | ГенераторСпецификации.ПрочитатьОписаниеСервиса(); 69 | 70 | Спецификация = ГенераторСпецификации.ПолучитьСпецификацию(); 71 | 72 | КаталогРезультатов = Новый Файл(КаталогВыгрузкиРезультатов); 73 | АбсолютныйПутьККаталогу = КаталогРезультатов.ПолноеИмя; 74 | ФС.ОбеспечитьКаталог(АбсолютныйПутьККаталогу); 75 | 76 | ПутьКФайлуРезультата = ОбъединитьПути(АбсолютныйПутьККаталогу, ИмяСервиса + "." + ФорматФайлаРезультата); 77 | 78 | ЗаписьТекста = Новый ЗаписьТекста(ПутьКФайлуРезультата, КодировкаТекста.UTF8NoBOM); 79 | ЗаписьТекста.Записать(Спецификация); 80 | ЗаписьТекста.Закрыть(); 81 | 82 | Лог.Информация("Файл спецификации сгенерирован: " + ПутьКФайлуРезультата); 83 | 84 | КонецЦикла; 85 | 86 | КонецПроцедуры 87 | -------------------------------------------------------------------------------- /tasks/test.os: -------------------------------------------------------------------------------- 1 | #Использовать 1testrunner 2 | #Использовать 1bdd 3 | 4 | Функция ПрогнатьТесты() 5 | 6 | Тестер = Новый Тестер; 7 | 8 | ПутьКТестам = ОбъединитьПути(ТекущийСценарий().Каталог, "..", "tests"); 9 | ПутьКОтчетуJUnit = ОбъединитьПути(ТекущийСценарий().Каталог, "../build"); 10 | 11 | КаталогТестов = Новый Файл(ПутьКТестам); 12 | Если Не КаталогТестов.Существует() Тогда 13 | Сообщить(СтрШаблон("Не найден каталог тестов %1", ПутьКТестам)); 14 | Возврат Истина; 15 | КонецЕсли; 16 | 17 | РезультатТестирования = Тестер.ТестироватьКаталог( 18 | КаталогТестов, 19 | Новый Файл(ПутьКОтчетуJUnit) 20 | ); 21 | 22 | Успешно = РезультатТестирования = 0; 23 | 24 | Возврат Успешно; 25 | 26 | КонецФункции // ПрогнатьТесты() 27 | 28 | Функция ПрогнатьФичи(Знач ПутьФич = "features", Знач ПутьОтчетаJUnit = "./build/bdd-log.xml") 29 | 30 | КаталогФич = ОбъединитьПути(".", ПутьФич); 31 | 32 | Файл_КаталогФич = Новый Файл(КаталогФич); 33 | 34 | ИсполнительБДД = Новый ИсполнительБДД; 35 | РезультатыВыполнения = ИсполнительБДД.ВыполнитьФичу(Файл_КаталогФич, Файл_КаталогФич); 36 | ИтоговыйРезультатВыполнения = ИсполнительБДД.ПолучитьИтоговыйСтатусВыполнения(РезультатыВыполнения); 37 | 38 | СтатусВыполнения = ИсполнительБДД.ВозможныеСтатусыВыполнения().НеВыполнялся; 39 | Если РезультатыВыполнения.Строки.Количество() > 0 Тогда 40 | 41 | СтатусВыполнения = ИсполнительБДД.ПолучитьИтоговыйСтатусВыполнения(РезультатыВыполнения); 42 | 43 | ИсполнительБДД.ВывестиИтоговыеРезультатыВыполнения(РезультатыВыполнения, Файл_КаталогФич.ЭтоКаталог()); 44 | КонецЕсли; 45 | 46 | ГенераторОтчетаJUnit = Новый ГенераторОтчетаJUnit; 47 | ГенераторОтчетаJUnit.Сформировать(РезультатыВыполнения, СтатусВыполнения, ПутьОтчетаJUnit); 48 | 49 | Сообщить(СтрШаблон("Результат прогона фич <%1>. Путь %2 50 | |", ИтоговыйРезультатВыполнения, ПутьФич)); 51 | 52 | Возврат ИтоговыйРезультатВыполнения <> ИсполнительБДД.ВозможныеСтатусыВыполнения().Сломался; 53 | КонецФункции 54 | 55 | // основной код 56 | 57 | ТекКаталог = ТекущийКаталог(); 58 | ФС.ОбеспечитьКаталог("build"); 59 | 60 | Попытка 61 | ТестыПрошли = ПрогнатьТесты(); 62 | Исключение 63 | ТестыПрошли = Ложь; 64 | Сообщить(СтрШаблон("Тесты через 1testrunner выполнены неудачно 65 | |%1 66 | |%2", ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()), ОписаниеОшибки())); 67 | КонецПопытки; 68 | 69 | УстановитьТекущийКаталог(ТекКаталог); 70 | 71 | Попытка 72 | ФичиПрошли = ПрогнатьФичи("features"); 73 | Исключение 74 | ФичиПрошли = Ложь; 75 | Сообщить(СтрШаблон("Тесты поведения через 1bdd выполнены неудачно 76 | |%1", ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()))); 77 | КонецПопытки; 78 | 79 | ТестыПрошли = Истина; // TODO: убрать, когда будут тесты 80 | 81 | Сообщить(СтрШаблон("Результат прогона тестов <%1> 82 | |", ТестыПрошли)); 83 | Сообщить(СтрШаблон("Результат прогона основных фич <%1> 84 | |", ФичиПрошли)); 85 | 86 | Если НЕ ТестыПрошли Или НЕ ФичиПрошли Тогда 87 | ВызватьИсключение "Тестирование завершилось неудачно!"; 88 | КонецЕсли; 89 | -------------------------------------------------------------------------------- /tests/fixtures/cf-edt/src/HTTPServices/UserAPI/UserAPI.mdo: -------------------------------------------------------------------------------- 1 | 2 | 3 | UserAPI 4 | 5 | ru 6 | API управления доступом 7 | 8 | 1.0 9 | user_api 10 | AutoUse 11 | 20 12 | 13 | ПользователиСписок 14 | 15 | ru 16 | user 17 | 18 | 19 | 20 | GET 21 | 22 | ru 23 | GET 24 | 25 | Получить список пользователей 26 | ПользователиСписокGET 27 | 28 | 29 | 30 | Пользователь 31 | 32 | ru 33 | user 34 | 35 | 36 | 37 | GET 38 | 39 | ru 40 | GET 41 | 42 | Получить свойства пользователя 43 | ПользовательGET 44 | 45 | 46 | PATCH 47 | 48 | ru 49 | PATCH 50 | 51 | Изменить свойство пользователя 52 | PATCH 53 | ПользовательPATCH 54 | 55 | 56 | PUT 57 | 58 | ru 59 | PUT 60 | 61 | Изменить все свойства пользователя 62 | PUT 63 | ПользовательPUT 64 | 65 | 66 | DELETE 67 | 68 | ru 69 | DELETE 70 | 71 | Удалить пользователя 72 | DELETE 73 | ПользовательDELETE 74 | 75 | 76 | 77 | ПользовательНовый 78 | 79 | ru 80 | user 81 | 82 | 83 | 84 | POST 85 | 86 | ru 87 | POST 88 | 89 | Создать нового пользователя 90 | POST 91 | ПользовательНовыйPOST 92 | 93 | 94 | 95 | -------------------------------------------------------------------------------- /simple-ui/spec-admin/list.os: -------------------------------------------------------------------------------- 1 | // Предопределенная функция. Является точкой входа в обработку запроса. 2 | // 3 | Функция ОбработкаВызоваHTTPСервиса(Запрос) Экспорт 4 | 5 | Если Запрос.HTTPМетод = "GET" Тогда 6 | Возврат МетодОбработкиGET(Запрос); 7 | Иначе 8 | Возврат МетодОбработкиНеизвестен(Запрос); 9 | КонецЕсли; 10 | 11 | КонецФункции 12 | 13 | Функция МетодОбработкиGET(Запрос) 14 | 15 | РазделительПути = ПолучитьРазделительПути(); 16 | 17 | // поиск файлов 18 | ТекущийКаталог = ТекущийСценарий().Каталог; 19 | КаталогФайлов = ОбъединитьПути(ТекущийКаталог, "Files"); 20 | 21 | Файлы = НайтиФайлы(КаталогФайлов, "*.json", Истина); 22 | 23 | // анализ поиска 24 | ПереченьПроектов = Новый Соответствие; 25 | 26 | Для Каждого Файл Из Файлы Цикл 27 | 28 | Путь = Файл.Путь; 29 | 30 | ИмяПроекта = СтрЗаменить(СтрЗаменить(Путь, КаталогФайлов, ""), РазделительПути, ""); 31 | 32 | ПереченьСервисов = ПереченьПроектов.Получить(ИмяПроекта); 33 | 34 | Если ПереченьСервисов = Неопределено Тогда 35 | ПереченьСервисов = Новый Массив; 36 | КонецЕсли; 37 | 38 | ИмяСервиса = Файл.ИмяБезРасширения; 39 | 40 | ПереченьСервисов.Добавить(ИмяСервиса); 41 | 42 | ПереченьПроектов.Вставить(ИмяПроекта, ПереченьСервисов); 43 | 44 | КонецЦикла; 45 | 46 | // сформируем ответ 47 | ЗаписьJSON = Новый ЗаписьJSON(); 48 | ЗаписьJSON.УстановитьСтроку(); 49 | ЗаписьJSON.ЗаписатьНачалоМассива(); 50 | 51 | Для Каждого КЗ Из ПереченьПроектов Цикл 52 | 53 | ЗаписьJSON.ЗаписатьНачалоОбъекта(); 54 | 55 | // 56 | ЗаписьJSON.ЗаписатьИмяСвойства("name"); 57 | ЗаписьJSON.ЗаписатьЗначение(КЗ.Ключ); 58 | 59 | // 60 | ЗаписьJSON.ЗаписатьИмяСвойства("services"); 61 | 62 | ЗаписьJSON.ЗаписатьНачалоМассива(); 63 | 64 | Для Каждого ИмяСервиса ИЗ КЗ.Значение Цикл 65 | ЗаписьJSON.ЗаписатьЗначение(ИмяСервиса); 66 | КонецЦикла; 67 | 68 | ЗаписьJSON.ЗаписатьКонецМассива(); 69 | 70 | ЗаписьJSON.ЗаписатьКонецОбъекта(); 71 | 72 | КонецЦикла; 73 | 74 | ЗаписьJSON.ЗаписатьКонецМассива(); 75 | 76 | Возврат ОтветУспешно(ЗаписьJSON.Закрыть()); 77 | 78 | КонецФункции 79 | 80 | Функция МетодОбработкиНеизвестен(Запрос) 81 | Возврат ОтветОшибка("Processing method unknown!"); 82 | КонецФункции 83 | 84 | Функция ОтветОшибка(ТекстОшибки = "") 85 | 86 | Ответ = Новый HTTPСервисОтвет(400); 87 | Ответ.УстановитьТелоИзСтроки(СтандартноеТелоОтвета(Ложь, ТекстОшибки)); 88 | 89 | Возврат Ответ; 90 | 91 | КонецФункции 92 | 93 | Функция ОтветУспешно(ТелоОтвета = Неопределено) 94 | 95 | Ответ = Новый HTTPСервисОтвет(200); 96 | 97 | Если ТелоОтвета = Неопределено Тогда 98 | Ответ.УстановитьТелоИзСтроки(СтандартноеТелоОтвета()); 99 | Иначе 100 | Ответ.УстановитьТелоИзСтроки(ТелоОтвета); 101 | КонецЕсли; 102 | 103 | Возврат Ответ; 104 | 105 | КонецФункции 106 | 107 | Функция СтандартноеТелоОтвета(Успех = Истина, ТекстОшибки = "") 108 | 109 | ЗаписьJSON = Новый ЗаписьJSON(); 110 | ЗаписьJSON.УстановитьСтроку(); 111 | 112 | ЗаписьJSON.ЗаписатьНачалоОбъекта(); 113 | 114 | ЗаписьJSON.ЗаписатьИмяСвойства("success"); 115 | ЗаписьJSON.ЗаписатьЗначение(Успех); 116 | 117 | Если НЕ Успех Тогда 118 | 119 | ЗаписьJSON.ЗаписатьИмяСвойства("error_message"); 120 | ЗаписьJSON.ЗаписатьЗначение(ТекстОшибки); 121 | 122 | КонецЕсли; 123 | 124 | ЗаписьJSON.ЗаписатьКонецОбъекта(); 125 | 126 | Возврат ЗаписьJSON.Закрыть(); 127 | 128 | КонецФункции -------------------------------------------------------------------------------- /simple-ui/upload.os: -------------------------------------------------------------------------------- 1 | #Использовать cmdline 2 | #Использовать json 3 | #Использовать swagger 4 | 5 | Перем ИмяПроекта; 6 | Перем ПутьКПроекту; 7 | Перем ТипПроекта; 8 | Перем АдминкаURL; 9 | Перем Хост; 10 | Перем База1С; 11 | 12 | Процедура ИнициализироватьПараметрыЗапуска() 13 | 14 | Парсер = Новый ПарсерАргументовКоманднойСтроки(); 15 | 16 | Парсер.ДобавитьИменованныйПараметр("-name"); 17 | Парсер.ДобавитьИменованныйПараметр("-path"); 18 | Парсер.ДобавитьИменованныйПараметр("-type"); 19 | Парсер.ДобавитьИменованныйПараметр("-adminurl"); 20 | Парсер.ДобавитьИменованныйПараметр("-host"); 21 | Парсер.ДобавитьИменованныйПараметр("-onecbase"); 22 | 23 | Параметры = Парсер.Разобрать(АргументыКоманднойСтроки); 24 | 25 | ИмяПроекта = Параметры["-name"]; 26 | ПутьКПроекту = Параметры["-path"]; 27 | ТипПроекта = Параметры["-type"]; 28 | АдминкаURL = Параметры["-adminurl"]; 29 | Хост = Параметры["-host"]; 30 | База1С = Параметры["-onecbase"]; 31 | 32 | КонецПроцедуры 33 | 34 | Процедура ОшибкаСервиса(HTTPЗапрос, HTTPОтвет) 35 | 36 | Сообщить("Обращение: " + HTTPЗапрос.АдресРесурса); 37 | Сообщить("Код ответа: " + HTTPОтвет.КодСостояния); 38 | Сообщить("Тело ответа: " + HTTPОтвет.ПолучитьТелоКакСтроку()); 39 | 40 | ЗавершитьРаботу(0); 41 | 42 | КонецПроцедуры 43 | 44 | // инициализация 45 | ИнициализироватьПараметрыЗапуска(); 46 | 47 | // внутренние переменные 48 | ЗагруженныеСпецификации = Новый Массив; 49 | ОбновленныеСпецификации = Новый Массив; 50 | 51 | HTTPСоединение = Новый HTTPСоединение(АдминкаURL); 52 | 53 | Ответ200 = 200; 54 | 55 | // получим текущий список спецификаций проекта 56 | ЗапросСписок = Новый HTTPЗапрос("list.os"); 57 | 58 | HTTPОтвет = HTTPСоединение.Получить(ЗапросСписок); 59 | 60 | Если HTTPОтвет.КодСостояния <> Ответ200 Тогда 61 | ОшибкаСервиса(ЗапросСписок, HTTPОтвет); 62 | КонецЕсли; 63 | 64 | ТелоОтвета = HTTPОтвет.ПолучитьТелоКакСтроку(); 65 | 66 | ПарсерJSON = Новый ПарсерJSON(); 67 | 68 | ПереченьСпецификаций = ПарсерJSON.ПрочитатьJSON(ТелоОтвета); 69 | 70 | Для Каждого Проект Из ПереченьСпецификаций Цикл 71 | 72 | Если ИмяПроекта <> Проект["name"] Тогда 73 | Продолжить; 74 | КонецЕсли; 75 | 76 | Для Каждого ИмяСервиса Из Проект["services"] Цикл 77 | ЗагруженныеСпецификации.Добавить(ИмяСервиса); 78 | КонецЦикла; 79 | 80 | Прервать; 81 | 82 | КонецЦикла; 83 | 84 | // подключем проект 85 | ПарсерМетаданных = Новый ПарсерМетаданных(); 86 | 87 | Если НЕ ПарсерМетаданных.ПодключитьКонфигурацию(ПутьКПроекту, ТипПроекта) Тогда 88 | 89 | Сообщить("Не удалось подключить конфигурацию!", СтатусСообщения.Внимание); 90 | ЗавершитьРаботу(0); 91 | 92 | КонецЕсли; 93 | 94 | // парсим все сервисы конфигурации 95 | ПарсерМетаданных.ВыполнитьПарсингКонфигурации(); 96 | 97 | Для Каждого КЗ Из ПарсерМетаданных.ВнутренниеОписанияСервисов Цикл 98 | 99 | ИмяСервиса = КЗ.Ключ; 100 | ВнутреннееОписание = КЗ.Значение; 101 | 102 | ВнутреннееОписание.Хост = Хост; 103 | ВнутреннееОписание.База1С = База1С; 104 | 105 | // получаем OAS 106 | ГенераторСпецификации = Новый ГенераторСпецификации(ВнутреннееОписание); 107 | 108 | ГенераторСпецификации.ПрочитатьОписаниеСервиса(); 109 | 110 | Спецификация = ГенераторСпецификации.ПолучитьСпецификацию(); 111 | 112 | // отправляем в админку 113 | ЗапросСпецификация = Новый HTTPЗапрос("spec.os?project=" + ИмяПроекта + "&service=" + ИмяСервиса); 114 | ЗапросСпецификация.УстановитьТелоИзСтроки(Спецификация); 115 | 116 | HTTPОтвет = HTTPСоединение.Записать(ЗапросСпецификация); 117 | 118 | Если HTTPОтвет.КодСостояния <> Ответ200 Тогда 119 | ОшибкаСервиса(ЗапросСпецификация, HTTPОтвет); 120 | КонецЕсли; 121 | 122 | ОбновленныеСпецификации.Добавить(ИмяСервиса); 123 | 124 | КонецЦикла; 125 | 126 | Для Каждого ИмяСервиса Из ЗагруженныеСпецификации Цикл 127 | 128 | Если ОбновленныеСпецификации.Найти(ИмяСервиса) <> Неопределено Тогда 129 | Продолжить; 130 | КонецЕсли; 131 | 132 | ЗапросСпецификация = Новый HTTPЗапрос("spec.os?project=" + ИмяПроекта + "&service=" + ИмяСервиса); 133 | 134 | HTTPОтвет = HTTPСоединение.Удалить(ЗапросСпецификация); 135 | 136 | Если HTTPОтвет.КодСостояния <> Ответ200 Тогда 137 | ОшибкаСервиса(ЗапросСпецификация, HTTPОтвет); 138 | КонецЕсли; 139 | 140 | КонецЦикла; -------------------------------------------------------------------------------- /simple-ui/spec-admin/spec.os: -------------------------------------------------------------------------------- 1 | // Предопределенная функция. Является точкой входа в обработку запроса. 2 | // 3 | Функция ОбработкаВызоваHTTPСервиса(Запрос) Экспорт 4 | 5 | Если Запрос.HTTPМетод = "GET" Тогда 6 | Возврат МетодОбработкиGET(Запрос); 7 | ИначеЕсли Запрос.HTTPМетод = "PUT" Тогда 8 | Возврат МетодОбработкиPUT(Запрос); 9 | ИначеЕсли Запрос.HTTPМетод = "DELETE" Тогда 10 | Возврат МетодОбработкиDELETE(Запрос); 11 | Иначе 12 | Возврат МетодОбработкиНеизвестен(Запрос); 13 | КонецЕсли; 14 | 15 | КонецФункции 16 | 17 | Функция МетодОбработкиGET(Запрос) 18 | 19 | ИмяПроекта = Запрос.ПараметрыЗапроса.Получить("project"); 20 | ИмяСервиса = Запрос.ПараметрыЗапроса.Получить("service"); 21 | 22 | Если ИмяПроекта = Неопределено Тогда 23 | Возврат ОтветОшибка("Missing parametr 'project'!"); 24 | КонецЕсли; 25 | 26 | Если ИмяСервиса = Неопределено Тогда 27 | Возврат ОтветОшибка("Missing parametr 'service'!"); 28 | КонецЕсли; 29 | 30 | Попытка 31 | 32 | // создаем окружение 33 | ТекущийКаталог = ТекущийСценарий().Каталог; 34 | КаталогПроекта = ОбъединитьПути(ТекущийКаталог, "Files", ИмяПроекта); 35 | 36 | ИмяФайла = ИмяСервиса + ".json"; 37 | ПолныйПутьКФайлу = ОбъединитьПути(КаталогПроекта, ИмяФайла); 38 | 39 | // читаем файл 40 | ЧтениеТекста = Новый ЧтениеТекста(ПолныйПутьКФайлу); 41 | Спецификация = ЧтениеТекста.Прочитать(); 42 | ЧтениеТекста.Закрыть(); 43 | 44 | Исключение 45 | Возврат ОтветОшибка(ОписаниеОшибки()); 46 | КонецПопытки; 47 | 48 | Возврат ОтветУспешно(Спецификация); 49 | 50 | КонецФункции 51 | 52 | Функция МетодОбработкиPUT(Запрос) 53 | 54 | ИмяПроекта = Запрос.ПараметрыЗапроса.Получить("project"); 55 | ИмяСервиса = Запрос.ПараметрыЗапроса.Получить("service"); 56 | 57 | Если ИмяПроекта = Неопределено Тогда 58 | Возврат ОтветОшибка("Missing parametr 'project'!"); 59 | КонецЕсли; 60 | 61 | Если ИмяСервиса = Неопределено Тогда 62 | Возврат ОтветОшибка("Missing parametr 'service'!"); 63 | КонецЕсли; 64 | 65 | Спецификация = Запрос.ПолучитьТелоКакСтроку(); 66 | 67 | Попытка 68 | 69 | // создаем окружение 70 | ТекущийКаталог = ТекущийСценарий().Каталог; 71 | КаталогПроекта = ОбъединитьПути(ТекущийКаталог, "Files", ИмяПроекта); 72 | 73 | СоздатьКаталог(КаталогПроекта); 74 | 75 | ИмяФайла = ИмяСервиса + ".json"; 76 | ПолныйПутьКФайлу = ОбъединитьПути(КаталогПроекта, ИмяФайла); 77 | 78 | // записываем файл 79 | ЗаписьТекста = Новый ЗаписьТекста(ПолныйПутьКФайлу); 80 | ЗаписьТекста.Записать(Спецификация); 81 | ЗаписьТекста.Закрыть(); 82 | 83 | Исключение 84 | Возврат ОтветОшибка(ОписаниеОшибки()); 85 | КонецПопытки; 86 | 87 | Возврат ОтветУспешно(); 88 | 89 | КонецФункции 90 | 91 | Функция МетодОбработкиDELETE(Запрос) 92 | 93 | ИмяПроекта = Запрос.ПараметрыЗапроса.Получить("project"); 94 | ИмяСервиса = Запрос.ПараметрыЗапроса.Получить("service"); 95 | 96 | Если ИмяПроекта = Неопределено Тогда 97 | Возврат ОтветОшибка("Missing parametr 'project'!"); 98 | КонецЕсли; 99 | 100 | Если ИмяСервиса = Неопределено Тогда 101 | Возврат ОтветОшибка("Missing parametr 'service'!"); 102 | КонецЕсли; 103 | 104 | Попытка 105 | 106 | // создаем окружение 107 | ТекущийКаталог = ТекущийСценарий().Каталог; 108 | КаталогПроекта = ОбъединитьПути(ТекущийКаталог, "Files", ИмяПроекта); 109 | 110 | ИмяФайла = ИмяСервиса + ".json"; 111 | ПолныйПутьКФайлу = ОбъединитьПути(КаталогПроекта, ИмяФайла); 112 | 113 | // удаляем файл 114 | УдалитьФайлы(ПолныйПутьКФайлу); 115 | 116 | Исключение 117 | Возврат ОтветОшибка(ОписаниеОшибки()); 118 | КонецПопытки; 119 | 120 | Возврат ОтветУспешно(); 121 | 122 | КонецФункции 123 | 124 | Функция МетодОбработкиНеизвестен(Запрос) 125 | Возврат ОтветОшибка("Processing method unknown!"); 126 | КонецФункции 127 | 128 | Функция ОтветОшибка(ТекстОшибки = "") 129 | 130 | Ответ = Новый HTTPСервисОтвет(400); 131 | Ответ.УстановитьТелоИзСтроки(СтандартноеТелоОтвета(Ложь, ТекстОшибки)); 132 | 133 | Возврат Ответ; 134 | 135 | КонецФункции 136 | 137 | Функция ОтветУспешно(ТелоОтвета = Неопределено) 138 | 139 | Ответ = Новый HTTPСервисОтвет(200); 140 | 141 | Если ТелоОтвета = Неопределено Тогда 142 | Ответ.УстановитьТелоИзСтроки(СтандартноеТелоОтвета()); 143 | Иначе 144 | Ответ.УстановитьТелоИзСтроки(ТелоОтвета); 145 | КонецЕсли; 146 | 147 | Возврат Ответ; 148 | 149 | КонецФункции 150 | 151 | Функция СтандартноеТелоОтвета(Успех = Истина, ТекстОшибки = "") 152 | 153 | ЗаписьJSON = Новый ЗаписьJSON(); 154 | ЗаписьJSON.УстановитьСтроку(); 155 | 156 | ЗаписьJSON.ЗаписатьНачалоОбъекта(); 157 | 158 | ЗаписьJSON.ЗаписатьИмяСвойства("success"); 159 | ЗаписьJSON.ЗаписатьЗначение(Успех); 160 | 161 | Если НЕ Успех Тогда 162 | 163 | ЗаписьJSON.ЗаписатьИмяСвойства("error_message"); 164 | ЗаписьJSON.ЗаписатьЗначение(ТекстОшибки); 165 | 166 | КонецЕсли; 167 | 168 | ЗаписьJSON.ЗаписатьКонецОбъекта(); 169 | 170 | Возврат ЗаписьJSON.Закрыть(); 171 | 172 | КонецФункции -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Формирование swagger спецификации на основании метаданных конфигурации 1С. 2 | 3 | ## Пара ссылок по теме 4 | 5 | [Wiki](https://ru.wikipedia.org/wiki/OpenAPI_(%D1%81%D0%BF%D0%B5%D1%86%D0%B8%D1%84%D0%B8%D0%BA%D0%B0%D1%86%D0%B8%D1%8F)) 6 | 7 | [Описание формата](https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md) 8 | 9 | [Сайт Swagger](https://swagger.io/) 10 | 11 | [Swagger Editor (быстро проверить свои jsonчики)](https://editor.swagger.io/) 12 | 13 | ## Принцип работы библиотеки 14 | 15 | На основании выгрузки конфигурации в файлы (в будущем добавлю поддержку edt) производится поиск/парсинг/описание http сервисов и преобразование полученных данных в спецификацию swagger (json на выходе). 16 | 17 | Парсинг модуля сервиса предназначен для комментариев вызовов по стандрату [ИТС](https://its.1c.ru/db/v8std#content:453:hdoc) 18 | 19 | ## Дополнительное описание методов 20 | 21 | ### Параметры 22 | 23 | В блоке параметров может быть описана сложная структура входящих данных. Уровень вложенности параметра определяется количеством знаков * перед именем параметра. 24 | 25 | Имя сложного типа должно состоять из одного слова и быть уникальным. 26 | 27 | Для описания множественных значений перед названием типа должна быть ключевая фраза *Массив из*. 28 | 29 | Для обязательных парметров в тексте описания нужно добавить ключевое слово *обязательный*. 30 | 31 | ```bsl 32 | // Параметры: 33 | // userID - Строка - Идентификатор пользователя 34 | // messageId - Строка - Идентификатор сообщения, обязательный 35 | // body - Массив из Accept - Информация о подтверждении 36 | // * orderId - Строка - ID заказа 37 | // * data - Массив из AdditionalData - Дополнительная информация 38 | // ** name - Строка - Имя свойства 39 | // ** value - Массив из Строка - Значения свойства 40 | // * status - Строка - Статус 41 | // ~ Подтверждено - Статус "Подтверждено" 42 | // ~ Отклонено - Статус "Отклонено" 43 | ``` 44 | 45 | ### Формат данных 46 | 47 | Формат входящих и исходящих данных описывается блоками *Варианты вызова* и *Варианты ответа*: 48 | 49 | ```bsl 50 | // Варианты вызова: 51 | // application/json 52 | // application/xml 53 | // 54 | // Варианты ответа: 55 | // application/json 56 | // text/html 57 | ``` 58 | 59 | ### Коды ответов 60 | 61 | Коды ответа указываются в формате "Код - Описание". 62 | 63 | Для каждого кода ответа дополнительно можно определить возвращаемое значение. Для этого код ответа должен быть описан по шаблону "Код - Возвращаемое значение - Описание". 64 | 65 | Поддерживается сложная структура возвращаемых данных. 66 | 67 | ```bsl 68 | // Коды ответов: 69 | // 200 - Массив из Order - Массив заказов 70 | // * orderId - Строка - ID заказа 71 | // * status - Строка - Статус 72 | // * taskList - Массив из Task - Массив задач 73 | // ** taskId - Строка - ID задания 74 | // ** taskNumber - Строка - Номер задания 75 | // 400 - Ошибка выполнения 76 | // 401 - Некорректный токен авторизации 77 | ``` 78 | 79 | ## Пример использования библиотеки 80 | 81 | ```bsl 82 | #Использовать swagger 83 | 84 | // класс для парсинга метаданных конфигурации 85 | ПарсерМетаданных = Новый ПарсерМетаданных(); 86 | 87 | Если ПарсерМетаданных.ПодключитьКонфигурацию(ПутьВыгрузкиКонфигурации, "xml") Тогда 88 | 89 | // без параметров читаем все сервисы, возможен отбор по названию через запятую 90 | ПарсерМетаданных.ВыполнитьПарсингКонфигурации(); 91 | 92 | Для Каждого КЗ Из ПарсерМетаданных.ВнутренниеОписанияСервисов Цикл 93 | 94 | ОписаниеСервиса = КЗ.Значение; 95 | 96 | // ОписаниеСервиса["Хост"] = "1c-subs"; 97 | // ОписаниеСервиса["КорневойURL"] = "/perf-metrics/hs" + ОписаниеСервиса["КорневойURL"]; 98 | 99 | // класс генерации спецификации, создаем на результате работы ПарсерМетаданных 100 | ГенераторСпецификации = Новый ГенераторСпецификации(ОписаниеСервиса); 101 | 102 | ГенераторСпецификации.ПрочитатьОписаниеСервиса(); 103 | 104 | // ПолучитьСпецификацию() - возвращает текст 105 | // СохранитьСпецификацию(КаталогВыгрузки, "json") - сохраняет в файл 106 | Сообщить(ГенераторСпецификации.ПолучитьСпецификацию()); 107 | 108 | КонецЦикла; 109 | 110 | Иначе 111 | Сообщить("Не удалось подключить конфигурацию!", СтатусСообщения.Внимание); 112 | КонецЕсли; 113 | ``` 114 | 115 | Пример получения спецификации в скрипте [example_specgenerator.os](https://github.com/botokash/swagger/blob/master/examples/script/example_specgenerator.os) 116 | 117 | ## Simple-UI 118 | 119 | Пример реализация быстрого каталогизатора спецификаций внутри компании. Используем готовый [swagger-ui](https://github.com/swagger-api/swagger-ui), rest сервисы на oscript и IIS. 120 | 121 | 1. Создаем виртуальный каталог "onec-swagger-ui", закидываем внутрь [dist](https://github.com/swagger-api/swagger-ui/tree/master/dist) из репозитария swagger-ui. 122 | 2. Создаем приложение "onec-swagger-admin", внутрь ложим [rest-admin](https://github.com/botokash/swagger/tree/master/simple-ui/rest-admin). 123 | 3. Заменяем index.html на [новый](https://github.com/botokash/swagger/blob/master/simple-ui/index.html). 124 | 4. В новом index.html указываем в переменной ```admin_url``` свой сервер IIS публикаци rest-admin. 125 | 5. Загрузка спецификаций будет происходить скриптом [upload.os](https://github.com/botokash/swagger/blob/master/simple-ui/upload.os) следующей командой: ```oscript .\upload.os -name ИмяПроекта -path ПутьКВыгрузкеФайлов -type xml -adminurl http://ВашСервер/onec-swagger-admin/``` -------------------------------------------------------------------------------- /tests/fixtures/cf-xml/HTTPServices/UserAPI.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | UserAPI 6 | 7 | 8 | ru 9 | API управления доступом 10 | 11 | 12 | 1.0 13 | user_api 14 | AutoUse 15 | 20 16 | 17 | 18 | 19 | 20 | ПользователиСписок 21 | 22 | 23 | ru 24 | user 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | GET 34 | 35 | 36 | ru 37 | GET 38 | 39 | 40 | Получить список пользователей 41 | GET 42 | ПользователиСписокGET 43 | 44 | 45 | 46 | 47 | 48 | 49 | Пользователь 50 | 51 | 52 | ru 53 | user 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | GET 63 | 64 | 65 | ru 66 | GET 67 | 68 | 69 | Получить свойства пользователя 70 | GET 71 | ПользовательGET 72 | 73 | 74 | 75 | 76 | PATCH 77 | 78 | 79 | ru 80 | PATCH 81 | 82 | 83 | Изменить свойство пользователя 84 | PATCH 85 | ПользовательPATCH 86 | 87 | 88 | 89 | 90 | PUT 91 | 92 | 93 | ru 94 | PUT 95 | 96 | 97 | Изменить все свойства пользователя 98 | PUT 99 | ПользовательPUT 100 | 101 | 102 | 103 | 104 | DELETE 105 | 106 | 107 | ru 108 | DELETE 109 | 110 | 111 | Удалить пользователя 112 | DELETE 113 | ПользовательDELETE 114 | 115 | 116 | 117 | 118 | 119 | 120 | ПользовательНовый 121 | 122 | 123 | ru 124 | user 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | POST 134 | 135 | 136 | ru 137 | POST 138 | 139 | 140 | Создать нового пользователя 141 | POST 142 | ПользовательНовыйPOST 143 | 144 | 145 | 146 | 147 | 148 | 149 | -------------------------------------------------------------------------------- /tests/fixtures/cf-xml/Configuration.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 9cd510cd-abfc-11d4-9434-004095e12fc7 7 | ec6f8551-0f3a-48fa-a397-f580af946cd8 8 | 9 | 10 | 9fcd25a0-4822-11d4-9414-008048da11f9 11 | 203bd12e-aab8-4b0d-9f21-22fe7899bc07 12 | 13 | 14 | e3687481-0a87-462c-a166-9f34594f9bba 15 | e2ce2802-088c-4d50-9fe3-3e72d1e30815 16 | 17 | 18 | 9de14907-ec23-4a07-96f0-85521cb6b53b 19 | 41352a89-4011-478a-a244-8b52b7e37625 20 | 21 | 22 | 51f2d5d8-ea4d-4064-8892-82951750031e 23 | 90193da3-9859-4f8e-b332-051d31392404 24 | 25 | 26 | e68182ea-4237-4383-967f-90c1e3370bc7 27 | f760d41d-d761-4b7b-a594-8db71544107a 28 | 29 | 30 | 31 | Конфигурация 32 | 33 | 34 | 35 | Version8_3_12 36 | ManagedApplication 37 | 38 | PlatformApplication 39 | 40 | Russian 41 | 42 | 43 | 44 | 45 | false 46 | false 47 | false 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | Multimedia 63 | false 64 | 65 | 66 | Location 67 | false 68 | 69 | 70 | Contacts 71 | false 72 | 73 | 74 | Calendars 75 | false 76 | 77 | 78 | Telephony 79 | false 80 | 81 | 82 | PushNotification 83 | false 84 | 85 | 86 | LocalNotification 87 | false 88 | 89 | 90 | Print 91 | false 92 | 93 | 94 | InAppPurchases 95 | false 96 | 97 | 98 | Ads 99 | false 100 | 101 | 102 | BackgroundLocation 103 | false 104 | 105 | 106 | BackgroundAudioPlayback 107 | false 108 | 109 | 110 | FileExchangeWithPersonalComputer 111 | false 112 | 113 | 114 | Normal 115 | 116 | 117 | Language.Русский 118 | 119 | 120 | 121 | 122 | 123 | Managed 124 | NotAutoFree 125 | DontUse 126 | DontUse 127 | Taxi 128 | Version8_3_12 129 | 130 | 131 | 132 | Русский 133 | UserAPI 134 | 135 | 136 | -------------------------------------------------------------------------------- /tests/fixtures/UserAPI.json: -------------------------------------------------------------------------------- 1 | { 2 | "swagger": "2.0", 3 | "info": { 4 | "description": "API управления доступом", 5 | "version": "1.0", 6 | "title": "UserAPI", 7 | "termsOfService": "" 8 | }, 9 | "host": "", 10 | "basePath": "/user_api", 11 | "tags": [ 12 | { 13 | "name": "user", 14 | "description": "" 15 | } 16 | ], 17 | "schemes": [ 18 | "https", 19 | "http" 20 | ], 21 | "paths": { 22 | "/user/list": { 23 | "get": { 24 | "tags": [ 25 | "user" 26 | ], 27 | "summary": "Получить список пользователей", 28 | "description": "Возвращает полный список пользователей в базе 1С", 29 | "consumes": [], 30 | "produces": [ 31 | "plain/text" 32 | ], 33 | "parameters": "", 34 | "responses": { 35 | "200": { 36 | "description": "запрос выполнен" 37 | }, 38 | "500": { 39 | "description": "внутренняя ошибка сервера" 40 | } 41 | } 42 | } 43 | }, 44 | "/user/{userID}": { 45 | "get": { 46 | "tags": [ 47 | "user" 48 | ], 49 | "summary": "Получить свойства пользователя", 50 | "description": "Возвращает все свойства указанного пользователя в базе 1С", 51 | "consumes": [], 52 | "produces": [ 53 | "plain/text" 54 | ], 55 | "parameters": [ 56 | { 57 | "name": "userID", 58 | "in": "path", 59 | "description": "GUID пользователя ИБ", 60 | "required": true, 61 | "type": "string", 62 | "format": "" 63 | } 64 | ], 65 | "responses": { 66 | "200": { 67 | "description": "запрос выполнен" 68 | }, 69 | "404": { 70 | "description": "пользователь по userID не найден" 71 | }, 72 | "500": { 73 | "description": "внутренняя ошибка сервера" 74 | } 75 | } 76 | }, 77 | "patch": { 78 | "tags": [ 79 | "user" 80 | ], 81 | "summary": "Изменить свойство пользователя", 82 | "description": "Изменяет одно свойство указанного пользователя в базе 1С", 83 | "consumes": [], 84 | "produces": [ 85 | "plain/text" 86 | ], 87 | "parameters": [ 88 | { 89 | "name": "userID", 90 | "in": "path", 91 | "description": "GUID пользователя ИБ", 92 | "required": true, 93 | "type": "string", 94 | "format": "" 95 | }, 96 | { 97 | "name": "property", 98 | "in": "query", 99 | "description": "ключ изменяемого свойства", 100 | "required": true, 101 | "type": "string", 102 | "format": "" 103 | }, 104 | { 105 | "name": "value", 106 | "in": "query", 107 | "description": "новое значение", 108 | "required": true, 109 | "type": "string", 110 | "format": "" 111 | } 112 | ], 113 | "responses": { 114 | "200": { 115 | "description": "запрос выполнен" 116 | }, 117 | "404": { 118 | "description": "пользователь по userID не найден" 119 | }, 120 | "500": { 121 | "description": "внутренняя ошибка сервера" 122 | } 123 | } 124 | }, 125 | "put": { 126 | "tags": [ 127 | "user" 128 | ], 129 | "summary": "Изменить все свойства пользователя", 130 | "description": "Изменяет все свойства указанного пользователя в базе 1С", 131 | "consumes": [], 132 | "produces": [ 133 | "plain/text" 134 | ], 135 | "parameters": [ 136 | { 137 | "name": "body", 138 | "in": "body", 139 | "description": "новые свойства пользователя", 140 | "required": true, 141 | "type": "string", 142 | "format": "" 143 | }, 144 | { 145 | "name": "userID", 146 | "in": "path", 147 | "description": "GUID пользователя ИБ", 148 | "required": true, 149 | "type": "string", 150 | "format": "" 151 | } 152 | ], 153 | "responses": { 154 | "200": { 155 | "description": "запрос выполнен" 156 | }, 157 | "404": { 158 | "description": "пользователь по userID не найден" 159 | }, 160 | "500": { 161 | "description": "внутренняя ошибка сервера" 162 | } 163 | } 164 | }, 165 | "delete": { 166 | "tags": [ 167 | "user" 168 | ], 169 | "summary": "Удалить пользователя", 170 | "description": "Удаляет указанного пользователя в базе 1С", 171 | "consumes": [], 172 | "produces": [ 173 | "plain/text" 174 | ], 175 | "parameters": [ 176 | { 177 | "name": "userID", 178 | "in": "path", 179 | "description": "GUID пользователя ИБ", 180 | "required": true, 181 | "type": "string", 182 | "format": "" 183 | } 184 | ], 185 | "responses": { 186 | "200": { 187 | "description": "запрос выполнен" 188 | }, 189 | "404": { 190 | "description": "пользователь по userID не найден" 191 | }, 192 | "500": { 193 | "description": "внутренняя ошибка сервера" 194 | } 195 | } 196 | } 197 | }, 198 | "/user": { 199 | "post": { 200 | "tags": [ 201 | "user" 202 | ], 203 | "summary": "Создать нового пользователя", 204 | "description": "Создает нового пользователя в базе 1С", 205 | "consumes": [], 206 | "produces": [ 207 | "plain/text" 208 | ], 209 | "parameters": [ 210 | { 211 | "name": "body", 212 | "in": "body", 213 | "description": "свойства нового пользователя", 214 | "required": true, 215 | "type": "string", 216 | "format": "" 217 | } 218 | ], 219 | "responses": { 220 | "200": { 221 | "description": "запрос выполнен" 222 | }, 223 | "500": { 224 | "description": "внутренняя ошибка сервера" 225 | } 226 | } 227 | } 228 | } 229 | }, 230 | "externalDocs": { 231 | "description": "Find out more about Swagger", 232 | "url": "http://swagger.io" 233 | } 234 | } -------------------------------------------------------------------------------- /src/Классы/metadataparser.os: -------------------------------------------------------------------------------- 1 | #Использовать fs 2 | #Использовать xml-parser 3 | 4 | Перем ВнутренниеОписанияСервисов Экспорт; 5 | 6 | Перем ПутьКОписаниюСервисов; 7 | Перем мТипПроекта; 8 | 9 | // Инициализация объекта класса 10 | // 11 | Процедура ПриСозданииОбъекта() 12 | 13 | ВнутренниеОписанияСервисов = Новый Соответствие; 14 | 15 | КонецПроцедуры 16 | 17 | // Устанавливает внутренние параметры работы парсера 18 | // 19 | // Параметры: 20 | // ПутьКПроекту - Строка - каталог проекта конфигурации 1С 21 | // ТипПроекта - Строка - структура хранения конфигурационных файлов (xml, edt) 22 | // 23 | // Возвращаемое значение: 24 | // Булево - успешность подключения конфигурации 25 | // 26 | Функция ПодключитьКонфигурацию(Знач ПутьКПроекту, Знач ТипПроекта = "") Экспорт 27 | 28 | Если НЕ ФС.Существует(ПутьКПроекту) Тогда 29 | 30 | Сообщить("Не найден каталог: " + ПутьКПроекту); 31 | Возврат Ложь; 32 | 33 | КонецЕсли; 34 | 35 | Если ПустаяСтрока(ТипПроекта) Тогда 36 | ТипПроекта = ОпределитьФорматИсходногоКода(ПутьКПроекту); 37 | КонецЕсли; 38 | 39 | Если ТипПроекта = "xml" Тогда 40 | ПутьКОписаниюСервисов = ОбъединитьПути(ПутьКПроекту, "HTTPServices"); 41 | ИначеЕсли ТипПроекта = "edt" Тогда 42 | ПутьКОписаниюСервисов = ОбъединитьПути(ПутьКПроекту, "src", "HTTPServices"); 43 | Иначе 44 | 45 | Сообщить("Неизвестный тип проекта конфигурцаии 1С: " + ТипПроекта); 46 | Возврат Ложь; 47 | 48 | КонецЕсли; 49 | 50 | мТипПроекта = ТипПроекта; 51 | 52 | Возврат Истина; 53 | 54 | КонецФункции 55 | 56 | Функция ОпределитьФорматИсходногоКода(ПутьКИсходномуКоду) 57 | 58 | ПутьКФайлуКонфигурации = ОбъединитьПути(ПутьКИсходномуКоду, "Configuration.xml"); 59 | ПутьКФайлуКонфигурацииEDT = ОбъединитьПути(ПутьКИсходномуКоду, "src", "Configuration", "Configuration.mdo"); 60 | 61 | Если ФС.ФайлСуществует(ПутьКФайлуКонфигурации) Тогда 62 | 63 | Возврат "xml"; 64 | 65 | ИначеЕсли ФС.ФайлСуществует(ПутьКФайлуКонфигурацииEDT) Тогда 66 | 67 | Возврат "edt"; 68 | 69 | Иначе 70 | 71 | ВызватьИсключение("Не найден исходный код конфигурации или он выгружен в неизвестном формате"); 72 | 73 | КонецЕсли; 74 | 75 | КонецФункции 76 | 77 | // Спарсить подключенный проект конфигурации и создать спецификации 78 | // 79 | // Параметры: 80 | // Отбор - Строка - Наименование конкретных сервисов через запятую, именно которые необходимо спарсить 81 | // 82 | Процедура ВыполнитьПарсингКонфигурации(Отбор = Неопределено) Экспорт 83 | 84 | Если мТипПроекта = "xml" Тогда 85 | ПарсингПроектаXML(Отбор); 86 | ИначеЕсли мТипПроекта = "edt" Тогда 87 | ПарсингПроектаEDT(Отбор); 88 | КонецЕсли; 89 | 90 | КонецПроцедуры 91 | 92 | Процедура ПарсингПроектаXML(Отбор) 93 | 94 | Если Отбор = Неопределено Тогда 95 | Маска = "*.xml"; 96 | Иначе 97 | 98 | НаборСервисов = СтрРазделить(Отбор, ",", Ложь); 99 | 100 | Маска = ".xml"; 101 | 102 | Для Каждого ИмяСервиса Из НаборСервисов Цикл 103 | Маска = ИмяСервиса + ".xml|"; 104 | КонецЦикла; 105 | 106 | Маска = Лев(Маска, СтрДлина(Маска) - 1); 107 | 108 | КонецЕсли; 109 | 110 | ФайлыXML = НайтиФайлы(ПутьКОписаниюСервисов, Маска); 111 | 112 | Для Каждого Файл Из ФайлыXML Цикл 113 | 114 | ПутьКФайлу = Файл.ПолноеИмя; 115 | 116 | ПроцессорXML = Новый СериализацияДанныхXML(); 117 | 118 | РезультатЧтения = ПроцессорXML.ПрочитатьИзФайла(ПутьКФайлу); 119 | 120 | ОписаниеСервиса = ПолучитьОписаниеСервисаПоXML(РезультатЧтения); 121 | 122 | ВнутренниеОписанияСервисов.Вставить(ОписаниеСервиса.Имя, ОписаниеСервиса); 123 | 124 | КонецЦикла; 125 | 126 | КонецПроцедуры 127 | 128 | Процедура ПарсингПроектаEDT(Отбор) 129 | Если Отбор = Неопределено Тогда 130 | Маска = "*.mdo"; 131 | Иначе 132 | 133 | НаборСервисов = СтрРазделить(Отбор, ",", Ложь); 134 | 135 | Маска = ""; 136 | 137 | Для Каждого ИмяСервиса Из НаборСервисов Цикл 138 | Маска = Маска + ИмяСервиса + ".mdo|"; 139 | КонецЦикла; 140 | 141 | Маска = Лев(Маска, СтрДлина(Маска) - 1); 142 | 143 | КонецЕсли; 144 | 145 | ФайлыMDO = НайтиФайлы(ПутьКОписаниюСервисов, Маска, Истина); 146 | Для Каждого Файл Из ФайлыMDO Цикл 147 | 148 | ПутьКФайлу = Файл.ПолноеИмя; 149 | 150 | ПроцессорXML = Новый СериализацияДанныхXML(); 151 | 152 | РезультатЧтения = ПроцессорXML.ПрочитатьИзФайла(ПутьКФайлу); 153 | 154 | ОписаниеСервиса = ПолучитьОписаниеСервисаПоMDO(РезультатЧтения); 155 | 156 | ВнутренниеОписанияСервисов.Вставить(ОписаниеСервиса.Имя, ОписаниеСервиса); 157 | 158 | КонецЦикла; 159 | КонецПроцедуры 160 | 161 | Функция ПолучитьОписаниеСервисаПоMDO(РезультатЧтения) 162 | 163 | Результат = ПолучитьСтруктуруОписанияСервиса(); 164 | 165 | ФайлМодуля = "Module.bsl"; 166 | 167 | МассивСвойствСервиса = РезультатЧтения["HTTPService"]["_Элементы"]; 168 | 169 | Результат.Имя = НайтиЗначениеСвойства(МассивСвойствСервиса, "Name"); 170 | Результат.Описание = НайтиЗначениеСвойства(МассивСвойствСервиса, "Synonym")["value"]; 171 | 172 | Результат.Версия = НайтиЗначениеСвойства(МассивСвойствСервиса, "Comment"); 173 | Результат.КорневойURL = "/" + НайтиЗначениеСвойства(МассивСвойствСервиса, "RootURL"); 174 | 175 | // парсим модуль 176 | ПутьКФайлуМодуля = ОбъединитьПути(ПутьКОписаниюСервисов, Результат.Имя, ФайлМодуля); 177 | 178 | ПарсерКода = Новый ПарсерКода(ПутьКФайлуМодуля); 179 | ПарсерКода.Прочитать(); 180 | 181 | // читаем описание шаблонов 182 | ШаблоныСервиса = НайтиЗначенияСвойства(МассивСвойствСервиса, "urlTemplates"); 183 | 184 | Для Каждого УзелШаблона Из ШаблоныСервиса Цикл 185 | 186 | СвойстваШаблона = УзелШаблона["_Элементы"]; 187 | 188 | // 189 | ШаблонURL = ПолучитьСтруктуруШаблонаURL(); 190 | 191 | ШаблонURL.Имя = НайтиЗначениеСвойства(СвойстваШаблона, "Name"); 192 | ШаблонURL.Описание = НайтиЗначениеСвойства(СвойстваШаблона, "Comment"); 193 | ШаблонURL.Тэг = НайтиЗначениеСвойства(СвойстваШаблона, "Synonym")["value"]; 194 | ШаблонURL.Путь = НайтиЗначениеСвойства(СвойстваШаблона, "Template"); 195 | 196 | // найдем параметры в пути 197 | ПараметрыВПути = Новый Массив; 198 | 199 | СоставПути = СтрРазделить(ШаблонURL.Путь, "/", Ложь); 200 | 201 | Для Каждого Элемент Из СоставПути Цикл 202 | 203 | Если Лев(Элемент, 1) = "{" И Прав(Элемент, 1) = "}" Тогда 204 | ПараметрыВПути.Добавить(Сред(Элемент, 2, СтрДлина(Элемент) - 2)); 205 | КонецЕсли; 206 | 207 | КонецЦикла; 208 | 209 | Если ПараметрыВПути.Количество() <> 0 Тогда 210 | ШаблонURL.ПараметрыВПути = ПараметрыВПути; 211 | КонецЕсли; 212 | 213 | // читаем методы шаблона 214 | МетодыШаблона = НайтиЗначенияСвойства(УзелШаблона["_Элементы"], "methods"); 215 | 216 | Для Каждого УзелМетода Из МетодыШаблона Цикл 217 | 218 | СвойстваМетода = УзелМетода["_Элементы"]; 219 | 220 | Метод = ПолучитьСтруктуруМетодаШаблонаURL(); 221 | 222 | Метод.Метод = НайтиЗначениеСвойства(СвойстваМетода, "HTTPMethod", "GET"); 223 | Метод.Имя = НайтиЗначениеСвойства(СвойстваМетода, "Name"); 224 | Метод.Резюме = НайтиЗначениеСвойства(СвойстваМетода, "Comment"); 225 | Метод.Вызов = НайтиЗначениеСвойства(СвойстваМетода, "Handler"); 226 | 227 | ОписаниеВызова = ПарсерКода.КартаМодуля.Получить(ВРег(Метод.Вызов)); 228 | 229 | Если ОписаниеВызова <> Неопределено Тогда 230 | 231 | Метод.Описание = ОписаниеВызова.Описание; 232 | Метод.ВходящиеПараметры = ОписаниеВызова.ВходящиеПараметры; 233 | Метод.ВозвращаемоеЗначение = ОписаниеВызова.ВозвращаемоеЗначение; 234 | Метод.КодыОтветов = ОписаниеВызова.КодыОтветов; 235 | Метод.ВариантыВызова = ОписаниеВызова.ВариантыВызова; 236 | Метод.ВариантыОтвета = ОписаниеВызова.ВариантыОтвета; 237 | 238 | КонецЕсли; 239 | 240 | ШаблонURL.Методы.Добавить(Метод); 241 | 242 | КонецЦикла; 243 | 244 | Результат.ШаблоныURL.Добавить(ШаблонURL); 245 | 246 | КонецЦикла; 247 | 248 | Возврат Результат; 249 | 250 | КонецФункции 251 | 252 | Функция ПолучитьОписаниеСервисаПоXML(РезультатЧтения) 253 | 254 | Результат = ПолучитьСтруктуруОписанияСервиса(); 255 | 256 | ФайлМодуля = "Module.bsl"; 257 | 258 | БазовыйУзел = РезультатЧтения["MetaDataObject"]["_Элементы"]["HTTPService"]; 259 | 260 | // читаем свойства 261 | СвойстваСервиса = БазовыйУзел["_Элементы"]["Properties"]; 262 | 263 | Результат.Имя = СвойстваСервиса["Name"]; 264 | Результат.Описание = ПолучитьЗначениеЯзыковогоУзла(СвойстваСервиса["Synonym"]); 265 | Результат.Версия = СвойстваСервиса["Comment"]; 266 | Результат.КорневойURL = "/" + СвойстваСервиса["RootURL"]; 267 | 268 | // парсим модуль 269 | ПутьКФайлуМодуля = ОбъединитьПути(ПутьКОписаниюСервисов, Результат.Имя, "Ext", ФайлМодуля); 270 | 271 | ПарсерКода = Новый ПарсерКода(ПутьКФайлуМодуля); 272 | ПарсерКода.Прочитать(); 273 | 274 | // читаем описание шаблонов 275 | ШаблоныСервиса = БазовыйУзел["_Элементы"]["ChildObjects"]; 276 | 277 | Если ТипЗнч(БазовыйУзел["_Элементы"]["ChildObjects"]) = Тип("Соответствие") Тогда 278 | 279 | ШаблоныСервиса = Новый Массив; 280 | 281 | ШаблоныСервиса.Добавить(БазовыйУзел["_Элементы"]["ChildObjects"]); 282 | 283 | Иначе 284 | 285 | ШаблоныСервиса = БазовыйУзел["_Элементы"]["ChildObjects"]; 286 | 287 | КонецЕсли; 288 | 289 | Для Каждого УзелШаблона Из ШаблоныСервиса Цикл 290 | 291 | СвойстваШаблона = УзелШаблона["URLTemplate"]["_Элементы"]["Properties"]; 292 | 293 | // 294 | ШаблонURL = ПолучитьСтруктуруШаблонаURL(); 295 | 296 | ШаблонURL.Имя = СвойстваШаблона["Name"]; 297 | ШаблонURL.Описание = СвойстваШаблона["Comment"]; 298 | ШаблонURL.Тэг = ПолучитьЗначениеЯзыковогоУзла(СвойстваШаблона["Synonym"]); 299 | ШаблонURL.Путь = СвойстваШаблона["Template"]; 300 | 301 | // найдем параметры в пути 302 | ПараметрыВПути = Новый Массив; 303 | 304 | СоставПути = СтрРазделить(ШаблонURL.Путь, "/", Ложь); 305 | 306 | Для Каждого Элемент Из СоставПути Цикл 307 | 308 | Если Лев(Элемент, 1) = "{" И Прав(Элемент, 1) = "}" Тогда 309 | ПараметрыВПути.Добавить(Сред(Элемент, 2, СтрДлина(Элемент) - 2)); 310 | КонецЕсли; 311 | 312 | КонецЦикла; 313 | 314 | Если ПараметрыВПути.Количество() <> 0 Тогда 315 | ШаблонURL.ПараметрыВПути = ПараметрыВПути; 316 | КонецЕсли; 317 | 318 | // 319 | МетодыШаблона = УзелШаблона["URLTemplate"]["_Элементы"]["ChildObjects"]; 320 | 321 | Для Каждого УзелМетода Из МетодыШаблона Цикл 322 | 323 | Если ТипЗнч(УзелМетода) = Тип("Соответствие") Тогда 324 | СвойстваМетода = УзелМетода["Method"]["_Элементы"]["Properties"]; 325 | Иначе 326 | СвойстваМетода = УзелМетода.Значение["_Элементы"]["Properties"]; 327 | КонецЕсли; 328 | 329 | Метод = ПолучитьСтруктуруМетодаШаблонаURL(); 330 | 331 | Метод.Метод = СвойстваМетода["HTTPMethod"]; 332 | Метод.Имя = СвойстваМетода["Name"]; 333 | Метод.Резюме = СвойстваМетода["Comment"]; 334 | Метод.Вызов = СвойстваМетода["Handler"]; 335 | 336 | ОписаниеВызова = ПарсерКода.КартаМодуля.Получить(ВРег(Метод.Вызов)); 337 | 338 | Если ОписаниеВызова <> Неопределено Тогда 339 | 340 | Метод.Описание = ОписаниеВызова.Описание; 341 | Метод.ВходящиеПараметры = ОписаниеВызова.ВходящиеПараметры; 342 | Метод.ВозвращаемоеЗначение = ОписаниеВызова.ВозвращаемоеЗначение; 343 | Метод.КодыОтветов = ОписаниеВызова.КодыОтветов; 344 | Метод.ВариантыВызова = ОписаниеВызова.ВариантыВызова; 345 | Метод.ВариантыОтвета = ОписаниеВызова.ВариантыОтвета; 346 | 347 | КонецЕсли; 348 | 349 | ШаблонURL.Методы.Добавить(Метод); 350 | 351 | КонецЦикла; 352 | 353 | Результат.ШаблоныURL.Добавить(ШаблонURL); 354 | 355 | КонецЦикла; 356 | 357 | Возврат Результат; 358 | 359 | КонецФункции 360 | 361 | Функция ПолучитьЗначениеЯзыковогоУзла(УзелXML, Локаль = "ru") 362 | 363 | Результат = ""; 364 | 365 | Для Каждого УзелЭлемента Из УзелXML Цикл 366 | 367 | СвойстваЭлемента = УзелЭлемента.Значение; 368 | 369 | Если СвойстваЭлемента["lang"] = Локаль Тогда 370 | 371 | Результат = СвойстваЭлемента["content"]; 372 | Прервать; 373 | 374 | КонецЕсли; 375 | 376 | КонецЦикла; 377 | 378 | Возврат Результат; 379 | 380 | КонецФункции 381 | 382 | Функция НайтиЗначениеСвойства(Свойства, Ключ, ЗначениеПоУмолчанию = "") 383 | 384 | Результат = ЗначениеПоУмолчанию; 385 | 386 | Если ТипЗнч(Свойства) = Тип("Массив") Тогда 387 | Для Каждого УзелЭлемента Из Свойства Цикл 388 | 389 | Для Каждого КлючИЗначение Из УзелЭлемента Цикл 390 | КлючЭлемента = КлючИЗначение.Ключ; 391 | СвойстваЭлемента = КлючИЗначение.Значение; 392 | 393 | Если НРег(КлючЭлемента) = НРег(Ключ) Тогда 394 | 395 | Результат = СвойстваЭлемента; 396 | Прервать; 397 | 398 | КонецЕсли; 399 | 400 | КонецЦикла; 401 | 402 | КонецЦикла; 403 | Иначе // соответствие 404 | 405 | Для Каждого КлючИЗначение Из Свойства Цикл 406 | КлючЭлемента = КлючИЗначение.Ключ; 407 | СвойстваЭлемента = КлючИЗначение.Значение; 408 | 409 | Если НРег(КлючЭлемента) = НРег(Ключ) Тогда 410 | 411 | Результат = СвойстваЭлемента; 412 | Прервать; 413 | 414 | КонецЕсли; 415 | 416 | КонецЦикла; 417 | 418 | КонецЕсли; 419 | 420 | Возврат Результат; 421 | 422 | КонецФункции 423 | 424 | Функция НайтиЗначенияСвойства(Свойства, Ключ) 425 | 426 | РезультатМассив = Новый Массив; 427 | 428 | Если ТипЗнч(Свойства) = Тип("Массив") Тогда 429 | Для Каждого УзелЭлемента Из Свойства Цикл 430 | 431 | Для Каждого КлючИЗначение Из УзелЭлемента Цикл 432 | КлючЭлемента = КлючИЗначение.Ключ; 433 | СвойстваЭлемента = КлючИЗначение.Значение; 434 | 435 | Если НРег(КлючЭлемента) = НРег(Ключ) Тогда 436 | 437 | РезультатМассив.Добавить(СвойстваЭлемента); 438 | 439 | КонецЕсли; 440 | 441 | КонецЦикла; 442 | 443 | КонецЦикла; 444 | Иначе // соответствие 445 | 446 | Для Каждого КлючИЗначение Из Свойства Цикл 447 | КлючЭлемента = КлючИЗначение.Ключ; 448 | СвойстваЭлемента = КлючИЗначение.Значение; 449 | 450 | Если НРег(КлючЭлемента) = НРег(Ключ) Тогда 451 | 452 | РезультатМассив.Добавить(СвойстваЭлемента); 453 | 454 | КонецЕсли; 455 | 456 | КонецЦикла; 457 | 458 | КонецЕсли; 459 | 460 | Возврат РезультатМассив; 461 | 462 | КонецФункции 463 | Функция ПолучитьСтруктуруОписанияСервиса() 464 | 465 | Результат = Новый Структура; 466 | 467 | Результат.Вставить("Имя"); 468 | Результат.Вставить("Описание"); 469 | Результат.Вставить("Версия"); 470 | Результат.Вставить("Хост"); 471 | Результат.Вставить("КорневойURL"); 472 | Результат.Вставить("ШаблоныURL", Новый Массив); 473 | Результат.Вставить("База1С"); 474 | 475 | Возврат Результат; 476 | 477 | КонецФункции 478 | 479 | Функция ПолучитьСтруктуруШаблонаURL() 480 | 481 | Результат = Новый Структура; 482 | 483 | Результат.Вставить("Имя"); 484 | Результат.Вставить("Описание"); 485 | Результат.Вставить("Тэг"); 486 | Результат.Вставить("Путь"); 487 | Результат.Вставить("ПараметрыВПути"); 488 | Результат.Вставить("Методы", Новый Массив); 489 | 490 | Возврат Результат; 491 | 492 | КонецФункции 493 | 494 | Функция ПолучитьСтруктуруМетодаШаблонаURL() 495 | 496 | Результат = Новый Структура; 497 | 498 | Результат.Вставить("Метод"); 499 | Результат.Вставить("Имя"); 500 | Результат.Вставить("Резюме"); 501 | Результат.Вставить("Описание"); 502 | Результат.Вставить("Вызов"); 503 | Результат.Вставить("ВходящиеПараметры"); 504 | Результат.Вставить("ВозвращаемоеЗначение"); 505 | Результат.Вставить("КодыОтветов"); 506 | Результат.Вставить("ВариантыВызова"); 507 | Результат.Вставить("ВариантыОтвета"); 508 | 509 | Возврат Результат; 510 | 511 | КонецФункции -------------------------------------------------------------------------------- /src/Классы/codeparser.os: -------------------------------------------------------------------------------- 1 | Перем ТекстМодуля; 2 | 3 | Перем ПоискБлокиВызовов; 4 | Перем ПоискИмяВызова; 5 | Перем ПоискТипВызова; 6 | Перем РазделительБлокаВызова; 7 | Перем РазделительБлокаКомментария; 8 | Перем ОчисткаБлокаКомментария; 9 | Перем РазделительБлокаПараметровКомментария; 10 | Перем РазделительБлокаКодыОтветовКомментария; 11 | 12 | Перем КартаМодуля Экспорт; 13 | 14 | // Инициализация объекта класса 15 | // 16 | // Параметры: 17 | // ПутьКМодулю - Строка - Местоположение исследуемого модуля 18 | // 19 | Процедура ПриСозданииОбъекта(ПутьКМодулю) 20 | 21 | // чтение содержимого модуля 22 | Файл = Новый ТекстовыйДокумент; 23 | Файл.Прочитать(ПутьКМодулю, КодировкаТекста.UTF8); 24 | 25 | ТекстМодуля = СокрЛП(Файл.ПолучитьТекст()); 26 | 27 | // инициализация регулярок для парсинга 28 | рв_НачалоВызова = "[Пп][Рр][Оо][Цц][Ее][Дд][Уу][Рр][Аа]|[Фф][Уу][Нн][Кк][Цц][Ии][Яя]"; 29 | рв_КонецВызова = "[Кк][Оо][Нн][Ее][Цц][Пп][Рр][Оо][Цц][Ее][Дд][Уу][Рр][Ыы]|[Кк][Оо][Нн][Ее][Цц][Фф][Уу][Нн][Кк][Цц][Ии][Ии]"; 30 | 31 | рв_ПоискБлокиВызовов = "(?=(" + рв_НачалоВызова + "|^\/\/))(.|\n)*?(?<=" + рв_КонецВызова + ")"; 32 | рв_РазделительБлокаВызова = "(?=^\/+[\t\s]*$)*(?=" + рв_НачалоВызова + ")"; 33 | рв_РазделительБлокаКомментария = "^\/+[\t\s]*$"; 34 | рв_ОчисткаБлокаКомментария = "\/\/(\t|\s)*"; 35 | рв_РазделительБлокаПараметровКомментария = "(?=^[а-яА-Яa-zA-Z]*.-.[а-яА-Яa-zA-Z ]*.-..*)"; 36 | рв_РазделительБлокаКодыОтветовКомментария = "(?=^[0-9]*.-.[а-яА-Яa-zA-Z]*.*)"; 37 | 38 | ПоискБлокиВызовов = Новый РегулярноеВыражение(рв_ПоискБлокиВызовов); 39 | ПоискИмяВызова = Новый РегулярноеВыражение("(?<=" + рв_НачалоВызова + ").*(?=\()"); 40 | ПоискТипВызова = Новый РегулярноеВыражение("^(" + рв_НачалоВызова + ")"); 41 | РазделительБлокаВызова = Новый РегулярноеВыражение(рв_РазделительБлокаВызова); 42 | РазделительБлокаКомментария = Новый РегулярноеВыражение(рв_РазделительБлокаКомментария); 43 | ОчисткаБлокаКомментария = Новый РегулярноеВыражение(рв_ОчисткаБлокаКомментария); 44 | РазделительБлокаПараметровКомментария = Новый РегулярноеВыражение(рв_РазделительБлокаПараметровКомментария); 45 | РазделительБлокаКодыОтветовКомментария = Новый РегулярноеВыражение(рв_РазделительБлокаКодыОтветовКомментария); 46 | 47 | // инициализация внутренних структур 48 | КартаМодуля = Новый Соответствие(); 49 | 50 | КонецПроцедуры 51 | 52 | Процедура Прочитать() Экспорт 53 | 54 | СовпаденияБлокиВызовов = ПоискБлокиВызовов.НайтиСовпадения(ТекстМодуля); 55 | 56 | Для Каждого Совпадение Из СовпаденияБлокиВызовов Цикл 57 | 58 | СодержимоеКомментария = ""; 59 | КодВызова = ""; 60 | 61 | СодержимоеВызова = СокрЛП(Совпадение.Значение); 62 | 63 | ИмяВызова = ПолучитьИмяВызова(СодержимоеВызова); 64 | ТипВызова = ПолучитьТипВызова(СодержимоеВызова); 65 | 66 | // разделим вызов на блоки - комментарий и код 67 | БлокиВызова = РазделительБлокаВызова.Разделить(СодержимоеВызова); 68 | 69 | Для Каждого ТекстБлокаВызова Из БлокиВызова Цикл 70 | 71 | СодержимоеБлокаВызова = СокрЛП(ТекстБлокаВызова); 72 | 73 | Если Лев(СодержимоеБлокаВызова, 2) = "//" Тогда 74 | СодержимоеКомментария = СодержимоеБлокаВызова; 75 | Иначе 76 | КодВызова = СодержимоеБлокаВызова; 77 | КонецЕсли; 78 | 79 | КонецЦикла; 80 | 81 | // распарсим комментарий, ожидаем стандарт ИТС с поправками для сервисов 82 | СоставКомментария = ПолучитьСоставКомментария(СодержимоеКомментария); 83 | 84 | // добавим в карту вызовов 85 | ОписаниеВызова = НовоеОписаниеВызова(); 86 | 87 | ОписаниеВызова.Имя = ИмяВызова; 88 | ОписаниеВызова.Тип = ТипВызова; 89 | ОписаниеВызова.Код = КодВызова; 90 | ОписаниеВызова.Описание = СоставКомментария.Описание; 91 | ОписаниеВызова.ВходящиеПараметры = СоставКомментария.ВходящиеПараметры; 92 | ОписаниеВызова.ВозвращаемоеЗначение = СоставКомментария.ВозвращаемоеЗначение; 93 | ОписаниеВызова.КодыОтветов = СоставКомментария.КодыОтветов; 94 | ОписаниеВызова.ВариантыВызова = СоставКомментария.ВариантыВызова; 95 | ОписаниеВызова.ВариантыОтвета = СоставКомментария.ВариантыОтвета; 96 | 97 | КартаМодуля.Вставить(ВРег(ИмяВызова), ОписаниеВызова); 98 | 99 | КонецЦикла; 100 | 101 | КонецПроцедуры 102 | 103 | Функция ПолучитьИмяВызова(СодержимоеВызова) 104 | 105 | Результат = ""; 106 | 107 | Совпадения = ПоискИмяВызова.НайтиСовпадения(СодержимоеВызова); 108 | 109 | Если Совпадения.Количество() = 0 Тогда 110 | Сообщить("Не найдено имя вызова в блоке!"); 111 | КонецЕсли; 112 | 113 | Результат = СокрЛП(Совпадения[0].Значение); 114 | 115 | Возврат Результат; 116 | 117 | КонецФункции 118 | 119 | Функция ПолучитьТипВызова(СодержимоеВызова) 120 | 121 | Результат = ""; 122 | 123 | Совпадения = ПоискТипВызова.НайтиСовпадения(СодержимоеВызова); 124 | 125 | Если Совпадения.Количество() = 0 Тогда 126 | Сообщить("Не найден тип вызова в блоке!"); 127 | КонецЕсли; 128 | 129 | Результат = СокрЛП(Совпадения[0].Значение); 130 | 131 | Возврат Результат; 132 | 133 | КонецФункции 134 | 135 | Функция ПолучитьСоставКомментария(СодержимоеКомментария) 136 | 137 | Результат = Новый Структура; 138 | 139 | Результат.Вставить("Описание", Неопределено); 140 | Результат.Вставить("ВходящиеПараметры", Неопределено); 141 | Результат.Вставить("ВариантыВызова", Неопределено); 142 | Результат.Вставить("ВариантыОтвета", Неопределено); 143 | Результат.Вставить("ВозвращаемоеЗначение", Неопределено); 144 | Результат.Вставить("КодыОтветов", Неопределено); 145 | 146 | Результат.Вставить("Пример", Неопределено); 147 | 148 | Если СодержимоеКомментария <> "" Тогда 149 | 150 | БлокиКомментария = РазделительБлокаКомментария.Разделить(СодержимоеКомментария); 151 | 152 | Для Каждого ТекстБлокаКомментария Из БлокиКомментария Цикл 153 | 154 | СодержимоеБлока = ОчиститьТекстБлокаКомментария(ТекстБлокаКомментария); 155 | 156 | Если СодержимоеБлока = "" Тогда 157 | Продолжить; 158 | КонецЕсли; 159 | 160 | Если СтрНачинаетсяС(СодержимоеБлока, "Параметры:") Тогда 161 | Результат.ВходящиеПараметры = ПолучитьВходящиеПараметрыИзКомментария(СодержимоеБлока); 162 | ИначеЕсли СтрНачинаетсяС(СодержимоеБлока, "Варианты вызова:") Тогда 163 | Результат.ВариантыВызова = ПолучитьВариантыВызоваИзКомментария(СодержимоеБлока); 164 | ИначеЕсли СтрНачинаетсяС(СодержимоеБлока, "Варианты ответа:") Тогда 165 | Результат.ВариантыОтвета = ПолучитьВариантыОтветаИзКомментария(СодержимоеБлока); 166 | ИначеЕсли СтрНачинаетсяС(СодержимоеБлока, "Возвращаемое значение:") Тогда 167 | Результат.ВозвращаемоеЗначение = СодержимоеБлока; 168 | ИначеЕсли СтрНачинаетсяС(СодержимоеБлока, "Коды ответов:") Тогда 169 | Результат.КодыОтветов = ПолучитьКодыОтветовИзКомментария(СодержимоеБлока); 170 | ИначеЕсли СтрНачинаетсяС(СодержимоеБлока, "Пример:") Тогда 171 | Результат.Пример = СодержимоеБлока; 172 | Иначе 173 | Результат.Описание = СодержимоеБлока; 174 | КонецЕсли; 175 | 176 | КонецЦикла; 177 | 178 | КонецЕсли; 179 | 180 | Возврат Результат; 181 | 182 | КонецФункции 183 | 184 | Функция ОчиститьТекстБлокаКомментария(ТекстБлокаКомментария) 185 | 186 | Результат = СокрЛП(ТекстБлокаКомментария); 187 | 188 | Результат = ОчисткаБлокаКомментария.Заменить(Результат, ""); 189 | 190 | Возврат Результат; 191 | 192 | КонецФункции 193 | 194 | Функция ПолучитьВходящиеПараметрыИзКомментария(Текст) 195 | 196 | Результат = Новый Массив; 197 | 198 | ТекстПараметры = СтрЗаменить(Текст, "Параметры:", ""); 199 | 200 | ОписанияПараметров = РазделительБлокаПараметровКомментария.Разделить(ТекстПараметры); 201 | 202 | Для Каждого ТекстОписанияПараметра Из ОписанияПараметров Цикл 203 | 204 | Если НЕ ЗначениеЗаполнено(ТекстОписанияПараметра) Тогда 205 | Продолжить; 206 | КонецЕсли; 207 | 208 | СтрокиОписанияПараметра = СтрРазделить(ТекстОписанияПараметра, Символы.ПС, Ложь); 209 | 210 | // первая строка всегда должна быть по стандарту 211 | ЗаголовокПараметра = СтрокиОписанияПараметра[0]; 212 | 213 | // ожидаем строку вида "Имя - Тип - Описание" 214 | СоставЗаголовкаПараметра = СтрРазделить(ЗаголовокПараметра, "-", Ложь); 215 | 216 | Если СоставЗаголовкаПараметра.Количество() <> 3 Тогда 217 | Сообщить("Некорректное описание параметра в строке: " + Символы.ПС + ЗаголовокПараметра); 218 | КонецЕсли; 219 | 220 | ОписаниеВходящегоПараметра = НовоеОписаниеПараметра(); 221 | 222 | ОписаниеВходящегоПараметра.Имя = СокрЛП(СоставЗаголовкаПараметра[0]); 223 | ОписаниеВходящегоПараметра.Тип = СокрЛП(СоставЗаголовкаПараметра[1]); 224 | ОписаниеВходящегоПараметра.Описание = СокрЛП(СоставЗаголовкаПараметра[2]); 225 | ОписаниеВходящегоПараметра.Обязательный = СтрНайти(ОписаниеВходящегоПараметра.Описание, "обязательный") > 0; 226 | 227 | // проверим доп. данные 228 | КоличествоСтрок = СтрокиОписанияПараметра.Количество(); 229 | 230 | Если КоличествоСтрок > 1 Тогда 231 | ЗаполнитьОписаниеПараметра(ОписаниеВходящегоПараметра, СтрокиОписанияПараметра, КоличествоСтрок); 232 | КонецЕсли; 233 | 234 | Результат.Добавить(ОписаниеВходящегоПараметра); 235 | 236 | КонецЦикла; 237 | 238 | Возврат ?(Результат.Количество() = 0, Неопределено, Результат); 239 | 240 | КонецФункции 241 | 242 | Функция ПолучитьВариантыВызоваИзКомментария(Текст) 243 | 244 | Результат = Новый Массив; 245 | 246 | ТекстПараметры = СтрЗаменить(Текст, "Варианты вызова:", ""); 247 | 248 | ОписанияВариантовВызова = СтрРазделить(ТекстПараметры, Символы.ПС); 249 | 250 | Для Каждого ТекстВариантовВызова Из ОписанияВариантовВызова Цикл 251 | 252 | Если НЕ ЗначениеЗаполнено(ТекстВариантовВызова) Тогда 253 | Продолжить; 254 | КонецЕсли; 255 | 256 | Результат.Добавить(СокрЛП(ТекстВариантовВызова)); 257 | 258 | КонецЦикла; 259 | 260 | Возврат ?(Результат.Количество() = 0, Неопределено, Результат); 261 | 262 | КонецФункции 263 | 264 | Функция ПолучитьВариантыОтветаИзКомментария(Текст) 265 | 266 | Результат = Новый Массив; 267 | 268 | ТекстПараметры = СтрЗаменить(Текст, "Варианты ответа:", ""); 269 | 270 | ОписанияВариантовОтвета = СтрРазделить(ТекстПараметры, Символы.ПС); 271 | 272 | Для Каждого ТекстВариантовОтвета Из ОписанияВариантовОтвета Цикл 273 | 274 | Если НЕ ЗначениеЗаполнено(ТекстВариантовОтвета) Тогда 275 | Продолжить; 276 | КонецЕсли; 277 | 278 | Результат.Добавить(СокрЛП(ТекстВариантовОтвета)); 279 | 280 | КонецЦикла; 281 | 282 | Возврат ?(Результат.Количество() = 0, Неопределено, Результат); 283 | 284 | КонецФункции 285 | 286 | Функция ПолучитьКодыОтветовИзКомментария(Текст) 287 | 288 | Результат = Новый Массив; 289 | 290 | ТекстКодыОтветов = СтрЗаменить(Текст, "Коды ответов:", ""); 291 | 292 | ОписанияКодовОтветов = РазделительБлокаКодыОтветовКомментария.Разделить(ТекстКодыОтветов); 293 | 294 | Для Каждого ТекстКодовОтветов Из ОписанияКодовОтветов Цикл 295 | 296 | Если НЕ ЗначениеЗаполнено(ТекстКодовОтветов) Тогда 297 | Продолжить; 298 | КонецЕсли; 299 | 300 | СтрокиКодовОтветов = СтрРазделить(ТекстКодовОтветов, Символы.ПС, Ложь); 301 | 302 | // первая строка может быть по шаблону "Код - Описание" или "Код - Возвращаемое значение - Описание" 303 | ЗаголовокКодаОтвета = СтрокиКодовОтветов[0]; 304 | 305 | // ожидаем строку вида "Код - Описание" или "Код - Возвращаемое значение - Описание" 306 | СоставКодаОтвета = СтрРазделить(ЗаголовокКодаОтвета, "-", Ложь); 307 | 308 | Если СоставКодаОтвета.Количество() <> 2 И СоставКодаОтвета.Количество() <> 3 Тогда 309 | Сообщить("Некорректное описание кода ответа в строке: " + Символы.ПС + ЗаголовокКодаОтвета); 310 | КонецЕсли; 311 | 312 | ОписаниеКодаОтвета = НовоеОписаниеКодаОтвета(); 313 | 314 | ОписаниеКодаОтвета.Код = СокрЛП(СоставКодаОтвета[0]); 315 | 316 | Если СоставКодаОтвета.Количество() = 2 Тогда 317 | ОписаниеКодаОтвета.Описание = СокрЛП(СоставКодаОтвета[1]); 318 | ИначеЕсли СоставКодаОтвета.Количество() = 3 Тогда 319 | ОписаниеКодаОтвета.Тип = СокрЛП(СоставКодаОтвета[1]); 320 | ОписаниеКодаОтвета.Описание = СокрЛП(СоставКодаОтвета[2]); 321 | КонецЕсли; 322 | 323 | // проверим доп. данные 324 | КоличествоСтрок = СтрокиКодовОтветов.Количество(); 325 | 326 | Если КоличествоСтрок > 1 Тогда 327 | 328 | Для НомерСтроки = 1 По (КоличествоСтрок - 1) Цикл 329 | ЗаполнитьОписаниеПараметра(ОписаниеКодаОтвета, СтрокиКодовОтветов, КоличествоСтрок); 330 | КонецЦикла; 331 | 332 | КонецЕсли; 333 | 334 | Результат.Добавить(ОписаниеКодаОтвета); 335 | 336 | КонецЦикла; 337 | 338 | Возврат ?(Результат.Количество() = 0, Неопределено, Результат); 339 | 340 | КонецФункции 341 | 342 | Процедура ЗаполнитьОписаниеПараметра(ОписаниеПараметра, СтрокиОписанияПараметра, КоличествоСтрок) 343 | 344 | ИерархияПараметров = Новый Соответствие(); 345 | ТекущийУровень = 1; 346 | ИерархияПараметров.Вставить(ТекущийУровень, ОписаниеПараметра); 347 | 348 | ОписаниеСоставногоТипа = Неопределено; 349 | ПредыдущийПараметр = ОписаниеПараметра; 350 | 351 | Для НомерСтроки = 1 По (КоличествоСтрок - 1) Цикл 352 | 353 | ТекущаяСтрока = СтрокиОписанияПараметра[НомерСтроки]; 354 | 355 | УровеньПараметра = СтрЧислоВхождений(ТекущаяСтрока, "*"); 356 | 357 | Если УровеньПараметра > ТекущийУровень И ОписаниеСоставногоТипа <> Неопределено Тогда 358 | ТекущийУровень = УровеньПараметра; 359 | ИерархияПараметров.Вставить(ТекущийУровень, ОписаниеСоставногоТипа); 360 | ИначеЕсли УровеньПараметра < ТекущийУровень И УровеньПараметра > 0 Тогда 361 | ТекущийУровень = УровеньПараметра; 362 | КонецЕсли; 363 | 364 | Если Лев(ТекущаяСтрока, 1) = "*" Тогда 365 | 366 | // строка вида "* Имя - Тип - Описание" 367 | СоставЗаголовкаСоставногоТипа = СтрРазделить(СтрЗаменить(ТекущаяСтрока, "*", ""), "-", Ложь); 368 | 369 | Если СоставЗаголовкаСоставногоТипа.Количество() <> 3 Тогда 370 | Сообщить("Некорректное описание параметра в строке: " + Символы.ПС + ТекущаяСтрока); 371 | КонецЕсли; 372 | 373 | ОписаниеСоставногоТипа = НовоеОписаниеПараметра(); 374 | 375 | ОписаниеСоставногоТипа.Имя = СокрЛП(СоставЗаголовкаСоставногоТипа[0]); 376 | ОписаниеСоставногоТипа.Тип = СокрЛП(СоставЗаголовкаСоставногоТипа[1]); 377 | ОписаниеСоставногоТипа.Описание = СокрЛП(СоставЗаголовкаСоставногоТипа[2]); 378 | 379 | Если ИерархияПараметров[ТекущийУровень].СоставнойТип = Неопределено Тогда 380 | ИерархияПараметров[ТекущийУровень].СоставнойТип = Новый Массив(); 381 | КонецЕсли; 382 | 383 | ИерархияПараметров[ТекущийУровень].СоставнойТип.Добавить(ОписаниеСоставногоТипа); 384 | 385 | ПредыдущийПараметр = ОписаниеСоставногоТипа; 386 | 387 | ИначеЕсли Лев(ТекущаяСтрока, 1) = "~" Тогда 388 | 389 | // строка вида "~ Значение - Описание" 390 | СоставЗаголовкаВозможногоЗначения = СтрРазделить(СтрЗаменить(ТекущаяСтрока, "~", ""), "-", Ложь); 391 | 392 | ОписаниеВозможногоЗначения = Новый Структура("Значение, Описание"); 393 | 394 | ОписаниеВозможногоЗначения.Значение = СокрЛП(СоставЗаголовкаВозможногоЗначения[0]); 395 | ОписаниеВозможногоЗначения.Описание = СокрЛП(СоставЗаголовкаВозможногоЗначения[1]); 396 | 397 | Если ПредыдущийПараметр.ВозможныеЗначения = Неопределено Тогда 398 | ПредыдущийПараметр.ВозможныеЗначения = Новый Массив(); 399 | КонецЕсли; 400 | 401 | ПредыдущийПараметр.ВозможныеЗначения.Добавить(ОписаниеВозможногоЗначения); 402 | 403 | Иначе 404 | ПредыдущийПараметр.Описание = ИерархияПараметров[ТекущийУровень].Описание + Символы.ПС + ТекущаяСтрока; 405 | КонецЕсли; 406 | 407 | КонецЦикла; 408 | 409 | КонецПроцедуры 410 | 411 | Функция НовоеОписаниеВызова() 412 | Возврат Новый Структура("Имя, Тип, Код, Описание, ВходящиеПараметры, ВозвращаемоеЗначение, КодыОтветов, ВариантыВызова, ВариантыОтвета"); 413 | КонецФункции 414 | 415 | Функция НовоеОписаниеПараметра() 416 | Возврат Новый Структура("Имя, Тип, Описание, ВозможныеЗначения, Обязательный, СоставнойТип"); 417 | КонецФункции 418 | 419 | Функция НовоеОписаниеКодаОтвета() 420 | Возврат Новый Структура("Код, Тип, Описание, ВозможныеЗначения, СоставнойТип"); 421 | КонецФункции -------------------------------------------------------------------------------- /src/Классы/specgenerator.os: -------------------------------------------------------------------------------- 1 | // Полное описание спецификации тут: 2 | // https://github.com/OAI/OpenAPI-Specification/blob/master/versions/2.0.md 3 | 4 | #Использовать json 5 | 6 | Перем ОписаниеСевриса; 7 | Перем ОбъектДанных; 8 | Перем ТэгиШаблонов; 9 | Перем ОписаниеТипов; 10 | Перем СтрокаОпределенияМассива; 11 | 12 | // Инициализация объекта класса 13 | // 14 | // Параметры: 15 | // ВнутреннееОписаниеСервиса - Структура - внутреннее описание сервиса от metadataparser.os 16 | // 17 | Процедура ПриСозданииОбъекта(ВнутреннееОписаниеСервиса) 18 | 19 | ОписаниеСевриса = ВнутреннееОписаниеСервиса; 20 | 21 | ОбъектДанных = НовыйБазовыйОбъект(); 22 | 23 | ТэгиШаблонов = Новый Массив; 24 | 25 | ОписаниеТипов = Новый Соответствие; 26 | 27 | СтрокаОпределенияМассива = "Массив из "; 28 | 29 | КонецПроцедуры 30 | 31 | #Область ПрограммныйИнтерфейс 32 | 33 | // Интерпретирует описание сервиса конфигурации 1С 34 | // в метаданные спецификации "Swagger 2.0" 35 | // 36 | Процедура ПрочитатьОписаниеСервиса() Экспорт 37 | 38 | // заполняем корневые свойства 39 | ОбъектДанных.host = ОписаниеСевриса.Хост; 40 | ОбъектДанных.basePath = ?( 41 | ЗначениеЗаполнено(ОписаниеСевриса.База1С), 42 | СтрШаблон("/%1/hs%2", ОписаниеСевриса.База1С, ОписаниеСевриса.КорневойURL), 43 | ОписаниеСевриса.КорневойURL 44 | ); 45 | 46 | // заполняем info 47 | ОбъектДанных.info = НовыйБлокИнфо(); 48 | 49 | ОбъектДанных.info.title = ОписаниеСевриса.Имя; 50 | ОбъектДанных.info.description = ОписаниеСевриса.Описание; 51 | ОбъектДанных.info.version = ОписаниеСевриса.Версия; 52 | 53 | // заполняем paths 54 | Для Каждого ШаблонURL Из ОписаниеСевриса.ШаблоныURL Цикл 55 | ПрочитатьШаблонURL(ШаблонURL); 56 | КонецЦикла; 57 | 58 | // заполняем tags 59 | Для Каждого ИмяТэга Из ТэгиШаблонов Цикл 60 | 61 | Тэг = НовыйБлокТэга(); 62 | 63 | Тэг.name = ИмяТэга; 64 | Тэг.description = ""; 65 | 66 | ОбъектДанных.tags.Добавить(Тэг); 67 | 68 | КонецЦикла; 69 | 70 | // заполняем definitions 71 | ОбъектДанных.definitions = ОписаниеТипов; 72 | 73 | КонецПроцедуры 74 | 75 | // Сохраняет спецификацию в файл 76 | // 77 | // Параметры: 78 | // ПутьВыгрузки - Строка - каталог для сохранения файла спецификации 79 | // Формат - Строка - пока только умеет в json 80 | // 81 | Процедура СохранитьСпецификацию(ПутьВыгрузки, Формат = "json") Экспорт 82 | 83 | Если Формат = "json" Тогда 84 | 85 | ПарсерJSON = Новый ПарсерJSON(); 86 | 87 | Текст = ПарсерJSON.ЗаписатьJSON(ОбъектДанных); 88 | 89 | ИмяФайла = ОбъектДанных.info.title + ".json"; 90 | 91 | ПолныйПутьКФайлу = ОбъединитьПути(ПутьВыгрузки, ИмяФайла); 92 | 93 | ЗаписьТекста = Новый ЗаписьТекста(ПолныйПутьКФайлу); 94 | 95 | ЗаписьТекста.Записать(Текст); 96 | 97 | Иначе 98 | 99 | Сообщить("Неизвестный формат!"); 100 | 101 | КонецЕсли; 102 | 103 | КонецПроцедуры 104 | 105 | // Получает спецификацию в виде строки 106 | // 107 | // Параметры: 108 | // ПутьВыгрузки - Строка - каталог для сохранения файла спецификации 109 | // Формат - Строка - пока только умеет в json 110 | // 111 | // Возвращаемое значение: 112 | // Строка - спецификация 113 | // 114 | Функция ПолучитьСпецификацию(Формат = "json") Экспорт 115 | 116 | Результат = Неопределено; 117 | 118 | Если Формат = "json" Тогда 119 | 120 | ПарсерJSON = Новый ПарсерJSON(); 121 | 122 | Результат = ПарсерJSON.ЗаписатьJSON(ОбъектДанных); 123 | 124 | Иначе 125 | 126 | Сообщить("Неизвестный формат!"); 127 | 128 | КонецЕсли; 129 | 130 | Возврат Результат; 131 | 132 | КонецФункции 133 | 134 | #КонецОбласти 135 | 136 | #Область ЧтениеВнутреннихОписаний 137 | 138 | Процедура ПрочитатьШаблонURL(ШаблонURL) 139 | 140 | ПоддерживаемыеМетоды = ПоддерживаемыеМетодыСпецификации(); 141 | 142 | // проверим тэг 143 | Если ТэгиШаблонов.Найти(ШаблонURL.Тэг) = Неопределено Тогда 144 | ТэгиШаблонов.Добавить(ШаблонURL.Тэг); 145 | КонецЕсли; 146 | 147 | // заполняем path 148 | ДанныеПути = Новый Структура; 149 | 150 | Для Каждого МетодШаблона Из ШаблонURL.Методы Цикл 151 | 152 | ЕстьПараметрыВПути = (ШаблонURL.ПараметрыВПути <> Неопределено); 153 | 154 | // заполняем operation object 155 | Метод = НовыйБлокМетода(); 156 | 157 | Метод.tags.Добавить(ШаблонURL.Тэг); 158 | Метод.summary = МетодШаблона.Резюме; 159 | Метод.description = МетодШаблона.Описание; 160 | 161 | // опишем параметры 162 | Если МетодШаблона.ВходящиеПараметры <> Неопределено Тогда 163 | 164 | Для Каждого ОписаниеПараметра Из МетодШаблона.ВходящиеПараметры Цикл 165 | 166 | ПараметрМетода = НовыйБлокПараметраМетода(); 167 | 168 | ПараметрМетода.name = ОписаниеПараметра.Имя; 169 | ПараметрМетода.description = ОписаниеПараметра.Описание; 170 | 171 | ТипДанныхПараметра = ПривестиКТипу(ОписаниеПараметра.Тип); 172 | 173 | Если НРег(ОписаниеПараметра.Имя) = "body" Тогда 174 | 175 | ПараметрМетода.in = "body"; 176 | ПараметрМетода.required = Истина; 177 | 178 | Если ТипДанныхПараметра.type <> "array" Тогда 179 | ПараметрМетода.schema = НовыйУказательНаТип(ТипДанныхПараметра.type); 180 | Иначе 181 | ПараметрМетода.schema = НовыйУказательНаТип(ТипДанныхПараметра.items.type, Истина); 182 | КонецЕсли; 183 | 184 | ИначеЕсли ЕстьПараметрыВПути И ШаблонURL.ПараметрыВПути.Найти(ОписаниеПараметра.Имя) <> Неопределено Тогда 185 | 186 | ПараметрМетода.in = "path"; 187 | ПараметрМетода.required = Истина; 188 | ЗаполнитьЗначенияСвойств(ПараметрМетода, ТипДанныхПараметра); 189 | 190 | Иначе 191 | 192 | ПараметрМетода.in = "query"; 193 | ПараметрМетода.required = ОписаниеПараметра.Обязательный; 194 | ЗаполнитьЗначенияСвойств(ПараметрМетода, ТипДанныхПараметра); 195 | 196 | КонецЕсли; 197 | 198 | Если ЗначениеЗаполнено(ОписаниеПараметра.ВозможныеЗначения) Тогда 199 | 200 | Если ТипДанныхПараметра.type <> "array" Тогда 201 | ПараметрМетода.Вставить("enum", Новый Массив); 202 | ПеречислениеЗначений = ПараметрМетода.enum; 203 | Иначе 204 | ПараметрМетода.items.Вставить("enum", Новый Массив); 205 | ПеречислениеЗначений = ПараметрМетода.items.enum; 206 | КонецЕсли; 207 | 208 | Для Каждого ОписаниеВозможногоЗначения Из ОписаниеПараметра.ВозможныеЗначения Цикл 209 | ПеречислениеЗначений.Добавить(ОписаниеВозможногоЗначения.Значение); 210 | КонецЦикла; 211 | 212 | КонецЕсли; 213 | 214 | Если НЕ ЗначениеЗаполнено(ПараметрМетода.type) Тогда 215 | ПараметрМетода.Удалить("type"); 216 | КонецЕсли; 217 | 218 | Если НЕ ЗначениеЗаполнено(ПараметрМетода.format) Тогда 219 | ПараметрМетода.Удалить("format"); 220 | КонецЕсли; 221 | 222 | Если НЕ ЗначениеЗаполнено(ПараметрМетода.schema) Тогда 223 | ПараметрМетода.Удалить("schema"); 224 | КонецЕсли; 225 | 226 | Если НЕ ЗначениеЗаполнено(ПараметрМетода.items) Тогда 227 | ПараметрМетода.Удалить("items"); 228 | КонецЕсли; 229 | 230 | СгенерироватьОписаниеТипов(ОписаниеПараметра); 231 | 232 | Метод.parameters.Добавить(ПараметрМетода); 233 | 234 | КонецЦикла; 235 | 236 | ИначеЕсли ШаблонURL.ПараметрыВПути <> Неопределено Тогда 237 | 238 | Для Каждого ИмяПараметра Из ШаблонURL.ПараметрыВПути Цикл 239 | 240 | ПараметрМетода = НовыйБлокПараметраМетода(); 241 | 242 | ПараметрМетода.name = ИмяПараметра; 243 | ПараметрМетода.in = "path"; 244 | ПараметрМетода.required = Истина; 245 | 246 | Метод.parameters.Добавить(ПараметрМетода); 247 | 248 | КонецЦикла; 249 | 250 | Иначе 251 | Метод.parameters = Новый Массив; 252 | КонецЕсли; 253 | 254 | // опишем варианты вызова 255 | Если МетодШаблона.ВариантыВызова <> Неопределено Тогда 256 | 257 | Для Каждого ОписаниеВарианта Из МетодШаблона.ВариантыВызова Цикл 258 | Метод.consumes.Добавить(ОписаниеВарианта); 259 | КонецЦикла; 260 | 261 | КонецЕсли; 262 | 263 | // опишем варианты ответа 264 | Если МетодШаблона.ВариантыОтвета <> Неопределено Тогда 265 | 266 | Для Каждого ОписаниеВарианта Из МетодШаблона.ВариантыОтвета Цикл 267 | Метод.produces.Добавить(ОписаниеВарианта); 268 | КонецЦикла; 269 | 270 | КонецЕсли; 271 | 272 | // опишем возвращаемое значение 273 | Если МетодШаблона.ВозвращаемоеЗначение <> Неопределено Тогда 274 | // TODO: 275 | КонецЕсли; 276 | 277 | // опишем коды ответов 278 | Если МетодШаблона.КодыОтветов = Неопределено Тогда 279 | 280 | // ответ всегда 200... 281 | ОтветЗапроса = НовыйБлокОтвета(); 282 | ОтветЗапроса.description = "successful operation"; 283 | ОтветЗапроса.Удалить("schema"); 284 | Метод.responses.Вставить("200", ОтветЗапроса); 285 | 286 | Иначе 287 | 288 | Для Каждого КодОтвета Из МетодШаблона.КодыОтветов Цикл 289 | 290 | ОтветЗапроса = НовыйБлокОтвета(); 291 | ОтветЗапроса.description = КодОтвета.Описание; 292 | 293 | Если ЗначениеЗаполнено(КодОтвета.Тип) Тогда 294 | 295 | ТипДанныхПараметра = ПривестиКТипу(КодОтвета.Тип); 296 | 297 | Если ТипДанныхПараметра.type <> "array" Тогда 298 | ОтветЗапроса.schema = НовыйУказательНаТип(ТипДанныхПараметра.type); 299 | Иначе 300 | ОтветЗапроса.schema = НовыйУказательНаТип(ТипДанныхПараметра.items.type, Истина); 301 | КонецЕсли; 302 | 303 | СгенерироватьОписаниеТипов(КодОтвета); 304 | 305 | КонецЕсли; 306 | 307 | Если НЕ ЗначениеЗаполнено(ОтветЗапроса.schema) Тогда 308 | ОтветЗапроса.Удалить("schema"); 309 | КонецЕсли; 310 | 311 | Метод.responses.Вставить(КодОтвета.Код, ОтветЗапроса); 312 | 313 | КонецЦикла; 314 | 315 | КонецЕсли; 316 | 317 | // 318 | ТекущийМетод = НРег(МетодШаблона.Метод); 319 | 320 | Если ТекущийМетод = "any" Тогда 321 | 322 | // если в конфигурации выбран метод "Любой" 323 | // то клонируем его на все поддерживаемые в спецификации 324 | Для Каждого ПоддерживаемыйМетод Из ПоддерживаемыеМетоды Цикл 325 | ДанныеПути.Вставить(ПоддерживаемыйМетод, Метод); 326 | КонецЦикла; 327 | 328 | Иначе 329 | ДанныеПути.Вставить(ТекущийМетод, Метод); 330 | КонецЕсли; 331 | 332 | КонецЦикла; 333 | 334 | ОбъектДанных.paths.Вставить(ШаблонURL.Путь, ДанныеПути); 335 | 336 | КонецПроцедуры 337 | 338 | Процедура СгенерироватьОписаниеТипов(ОписаниеПараметра) 339 | 340 | Если ЗначениеЗаполнено(ОписаниеПараметра.СоставнойТип) Тогда 341 | 342 | ОпределениеСоставногоТипа = НовыйБлокОпределений(); 343 | ОпределениеСоставногоТипа.type = "object"; 344 | ОпределениеСоставногоТипа.properties = Новый Соответствие; 345 | 346 | Для Каждого ВложенныйПараметр Из ОписаниеПараметра.СоставнойТип Цикл 347 | 348 | ТипДанныхПараметра = ПривестиКТипу(ВложенныйПараметр.Тип); 349 | 350 | Если ВложенныйПараметр.СоставнойТип = Неопределено Тогда 351 | 352 | СвойствоТипа = НовыйБлокСвойстваТипа(); 353 | ЗаполнитьЗначенияСвойств(СвойствоТипа, ТипДанныхПараметра); 354 | СвойствоТипа.description = ВложенныйПараметр.Описание; 355 | 356 | Если ЗначениеЗаполнено(ВложенныйПараметр.ВозможныеЗначения) Тогда 357 | 358 | Если ТипДанныхПараметра.type <> "array" Тогда 359 | СвойствоТипа.Вставить("enum", Новый Массив); 360 | ПеречислениеЗначений = СвойствоТипа.enum; 361 | Иначе 362 | СвойствоТипа.items.Вставить("enum", Новый Массив); 363 | ПеречислениеЗначений = СвойствоТипа.items.enum; 364 | КонецЕсли; 365 | 366 | Для Каждого ОписаниеВозможногоЗначения Из ВложенныйПараметр.ВозможныеЗначения Цикл 367 | ПеречислениеЗначений.Добавить(ОписаниеВозможногоЗначения.Значение); 368 | КонецЦикла; 369 | 370 | КонецЕсли; 371 | 372 | Если НЕ ЗначениеЗаполнено(СвойствоТипа.type) Тогда 373 | СвойствоТипа.Удалить("type"); 374 | КонецЕсли; 375 | 376 | Если НЕ ЗначениеЗаполнено(СвойствоТипа.format) Тогда 377 | СвойствоТипа.Удалить("format"); 378 | КонецЕсли; 379 | 380 | Если НЕ ЗначениеЗаполнено(СвойствоТипа.items) Тогда 381 | СвойствоТипа.Удалить("items"); 382 | КонецЕсли; 383 | 384 | ОпределениеСоставногоТипа.properties.Вставить(ВложенныйПараметр.Имя, СвойствоТипа); 385 | 386 | Иначе 387 | 388 | СгенерироватьОписаниеТипов(ВложенныйПараметр); 389 | 390 | Если ТипДанныхПараметра.type <> "array" Тогда 391 | ОпределениеСоставногоТипа.properties.Вставить(ВложенныйПараметр.Имя, НовыйУказательНаТип(ТипДанныхПараметра.type)); 392 | Иначе 393 | ОпределениеСоставногоТипа.properties.Вставить(ВложенныйПараметр.Имя, НовыйУказательНаТип(ТипДанныхПараметра.items.type, Истина)); 394 | КонецЕсли; 395 | 396 | КонецЕсли; 397 | 398 | КонецЦикла; 399 | 400 | ОписаниеТипов.Вставить(СтрЗаменить(ОписаниеПараметра.Тип, СтрокаОпределенияМассива, ""), ОпределениеСоставногоТипа); 401 | 402 | КонецЕсли; 403 | 404 | КонецПроцедуры 405 | 406 | #КонецОбласти 407 | 408 | #Область ОписаниеМетаданных 409 | 410 | // Описывает базовую стуктуру данных 411 | // 412 | // Возвращаемое значение: 413 | // Структура - структура данных 414 | // 415 | Функция НовыйБазовыйОбъект() 416 | 417 | Результат = Новый Структура; 418 | 419 | Результат.Вставить("swagger", "2.0"); 420 | Результат.Вставить("info"); 421 | Результат.Вставить("host"); 422 | Результат.Вставить("basePath"); 423 | Результат.Вставить("tags", Новый Массив); 424 | Результат.Вставить("schemes", Новый Массив); 425 | Результат.Вставить("paths", Новый Соответствие); 426 | //Результат.Вставить("securityDefinitions"); 427 | Результат.Вставить("definitions"); 428 | Результат.Вставить("externalDocs", Новый Соответствие); 429 | 430 | Результат["externalDocs"].Вставить("description", "Find out more about Swagger"); 431 | Результат["externalDocs"].Вставить("url", "http://swagger.io"); 432 | Результат["schemes"].Добавить("http"); 433 | Результат["schemes"].Добавить("https"); 434 | Возврат Результат; 435 | 436 | КонецФункции 437 | 438 | // Описывает блок общей информации 439 | // 440 | // Возвращаемое значение: 441 | // Структура - структура данных 442 | // 443 | Функция НовыйБлокИнфо() 444 | 445 | Результат = Новый Структура; 446 | 447 | Результат.Вставить("description"); 448 | Результат.Вставить("version"); 449 | Результат.Вставить("title"); 450 | Результат.Вставить("termsOfService"); 451 | //Результат.Вставить("contact"); 452 | //Результат.Вставить("license"); 453 | 454 | Возврат Результат; 455 | 456 | КонецФункции 457 | 458 | // Описывает блок контактов разработчиков 459 | // 460 | // Возвращаемое значение: 461 | // Структура - структура данных 462 | // 463 | Функция НовыйБлокКонтактов() 464 | 465 | Результат = Новый Структура; 466 | 467 | Результат.Вставить("email"); 468 | 469 | Возврат Результат; 470 | 471 | КонецФункции 472 | 473 | // Описывает блок лицензии 474 | // 475 | // Возвращаемое значение: 476 | // Структура - структура данных 477 | // 478 | Функция НовыйБлокЛицензии() 479 | 480 | Результат = Новый Структура; 481 | 482 | Результат.Вставить("name"); 483 | Результат.Вставить("url"); 484 | 485 | Возврат Результат; 486 | 487 | КонецФункции 488 | 489 | // Описывает блок данных тэга 490 | // 491 | // Возвращаемое значение: 492 | // Структура - структура данных 493 | // 494 | Функция НовыйБлокТэга() 495 | 496 | Результат = Новый Структура; 497 | 498 | Результат.Вставить("name"); 499 | Результат.Вставить("description"); 500 | //Результат.Вставить("externalDocs"); 501 | 502 | Возврат Результат; 503 | 504 | КонецФункции 505 | 506 | // Описывает блок метода сервиса 507 | // 508 | // Возвращаемое значение: 509 | // Структура - структура данных 510 | // 511 | Функция НовыйБлокМетода() 512 | 513 | Результат = Новый Структура; 514 | 515 | Результат.Вставить("tags", Новый Массив); 516 | Результат.Вставить("summary"); 517 | Результат.Вставить("description"); 518 | //Результат.Вставить("operationId"); 519 | Результат.Вставить("consumes", Новый Массив); 520 | Результат.Вставить("produces", Новый Массив); 521 | Результат.Вставить("parameters", Новый Массив); 522 | Результат.Вставить("responses", Новый Соответствие); 523 | //Результат.Вставить("security"); 524 | 525 | Возврат Результат; 526 | 527 | КонецФункции 528 | 529 | // Описывает блок параметра метода сервиса 530 | // 531 | // Возвращаемое значение: 532 | // Структура - структура данных 533 | // 534 | Функция НовыйБлокПараметраМетода() 535 | 536 | Результат = Новый Структура; 537 | 538 | Результат.Вставить("name"); 539 | Результат.Вставить("in"); 540 | Результат.Вставить("description"); 541 | Результат.Вставить("required"); 542 | Результат.Вставить("type"); 543 | Результат.Вставить("format"); 544 | Результат.Вставить("schema"); 545 | Результат.Вставить("items"); 546 | 547 | Возврат Результат; 548 | 549 | КонецФункции 550 | 551 | // Описывает блок ссылки на документацию 552 | // 553 | // Возвращаемое значение: 554 | // Структура - структура данных 555 | // 556 | Функция НовыйБлокСсылкиНаДокументацию() 557 | 558 | Результат = Новый Структура; 559 | 560 | Результат.Вставить("description"); 561 | Результат.Вставить("url"); 562 | 563 | Возврат Результат; 564 | 565 | КонецФункции 566 | 567 | // Описывает блок определений 568 | // 569 | // Возвращаемое значение: 570 | // Структура - структура данных 571 | // 572 | Функция НовыйБлокОпределений() 573 | 574 | Результат = Новый Структура; 575 | 576 | Результат.Вставить("type"); 577 | Результат.Вставить("properties"); 578 | 579 | Возврат Результат; 580 | 581 | КонецФункции 582 | 583 | // Описывает блок свойства типа 584 | // 585 | // Возвращаемое значение: 586 | // Структура - структура данных 587 | // 588 | Функция НовыйБлокСвойстваТипа() 589 | 590 | Результат = Новый Структура; 591 | 592 | Результат.Вставить("type"); 593 | Результат.Вставить("format"); 594 | Результат.Вставить("description"); 595 | Результат.Вставить("items"); 596 | 597 | Возврат Результат; 598 | 599 | КонецФункции 600 | 601 | // Описывает блок ответа 602 | // 603 | // Возвращаемое значение: 604 | // Структура - структура данных 605 | // 606 | Функция НовыйБлокОтвета() 607 | 608 | Результат = Новый Структура; 609 | 610 | Результат.Вставить("description"); 611 | Результат.Вставить("schema"); 612 | 613 | Возврат Результат; 614 | 615 | КонецФункции 616 | 617 | // Описывает указатель на тип 618 | // 619 | // Параметры: 620 | // Тип - Строка - тип данных 621 | // ЭтоМассив - Булево - признак массива 622 | // 623 | // Возвращаемое значение: 624 | // Соответствие - указатель 625 | // 626 | Функция НовыйУказательНаТип(Тип, ЭтоМассив = Ложь) 627 | 628 | Результат = Новый Соответствие; 629 | 630 | Если ЭтоМассив Тогда 631 | ОписаниеМассива = Новый Соответствие; 632 | ОписаниеМассива.Вставить("$ref", СтрШаблон("#/definitions/%1", Тип)); 633 | Результат.Вставить("items", ОписаниеМассива); 634 | Результат.Вставить("type", "array"); 635 | Иначе 636 | Результат.Вставить("$ref", СтрШаблон("#/definitions/%1", Тип)); 637 | КонецЕсли; 638 | 639 | Возврат Результат; 640 | 641 | КонецФункции 642 | 643 | #КонецОбласти 644 | 645 | #Область ПрочиеМетоды 646 | 647 | Функция ПривестиКТипу(Знач Текст) 648 | 649 | Результат = Новый Структура("type, format, items"); 650 | 651 | Если СтрНачинаетсяС(Текст, СтрокаОпределенияМассива) Тогда 652 | Результат.type = "array"; 653 | Результат.items = Новый Структура("type, format"); 654 | ТипФормат = Результат.items; 655 | Текст = СтрЗаменить(Текст, СтрокаОпределенияМассива, ""); 656 | Иначе 657 | ТипФормат = Результат; 658 | КонецЕсли; 659 | 660 | Ключ = НРег(Текст); 661 | 662 | Если Ключ = "строка" Тогда 663 | ТипФормат.type = "string"; 664 | ИначеЕсли Ключ = "число" Тогда 665 | ТипФормат.type = "number"; 666 | ИначеЕсли Ключ = "булево" Тогда 667 | ТипФормат.type = "boolean"; 668 | ИначеЕсли Ключ = "файл" Тогда 669 | ТипФормат.type = "file"; 670 | ИначеЕсли Ключ = "дата" Тогда 671 | ТипФормат.type = "string"; 672 | ТипФормат.format = "date"; 673 | Иначе 674 | ТипФормат.type = Текст; 675 | КонецЕсли; 676 | 677 | Возврат Результат; 678 | 679 | КонецФункции 680 | 681 | Функция ПривестиКФормату(Текст) 682 | 683 | Ключ = НРег(Текст); 684 | 685 | Если Ключ = "строка" Тогда 686 | Возврат "string"; 687 | ИначеЕсли Ключ = "число" Тогда 688 | Возврат "number"; 689 | ИначеЕсли Ключ = "булево" Тогда 690 | Возврат "boolean"; 691 | ИначеЕсли Ключ = "массив" Тогда 692 | Возврат "array"; 693 | ИначеЕсли Ключ = "файл" Тогда 694 | Возврат "file"; 695 | Иначе 696 | Возврат ""; 697 | КонецЕсли; 698 | 699 | КонецФункции 700 | 701 | Функция ПоддерживаемыеМетодыСпецификации() 702 | 703 | Результат = Новый Массив; 704 | 705 | Результат.Добавить("get"); 706 | Результат.Добавить("post"); 707 | Результат.Добавить("put"); 708 | Результат.Добавить("patch"); 709 | Результат.Добавить("delete"); 710 | Результат.Добавить("head"); 711 | Результат.Добавить("trace"); 712 | 713 | Возврат Результат; 714 | 715 | КонецФункции 716 | 717 | #КонецОбласти --------------------------------------------------------------------------------