@codegena/oapi3ts
Version:
Codegeneration from OAS3 to TypeScript
1,077 lines (1,065 loc) • 131 kB
JavaScript
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('typescript'), require('lodash'), require('ajv'), require('json-pointer'), require('@codegena/definitions/json-schema'), require('@codegena/definitions/oas3'), require('prettier/standalone'), require('prettier/parser-markdown'), require('prettier/parser-typescript')) :
typeof define === 'function' && define.amd ? define('@codegena/oapi3ts', ['exports', 'typescript', 'lodash', 'ajv', 'json-pointer', '@codegena/definitions/json-schema', '@codegena/definitions/oas3', 'prettier/standalone', 'prettier/parser-markdown', 'prettier/parser-typescript'], factory) :
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory((global.codegena = global.codegena || {}, global.codegena.oapi3ts = {}), global.typescript, global._, global.Ajv, global.jsonPointer, global.jsonSchema, global.oas3, global.prettier, global.prettierParserMD, global.prettierParserTS));
})(this, (function (exports, typescript, _, Ajv, jsonPointer, jsonSchema, oas3, prettier, prettierParserMD, prettierParserTS) { 'use strict';
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
function _interopNamespace(e) {
if (e && e.__esModule) return e;
var n = Object.create(null);
if (e) {
Object.keys(e).forEach(function (k) {
if (k !== 'default') {
var d = Object.getOwnPropertyDescriptor(e, k);
Object.defineProperty(n, k, d.get ? d : {
enumerable: true,
get: function () { return e[k]; }
});
}
});
}
n["default"] = e;
return Object.freeze(n);
}
var ___default = /*#__PURE__*/_interopDefaultLegacy(_);
var ___namespace = /*#__PURE__*/_interopNamespace(_);
var Ajv__default = /*#__PURE__*/_interopDefaultLegacy(Ajv);
var jsonPointer__namespace = /*#__PURE__*/_interopNamespace(jsonPointer);
var prettier__default = /*#__PURE__*/_interopDefaultLegacy(prettier);
var prettierParserMD__default = /*#__PURE__*/_interopDefaultLegacy(prettierParserMD);
var prettierParserTS__default = /*#__PURE__*/_interopDefaultLegacy(prettierParserTS);
var ParsingProblems = /** @class */ (function () {
function ParsingProblems() {
}
ParsingProblems.parsingWarning = function (message, meta) {
if (this.throwErrorOnWarning) {
throw new ParsingError(message, meta);
}
if (this.onWarnings) {
this.onWarnings(message, meta);
}
console.warn("WARNING: " + message + "\n" + ((meta && meta.jsonPath)
? "JSON Path of problem place: " + meta.jsonPath
: 'No json path attached.'));
};
return ParsingProblems;
}());
ParsingProblems.throwErrorOnWarning = false;
var ParsingError = /** @class */ (function () {
function ParsingError(message, meta) {
this.message = message;
this.meta = meta;
this.name = 'OAS3 Parsing Error';
}
return ParsingError;
}());
/******************************************************************************
Copyright (c) Microsoft Corporation.
Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
***************************************************************************** */
/* global Reflect, Promise */
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b)
if (Object.prototype.hasOwnProperty.call(b, p))
d[p] = b[p]; };
return extendStatics(d, b);
};
function __extends(d, b) {
if (typeof b !== "function" && b !== null)
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
}
var __assign = function () {
__assign = Object.assign || function __assign(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s)
if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
function __rest(s, e) {
var t = {};
for (var p in s)
if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function")
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
t[p[i]] = s[p[i]];
}
return t;
}
function __decorate(decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
r = Reflect.decorate(decorators, target, key, desc);
else
for (var i = decorators.length - 1; i >= 0; i--)
if (d = decorators[i])
r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
}
function __param(paramIndex, decorator) {
return function (target, key) { decorator(target, key, paramIndex); };
}
function __metadata(metadataKey, metadataValue) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function")
return Reflect.metadata(metadataKey, metadataValue);
}
function __awaiter(thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try {
step(generator.next(value));
}
catch (e) {
reject(e);
} }
function rejected(value) { try {
step(generator["throw"](value));
}
catch (e) {
reject(e);
} }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
}
function __generator(thisArg, body) {
var _ = { label: 0, sent: function () { if (t[0] & 1)
throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function () { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f)
throw new TypeError("Generator is already executing.");
while (_)
try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done)
return t;
if (y = 0, t)
op = [op[0] & 2, t.value];
switch (op[0]) {
case 0:
case 1:
t = op;
break;
case 4:
_.label++;
return { value: op[1], done: false };
case 5:
_.label++;
y = op[1];
op = [0];
continue;
case 7:
op = _.ops.pop();
_.trys.pop();
continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) {
_ = 0;
continue;
}
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) {
_.label = op[1];
break;
}
if (op[0] === 6 && _.label < t[1]) {
_.label = t[1];
t = op;
break;
}
if (t && _.label < t[2]) {
_.label = t[2];
_.ops.push(op);
break;
}
if (t[2])
_.ops.pop();
_.trys.pop();
continue;
}
op = body.call(thisArg, _);
}
catch (e) {
op = [6, e];
y = 0;
}
finally {
f = t = 0;
}
if (op[0] & 5)
throw op[1];
return { value: op[0] ? op[1] : void 0, done: true };
}
}
var __createBinding = Object.create ? (function (o, m, k, k2) {
if (k2 === undefined)
k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function () { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function (o, m, k, k2) {
if (k2 === undefined)
k2 = k;
o[k2] = m[k];
});
function __exportStar(m, o) {
for (var p in m)
if (p !== "default" && !Object.prototype.hasOwnProperty.call(o, p))
__createBinding(o, m, p);
}
function __values(o) {
var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
if (m)
return m.call(o);
if (o && typeof o.length === "number")
return {
next: function () {
if (o && i >= o.length)
o = void 0;
return { value: o && o[i++], done: !o };
}
};
throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
}
function __read(o, n) {
var m = typeof Symbol === "function" && o[Symbol.iterator];
if (!m)
return o;
var i = m.call(o), r, ar = [], e;
try {
while ((n === void 0 || n-- > 0) && !(r = i.next()).done)
ar.push(r.value);
}
catch (error) {
e = { error: error };
}
finally {
try {
if (r && !r.done && (m = i["return"]))
m.call(i);
}
finally {
if (e)
throw e.error;
}
}
return ar;
}
/** @deprecated */
function __spread() {
for (var ar = [], i = 0; i < arguments.length; i++)
ar = ar.concat(__read(arguments[i]));
return ar;
}
/** @deprecated */
function __spreadArrays() {
for (var s = 0, i = 0, il = arguments.length; i < il; i++)
s += arguments[i].length;
for (var r = Array(s), k = 0, i = 0; i < il; i++)
for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
r[k] = a[j];
return r;
}
function __spreadArray(to, from, pack) {
if (pack || arguments.length === 2)
for (var i = 0, l = from.length, ar; i < l; i++) {
if (ar || !(i in from)) {
if (!ar)
ar = Array.prototype.slice.call(from, 0, i);
ar[i] = from[i];
}
}
return to.concat(ar || Array.prototype.slice.call(from));
}
function __await(v) {
return this instanceof __await ? (this.v = v, this) : new __await(v);
}
function __asyncGenerator(thisArg, _arguments, generator) {
if (!Symbol.asyncIterator)
throw new TypeError("Symbol.asyncIterator is not defined.");
var g = generator.apply(thisArg, _arguments || []), i, q = [];
return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i;
function verb(n) { if (g[n])
i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; }
function resume(n, v) { try {
step(g[n](v));
}
catch (e) {
settle(q[0][3], e);
} }
function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); }
function fulfill(value) { resume("next", value); }
function reject(value) { resume("throw", value); }
function settle(f, v) { if (f(v), q.shift(), q.length)
resume(q[0][0], q[0][1]); }
}
function __asyncDelegator(o) {
var i, p;
return i = {}, verb("next"), verb("throw", function (e) { throw e; }), verb("return"), i[Symbol.iterator] = function () { return this; }, i;
function verb(n, f) { i[n] = o[n] ? function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : f ? f(v) : v; } : f; }
}
function __asyncValues(o) {
if (!Symbol.asyncIterator)
throw new TypeError("Symbol.asyncIterator is not defined.");
var m = o[Symbol.asyncIterator], i;
return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
function settle(resolve, reject, d, v) { Promise.resolve(v).then(function (v) { resolve({ value: v, done: d }); }, reject); }
}
function __makeTemplateObject(cooked, raw) {
if (Object.defineProperty) {
Object.defineProperty(cooked, "raw", { value: raw });
}
else {
cooked.raw = raw;
}
return cooked;
}
;
var __setModuleDefault = Object.create ? (function (o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function (o, v) {
o["default"] = v;
};
function __importStar(mod) {
if (mod && mod.__esModule)
return mod;
var result = {};
if (mod != null)
for (var k in mod)
if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k))
__createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
}
function __importDefault(mod) {
return (mod && mod.__esModule) ? mod : { default: mod };
}
function __classPrivateFieldGet(receiver, state, kind, f) {
if (kind === "a" && !f)
throw new TypeError("Private accessor was defined without a getter");
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver))
throw new TypeError("Cannot read private member from an object whose class did not declare it");
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
}
function __classPrivateFieldSet(receiver, state, value, kind, f) {
if (kind === "m")
throw new TypeError("Private method is not writable");
if (kind === "a" && !f)
throw new TypeError("Private accessor was defined without a setter");
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver))
throw new TypeError("Cannot write private member to an object whose class did not declare it");
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
}
function __classPrivateFieldIn(state, receiver) {
if (receiver === null || (typeof receiver !== "object" && typeof receiver !== "function"))
throw new TypeError("Cannot use 'in' operator on non-object");
return typeof state === "function" ? receiver === state : state.has(receiver);
}
/* tslint:disable triple-equals */
var defaultConfig = {
jsonPathRegex: /([\w:\/\\\.]+)?#(\/?[\w+\/?]+)/,
implicitTypesRefReplacement: false,
parametersModelName: function (baseTypeName) { return baseTypeName + "Parameters"; },
headersModelName: function (baseTypeName, code) { return baseTypeName + "HeadersResponse" + code; },
requestModelName: function (baseTypeName) { return baseTypeName + "Request"; },
responseModelName: function (baseTypeName, code, contentTypeKey) {
if (contentTypeKey === void 0) { contentTypeKey = null; }
return "" + baseTypeName + ___default["default"].capitalize(contentTypeKey) + "Response" + code;
},
typingsDirectory: './typings',
mocksDirectory: './mocks',
excludeFromComparison: [
'description',
'title',
'example',
'default',
'readonly',
],
defaultServerInfo: [
{
url: 'http://localhost'
}
]
};
var jsonPathRegex = /([\w:\/\\\.]+)?#(\/?[\w+\/?]+)/;
/**
* @param pieces
* @return
* JSON-Path according to [RFC-6901](https://tools.ietf.org/html/rfc6901)
* TODO refactor: move to common helper
*/
function makeJsonPath() {
var pieces = [];
for (var _i = 0; _i < arguments.length; _i++) {
pieces[_i] = arguments[_i];
}
return jsonPointer__namespace.compile(pieces);
}
/**
* Rethrow {@link ParsingError} if original error already handled at inner level
* @param {ParsingError | any} error
*/
function rethrowParsingError(error) {
if (error instanceof ParsingError) {
throw error;
}
}
/**
* Базовый класс загрузчика.
*/
var BaseConvertor = /** @class */ (function () {
function BaseConvertor(config) {
if (config === void 0) { config = defaultConfig; }
this.config = config;
}
BaseConvertor.prototype.loadOAPI3Structure = function (structure) {
if (!structure || !___default["default"].isObjectLike(structure)) {
throw new ParsingError([
"Expected structure to be object but got:",
JSON.stringify(structure, null, ' ')
].join('\n'));
}
this._operationsMeta = [];
this._structure = structure;
};
BaseConvertor.prototype.setForeignSchemeFn = function (fn) {
if (!___default["default"].isFunction(fn)) {
throw new ParsingError('Error in `setForeignSchemeFn`: argument has to be function!');
}
this._foreignSchemaFn = function (jsonPath) {
try {
return fn(jsonPath);
}
catch (e) {
throw new ParsingError('Error when trying to resolve schema!', { jsonPath: jsonPath });
}
};
};
BaseConvertor.prototype.getApiMeta = function () {
return this._operationsMeta;
};
/**
* Getting of "entry-points" from structure in {@link _structure} early
* loaded by {@link loadOAPI3Structure}.
*
* Entrypoints are:
*
* - Parameters
* - Requests
* - Responses
*
* ### Why it needed?
*
* Entrypoints is needed to use [Convertor.renderRecursive]{@link Convertor.renderRecursive}.
* It's like a pulling on thread where entrypoints are outstanding trheads.
*
* @param ApiMetaInfo metaInfo
* Mutable object where meta-information accumulates during
* API-info extracting.
*/
BaseConvertor.prototype.getOAPI3EntryPoints = function (context, metaInfo) {
var _this = this;
if (context === void 0) { context = {}; }
if (metaInfo === void 0) { metaInfo = []; }
var alreadyConverted = [];
// parameters
var methodsSchemes = this.getMethodsSchemes(metaInfo);
var dataTypeContainers = ___default["default"].map(methodsSchemes, function (schema, modelName) {
var container = _this.convert(schema, context, modelName);
// TODO Crutch. This class should never know about assignedTypes
// in GenericDescriptor
if (schema instanceof jsonSchema.Generic) {
___default["default"].each(container, function (description) {
if (description['assignedTypes']) {
description['assignedTypes'] = ['TCode', 'TContentType', 'T1', 'T2'];
}
});
}
// Исключение дубликатов.
// Дубликаты появляются, когда типы данные, которые
// ссылаются ($ref) без изменения на другие, подменяются
// моделями из `schema`.
return ___default["default"].map(container, function (descr) {
// Excluding of elements having common `originalSchemaPath`
// and simultaneously already related with.
if (descr.originalSchemaPath) {
if (___default["default"].findIndex(alreadyConverted, function (v) { return v === descr.originalSchemaPath; }) !== -1) {
return null;
}
alreadyConverted.push(descr.originalSchemaPath);
}
return descr;
});
});
var dataTypeContainer = ___default["default"].flattenDepth(dataTypeContainers);
return ___default["default"].compact(dataTypeContainer);
};
/**
* Получить дескриптор типа по JSON Path:
* возвращает уже созданный ранее, или создает
* новый при первом упоминании.
*
* @param path
* @param context
*/
BaseConvertor.prototype.findTypeByPath = function (path, context) {
var alreadyFound = ___default["default"].find(___default["default"].values(context), function (v) { return v.originalSchemaPath === path; });
return alreadyFound
? [alreadyFound]
: this._processSchema(path, context);
};
/**
* @deprecated will be renamed to `getSchemaByRef`
* @param ref
* @param pathWhereReferred
* @return
*/
BaseConvertor.prototype.getSchemaByPath = function (ref, pathWhereReferred) {
var pathMatches = ref.match(jsonPathRegex);
if (pathMatches) {
var filePath = pathMatches[1];
var schemaPath = pathMatches[2];
var src = filePath
? this._getForeignSchema(filePath)
: this._structure;
var result = ___default["default"].get(src, ___default["default"].trim(schemaPath, '#/\\').replace(/[\\\/]/g, '.'), undefined);
if (result === undefined) {
ParsingProblems.parsingWarning("Cant resolve " + ref + "!", {
oasStructure: this._structure,
relatedRef: ref,
jsonPath: pathWhereReferred
? makeJsonPath.apply(void 0, __spreadArray([], __read(pathWhereReferred))) : undefined
});
}
return result;
}
else {
throw new ParsingError("JSON Path error: " + ref + " is not valid JSON path!", {
oasStructure: this._structure,
relatedRef: ref,
jsonPath: pathWhereReferred
? makeJsonPath.apply(void 0, __spreadArray([], __read(pathWhereReferred))) : undefined
});
}
};
/**
* Извлечени схем из параметров, ответов и тел запросов для API.
* @param metaInfo
* Place for storing meta-info of API-method.
*/
BaseConvertor.prototype.getMethodsSchemes = function (metaInfo) {
var e_1, _a;
var struct = this._structure;
if (!struct) {
throw new ParsingError([
'There is no structure loaded!',
'Please, call method `loadOAPI3Structure` before!'
].join(' '));
}
var result = {};
var paths = struct.paths;
if (!paths) {
throw new ParsingError('No paths presented in OAS structure!', { oasStructure: struct });
}
for (var path in paths) {
// skip proto's properties
if (!paths.hasOwnProperty(path)) {
continue;
}
var jsonPathToPath = ['paths', path];
if (!path) {
ParsingProblems.parsingWarning('Path key cant be empty. Skipped.', {
oasStructure: struct,
jsonPath: makeJsonPath.apply(void 0, __spreadArray([], __read(jsonPathToPath)))
});
continue;
}
var pathItem = struct.paths[path];
if (!___default["default"].isObjectLike(pathItem)) {
ParsingProblems.parsingWarning('Item of "paths" should be object like. Skipped.', {
oasStructure: struct,
jsonPath: makeJsonPath.apply(void 0, __spreadArray([], __read(jsonPathToPath)))
});
continue;
}
var methods = [
'delete',
'get',
'head',
'options',
'patch',
'post',
'put',
'trace',
];
try {
for (var methods_1 = (e_1 = void 0, __values(methods)), methods_1_1 = methods_1.next(); !methods_1_1.done; methods_1_1 = methods_1.next()) {
var methodName = methods_1_1.value;
// skip proto's properties
if (!pathItem.hasOwnProperty(methodName)) {
continue;
}
var apiOperation = pathItem[methodName];
var jsonPathToOperation = __spreadArray(__spreadArray([], __read(jsonPathToPath)), [methodName]);
if (!___default["default"].isObjectLike(apiOperation)) {
ParsingProblems.parsingWarning('Operation should be object like. Skipped.', {
oasStructure: struct,
jsonPath: makeJsonPath.apply(void 0, __spreadArray([], __read(jsonPathToOperation)))
});
continue;
}
var baseTypeName = this._getOperationBaseName(apiOperation, methodName, path, jsonPathToOperation);
var servers = this._getOperationServers(apiOperation, jsonPathToOperation);
var metaInfoItem = {
apiSchemaFile: 'domain-api-schema',
baseTypeName: baseTypeName,
headersSchema: null,
headersModelName: null,
method: methodName.toUpperCase(),
mockData: {},
paramsModelName: null,
paramsSchema: null,
path: path,
queryParams: [],
requestIsRequired: false,
requestModelName: null,
requestSchema: null,
responseModelName: null,
responseSchema: null,
servers: servers,
// default noname
typingsDependencies: [],
typingsDirectory: 'typings',
};
var jsonSubPathToOperation = void 0;
try {
jsonSubPathToOperation = __spreadArray(__spreadArray([], __read(jsonPathToOperation)), ['parameters']);
// pick Parameters schema
___default["default"].assign(result, this._pickApiMethodParameters(metaInfoItem, apiOperation.parameters, jsonSubPathToOperation));
}
catch (error) {
rethrowParsingError(error);
throw new ParsingError('An error occurred at method parameters fetching', {
oasStructure: struct,
jsonPath: makeJsonPath.apply(void 0, __spreadArray([], __read(jsonSubPathToOperation))),
originalError: error
});
}
try {
jsonSubPathToOperation = __spreadArray(__spreadArray([], __read(jsonPathToOperation)), ['responses']);
// pick Responses schema
___default["default"].assign(result, this._pickApiMethodResponses(metaInfoItem, apiOperation.responses || {}, jsonSubPathToOperation));
}
catch (error) {
rethrowParsingError(error);
throw new ParsingError('An error occurred at method responses fetching', {
oasStructure: struct,
jsonPath: makeJsonPath.apply(void 0, __spreadArray([], __read(jsonSubPathToOperation))),
originalError: error
});
}
try {
jsonSubPathToOperation = __spreadArray(__spreadArray([], __read(jsonPathToOperation)), ['requestBody']);
// pick Request Body schema
___default["default"].assign(result, this._pickApiMethodRequest(apiOperation, metaInfoItem, __spreadArray([], __read(jsonSubPathToOperation))));
}
catch (error) {
rethrowParsingError(error);
throw new ParsingError('An error occurred at method request body fetching', {
oasStructure: struct,
jsonPath: makeJsonPath.apply(void 0, __spreadArray([], __read(jsonSubPathToOperation))),
originalError: error
});
}
metaInfo.push(metaInfoItem);
this._operationsMeta.push({
operationJsonPath: jsonPathToOperation,
apiMeta: metaInfoItem,
});
}
}
catch (e_1_1) { e_1 = { error: e_1_1 }; }
finally {
try {
if (methods_1_1 && !methods_1_1.done && (_a = methods_1.return)) _a.call(methods_1);
}
finally { if (e_1) throw e_1.error; }
}
}
return result;
};
/**
* Get parameters from the `parameters` section
* in method into {@link ApiMetaInfo}-object
*/
BaseConvertor.prototype._pickApiMethodParameters = function (metaInfoItem, parameters, jsonPathToOperation) {
var _this = this;
var result = {};
var paramsModelName = this.config.parametersModelName(metaInfoItem.baseTypeName);
var paramsSchema = {
properties: {},
required: [],
type: 'object'
};
// process parameters
___default["default"].each(parameters || [], function (parameter, index) {
if (parameter.$ref) {
parameter = ___default["default"].merge(___default["default"].omit(parameter, ['$ref']), _this.getSchemaByPath(parameter.$ref, __spreadArray(__spreadArray([], __read(jsonPathToOperation)), [String(index)])));
}
if (parameter.schema) {
paramsSchema.properties[parameter.name] = parameter.schema;
if (parameter.description) {
parameter.schema.description = parameter.description;
}
if (parameter.readOnly) {
paramsSchema.properties[parameter.name].readOnly = true;
}
if (parameter.required) {
paramsSchema.required.push(parameter.name);
}
if (Number(index) === 0) {
// metaInfoItem.typingsDependencies.push(paramsModelName);
metaInfoItem.paramsModelName = paramsModelName;
metaInfoItem.paramsSchema = paramsSchema;
}
if (parameter.in === oas3.Oas3ParameterTarget.Query) {
metaInfoItem.queryParams.push(parameter.name);
}
if (!paramsSchema.description) {
paramsSchema.description =
"Model of parameters for API `" + metaInfoItem.path + "`";
}
result[paramsModelName] = paramsSchema;
}
});
if (result[paramsModelName]) {
metaInfoItem.typingsDependencies.push(paramsModelName);
}
return result;
};
BaseConvertor.prototype._pickApiMethodResponses = function (metaInfoItem, responses, jsonPathToOperation) {
var _this = this;
var result = {};
___default["default"].each(responses, function (response, code) {
// todo do tests when $ref to schema.responses
if (response.$ref) {
response = ___default["default"].merge(___default["default"].omit(response, ['$ref']), _this.getSchemaByPath(response.$ref, __spreadArray(__spreadArray([], __read(jsonPathToOperation)), [String(code)])));
}
var mediaTypes = response.content
|| response.schema // Case for OAS2
|| {}; // Fallback
// if content set, but empty
if (___default["default"].keys(mediaTypes).length === 0) {
mediaTypes['application/json'] = null;
}
// todo пока обрабатываются только контент и заголовки
___default["default"].each(mediaTypes || {}, function (mediaContent, contentTypeKey) {
// todo do fallback if no `schema property`
var schema = ___default["default"].get(mediaContent, 'schema')
|| {
description: 'Empty response',
type: 'null',
}; // by default
if (!metaInfoItem.responseSchema) {
metaInfoItem.responseSchema = {};
}
// add description if it's set
if (response.description) {
schema.description = response.description;
}
___default["default"].set(metaInfoItem.responseSchema, [code, contentTypeKey], schema);
});
if (response.headers) {
// TODO has to be tested
var modelName = _this.config.headersModelName(metaInfoItem.baseTypeName, code);
result[modelName] = {
properties: response.headers,
type: 'object'
};
}
});
if (metaInfoItem.responseSchema) {
var modelName = this.config.responseModelName(metaInfoItem.baseTypeName, '', '');
metaInfoItem.responseModelName = modelName;
metaInfoItem.typingsDependencies.push(modelName);
result[modelName] = new jsonSchema.Generic(___default["default"].mapValues(metaInfoItem.responseSchema, function (subSchema) { return new jsonSchema.Generic(subSchema); }));
}
return result;
};
BaseConvertor.prototype._pickApiMethodRequest = function (apiOperation, metaInfoItem, jsonPathToOperation) {
var requestBody = apiOperation.requestBody;
var responses;
if (!requestBody) {
return null;
}
else {
metaInfoItem.requestIsRequired = !!requestBody.required;
if (!requestBody.content) {
return null;
}
var modelName = this.config.requestModelName(metaInfoItem.baseTypeName);
responses = ___default["default"](requestBody.content)
.mapValues(function (mediaContent, mediaTypeName) {
var mapResult = mediaContent.schema ? Object.assign({}, mediaContent.schema) : null;
if (apiOperation.requestBody.description && !mapResult.description) {
mapResult.description = apiOperation.requestBody.description;
}
return mapResult;
})
.value();
metaInfoItem.requestModelName = modelName;
metaInfoItem.requestSchema = responses;
metaInfoItem.typingsDependencies.push(modelName);
return ___default["default"].zipObject([modelName], [new jsonSchema.Generic(responses)]);
}
};
/**
* Получение нового дескриптора на основе JSON Path
* из текущей структуры.
*
* @param path
* @param context
*/
BaseConvertor.prototype._processSchema = function (path, context) {
var schema = this.getSchemaByPath(path);
var modelName = (___default["default"].trim(path, '/\\').match(/(\w+)$/) || [])[1];
if (!schema) {
throw new Error("Error: can't find schema with path: " + path + "!");
}
var results = this.convert(schema, context, modelName, null, path);
___default["default"].each(results, function (result) {
context[result.originalSchemaPath || result.modelName] = result;
});
return results;
};
BaseConvertor.prototype._getForeignSchema = function (ref) {
if (this._foreignSchemaFn) {
return this._foreignSchemaFn(ref);
}
else {
throw new ParsingError([
'Function for getting foreign scheme not set.',
"Use setForeignSchemeFn(). Path: " + ref + "."
].join('\n'), {
oasStructure: this._structure,
relatedRef: ref
});
}
};
BaseConvertor.prototype._getOperationBaseName = function (apiOperation, methodName, path, jsonPathToOperation) {
if (!apiOperation.operationId || !___default["default"].isString(apiOperation.operationId)) {
var baseNameFallback = ___default["default"].upperFirst(___default["default"].camelCase(jsonPathToOperation.join('-').replace(/[^\-\w]/g, '')));
ParsingProblems.parsingWarning([
"Wrong operation id \"" + apiOperation.operationId + "\".",
"Fallback basename is: \"" + baseNameFallback + "\"."
].join('\n'), {
oasStructure: this._structure,
jsonPath: makeJsonPath.apply(void 0, __spreadArray(__spreadArray([], __read(jsonPathToOperation)), ['operationId']))
});
return baseNameFallback;
}
var operationId = ___default["default"].camelCase(apiOperation.operationId.trim().replace(/[^\w+]/g, '_'));
return ___default["default"].upperFirst(operationId) || [
___default["default"].capitalize(methodName),
___default["default"].upperFirst(___default["default"].camelCase(path))
].join('');
};
BaseConvertor.prototype._getOperationServers = function (apiOperation, jsonPathToOperation) {
var servers = apiOperation.servers || this._structure.servers;
if (servers !== undefined && !___default["default"].isArray(servers)) {
ParsingProblems.parsingWarning('Servers should be array. Skipped.', {
oasStructure: this._structure,
jsonPath: makeJsonPath.apply(void 0, __spreadArray(__spreadArray([], __read(jsonPathToOperation)), ['servers']))
});
servers = [];
}
if (!servers || servers.length < 1) {
servers = defaultConfig.defaultServerInfo;
}
return servers;
};
return BaseConvertor;
}());
var commonPrettierOptions = {
plugins: [prettierParserMD__default["default"], prettierParserTS__default["default"]],
proseWrap: 'always',
singleQuote: true
};
var AbstractTypeScriptDescriptor = /** @class */ (function () {
function AbstractTypeScriptDescriptor(schema,
/**
* Родительский конвертор, который используется
* чтобы создавать вложенные дескрипторы.
*/
convertor,
/**
* Рабочий контекст
*/
context,
/**
* Название этой модели (может быть string
* или null).
*/
modelName,
/*
* Предлагаемое имя для типа данных: может
* применяться, если тип данных анонимный, но
* необходимо вынести его за пределы родительской
* модели по-ситуации (например, в случае с Enum).
*/
suggestedModelName,
/**
* Путь до оригинальной схемы, на основе
* которой было создано описание этого типа данных.
*/
originalSchemaPath,
/**
* Родительсткие модели.
*/
ancestors) {
this.schema = schema;
this.convertor = convertor;
this.context = context;
this.modelName = modelName;
this.suggestedModelName = suggestedModelName;
this.originalSchemaPath = originalSchemaPath;
this.ancestors = ancestors;
}
/**
* todo todo https://github.com/koshevy/codegena/issues/33
*/
AbstractTypeScriptDescriptor.prototype.getComments = function () {
return this.makeComment(this.schema.title, this.schema.description);
};
AbstractTypeScriptDescriptor.prototype.toString = function () {
return "" + (this.modelName || 'Anonymous Type') + (this.originalSchemaPath
? "(" + this.originalSchemaPath + ")"
: '');
};
/**
* Formatting code. Supports TypeScript and Markdown essences.
* todo https://github.com/koshevy/codegena/issues/33
*
* @param code
* @param codeType
*/
AbstractTypeScriptDescriptor.prototype.formatCode = function (code, codeType) {
if (codeType === void 0) { codeType = 'typescript'; }
var prettierOptions = Object.assign({ parser: codeType }, commonPrettierOptions);
return prettier__default["default"].format(code, prettierOptions);
};
/**
* todo todo https://github.com/koshevy/codegena/issues/33
*/
AbstractTypeScriptDescriptor.prototype.makeComment = function (title, description) {
var markdownText = this.formatCode([
title ? "## " + title : '',
(description || '').trim()
].join('\n'), 'markdown');
var commentLines = ___default["default"].compact(markdownText.split('\n'));
var comment = '';
if (commentLines.length) {
comment = "/**\n" + ___default["default"].map(commentLines, function (v) { return " * " + v; }).join('\n') + "\n */\n";
}
return comment;
};
return AbstractTypeScriptDescriptor;
}());
var AnyTypeScriptDescriptor = /** @class */ (function (_super) {
__extends(AnyTypeScriptDescriptor, _super);
function AnyTypeScriptDescriptor(schema,
/**
* Родительский конвертор, который используется
* чтобы создавать вложенные дескрипторы.
*/
convertor,
/**
* Рабочий контекст
*/
context,
/**
* Название этой модели (может быть string
* или null).
*/
modelName,
/*
* Предлагаемое имя для типа данных: может
* применяться, если тип данных анонимный, но
* необходимо вынести его за пределы родительской
* модели по-ситуации (например, в случае с Enum).
*/
suggestedModelName,
/**
* Путь до оригинальной схемы, на основе
* которой было создано описание этого типа данных.
*/
originalSchemaPath) {
var _this = _super.call(this, schema, convertor, context, modelName, suggestedModelName, originalSchemaPath) || this;
_this.schema = schema;
_this.context = context;
_this.modelName = modelName;
_this.suggestedModelName = suggestedModelName;
_this.originalSchemaPath = originalSchemaPath;
return _this;
}
/**
* Рендер типа данных в строку.
*
* @param childrenDependencies
* Immutable-массив, в который складываются все зависимости
* типов-потомков (если такие есть).
* @param rootLevel
* Говорит о том, что это рендер "корневого"
* уровня — то есть, не в составе другого типа,
* а самостоятельно.
*
*/
AnyTypeScriptDescriptor.prototype.render = function (childrenDependencies, rootLevel) {
if (rootLevel === void 0) { rootLevel = true; }
var comment = this.getComments();
return (rootLevel ? comment + "export type " + this.modelName + " = " : '') + "any";
};
return AnyTypeScriptDescriptor;
}(AbstractTypeScriptDescriptor));
var ArrayTypeScriptDescriptor = /** @class */ (function (_super) {
__extends(ArrayTypeScriptDescriptor, _super);
function ArrayTypeScriptDescriptor(schema,
/**
* Родительский конвертор, который используется
* чтобы создавать вложенные дескрипторы.
*/
convertor,
/**
* Рабочий контекст
*/
context,
/**
* Название этой модели (может быть string
* или null).
*/
modelName,
/*
* Предлагаемое имя для типа данных: может
* применяться, е