{"id":371492,"date":"2024-05-21T04:50:07","date_gmt":"2024-05-21T04:50:07","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=371492"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=371492","title":{"rendered":"<span>\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u044b\u0445 \u0448\u0430\u0431\u043b\u043e\u043d\u043e\u0432 \u0438 \u043a\u043e\u043d\u0444\u0438\u0433\u043e\u0432 \u0434\u043b\u044f swagger-typescript-api<\/span>"},"content":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p><a href=\"https:\/\/www.npmjs.com\/package\/swagger-typescript-api\" rel=\"noopener noreferrer nofollow\">swagger-typescript-api<\/a> &#8212; \u044d\u0442\u043e \u043c\u043e\u0449\u043d\u044b\u0439 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442 \u0434\u043b\u044f \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u043a\u043e\u0434\u0430 \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 <a href=\"https:\/\/www.openapis.org\/\" rel=\"noopener noreferrer nofollow\">OpenApi<\/a>-\u043a\u043e\u043d\u0442\u0430\u043a\u0442\u043e\u0432, \u043e \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0435 \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u043a\u043e\u0442\u043e\u0440\u044b\u043c \u044f \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u044b\u0432\u0430\u043b \u0432 <a href=\"https:\/\/habr.com\/ru\/articles\/799853\/\" rel=\"noopener noreferrer nofollow\">\u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u0439 \u0441\u0442\u0430\u0442\u044c\u0435<\/a>. \u0422\u0430\u043c \u0436\u0435 \u044f \u0443\u043f\u043e\u043c\u044f\u043d\u0443\u043b, \u0447\u0442\u043e \u0435\u0433\u043e \u043c\u043e\u0436\u043d\u043e \u043a\u0430\u0441\u0442\u043e\u043c\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043f\u043e\u0434 \u043d\u0443\u0436\u0434\u044b \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0441\u0432\u043e\u0438\u0445 \u0448\u0430\u0431\u043b\u043e\u043d\u043e\u0432.<\/p>\n<p>\u0418\u043c\u0435\u043d\u043d\u043e \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u044b\u0435 \u0448\u0430\u0431\u043b\u043e\u043d\u044b \u0438 \u0431\u043e\u043d\u0443\u0441\u043e\u043c, <a href=\"#config\" rel=\"noopener noreferrer nofollow\">\u043a\u0430\u0441\u0442\u043e\u043c\u043d\u0430\u044f \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044f<\/a>, \u0431\u0443\u0434\u0443\u0442 \u0440\u0430\u0441\u043a\u0440\u044b\u0442\u044b \u0432 \u0442\u0435\u043a\u0443\u0449\u0435\u0439 \u0441\u0442\u0430\u0442\u044c\u0435. \u041f\u043e\u0435\u0445\u0430\u043b\u0438!<\/p>\n<p>\u0427\u0442\u043e\u0431\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u044b\u0435 \u0448\u0430\u0431\u043b\u043e\u043d\u044b, \u043f\u0440\u0435\u0434\u0432\u0430\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043d\u0443\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435:<\/p>\n<ol>\n<li>\n<p>\u0421\u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0438\u0437 <a href=\"https:\/\/github.com\/acacode\/swagger-typescript-api\" rel=\"noopener noreferrer nofollow\">\u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u044f swagger-typescript-api<\/a> \u0448\u0430\u0431\u043b\u043e\u043d\u044b \u0432 \u0432\u0430\u0448 \u043f\u0440\u043e\u0435\u043a\u0442: <\/p>\n<ol>\n<li>\n<p>\u0418\u0437 \u00a0<a href=\"https:\/\/github.com\/acacode\/swagger-typescript-api\/tree\/next\/templates\/default\" rel=\"noopener noreferrer nofollow\">\/templates\/default<\/a>\u00a0\u0434\u043b\u044f \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u043e\u0431\u0449\u0435\u0433\u043e \u0444\u0430\u0439\u043b\u0430 \u0441 API \u0438 \u0442\u0438\u043f\u0430\u043c\u0438;<\/p>\n<\/li>\n<li>\n<p>\u0418\u0437 <a href=\"https:\/\/github.com\/acacode\/swagger-typescript-api\/tree\/next\/templates\/modular\" rel=\"noopener noreferrer nofollow\">\/templates\/modular<\/a> \u0434\u043b\u044f \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0445 \u0444\u0430\u0439\u043b\u043e\u0432 \u0441 API \u0438 \u0442\u0438\u043f\u0430\u043c\u0438;<\/p>\n<\/li>\n<li>\n<p>\u0418\u0437 <a href=\"https:\/\/github.com\/acacode\/swagger-typescript-api\/tree\/next\/templates\/base\" rel=\"noopener noreferrer nofollow\">\/templates\/base<\/a>\u00a0\u0448\u0430\u0431\u043b\u043e\u043d\u044b \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u0432 \u043f\u0435\u0440\u0432\u044b\u0445 \u0434\u0432\u0443\u0445 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u0430\u0445;<\/p>\n<\/li>\n<\/ol>\n<\/li>\n<li>\n<p>\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0444\u043b\u0430\u0433 <code>--templates PATH_TO_YOUR_TEMPLATES<\/code> \u0434\u043b\u044f \u043a\u043e\u043c\u0430\u043d\u0434\u044b \u043a\u043e\u0434\u043e\u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438;<\/p>\n<\/li>\n<li>\n<p>\u0418 \u043d\u0435\u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u043c\u043e\u0434\u0438\u0444\u0438\u0446\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0448\u0430\u0431\u043b\u043e\u043d\u044b.<\/p>\n<\/li>\n<\/ol>\n<p>\u0418\u043c\u0435\u043d\u043d\u043e \u0442\u0430\u043a \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043e \u0432 \u0434\u043e\u043a\u0435 \u043a \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0443. \u041e\u0434\u043d\u0430\u043a\u043e \u0435\u0441\u0442\u044c \u0440\u044f\u0434 \u043d\u0435 \u043e\u0447\u0435\u0432\u0438\u0434\u043d\u044b\u0445 \u043c\u043e\u043c\u0435\u043d\u0442\u043e\u0432. \u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0432\u0441\u0435 \u043f\u043e\u044d\u0442\u0430\u043f\u043d\u043e \u043d\u0430 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u043c\u043e\u0435\u0439 \u0437\u0430\u0434\u0430\u0447\u0438.<\/p>\n<p>\u041a\u0430\u043a \u044f \u043f\u0438\u0441\u0430\u043b \u0432 <a href=\"https:\/\/habr.com\/ru\/articles\/799853\/\" rel=\"noopener noreferrer nofollow\">\u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u0439 \u0441\u0442\u0430\u0442\u044c\u0435<\/a>, \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u044b\u0439 \u0445\u0443\u043a \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u0437\u0430\u043f\u0440\u043e\u0441\u0430\u043c\u0438. \u0415\u043c\u0443 \u043d\u0443\u0436\u043d\u043e \u0441\u043a\u0430\u0440\u043c\u043b\u0438\u0432\u0430\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u044e, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0441\u043e\u0437\u0434\u0430\u0435\u0442 \u043d\u043e\u0432\u044b\u0439 \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440 \u043a\u043b\u0430\u0441\u0441\u0430 API \u0438 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442 \u043d\u0443\u0436\u043d\u044b\u0439 \u043c\u0435\u0442\u043e\u0434. \u0412\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u044d\u0442\u043e \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/p>\n<pre><code class=\"typescript\">const [getContactDataPhones, contactDataPhonesListRd] = useFetchApiCallRd(   getContactDataApi, 'phonesApiGetPhones', );<\/code><\/pre>\n<p>\u041d\u0430\u0441 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u0443\u0435\u0442 \u0444\u0443\u043d\u043a\u0446\u0438\u044f <code>getContactDataApi<\/code>:<\/p>\n<pre><code class=\"typescript\">export const getContactDataApi = (   config: ApiConfig,   params: RequestParams, ) => ({   emailsApiGetEmails: (query: { pfpId: number; }) => new ContactDataApi(config).emails.getEmails(query, params),    phonesApiGetPhones: (query?: { pfpId?: number; leadId?: number; phoneType?: IPhoneType[]; isFormal?: boolean; }) => (     new ContactDataApi(config).phones.getPhones(query, params)   ),    phonesApiPostPhones: (data: INewPhone) => new ContactDataApi(config).phones.postPhones(data, params),    phonesApiGetMaskedPhone: (phoneNumber: string) => (     new ContactDataApi(config).phones.getMaskedPhone(phoneNumber, params)   ),    phonesApiPatchPhone: (contactDataId: string, data: IUpdatePhone) => (     new ContactDataApi(config).phones.patchPhone(contactDataId, data, params)   ),    phonesApiPostMaskPhone: (data: IMaskedPhoneRq) => new ContactDataApi(config).phones.postMaskPhone(data, params), }); <\/code><\/pre>\n<p>\u041a\u0430\u0441\u0442\u043e\u043c\u043d\u044b\u0439 \u0445\u0443\u043a \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u043d\u0430\u043c \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u044c \u043d\u0430\u0434 API \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u044d\u0442\u043e\u0439 \u043d\u0435 \u0445\u0438\u0442\u0440\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043f\u043e \u0441\u0443\u0442\u0438 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u0431\u0430\u0437\u043e\u0432\u0443\u044e \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044e \u043a\u043b\u0438\u0435\u043d\u0442\u0430 \u0447\u0435\u0440\u0435\u0437 \u0445\u0443\u043a \u0438 \u0441\u043e\u0437\u0434\u0430\u0435\u0442 \u043c\u0430\u043f\u0443 \u043c\u0435\u0442\u043e\u0434\u043e\u0432, \u0438\u0437 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0445\u0443\u043a \u0438\u0437\u0432\u043b\u0435\u043a\u0430\u0435\u0442 \u043d\u0443\u0436\u043d\u044b\u0439. \u0418 \u043e\u0441\u0442\u0430\u0435\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u0432\u044b\u0437\u0432\u0430\u0442\u044c \u0435\u0433\u043e, \u043a\u043e\u0433\u0434\u0430 \u043d\u0430\u043c \u044d\u0442\u043e \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f.<\/p>\n<p>\u0422\u0430\u043a \u0432\u043e\u0442 \u044d\u0442\u0443 \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u043c\u044b \u043f\u0438\u0441\u0430\u043b\u0438 \u0440\u0443\u043a\u0430\u043c\u0438. \u041f\u0440\u0438\u0448\u043b\u043e \u0432\u0440\u0435\u043c\u044f \u044d\u0442\u043e \u0438\u0441\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u044b\u0445 \u0448\u0430\u0431\u043b\u043e\u043d\u043e\u0432.<\/p>\n<p>\u041f\u0440\u0435\u0436\u0434\u0435 \u0432\u0441\u0435\u0433\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u043a \u043a\u043e\u043c\u0430\u043d\u0434\u0435 \u043a\u043e\u0434\u043e\u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u043f\u0443\u0442\u044c \u0434\u043e \u0441\u043a\u0430\u0447\u0430\u043d\u043d\u044b\u0445 \u0448\u0430\u0431\u043b\u043e\u043d\u043e\u0432:<\/p>\n<pre><code class=\"json\">{   \"swagger:generate-contact-data\": \"sta --path swagger\/contact-data.yaml --output src\/services\/contact-data\/ --api-class-name ContactDataApi --responses --type-prefix I --templates templates\/default\", }<\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043a\u043e\u0433\u0434\u0430 \u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440 \u0432\u0438\u0434\u0438\u0442 \u043d\u0430\u0448\u0438 \u0448\u0430\u0431\u043b\u043e\u043d\u044b, \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u0438 \u043c\u044b \u043d\u0430 \u043d\u0438\u0445 \u0432\u0437\u0433\u043b\u044f\u043d\u0435\u043c:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/9bb\/99e\/8ee\/9bb99e8ee59013f469de7e471f5221be.png\" width=\"872\" height=\"568\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/9bb\/99e\/8ee\/9bb99e8ee59013f469de7e471f5221be.png\"\/><\/figure>\n<p>\u042d\u0442\u043e \u043d\u0430\u0431\u043e\u0440 \u0448\u0430\u0431\u043b\u043e\u043d\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u044b \u0441\u043a\u0430\u0447\u0430\u043b\u0438 \u0438\u0437 <a href=\"https:\/\/github.com\/acacode\/swagger-typescript-api\" rel=\"noopener noreferrer nofollow\">\u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u044f swagger-typescript-api<\/a>. \u041a\u0430\u0436\u0434\u044b\u0439 \u0448\u0430\u0431\u043b\u043e\u043d \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0437\u0430 \u0441\u0432\u043e\u044e \u0447\u0430\u0441\u0442\u044c \u043a\u043e\u0434\u0430. \u041c\u044b \u043c\u043e\u0436\u0435\u043c \u0438\u0437\u043c\u0435\u043d\u044f\u0442\u044c \u0438\u0445 \u0438 \u0434\u0430\u0436\u0435 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0442\u044c \u0432 \u043d\u0438\u0445 \u0441\u0432\u043e\u0438 \u043f\u043e\u0434\u0448\u0430\u0431\u043b\u043e\u043d\u044b \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0434\u0438\u0440\u0435\u043a\u0442\u0438\u0432\u044b <code>includeFile(pathToTemplate, payload)<\/code>. \u0415\u0441\u043b\u0438 \u043f\u043e\u0434\u0448\u0430\u0431\u043b\u043e\u043d\u043e\u0432 \u0432 \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u0448\u0430\u0431\u043b\u043e\u043d\u044b \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0443\u0433\u043e\u0434\u043d\u043e, \u0442\u043e \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u0448\u0430\u0431\u043b\u043e\u043d\u044b \u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440 \u043e\u0436\u0438\u0434\u0430\u0435\u0442 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u0435:<\/p>\n<ul>\n<li>\n<p><code>api.ejs<\/code>\u00a0&#8212;\u00a0\u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0437\u0430 \u043a\u043b\u0430\u0441\u0441 API;<\/p>\n<\/li>\n<li>\n<p><code>data-contracts.ejs<\/code>\u00a0&#8212;\u00a0\u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0437\u0430 \u0442\u0438\u043f\u044b;<\/p>\n<\/li>\n<li>\n<p><code>http-client.ejs<\/code>\u00a0&#8212;\u00a0\u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0437\u0430 http-\u043a\u043b\u0438\u0435\u043d\u0442;<\/p>\n<\/li>\n<li>\n<p><code>procedure-call.ejs<\/code>\u00a0&#8212;\u00a0\u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0437\u0430 \u043c\u0435\u0442\u043e\u0434\u044b \u0432\u043d\u0443\u0442\u0440\u0438 \u043a\u043b\u0430\u0441\u0441\u0430 API;<\/p>\n<\/li>\n<li>\n<p><code>route-docs.ejs<\/code>\u00a0&#8212;\u00a0\u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0437\u0430 JSDOC \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043c\u0435\u0442\u043e\u0434\u0430 \u0432\u043d\u0443\u0442\u0440\u0438 \u043a\u043b\u0430\u0441\u0441\u0430 API;<\/p>\n<\/li>\n<li>\n<p><code>route-name.ejs<\/code>\u00a0&#8212;\u00a0\u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0437\u0430 \u0438\u043c\u044f \u043c\u0435\u0442\u043e\u0434\u0430 \u0432\u043d\u0443\u0442\u0440\u0438 \u043a\u043b\u0430\u0441\u0441\u0430 API;<\/p>\n<\/li>\n<li>\n<p><code>route-type.ejs<\/code>\u00a0&#8212;\u00a0(`&#8212;route-types\u00a0option`)\u00a0\u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0437\u0430 \u0442\u0438\u043f \u043c\u0435\u0442\u043e\u0434\u0430 \u0432\u043d\u0443\u0442\u0440\u0438 \u043a\u043b\u0430\u0441\u0441\u0430 API;<\/p>\n<\/li>\n<li>\n<p><code>data-contract-jsdoc.ejs<\/code>\u00a0&#8212;\u00a0\u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0437\u0430 JSDOC \u0434\u043b\u044f \u0442\u0438\u043f\u043e\u0432.<\/p>\n<\/li>\n<\/ul>\n<p>\u0421\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e, \u0447\u0442\u043e\u0431\u044b \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c http-\u043a\u043b\u0438\u0435\u043d\u0442, \u043d\u0443\u0436\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0435\u0433\u043e \u0448\u0430\u0431\u043b\u043e\u043d \u0432 \u043f\u0430\u043f\u043a\u0443, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u0432\u044b \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0435 \u043f\u0440\u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0438 \u043a\u043e\u043c\u0430\u043d\u0434\u044b, \u0438\u043d\u0430\u0447\u0435 \u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u0448\u0430\u0431\u043b\u043e\u043d \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e.<\/p>\n<p>\u041c\u043d\u0435 \u0436\u0435 \u043d\u0443\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u0434\u043e\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0448\u0430\u0431\u043b\u043e\u043d <a href=\"https:\/\/github.com\/acacode\/swagger-typescript-api\/blob\/master\/templates\/default\/api.ejs\" rel=\"noopener noreferrer nofollow\">api.ejs<\/a>. \u042f \u0434\u043e\u0431\u0430\u0432\u0438\u043b \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0443\u044e \u0437\u0430\u043f\u0438\u0441\u044c:<\/p>\n<pre><code class=\"javascript\">export const get&lt;%~ config.apiClassName %> = (config: ApiConfig, params: RequestParams) => ({   &lt;% for (const { routes: combinedRoutes = [], moduleName } of routes.combined) { %>     &lt;% for (const route of combinedRoutes) { %>      &lt;%~ includeFile('.\/procedure-call-getter.ejs', { ...it, moduleName, route }) %>      &lt;% } %>   &lt;% } %><\/code><\/pre>\n<p>\u042f \u043d\u0435 \u0433\u0443\u0440\u0443 \u043f\u043e ejs-\u0448\u0430\u0431\u043b\u043e\u043d\u0430\u043c \u0438 \u043d\u0430\u043f\u0438\u0441\u0430\u043b \u044d\u0442\u043e \u043f\u043e \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0438 \u0441 \u0443\u0436\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u043c \u043a\u043e\u0434\u043e\u043c. \u0422\u0430\u043a \u0447\u0442\u043e, \u0434\u0443\u043c\u0430\u044e, \u043b\u044e\u0431\u043e\u0439 \u0436\u0435\u043b\u0430\u044e\u0449\u0438\u0439 \u0441\u043c\u043e\u0436\u0435\u0442 \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u0442\u044c\u0441\u044f \u043f\u0440\u0438 \u0436\u0435\u043b\u0430\u043d\u0438\u0438.<\/p>\n<p>\u041a\u0430\u043a \u0432\u0438\u0434\u0438\u0442\u0435, \u044f \u0434\u043e\u0431\u0430\u0432\u0438\u043b \u0441\u0432\u043e\u0439 \u043f\u043e\u0434\u0448\u0430\u0431\u043b\u043e\u043d <code>procedure-call-getter.ejs<\/code>. \u041e\u043d \u0441\u0434\u0435\u043b\u0430\u043d \u043f\u043e \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0438 \u0441 <code>procedure-call.ejs<\/code>. \u0412\u043e\u0442 \u0447\u0442\u043e \u044f \u0442\u0430\u043c \u0443\u043a\u0430\u0437\u0430\u043b:<\/p>\n<pre><code class=\"javascript\">&lt;% const { utils, route, config, moduleName } = it; const { requestBodyInfo, responseBodyInfo, specificArgNameResolver } = route; const { _, getInlineParseContent, getParseContent, parseSchema, getComponentByRef, require } = utils; const { parameters, path, method, payload, query, formData, security, requestParams } = route.request; const { type, errorType, contentTypes } = route.response; const { HTTP_CLIENT, RESERVED_REQ_PARAMS_ARG_NAMES } = config.constants; const queryName = (query &amp;&amp; query.name) || \"query\"; const pathParams = _.values(parameters); const pathParamsNames = _.map(pathParams, \"name\");  const isFetchTemplate = config.httpClientType === HTTP_CLIENT.FETCH;  const requestConfigParam = {     name: specificArgNameResolver.resolve(RESERVED_REQ_PARAMS_ARG_NAMES),     optional: true,     type: \"RequestParams\",     defaultValue: \"{}\", }  const argToTmpl = ({ name, optional, type, defaultValue }) => `${name}${!defaultValue &amp;&amp; optional ? '?' : ''}: ${type}${defaultValue ? ` = ${defaultValue}` : ''}`; const argToName = ({ name }) => name;  const rawWrapperArgs = config.extractRequestParams ?     _.compact([         requestParams &amp;&amp; {           name: pathParams.length ? `{ ${_.join(pathParamsNames, \", \")}, ...${queryName} }` : queryName,           optional: false,           type: getInlineParseContent(requestParams),         },         ...(!requestParams ? pathParams : []),         payload,     ]) :     _.compact([         ...pathParams,         query,         payload,     ])  const wrapperArgs = _     \/\/ Sort by optionality     .sortBy(rawWrapperArgs, [o => o.optional])     .map(argToTmpl)     .join(', ')  const wrapperArgsNames = rawWrapperArgs     .map(argToName)     .join(', ')  const describeReturnType = () => {     if (!config.toJS) return \"\";      switch(config.httpClientType) {         case HTTP_CLIENT.AXIOS: {           return `Promise&lt;AxiosResponse&lt;${type}>>`         }         default: {           return `Promise&lt;HttpResponse&lt;${type}, ${errorType}>`         }     } }  const capitalizeFirstLetter = (string) => {     return string.charAt(0).toUpperCase() + string.slice(1); }  const unCapitalizeFirstLetter = (string) => {     return string.charAt(0).toLowerCase() + string.slice(1); }  %>  &lt;%~ unCapitalizeFirstLetter(config.apiClassName) %>&lt;%~ capitalizeFirstLetter(route.routeName.usage) %>: (&lt;%~ wrapperArgs %>)&lt;%~ config.toJS ? `: ${describeReturnType()}` : \"\" %>  => {     return new &lt;%~ config.apiClassName %>(config).&lt;%~ moduleName %>.&lt;%~ route.routeName.usage %>(         &lt;% if (wrapperArgs.length) { %> &lt;%~ wrapperArgsNames %>, &lt;% } %>         params,     ); },<\/code><\/pre>\n<p>\u0411\u043e\u043b\u044c\u0448\u0430\u044f \u0447\u0430\u0441\u0442\u044c \u0441\u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u043d\u0430 \u0438\u0437 <code>procedure-call.ejs<\/code>, \u0430 \u044f \u0434\u043e\u0431\u0430\u0432\u0438\u043b \u0442\u043e\u043b\u044c\u043a\u043e:<\/p>\n<pre><code class=\"javascript\">const capitalizeFirstLetter = (string) => {     return string.charAt(0).toUpperCase() + string.slice(1); }  const unCapitalizeFirstLetter = (string) => {     return string.charAt(0).toLowerCase() + string.slice(1); }  %>  &lt;%~ unCapitalizeFirstLetter(config.apiClassName) %>&lt;%~ capitalizeFirstLetter(route.routeName.usage) %>: (&lt;%~ wrapperArgs %>)&lt;%~ config.toJS ? `: ${describeReturnType()}` : \"\" %>  => {     return new &lt;%~ config.apiClassName %>(config).&lt;%~ moduleName %>.&lt;%~ route.routeName.usage %>(         &lt;% if (wrapperArgs.length) { %> &lt;%~ wrapperArgsNames %>, &lt;% } %>         params,     ); }, <\/code><\/pre>\n<p>\u0418 \u0442\u0435\u043f\u0435\u0440\u044c \u043d\u0443\u0436\u043d\u0430\u044f \u043c\u043d\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0442\u0430\u043a\u0436\u0435 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442\u0441\u044f:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/e12\/6c4\/c3e\/e126c4c3e5f52a98bd558d1b7e6662de.png\" width=\"2362\" height=\"1666\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/e12\/6c4\/c3e\/e126c4c3e5f52a98bd558d1b7e6662de.png\"\/><\/figure>\n<p><a class=\"anchor\" name=\"config\" id=\"config\"><\/a><\/p>\n<p>\u0410 \u0442\u0435\u043f\u0435\u0440\u044c \u0431\u043e\u043d\u0443\u0441 &#8212; \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u043e\u0433\u043e \u043a\u043e\u043d\u0444\u0438\u0433\u0430. \u0412 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u044f \u043f\u0438\u0441\u0430\u043b, \u0447\u0442\u043e \u043e\u043f\u0446\u0438\u044f <code>--type-prefix<\/code> \u0438\u043b\u0438 <code>--type-suffix<\/code> \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0435\u0442\u0441\u044f \u0438 \u043a \u0442\u0438\u043f\u0430\u043c, \u0438 \u043a \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430\u043c, \u0438 \u0434\u0430\u0436\u0435 \u043a \u0435\u043d\u0430\u043c\u0430\u043c, \u0447\u0442\u043e \u043c\u0435\u043d\u044f \u043b\u0438\u0447\u043d\u043e \u043d\u0435 \u0443\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0435\u0442, \u0442\u0430\u043a \u043a\u0430\u043a \u044f \u043b\u044e\u0431\u043b\u044e \u0438\u0445 \u0440\u0430\u0437\u0434\u0435\u043b\u044f\u0442\u044c, \u043a\u0430\u043a \u0440\u0430\u0437 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0435 \u043f\u0440\u0435\u0444\u0438\u043a\u0441\u044b \u0438 \u0441\u0443\u0444\u0444\u0438\u043a\u0441\u044b. \u0422\u0430\u043a\u0436\u0435 \u044f \u043d\u0430\u043f\u0438\u0441\u0430\u043b, \u0447\u0442\u043e \u044d\u0442\u0443 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0443 \u043c\u043e\u0436\u043d\u043e \u0440\u0435\u0448\u0438\u0442\u044c \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u044b\u0445 \u0448\u0430\u0431\u043b\u043e\u043d\u043e\u0432. \u041a \u0441\u043e\u0436\u0430\u043b\u0435\u043d\u0438\u044e, \u044f \u043e\u0448\u0438\u0431\u0441\u044f.<\/p>\n<p>\u042f \u0438\u0441\u043a\u0430\u043b \u0430\u043b\u044c\u0442\u0435\u0440\u043d\u0430\u0442\u0438\u0432\u043d\u044b\u0435 \u043f\u0443\u0442\u0438 \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u044d\u0442\u043e\u0439 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b, \u043d\u043e, \u043a \u0441\u043e\u0436\u0430\u043b\u0435\u043d\u0438\u044e, \u0438\u0445 \u043d\u0435\u0442. \u0412\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u044f \u043f\u043e\u0437\u0436\u0435 \u0441\u0434\u0435\u043b\u0430\u044e \u0432\u043a\u043b\u0430\u0434 \u0432 \u044d\u0442\u043e\u0442 \u043f\u0440\u043e\u0435\u043a\u0442, \u0442\u0430\u043a \u043a\u0430\u043a \u0443\u0436\u0435 \u043e\u0441\u043d\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u043b\u0441\u044f, \u043a\u0430\u043a \u043e\u043d \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442. \u0418 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u044d\u0442\u043e\u0442 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e.<\/p>\n<p>\u0410 \u043f\u043e\u043a\u0430 \u044f \u0441 \u044d\u0442\u0438\u043c \u0440\u0430\u0437\u0431\u0438\u0440\u0430\u043b\u0441\u044f, \u044f \u0443\u0437\u043d\u0430\u043b, \u043a\u0430\u043a \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u0443\u044e \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044e \u0434\u043b\u044f \u043a\u043e\u0434\u043e\u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438. \u042d\u0442\u043e \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043f\u043e\u043b\u0435\u0437\u043d\u044b\u043c, \u0435\u0441\u043b\u0438 \u0432\u0430\u043c \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u0442\u044c\u0441\u044f, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0437\u0430\u043c\u0435\u043d\u0438\u0442\u044c \u0442\u0438\u043f\u044b \u0434\u043b\u044f \u0434\u0430\u0442 \u0438\u043b\u0438 \u0447\u0435\u0433\u043e-\u0442\u043e \u0435\u0449\u0435.<\/p>\n<p>\u0412 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 \u0445\u043e\u0440\u043e\u0448\u043e \u043e\u043f\u0438\u0441\u0430\u043d\u043e, \u0447\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u043e\u0433\u043e \u043a\u043e\u043d\u0444\u0438\u0433\u0430, \u043d\u043e \u043d\u0435\u0442 \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u0432, \u043a\u0430\u043a \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0435\u0433\u043e \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0444\u043b\u0430\u0433\u0430 <code>--custom-config<\/code>. \u0410 \u044d\u0442\u043e \u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0432\u0441\u0442\u0430\u0432\u0438\u0442 \u0432 <a href=\"https:\/\/github.com\/acacode\/swagger-typescript-api\/issues\/691\" rel=\"noopener noreferrer nofollow\">\u0442\u0443\u043f\u0438\u043a<\/a> \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439.<\/p>\n<p>\u0412\u0441\u0435 \u043f\u0440\u043e\u0441\u0442\u043e! \u0414\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043f\u0435\u0440\u0435\u0434\u0430\u0442\u044c \u043f\u0443\u0442\u044c \u0434\u043e \u0444\u0430\u0439\u043b\u0430 \u0441 \u0432\u0430\u0448\u0438\u043c \u043a\u043e\u043d\u0444\u0438\u0433\u043e\u043c \u0447\u0435\u0440\u0435\u0437 \u044d\u0442\u0443 \u043e\u043f\u0446\u0438\u044e:<\/p>\n<pre><code class=\"json\">{   \"swagger:generate-contact-data\": \"sta --path swagger\/contact-data.yaml --output src\/services\/contact-data\/ --api-class-name ContactDataApi --responses --type-prefix I --templates templates\/default --custom-config generator.config.js\" }<\/code><\/pre>\n<p>\u0410 \u0432\u043e\u0442 \u043f\u0440\u0438\u043c\u0435\u0440 \u043a\u043e\u043d\u0444\u0438\u0433\u0430:<\/p>\n<pre><code class=\"javascript\">module.exports = {   hooks: {     onPreBuildRoutePath: (routePath) => void 0,     onBuildRoutePath: (routeData) => void 0,     onInsertPathParam: (pathParam) => void 0,     onCreateComponent: (schema) => schema,     onPreParseSchema: (originalSchema, typeName, schemaType) => void 0,     onParseSchema: (originalSchema, parsedSchema) => parsedSchema,     onCreateRoute: (routeData) => routeData,     onInit: (config, codeGenProcess) => config,     onPrepareConfig: (apiConfig) => apiConfig,     onCreateRequestParams: (rawType) => {},     onCreateRouteName: () => {},   onFormatTypeName: (typeName, rawTypeName, schemaType) => {},     onFormatRouteName: (routeInfo, templateRouteName) => {},   },   codeGenConstructs: (struct) => ({     Keyword: {       Number: 'number',       String: 'string',       Boolean: 'boolean',       Any: 'any',       Void: 'void',       Unknown: 'unknown',       Null: 'null',       Undefined: 'undefined',       Object: 'object',       File: 'File',       Date: 'Date',       Type: 'type',       Enum: 'enum',       Interface: 'interface',       Array: 'Array',       Record: 'Record',       Intersection: '&amp;',       Union: '|',     },     CodeGenKeyword: {       UtilRequiredKeys: 'UtilRequiredKeys',     },     \/**      * $A[] or Array&lt;$A>      *\/     ArrayType: (content) => {       if (this.anotherArrayType) {         return `Array&lt;${content}>`;       }        return `(${content})[]`;     },     \/**      * \"$A\"      *\/     StringValue: (content) => `\"${content}\"`,     \/**      * $A      *\/     BooleanValue: (content) => `${content}`,     \/**      * $A      *\/     NumberValue: (content) => `${content}`,     \/**      * $A      *\/     NullValue: (content) => content,     \/**      * $A1 | $A2      *\/     UnionType: (contents) => _.join(_.uniq(contents), ` | `),     \/**      * ($A1)      *\/     ExpressionGroup: (content) => (content ? `(${content})` : ''),     \/**      * $A1 &amp; $A2      *\/     IntersectionType: (contents) => _.join(_.uniq(contents), ` &amp; `),     \/**      * Record&lt;$A1, $A2>      *\/     RecordType: (key, value) => `Record&lt;${key}, ${value}>`,     \/**      * readonly $key?:$value      *\/     TypeField: ({ readonly, key, optional, value }) =>       _.compact([readonly &amp;&amp; 'readonly ', key, optional &amp;&amp; '?', ': ', value]).join(''),     \/**      * [key: $A1]: $A2      *\/     InterfaceDynamicField: (key, value) => `[key: ${key}]: ${value}`,     \/**      * $A1 = $A2      *\/     EnumField: (key, value) => `${key} = ${value}`,     \/**      * $A0.key = $A0.value,      * $A1.key = $A1.value,      * $AN.key = $AN.value,      *\/     EnumFieldsWrapper: (contents) => _.map(contents, ({ key, value }) => `  ${key} = ${value}`).join(',\\n'),     \/**      * {\\n $A \\n}      *\/     ObjectWrapper: (content) => `{\\n${content}\\n}`,     \/**      * \/** $A *\\\/      *\/     MultilineComment: (contents, formatFn) =>       [         ...(contents.length === 1           ? [`\/** ${contents[0]} *\/`]           : ['\/**', ...contents.map((content) => ` * ${content}`), ' *\/']),       ].map((part) => `${formatFn ? formatFn(part) : part}\\n`),     \/**      * $A1&lt;...$A2.join(,)>      *\/     TypeWithGeneric: (typeName, genericArgs) => {       return `${typeName}${genericArgs.length ? `&lt;${genericArgs.join(',')}>` : ''}`;     },   }), };<\/code><\/pre>\n<p>\u0412\u0441\u0435\u043c \u0441\u043f\u0430\u0441\u0438\u0431\u043e \u0437\u0430 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435!<\/p>\n<p>P.S. \u0415\u0441\u043b\u0438 \u0432\u0430\u043c \u0431\u0443\u0434\u0435\u0442 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e, \u0447\u0442\u043e \u0437\u0430 \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u044b\u0439 \u0445\u0443\u043a \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0434\u043b\u044f \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432, \u0442\u043e \u043d\u0430\u043f\u0438\u0448\u0438\u0442\u0435 \u0432 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u044f\u0445. \u0422\u0430\u043c \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0435\u0441\u0442\u044c \u043d\u0430 \u0447\u0442\u043e \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c. \u0412 \u044d\u0442\u043e\u043c \u0445\u0443\u043a\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0432\u0441\u044e \u0441\u0438\u043b\u0443 Typescript Generics.<\/p>\n<\/p>\n<\/div>\n<\/div>\n<\/div>\n<p><!----><!----><\/div>\n<p><!----><!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/articles\/802097\/\"> https:\/\/habr.com\/ru\/articles\/802097\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p><a href=\"https:\/\/www.npmjs.com\/package\/swagger-typescript-api\" rel=\"noopener noreferrer nofollow\">swagger-typescript-api<\/a> &#8212; \u044d\u0442\u043e \u043c\u043e\u0449\u043d\u044b\u0439 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442 \u0434\u043b\u044f \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u043a\u043e\u0434\u0430 \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 <a href=\"https:\/\/www.openapis.org\/\" rel=\"noopener noreferrer nofollow\">OpenApi<\/a>-\u043a\u043e\u043d\u0442\u0430\u043a\u0442\u043e\u0432, \u043e \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0435 \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u043a\u043e\u0442\u043e\u0440\u044b\u043c \u044f \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u044b\u0432\u0430\u043b \u0432 <a href=\"https:\/\/habr.com\/ru\/articles\/799853\/\" rel=\"noopener noreferrer nofollow\">\u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u0439 \u0441\u0442\u0430\u0442\u044c\u0435<\/a>. \u0422\u0430\u043c \u0436\u0435 \u044f \u0443\u043f\u043e\u043c\u044f\u043d\u0443\u043b, \u0447\u0442\u043e \u0435\u0433\u043e \u043c\u043e\u0436\u043d\u043e \u043a\u0430\u0441\u0442\u043e\u043c\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043f\u043e\u0434 \u043d\u0443\u0436\u0434\u044b \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0441\u0432\u043e\u0438\u0445 \u0448\u0430\u0431\u043b\u043e\u043d\u043e\u0432.<\/p>\n<p>\u0418\u043c\u0435\u043d\u043d\u043e \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u044b\u0435 \u0448\u0430\u0431\u043b\u043e\u043d\u044b \u0438 \u0431\u043e\u043d\u0443\u0441\u043e\u043c, <a href=\"#config\" rel=\"noopener noreferrer nofollow\">\u043a\u0430\u0441\u0442\u043e\u043c\u043d\u0430\u044f \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044f<\/a>, \u0431\u0443\u0434\u0443\u0442 \u0440\u0430\u0441\u043a\u0440\u044b\u0442\u044b \u0432 \u0442\u0435\u043a\u0443\u0449\u0435\u0439 \u0441\u0442\u0430\u0442\u044c\u0435. \u041f\u043e\u0435\u0445\u0430\u043b\u0438!<\/p>\n<p>\u0427\u0442\u043e\u0431\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u044b\u0435 \u0448\u0430\u0431\u043b\u043e\u043d\u044b, \u043f\u0440\u0435\u0434\u0432\u0430\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043d\u0443\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435:<\/p>\n<ol>\n<li>\n<p>\u0421\u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0438\u0437 <a href=\"https:\/\/github.com\/acacode\/swagger-typescript-api\" rel=\"noopener noreferrer nofollow\">\u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u044f swagger-typescript-api<\/a> \u0448\u0430\u0431\u043b\u043e\u043d\u044b \u0432 \u0432\u0430\u0448 \u043f\u0440\u043e\u0435\u043a\u0442: <\/p>\n<ol>\n<li>\n<p>\u0418\u0437 \u00a0<a href=\"https:\/\/github.com\/acacode\/swagger-typescript-api\/tree\/next\/templates\/default\" rel=\"noopener noreferrer nofollow\">\/templates\/default<\/a>\u00a0\u0434\u043b\u044f \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u043e\u0431\u0449\u0435\u0433\u043e \u0444\u0430\u0439\u043b\u0430 \u0441 API \u0438 \u0442\u0438\u043f\u0430\u043c\u0438;<\/p>\n<\/li>\n<li>\n<p>\u0418\u0437 <a href=\"https:\/\/github.com\/acacode\/swagger-typescript-api\/tree\/next\/templates\/modular\" rel=\"noopener noreferrer nofollow\">\/templates\/modular<\/a> \u0434\u043b\u044f \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0445 \u0444\u0430\u0439\u043b\u043e\u0432 \u0441 API \u0438 \u0442\u0438\u043f\u0430\u043c\u0438;<\/p>\n<\/li>\n<li>\n<p>\u0418\u0437 <a href=\"https:\/\/github.com\/acacode\/swagger-typescript-api\/tree\/next\/templates\/base\" rel=\"noopener noreferrer nofollow\">\/templates\/base<\/a>\u00a0\u0448\u0430\u0431\u043b\u043e\u043d\u044b \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u0432 \u043f\u0435\u0440\u0432\u044b\u0445 \u0434\u0432\u0443\u0445 \u0432\u0430\u0440\u0438\u0430\u043d\u0442\u0430\u0445;<\/p>\n<\/li>\n<\/ol>\n<\/li>\n<li>\n<p>\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0444\u043b\u0430\u0433 <code>--templates PATH_TO_YOUR_TEMPLATES<\/code> \u0434\u043b\u044f \u043a\u043e\u043c\u0430\u043d\u0434\u044b \u043a\u043e\u0434\u043e\u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438;<\/p>\n<\/li>\n<li>\n<p>\u0418 \u043d\u0435\u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u043c\u043e\u0434\u0438\u0444\u0438\u0446\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0448\u0430\u0431\u043b\u043e\u043d\u044b.<\/p>\n<\/li>\n<\/ol>\n<p>\u0418\u043c\u0435\u043d\u043d\u043e \u0442\u0430\u043a \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043e \u0432 \u0434\u043e\u043a\u0435 \u043a \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u0443. \u041e\u0434\u043d\u0430\u043a\u043e \u0435\u0441\u0442\u044c \u0440\u044f\u0434 \u043d\u0435 \u043e\u0447\u0435\u0432\u0438\u0434\u043d\u044b\u0445 \u043c\u043e\u043c\u0435\u043d\u0442\u043e\u0432. \u0420\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0432\u0441\u0435 \u043f\u043e\u044d\u0442\u0430\u043f\u043d\u043e \u043d\u0430 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u043c\u043e\u0435\u0439 \u0437\u0430\u0434\u0430\u0447\u0438.<\/p>\n<p>\u041a\u0430\u043a \u044f \u043f\u0438\u0441\u0430\u043b \u0432 <a href=\"https:\/\/habr.com\/ru\/articles\/799853\/\" rel=\"noopener noreferrer nofollow\">\u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u0439 \u0441\u0442\u0430\u0442\u044c\u0435<\/a>, \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u044b\u0439 \u0445\u0443\u043a \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u0437\u0430\u043f\u0440\u043e\u0441\u0430\u043c\u0438. \u0415\u043c\u0443 \u043d\u0443\u0436\u043d\u043e \u0441\u043a\u0430\u0440\u043c\u043b\u0438\u0432\u0430\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u044e, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0441\u043e\u0437\u0434\u0430\u0435\u0442 \u043d\u043e\u0432\u044b\u0439 \u044d\u043a\u0437\u0435\u043c\u043f\u043b\u044f\u0440 \u043a\u043b\u0430\u0441\u0441\u0430 API \u0438 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442 \u043d\u0443\u0436\u043d\u044b\u0439 \u043c\u0435\u0442\u043e\u0434. \u0412\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u044d\u0442\u043e \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/p>\n<pre><code class=\"typescript\">const [getContactDataPhones, contactDataPhonesListRd] = useFetchApiCallRd(   getContactDataApi, 'phonesApiGetPhones', );<\/code><\/pre>\n<p>\u041d\u0430\u0441 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u0443\u0435\u0442 \u0444\u0443\u043d\u043a\u0446\u0438\u044f <code>getContactDataApi<\/code>:<\/p>\n<pre><code class=\"typescript\">export const getContactDataApi = (   config: ApiConfig,   params: RequestParams, ) => ({   emailsApiGetEmails: (query: { pfpId: number; }) => new ContactDataApi(config).emails.getEmails(query, params),    phonesApiGetPhones: (query?: { pfpId?: number; leadId?: number; phoneType?: IPhoneType[]; isFormal?: boolean; }) => (     new ContactDataApi(config).phones.getPhones(query, params)   ),    phonesApiPostPhones: (data: INewPhone) => new ContactDataApi(config).phones.postPhones(data, params),    phonesApiGetMaskedPhone: (phoneNumber: string) => (     new ContactDataApi(config).phones.getMaskedPhone(phoneNumber, params)   ),    phonesApiPatchPhone: (contactDataId: string, data: IUpdatePhone) => (     new ContactDataApi(config).phones.patchPhone(contactDataId, data, params)   ),    phonesApiPostMaskPhone: (data: IMaskedPhoneRq) => new ContactDataApi(config).phones.postMaskPhone(data, params), }); <\/code><\/pre>\n<p>\u041a\u0430\u0441\u0442\u043e\u043c\u043d\u044b\u0439 \u0445\u0443\u043a \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u043d\u0430\u043c \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u044c \u043d\u0430\u0434 API \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u044d\u0442\u043e\u0439 \u043d\u0435 \u0445\u0438\u0442\u0440\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043f\u043e \u0441\u0443\u0442\u0438 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u0431\u0430\u0437\u043e\u0432\u0443\u044e \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044e \u043a\u043b\u0438\u0435\u043d\u0442\u0430 \u0447\u0435\u0440\u0435\u0437 \u0445\u0443\u043a \u0438 \u0441\u043e\u0437\u0434\u0430\u0435\u0442 \u043c\u0430\u043f\u0443 \u043c\u0435\u0442\u043e\u0434\u043e\u0432, \u0438\u0437 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0445\u0443\u043a \u0438\u0437\u0432\u043b\u0435\u043a\u0430\u0435\u0442 \u043d\u0443\u0436\u043d\u044b\u0439. \u0418 \u043e\u0441\u0442\u0430\u0435\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u0432\u044b\u0437\u0432\u0430\u0442\u044c \u0435\u0433\u043e, \u043a\u043e\u0433\u0434\u0430 \u043d\u0430\u043c \u044d\u0442\u043e \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f.<\/p>\n<p>\u0422\u0430\u043a \u0432\u043e\u0442 \u044d\u0442\u0443 \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u043c\u044b \u043f\u0438\u0441\u0430\u043b\u0438 \u0440\u0443\u043a\u0430\u043c\u0438. \u041f\u0440\u0438\u0448\u043b\u043e \u0432\u0440\u0435\u043c\u044f \u044d\u0442\u043e \u0438\u0441\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u044b\u0445 \u0448\u0430\u0431\u043b\u043e\u043d\u043e\u0432.<\/p>\n<p>\u041f\u0440\u0435\u0436\u0434\u0435 \u0432\u0441\u0435\u0433\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u043a \u043a\u043e\u043c\u0430\u043d\u0434\u0435 \u043a\u043e\u0434\u043e\u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u043f\u0443\u0442\u044c \u0434\u043e \u0441\u043a\u0430\u0447\u0430\u043d\u043d\u044b\u0445 \u0448\u0430\u0431\u043b\u043e\u043d\u043e\u0432:<\/p>\n<pre><code class=\"json\">{   \"swagger:generate-contact-data\": \"sta --path swagger\/contact-data.yaml --output src\/services\/contact-data\/ --api-class-name ContactDataApi --responses --type-prefix I --templates templates\/default\", }<\/code><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043a\u043e\u0433\u0434\u0430 \u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440 \u0432\u0438\u0434\u0438\u0442 \u043d\u0430\u0448\u0438 \u0448\u0430\u0431\u043b\u043e\u043d\u044b, \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u0438 \u043c\u044b \u043d\u0430 \u043d\u0438\u0445 \u0432\u0437\u0433\u043b\u044f\u043d\u0435\u043c:<\/p>\n<figure class=\"full-width\"><\/figure>\n<p>\u042d\u0442\u043e \u043d\u0430\u0431\u043e\u0440 \u0448\u0430\u0431\u043b\u043e\u043d\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u044b \u0441\u043a\u0430\u0447\u0430\u043b\u0438 \u0438\u0437 <a href=\"https:\/\/github.com\/acacode\/swagger-typescript-api\" rel=\"noopener noreferrer nofollow\">\u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u044f swagger-typescript-api<\/a>. \u041a\u0430\u0436\u0434\u044b\u0439 \u0448\u0430\u0431\u043b\u043e\u043d \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0437\u0430 \u0441\u0432\u043e\u044e \u0447\u0430\u0441\u0442\u044c \u043a\u043e\u0434\u0430. \u041c\u044b \u043c\u043e\u0436\u0435\u043c \u0438\u0437\u043c\u0435\u043d\u044f\u0442\u044c \u0438\u0445 \u0438 \u0434\u0430\u0436\u0435 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0442\u044c \u0432 \u043d\u0438\u0445 \u0441\u0432\u043e\u0438 \u043f\u043e\u0434\u0448\u0430\u0431\u043b\u043e\u043d\u044b \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0434\u0438\u0440\u0435\u043a\u0442\u0438\u0432\u044b <code>includeFile(pathToTemplate, payload)<\/code>. \u0415\u0441\u043b\u0438 \u043f\u043e\u0434\u0448\u0430\u0431\u043b\u043e\u043d\u043e\u0432 \u0432 \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u0448\u0430\u0431\u043b\u043e\u043d\u044b \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0443\u0433\u043e\u0434\u043d\u043e, \u0442\u043e \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u0448\u0430\u0431\u043b\u043e\u043d\u044b \u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440 \u043e\u0436\u0438\u0434\u0430\u0435\u0442 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u0435:<\/p>\n<ul>\n<li>\n<p><code>api.ejs<\/code>\u00a0&#8212;\u00a0\u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0437\u0430 \u043a\u043b\u0430\u0441\u0441 API;<\/p>\n<\/li>\n<li>\n<p><code>data-contracts.ejs<\/code>\u00a0&#8212;\u00a0\u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0437\u0430 \u0442\u0438\u043f\u044b;<\/p>\n<\/li>\n<li>\n<p><code>http-client.ejs<\/code>\u00a0&#8212;\u00a0\u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0437\u0430 http-\u043a\u043b\u0438\u0435\u043d\u0442;<\/p>\n<\/li>\n<li>\n<p><code>procedure-call.ejs<\/code>\u00a0&#8212;\u00a0\u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0437\u0430 \u043c\u0435\u0442\u043e\u0434\u044b \u0432\u043d\u0443\u0442\u0440\u0438 \u043a\u043b\u0430\u0441\u0441\u0430 API;<\/p>\n<\/li>\n<li>\n<p><code>route-docs.ejs<\/code>\u00a0&#8212;\u00a0\u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0437\u0430 JSDOC \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043c\u0435\u0442\u043e\u0434\u0430 \u0432\u043d\u0443\u0442\u0440\u0438 \u043a\u043b\u0430\u0441\u0441\u0430 API;<\/p>\n<\/li>\n<li>\n<p><code>route-name.ejs<\/code>\u00a0&#8212;\u00a0\u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0437\u0430 \u0438\u043c\u044f \u043c\u0435\u0442\u043e\u0434\u0430 \u0432\u043d\u0443\u0442\u0440\u0438 \u043a\u043b\u0430\u0441\u0441\u0430 API;<\/p>\n<\/li>\n<li>\n<p><code>route-type.ejs<\/code>\u00a0&#8212;\u00a0(`&#8212;route-types\u00a0option`)\u00a0\u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0437\u0430 \u0442\u0438\u043f \u043c\u0435\u0442\u043e\u0434\u0430 \u0432\u043d\u0443\u0442\u0440\u0438 \u043a\u043b\u0430\u0441\u0441\u0430 API;<\/p>\n<\/li>\n<li>\n<p><code>data-contract-jsdoc.ejs<\/code>\u00a0&#8212;\u00a0\u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0437\u0430 JSDOC \u0434\u043b\u044f \u0442\u0438\u043f\u043e\u0432.<\/p>\n<\/li>\n<\/ul>\n<p>\u0421\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e, \u0447\u0442\u043e\u0431\u044b \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c http-\u043a\u043b\u0438\u0435\u043d\u0442, \u043d\u0443\u0436\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0435\u0433\u043e \u0448\u0430\u0431\u043b\u043e\u043d \u0432 \u043f\u0430\u043f\u043a\u0443, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u0432\u044b \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0435 \u043f\u0440\u0438 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0438 \u043a\u043e\u043c\u0430\u043d\u0434\u044b, \u0438\u043d\u0430\u0447\u0435 \u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u0448\u0430\u0431\u043b\u043e\u043d \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e.<\/p>\n<p>\u041c\u043d\u0435 \u0436\u0435 \u043d\u0443\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u0434\u043e\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0448\u0430\u0431\u043b\u043e\u043d <a href=\"https:\/\/github.com\/acacode\/swagger-typescript-api\/blob\/master\/templates\/default\/api.ejs\" rel=\"noopener noreferrer nofollow\">api.ejs<\/a>. \u042f \u0434\u043e\u0431\u0430\u0432\u0438\u043b \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0443\u044e \u0437\u0430\u043f\u0438\u0441\u044c:<\/p>\n<pre><code class=\"javascript\">export const get&lt;%~ config.apiClassName %> = (config: ApiConfig, params: RequestParams) => ({   &lt;% for (const { routes: combinedRoutes = [], moduleName } of routes.combined) { %>     &lt;% for (const route of combinedRoutes) { %>      &lt;%~ includeFile('.\/procedure-call-getter.ejs', { ...it, moduleName, route }) %>      &lt;% } %>   &lt;% } %><\/code><\/pre>\n<p>\u042f \u043d\u0435 \u0433\u0443\u0440\u0443 \u043f\u043e ejs-\u0448\u0430\u0431\u043b\u043e\u043d\u0430\u043c \u0438 \u043d\u0430\u043f\u0438\u0441\u0430\u043b \u044d\u0442\u043e \u043f\u043e \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0438 \u0441 \u0443\u0436\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u043c \u043a\u043e\u0434\u043e\u043c. \u0422\u0430\u043a \u0447\u0442\u043e, \u0434\u0443\u043c\u0430\u044e, \u043b\u044e\u0431\u043e\u0439 \u0436\u0435\u043b\u0430\u044e\u0449\u0438\u0439 \u0441\u043c\u043e\u0436\u0435\u0442 \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u0442\u044c\u0441\u044f \u043f\u0440\u0438 \u0436\u0435\u043b\u0430\u043d\u0438\u0438.<\/p>\n<p>\u041a\u0430\u043a \u0432\u0438\u0434\u0438\u0442\u0435, \u044f \u0434\u043e\u0431\u0430\u0432\u0438\u043b \u0441\u0432\u043e\u0439 \u043f\u043e\u0434\u0448\u0430\u0431\u043b\u043e\u043d <code>procedure-call-getter.ejs<\/code>. \u041e\u043d \u0441\u0434\u0435\u043b\u0430\u043d \u043f\u043e \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0438 \u0441 <code>procedure-call.ejs<\/code>. \u0412\u043e\u0442 \u0447\u0442\u043e \u044f \u0442\u0430\u043c \u0443\u043a\u0430\u0437\u0430\u043b:<\/p>\n<pre><code class=\"javascript\">&lt;% const { utils, route, config, moduleName } = it; const { requestBodyInfo, responseBodyInfo, specificArgNameResolver } = route; const { _, getInlineParseContent, getParseContent, parseSchema, getComponentByRef, require } = utils; const { parameters, path, method, payload, query, formData, security, requestParams } = route.request; const { type, errorType, contentTypes } = route.response; const { HTTP_CLIENT, RESERVED_REQ_PARAMS_ARG_NAMES } = config.constants; const queryName = (query &amp;&amp; query.name) || \"query\"; const pathParams = _.values(parameters); const pathParamsNames = _.map(pathParams, \"name\");  const isFetchTemplate = config.httpClientType === HTTP_CLIENT.FETCH;  const requestConfigParam = {     name: specificArgNameResolver.resolve(RESERVED_REQ_PARAMS_ARG_NAMES),     optional: true,     type: \"RequestParams\",     defaultValue: \"{}\", }  const argToTmpl = ({ name, optional, type, defaultValue }) => `${name}${!defaultValue &amp;&amp; optional ? '?' : ''}: ${type}${defaultValue ? ` = ${defaultValue}` : ''}`; const argToName = ({ name }) => name;  const rawWrapperArgs = config.extractRequestParams ?     _.compact([         requestParams &amp;&amp; {           name: pathParams.length ? `{ ${_.join(pathParamsNames, \", \")}, ...${queryName} }` : queryName,           optional: false,           type: getInlineParseContent(requestParams),         },         ...(!requestParams ? pathParams : []),         payload,     ]) :     _.compact([         ...pathParams,         query,         payload,     ])  const wrapperArgs = _     \/\/ Sort by optionality     .sortBy(rawWrapperArgs, [o => o.optional])     .map(argToTmpl)     .join(', ')  const wrapperArgsNames = rawWrapperArgs     .map(argToName)     .join(', ')  const describeReturnType = () => {     if (!config.toJS) return \"\";      switch(config.httpClientType) {         case HTTP_CLIENT.AXIOS: {           return `Promise&lt;AxiosResponse&lt;${type}>>`         }         default: {           return `Promise&lt;HttpResponse&lt;${type}, ${errorType}>`         }     } }  const capitalizeFirstLetter = (string) => {     return string.charAt(0).toUpperCase() + string.slice(1); }  const unCapitalizeFirstLetter = (string) => {     return string.charAt(0).toLowerCase() + string.slice(1); }  %>  &lt;%~ unCapitalizeFirstLetter(config.apiClassName) %>&lt;%~ capitalizeFirstLetter(route.routeName.usage) %>: (&lt;%~ wrapperArgs %>)&lt;%~ config.toJS ? `: ${describeReturnType()}` : \"\" %>  => {     return new &lt;%~ config.apiClassName %>(config).&lt;%~ moduleName %>.&lt;%~ route.routeName.usage %>(         &lt;% if (wrapperArgs.length) { %> &lt;%~ wrapperArgsNames %>, &lt;% } %>         params,     ); },<\/code><\/pre>\n<p>\u0411\u043e\u043b\u044c\u0448\u0430\u044f \u0447\u0430\u0441\u0442\u044c \u0441\u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u043d\u0430 \u0438\u0437 <code>procedure-call.ejs<\/code>, \u0430 \u044f \u0434\u043e\u0431\u0430\u0432\u0438\u043b \u0442\u043e\u043b\u044c\u043a\u043e:<\/p>\n<pre><code class=\"javascript\">const capitalizeFirstLetter = (string) => {     return string.charAt(0).toUpperCase() + string.slice(1); }  const unCapitalizeFirstLetter = (string) => {     return string.charAt(0).toLowerCase() + string.slice(1); }  %>  &lt;%~ unCapitalizeFirstLetter(config.apiClassName) %>&lt;%~ capitalizeFirstLetter(route.routeName.usage) %>: (&lt;%~ wrapperArgs %>)&lt;%~ config.toJS ? `: ${describeReturnType()}` : \"\" %>  => {     return new &lt;%~ config.apiClassName %>(config).&lt;%~ moduleName %>.&lt;%~ route.routeName.usage %>(         &lt;% if (wrapperArgs.length) { %> &lt;%~ wrapperArgsNames %>, &lt;% } %>         params,     ); }, <\/code><\/pre>\n<p>\u0418 \u0442\u0435\u043f\u0435\u0440\u044c \u043d\u0443\u0436\u043d\u0430\u044f \u043c\u043d\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0442\u0430\u043a\u0436\u0435 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442\u0441\u044f:<\/p>\n<figure class=\"full-width\"><\/figure>\n<p><a class=\"anchor\" name=\"config\" id=\"config\"><\/a><\/p>\n<p>\u0410 \u0442\u0435\u043f\u0435\u0440\u044c \u0431\u043e\u043d\u0443\u0441 &#8212; \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u043e\u0433\u043e \u043a\u043e\u043d\u0444\u0438\u0433\u0430. \u0412 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u044f \u043f\u0438\u0441\u0430\u043b, \u0447\u0442\u043e \u043e\u043f\u0446\u0438\u044f <code>--type-prefix<\/code> \u0438\u043b\u0438 <code>--type-suffix<\/code> \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0435\u0442\u0441\u044f \u0438 \u043a \u0442\u0438\u043f\u0430\u043c, \u0438 \u043a \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430\u043c, \u0438 \u0434\u0430\u0436\u0435 \u043a \u0435\u043d\u0430\u043c\u0430\u043c, \u0447\u0442\u043e \u043c\u0435\u043d\u044f \u043b\u0438\u0447\u043d\u043e \u043d\u0435 \u0443\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0435\u0442, \u0442\u0430\u043a \u043a\u0430\u043a \u044f \u043b\u044e\u0431\u043b\u044e \u0438\u0445 \u0440\u0430\u0437\u0434\u0435\u043b\u044f\u0442\u044c, \u043a\u0430\u043a \u0440\u0430\u0437 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u0440\u0430\u0437\u043b\u0438\u0447\u043d\u044b\u0435 \u043f\u0440\u0435\u0444\u0438\u043a\u0441\u044b \u0438 \u0441\u0443\u0444\u0444\u0438\u043a\u0441\u044b. \u0422\u0430\u043a\u0436\u0435 \u044f \u043d\u0430\u043f\u0438\u0441\u0430\u043b, \u0447\u0442\u043e \u044d\u0442\u0443 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0443 \u043c\u043e\u0436\u043d\u043e \u0440\u0435\u0448\u0438\u0442\u044c \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u044b\u0445 \u0448\u0430\u0431\u043b\u043e\u043d\u043e\u0432. \u041a \u0441\u043e\u0436\u0430\u043b\u0435\u043d\u0438\u044e, \u044f \u043e\u0448\u0438\u0431\u0441\u044f.<\/p>\n<p>\u042f \u0438\u0441\u043a\u0430\u043b \u0430\u043b\u044c\u0442\u0435\u0440\u043d\u0430\u0442\u0438\u0432\u043d\u044b\u0435 \u043f\u0443\u0442\u0438 \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u044d\u0442\u043e\u0439 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b, \u043d\u043e, \u043a \u0441\u043e\u0436\u0430\u043b\u0435\u043d\u0438\u044e, \u0438\u0445 \u043d\u0435\u0442. \u0412\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u044f \u043f\u043e\u0437\u0436\u0435 \u0441\u0434\u0435\u043b\u0430\u044e \u0432\u043a\u043b\u0430\u0434 \u0432 \u044d\u0442\u043e\u0442 \u043f\u0440\u043e\u0435\u043a\u0442, \u0442\u0430\u043a \u043a\u0430\u043a \u0443\u0436\u0435 \u043e\u0441\u043d\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u043b\u0441\u044f, \u043a\u0430\u043a \u043e\u043d \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442. \u0418 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u044d\u0442\u043e\u0442 \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e.<\/p>\n<p>\u0410 \u043f\u043e\u043a\u0430 \u044f \u0441 \u044d\u0442\u0438\u043c \u0440\u0430\u0437\u0431\u0438\u0440\u0430\u043b\u0441\u044f, \u044f \u0443\u0437\u043d\u0430\u043b, \u043a\u0430\u043a \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u0443\u044e \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044e \u0434\u043b\u044f \u043a\u043e\u0434\u043e\u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438. \u042d\u0442\u043e \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043f\u043e\u043b\u0435\u0437\u043d\u044b\u043c, \u0435\u0441\u043b\u0438 \u0432\u0430\u043c \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u0442\u044c\u0441\u044f, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0437\u0430\u043c\u0435\u043d\u0438\u0442\u044c \u0442\u0438\u043f\u044b \u0434\u043b\u044f \u0434\u0430\u0442 \u0438\u043b\u0438 \u0447\u0435\u0433\u043e-\u0442\u043e \u0435\u0449\u0435.<\/p>\n<p>\u0412 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 \u0445\u043e\u0440\u043e\u0448\u043e \u043e\u043f\u0438\u0441\u0430\u043d\u043e, \u0447\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u043e\u0433\u043e \u043a\u043e\u043d\u0444\u0438\u0433\u0430, \u043d\u043e \u043d\u0435\u0442 \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u0432, \u043a\u0430\u043a \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0435\u0433\u043e \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0444\u043b\u0430\u0433\u0430 <code>--custom-config<\/code>. \u0410 \u044d\u0442\u043e \u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0432\u0441\u0442\u0430\u0432\u0438\u0442 \u0432 <a href=\"https:\/\/github.com\/acacode\/swagger-typescript-api\/issues\/691\" rel=\"noopener noreferrer nofollow\">\u0442\u0443\u043f\u0438\u043a<\/a> \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439.<\/p>\n<p>\u0412\u0441\u0435 \u043f\u0440\u043e\u0441\u0442\u043e! \u0414\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043f\u0435\u0440\u0435\u0434\u0430\u0442\u044c \u043f\u0443\u0442\u044c \u0434\u043e \u0444\u0430\u0439\u043b\u0430 \u0441 \u0432\u0430\u0448\u0438\u043c \u043a\u043e\u043d\u0444\u0438\u0433\u043e\u043c \u0447\u0435\u0440\u0435\u0437 \u044d\u0442\u0443 \u043e\u043f\u0446\u0438\u044e:<\/p>\n<pre><code class=\"json\">{   \"swagger:generate-contact-data\": \"sta --path swagger\/contact-data.yaml --output src\/services\/contact-data\/ --api-class-name ContactDataApi --responses --type-prefix I --templates templates\/default --custom-config generator.config.js\" }<\/code><\/pre>\n<p>\u0410 \u0432\u043e\u0442 \u043f\u0440\u0438\u043c\u0435\u0440 \u043a\u043e\u043d\u0444\u0438\u0433\u0430:<\/p>\n<pre><code class=\"javascript\">module.exports = {   hooks: {     onPreBuildRoutePath: (routePath) => void 0,     onBuildRoutePath: (routeData) => void 0,     onInsertPathParam: (pathParam) => void 0,     onCreateComponent: (schema) => schema,     onPreParseSchema: (originalSchema, typeName, schemaType) => void 0,     onParseSchema: (originalSchema, parsedSchema) => parsedSchema,     onCreateRoute: (routeData) => routeData,     onInit: (config, codeGenProcess) => config,     onPrepareConfig: (apiConfig) => apiConfig,     onCreateRequestParams: (rawType) => {},     onCreateRouteName: () => {},   onFormatTypeName: (typeName, rawTypeName, schemaType) => {},     onFormatRouteName: (routeInfo, templateRouteName) => {},   },<\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-371492","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/371492","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=371492"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/371492\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=371492"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=371492"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=371492"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}