1
0
mirror of https://github.com/Bayselonarrend/OpenIntegrations.git synced 2025-03-21 21:27:27 +02:00

Доработка формирования описаний Swagger

This commit is contained in:
Anton Titovets 2025-02-05 21:03:33 +03:00
parent 5b2cdb288e
commit 8c12fd89d9
6 changed files with 7126 additions and 6655 deletions
service/dictionaries
src/ru
OInt/tools
OPI/src/CommonModules
OPI_Инструменты
OPI_ПолучениеДанныхТестов

File diff suppressed because it is too large Load Diff

@ -254,9 +254,9 @@
Иначе
ТекстВыполнения = СтруктураВыполнения["Результат"];
Выполнить(ТекстВыполнения);
Ответ = Новый Структура("result,data", Истина, Ответ);

@ -42,6 +42,7 @@
// Раскомментировать, если выполняется OneScript
#Использовать "./internal"
#Использовать "../../data"
#Использовать asserts
#Область СлужебныйПрограммныйИнтерфейс
@ -537,6 +538,12 @@
Если Записывать Тогда
ЗаписатьВызовCLI(Библиотека, Метод, Опции);
Попытка
ЗаписатьСтраницуSwagger(Библиотека, Метод, Опции);
Исключение
Сообщить("Swagger: " + ОписаниеОшибки());
КонецПопытки;
КонецЕсли;
Попытка
@ -2189,9 +2196,9 @@
Функция ПолучитьОбщийМодуль(Знач Имя)
Модуль = Вычислить(Имя);
Возврат Модуль;
@ -2477,14 +2484,219 @@
Если Не OPI_Инструменты.ЭтоOneScript() Тогда
Возврат;
КонецЕсли;
КаталогСтраниц = КаталогSwagger();
КаталогБиблиотеки = КаталогСтраниц + Библиотека + "/";
ФайлМетода = КаталогБиблиотеки + Метод + ".json";
ПростейшийМетод = ОпределитьПростейшийHttpМетод(Опции);
СоставОПИ = Новый("LibraryComposition");
СоставБиблиотеки = СоставОПИ.ПолучитьСостав(Библиотека);
СоставМетода = СоставБиблиотеки.НайтиСтроки(Новый Структура("Метод", Метод));
ТаблицаОпций = Новый ТаблицаЗначений;
ТаблицаОпций.Колонки.Добавить("Ключ");
ТаблицаОпций.Колонки.Добавить("Значение");
ТаблицаОпций.Колонки.Добавить("Описание");
Для Каждого СтрокаСостава Из СоставМетода Цикл
НоваяСтрока = ТаблицаОпций.Добавить();
НоваяСтрока.Ключ = СтрЗаменить(СтрокаСостава.Параметр, "--", "");
НоваяСтрока.Описание = СтрокаСостава.Описание;
OPI_Инструменты.ПолеКоллекцииСуществует(Опции, НоваяСтрока.Опция, НоваяСтрока.Значение);
КонецЦикла;
СтруктураОписания = Новый Структура;
Если ПростейшийМетод = "GET" Тогда
СтруктураОписания.Вставить("get", ПолучитьОписаниеGet(ТаблицаОпций));
КонецЕсли;
КаталогСтраниц = КаталогSwagger();
ЕстьВариантJSON = ПростейшийМетод = "GET" Или ПростейшийМетод = "POST";
СтруктураОписания.Вставить("post", ПолучитьОписаниеPost(ТаблицаОпций, ЕстьВариантJSON));
OPI_Инструменты.ЗаписатьJSONФайл(СтруктураОписания, ФайлМетода);
КонецПроцедуры
Функция ОпределитьПростейшийHttpМетод(Знач Опции)
ЕстьДвоичные = Ложь;
ЕстьJSON = Ложь;
Для Каждого Опция Из Опции Цикл
Значение = Опция.Значение;
Ключ = Опция.Ключ;
Если Ключ = "out" Тогда
Продолжить;
КонецЕсли;
Если ТипЗнч(Значение) = Тип("ДвоичныеДанные") Тогда
ЕстьДвоичные = Истина;
Прервать;
ИначеЕсли ТипЗнч(Значение) = Тип("Строка") Тогда
ФайлЗначения = Новый Файл(Значение);
Если ФайлЗначения.Существует() И ФайлЗначения.ЭтоФайл() Тогда
ЕстьДвоичные = Истина;
Прервать;
Иначе
OPI_ПреобразованиеТипов.ПолучитьКоллекцию(Значение);
КонецЕсли;
КонецЕсли;
ТекущийТип = ТипЗнч(Значение);
Если ТекущийТип = Тип("Соответствие") Или ТекущийТип = Тип("Структура") Тогда
ЕстьJSON = Истина;
КонецЕсли;
КонецЦикла;
Если Не ЕстьДвоичные И Не ЕстьJSON Тогда
Метод = "GET";
ИначеЕсли Не ЕстьДвоичные Тогда
Метод = "POST";
Иначе
Метод = "FORM";
КонецЕсли;
Возврат Метод;
КонецФункции
Функция ПолучитьОписаниеGet(Знач ТаблицаОпций)
СтруктураОписания = Новый Структура;
СтруктураОписания.Вставить("summary", "Выполнение через метод GET");
МассивПараметров = Новый Массив;
СоответствиеТипов = СоответствиеТиповSwagger();
Для Каждого Опция Из ТаблицаОпций Цикл
Ключ = Опция.Ключ;
Значение = Опция.Значение;
Описание = Опция.Описание;
СтруктураПараметра = Новый Структура;
СтруктураПараметра.Вставить("name", Ключ);
СтруктураПараметра.Вставить("in" , "query");
ТипSwagger = СоответствиеТипов.Получить(ТипЗнч(Значение));
ТипSwagger = ?(ЗначениеЗаполнено(ТипSwagger), ТипSwagger, СоответствиеТипов.Получить(Тип("Строка")));
СтруктураПараметра.Вставить("schema" , ТипSwagger);
СтруктураПараметра.Вставить("description", Описание);
МассивПараметров.Добавить(СтруктураПараметра);
КонецЦикла;
СтруктураОписания.Вставить("parameters", МассивПараметров);
Возврат СтруктураОписания;
КонецФункции
Функция ПолучитьОписаниеPost(Знач ТаблицаОпций, Знач ЕстьВариантJSON)
Описание = "Выполнение через метод POST (%1)";
Описание = СтрШаблон(Описание, ?(ЕстьВариантJSON, "JSON или form-data", "form-data"));
СтруктураОписания = Новый Структура;
СтруктураОписания.Вставить("summary", Описание);
СтруктураТела = Новый Структура;
СтруктураТела.Вставить("required", Истина);
СоответствиеВариантовТела = СформироватьВариантыТела(ТаблицаОпций, ЕстьВариантJSON);
СтруктураТела.Вставить("content", СоответствиеВариантовТела);
СтруктураОписания.Вставить("requestBody", СтруктураТела);
Возврат СтруктураОписания;
КонецФункции
Функция СформироватьВариантыТела(Знач ТаблицаОпций, Знач ЕстьВариантJSON)
СоответствиеТипов = СоответствиеТиповSwagger();
СтруктураТела = Новый Структура;
СтруктураСхемы = Новый Структура;
СтруктураСхемы.Вставить("type", "object");
СтруктураСвойств = Новый Структура;
Для Каждого Опция Из ТаблицаОпций Цикл
Ключ = Опция.Ключ;
Значение = Опция.Значение;
Описание = Опция.Описание;
СтруктураСвойства = Новый Структура;
ТипSwagger = СоответствиеТипов.Получить(ТипЗнч(Значение));
ТипSwagger = ?(ЗначениеЗаполнено(ТипSwagger), ТипSwagger, СоответствиеТипов.Получить(Тип("Строка")));
СтруктураСвойства.Вставить("type" , ТипSwagger);
СтруктураСвойства.Вставить("description", Описание);
СтруктураСвойств.Вставить(Ключ, СтруктураСвойства);
КонецЦикла;
СтруктураСхемы.Вставить("properties", СтруктураСвойств);
СтруктураТела.Вставить("schema", СтруктураСхемы);
СоответствиеВариантов = Новый Соответствие;
СоответствиеВариантов.Вставить("multipart/form-data", СтруктураТела);
Если ЕстьВариантJSON Тогда
СоответствиеВариантов.Вставить("application/json", СтруктураТела);
КонецЕсли;
Возврат СоответствиеВариантов;
КонецФункции
Функция СоответствиеТиповSwagger()
СоответствиеТипов = Новый Соответствие;
СоответствиеТипов.Вставить(Тип("Строка") , Новый Структура("type", "string"));
СоответствиеТипов.Вставить(Тип("Дата") , Новый Структура("type,format", "string", "date-time"));
СоответствиеТипов.Вставить(Тип("Число") , Новый Структура("type", "number"));
СоответствиеТипов.Вставить(Тип("Булево") , Новый Структура("type", "boolean"));
СоответствиеТипов.Вставить(Тип("Массив") , Новый Структура("type,items", "array", Новый Структура("type","string")));
СоответствиеТипов.Вставить(Тип("Структура") , Новый Структура("type", "object"));
СоответствиеТипов.Вставить(Тип("Соответствие") , Новый Структура("type", "object"));
СоответствиеТипов.Вставить(Тип("ДвоичныеДанные"), Новый Структура("type", "file"));
Возврат СоответствиеТипов;
КонецФункции
Функция КаталогSwagger()
Возврат "./docs/ru/openapi/"
Возврат "./docs/ru/openapi/";
КонецФункции
#КонецОбласти

@ -520,6 +520,16 @@
КонецФункции
Процедура ЗаписатьJSONФайл(Данные, Путь) Экспорт
ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.ОткрытьФайл(Путь, , , Новый ПараметрыЗаписиJSON(, Символы.Таб));
ЗаписатьJSON(ЗаписьJSON, Данные);
ЗаписьJSON.Закрыть();
КонецПроцедуры
#КонецОбласти
#Область XML

@ -520,6 +520,16 @@
КонецФункции
Процедура ЗаписатьJSONФайл(Данные, Путь) Экспорт
ЗаписьJSON = Новый ЗаписьJSON;
ЗаписьJSON.ОткрытьФайл(Путь, , , Новый ПараметрыЗаписиJSON(, Символы.Таб));
ЗаписатьJSON(ЗаписьJSON, Данные);
ЗаписьJSON.Закрыть();
КонецПроцедуры
#КонецОбласти
#Область XML

@ -42,6 +42,7 @@
// Раскомментировать, если выполняется OneScript
// #Использовать "./internal"
// #Использовать "../../data"
// #Использовать asserts
#Область СлужебныйПрограммныйИнтерфейс
@ -537,6 +538,12 @@
Если Записывать Тогда
ЗаписатьВызовCLI(Библиотека, Метод, Опции);
Попытка
ЗаписатьСтраницуSwagger(Библиотека, Метод, Опции);
Исключение
Сообщить("Swagger: " + ОписаниеОшибки());
КонецПопытки;
КонецЕсли;
Попытка
@ -2477,14 +2484,219 @@
Если Не OPI_Инструменты.ЭтоOneScript() Тогда
Возврат;
КонецЕсли;
КаталогСтраниц = КаталогSwagger();
КаталогБиблиотеки = КаталогСтраниц + Библиотека + "/";
ФайлМетода = КаталогБиблиотеки + Метод + ".json";
ПростейшийМетод = ОпределитьПростейшийHttpМетод(Опции);
СоставОПИ = Новый("LibraryComposition");
СоставБиблиотеки = СоставОПИ.ПолучитьСостав(Библиотека);
СоставМетода = СоставБиблиотеки.НайтиСтроки(Новый Структура("Метод", Метод));
ТаблицаОпций = Новый ТаблицаЗначений;
ТаблицаОпций.Колонки.Добавить("Ключ");
ТаблицаОпций.Колонки.Добавить("Значение");
ТаблицаОпций.Колонки.Добавить("Описание");
Для Каждого СтрокаСостава Из СоставМетода Цикл
НоваяСтрока = ТаблицаОпций.Добавить();
НоваяСтрока.Ключ = СтрЗаменить(СтрокаСостава.Параметр, "--", "");
НоваяСтрока.Описание = СтрокаСостава.Описание;
OPI_Инструменты.ПолеКоллекцииСуществует(Опции, НоваяСтрока.Опция, НоваяСтрока.Значение);
КонецЦикла;
СтруктураОписания = Новый Структура;
Если ПростейшийМетод = "GET" Тогда
СтруктураОписания.Вставить("get", ПолучитьОписаниеGet(ТаблицаОпций));
КонецЕсли;
КаталогСтраниц = КаталогSwagger();
ЕстьВариантJSON = ПростейшийМетод = "GET" Или ПростейшийМетод = "POST";
СтруктураОписания.Вставить("post", ПолучитьОписаниеPost(ТаблицаОпций, ЕстьВариантJSON));
OPI_Инструменты.ЗаписатьJSONФайл(СтруктураОписания, ФайлМетода);
КонецПроцедуры
Функция ОпределитьПростейшийHttpМетод(Знач Опции)
ЕстьДвоичные = Ложь;
ЕстьJSON = Ложь;
Для Каждого Опция Из Опции Цикл
Значение = Опция.Значение;
Ключ = Опция.Ключ;
Если Ключ = "out" Тогда
Продолжить;
КонецЕсли;
Если ТипЗнч(Значение) = Тип("ДвоичныеДанные") Тогда
ЕстьДвоичные = Истина;
Прервать;
ИначеЕсли ТипЗнч(Значение) = Тип("Строка") Тогда
ФайлЗначения = Новый Файл(Значение);
Если ФайлЗначения.Существует() И ФайлЗначения.ЭтоФайл() Тогда
ЕстьДвоичные = Истина;
Прервать;
Иначе
OPI_ПреобразованиеТипов.ПолучитьКоллекцию(Значение);
КонецЕсли;
КонецЕсли;
ТекущийТип = ТипЗнч(Значение);
Если ТекущийТип = Тип("Соответствие") Или ТекущийТип = Тип("Структура") Тогда
ЕстьJSON = Истина;
КонецЕсли;
КонецЦикла;
Если Не ЕстьДвоичные И Не ЕстьJSON Тогда
Метод = "GET";
ИначеЕсли Не ЕстьДвоичные Тогда
Метод = "POST";
Иначе
Метод = "FORM";
КонецЕсли;
Возврат Метод;
КонецФункции
Функция ПолучитьОписаниеGet(Знач ТаблицаОпций)
СтруктураОписания = Новый Структура;
СтруктураОписания.Вставить("summary", "Выполнение через метод GET");
МассивПараметров = Новый Массив;
СоответствиеТипов = СоответствиеТиповSwagger();
Для Каждого Опция Из ТаблицаОпций Цикл
Ключ = Опция.Ключ;
Значение = Опция.Значение;
Описание = Опция.Описание;
СтруктураПараметра = Новый Структура;
СтруктураПараметра.Вставить("name", Ключ);
СтруктураПараметра.Вставить("in" , "query");
ТипSwagger = СоответствиеТипов.Получить(ТипЗнч(Значение));
ТипSwagger = ?(ЗначениеЗаполнено(ТипSwagger), ТипSwagger, СоответствиеТипов.Получить(Тип("Строка")));
СтруктураПараметра.Вставить("schema" , ТипSwagger);
СтруктураПараметра.Вставить("description", Описание);
МассивПараметров.Добавить(СтруктураПараметра);
КонецЦикла;
СтруктураОписания.Вставить("parameters", МассивПараметров);
Возврат СтруктураОписания;
КонецФункции
Функция ПолучитьОписаниеPost(Знач ТаблицаОпций, Знач ЕстьВариантJSON)
Описание = "Выполнение через метод POST (%1)";
Описание = СтрШаблон(Описание, ?(ЕстьВариантJSON, "JSON или form-data", "form-data"));
СтруктураОписания = Новый Структура;
СтруктураОписания.Вставить("summary", Описание);
СтруктураТела = Новый Структура;
СтруктураТела.Вставить("required", Истина);
СоответствиеВариантовТела = СформироватьВариантыТела(ТаблицаОпций, ЕстьВариантJSON);
СтруктураТела.Вставить("content", СоответствиеВариантовТела);
СтруктураОписания.Вставить("requestBody", СтруктураТела);
Возврат СтруктураОписания;
КонецФункции
Функция СформироватьВариантыТела(Знач ТаблицаОпций, Знач ЕстьВариантJSON)
СоответствиеТипов = СоответствиеТиповSwagger();
СтруктураТела = Новый Структура;
СтруктураСхемы = Новый Структура;
СтруктураСхемы.Вставить("type", "object");
СтруктураСвойств = Новый Структура;
Для Каждого Опция Из ТаблицаОпций Цикл
Ключ = Опция.Ключ;
Значение = Опция.Значение;
Описание = Опция.Описание;
СтруктураСвойства = Новый Структура;
ТипSwagger = СоответствиеТипов.Получить(ТипЗнч(Значение));
ТипSwagger = ?(ЗначениеЗаполнено(ТипSwagger), ТипSwagger, СоответствиеТипов.Получить(Тип("Строка")));
СтруктураСвойства.Вставить("type" , ТипSwagger);
СтруктураСвойства.Вставить("description", Описание);
СтруктураСвойств.Вставить(Ключ, СтруктураСвойства);
КонецЦикла;
СтруктураСхемы.Вставить("properties", СтруктураСвойств);
СтруктураТела.Вставить("schema", СтруктураСхемы);
СоответствиеВариантов = Новый Соответствие;
СоответствиеВариантов.Вставить("multipart/form-data", СтруктураТела);
Если ЕстьВариантJSON Тогда
СоответствиеВариантов.Вставить("application/json", СтруктураТела);
КонецЕсли;
Возврат СоответствиеВариантов;
КонецФункции
Функция СоответствиеТиповSwagger()
СоответствиеТипов = Новый Соответствие;
СоответствиеТипов.Вставить(Тип("Строка") , Новый Структура("type", "string"));
СоответствиеТипов.Вставить(Тип("Дата") , Новый Структура("type,format", "string", "date-time"));
СоответствиеТипов.Вставить(Тип("Число") , Новый Структура("type", "number"));
СоответствиеТипов.Вставить(Тип("Булево") , Новый Структура("type", "boolean"));
СоответствиеТипов.Вставить(Тип("Массив") , Новый Структура("type,items", "array", Новый Структура("type","string")));
СоответствиеТипов.Вставить(Тип("Структура") , Новый Структура("type", "object"));
СоответствиеТипов.Вставить(Тип("Соответствие") , Новый Структура("type", "object"));
СоответствиеТипов.Вставить(Тип("ДвоичныеДанные"), Новый Структура("type", "file"));
Возврат СоответствиеТипов;
КонецФункции
Функция КаталогSwagger()
Возврат "./docs/ru/openapi/"
Возврат "./docs/ru/openapi/";
КонецФункции
#КонецОбласти