diff --git a/CHANGELOG.md b/CHANGELOG.md index a162aeb..a8ea0fe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,23 @@ +## [2.7.0](https://github.com/joolfe/postman-to-openapi/compare/2.6.2...2.7.0) (2022-09-18) + + +### Features + +* disabled but duplicating params (not supported by OpenAPI) ([4310197](https://github.com/joolfe/postman-to-openapi/commit/4310197386afcdd61aa2d640fa7935eda6f44f41)) +* transform disabled option WIP ([b4858a2](https://github.com/joolfe/postman-to-openapi/commit/b4858a2d82beefe72f41d5debf95028711bb041d)) + + +### Bug Fixes + +* incorrect conflict in previous merge ([9face89](https://github.com/joolfe/postman-to-openapi/commit/9face89b85d5a77f07743c7ab3355077c300a40e)) + + +### Documentation + +* update docs about new feature ([d6c1141](https://github.com/joolfe/postman-to-openapi/commit/d6c1141970ac902304f83d116d95c5923635cee0)) +* update typescript definition ([253dec7](https://github.com/joolfe/postman-to-openapi/commit/253dec7bb470a14dc1af6fb323aaae92d6b103c6)) +* updates and links ([5e92c6d](https://github.com/joolfe/postman-to-openapi/commit/5e92c6d83cb61a6d628eb844bb649eafc189c41b)) + ### [2.6.2](https://github.com/joolfe/postman-to-openapi/compare/2.6.1...2.6.2) (2022-09-17) diff --git a/docs/index.md b/docs/index.md index ff5ae2f..cdccd8e 100644 --- a/docs/index.md +++ b/docs/index.md @@ -124,7 +124,7 @@ The third parameter used in the library method is an `options` object containing |------------------|------------------------------------------------------------------------------------| | [info](#info-object) | Basic API information | | [defaultTag](#defaulttag-string) | Values of the default tag object. | -| [pathDepth](#pathdepth-number) | Number of subpaths that should be part of the operation path. | +| [pathDepth](#pathdepth-number) | Number of sub-paths that should be part of the operation path. | | [auth](#auth-object) | Global authorization definition object. | | [servers](#servers-array) | Server list for the OpenApi specs. | | [externalDocs](#externaldocs-object) | Info about the API external documentation. | @@ -144,8 +144,8 @@ The basic information of the API is obtained from Postman collection as describe | `version` | String. The version of the OpenAPI document. | | `description` | String. A short description of the API. | | `termsOfService` | String. A URL to the Terms of Service for the API. MUST be in the format of a URL. | -| `contact` | Object. The contact information for the exposed API. See details in [License and Contact configuration](#license-and-contact-configuration) section. | -| `license` | Object. The license information for the exposed API.See details in [License and Contact configuration](#license-and-contact-configuration) section. | +| `contact` | Object. The contact information for the exposed API. See details in [Pass data as postman collection variables](#pass-data-as-postman-collection-variables) section. | +| `license` | Object. The license information for the exposed API.See details in [Pass data as postman collection variables](#pass-data-as-postman-collection-variables) section. | | `xLogo` | Object. Contain the info for the `x-logo` extension defined by [redoc](https://github.com/Redocly/redoc/blob/master/docs/redoc-vendor-extensions.md#x-logo) | Basically this are the required and relevant parameters defined in OpenAPI spec [info object](http://spec.openapis.org/oas/v3.0.3.html#info-object), an example of the option will be: @@ -253,7 +253,7 @@ The info about the API external documentation, as described in OpenAPI spec [Ext } ``` -This info can be provided as collection variables in the same way as described in section [License and Contact configuration](#license-and-contact-configuration), you can setup the variables `externalDocs.url` and `externalDocs.description` for provide the information. +This info can be provided as collection variables in the same way as described in section [Pass data as postman collection variables](#pass-data-as-postman-collection-variables), you can setup the variables `externalDocs.url` and `externalDocs.description` for provide the information. ### folders (Object) @@ -349,10 +349,20 @@ Take into account that variable values provided in the `additionalVars` Object s ### outputFormat (string) -Indicates the resulting format of the OpenAPI document between `json` and `yaml`, the resulting file will be writte using this format and also the result value fo the method `postmanToOpenApi(...)` will use this format. +Indicates the resulting format of the OpenAPI document between `json` and `yaml`, the resulting file will be write using this format and also the result value fo the method `postmanToOpenApi(...)` will use this format. Default value is `yaml`, if you use a unknown value `yaml` will be used. +### disabledParams (object) + +By default all parameters in the postman collection that has the field `"disabled": true` are ignored and not included in the resulting OpenAPI doc, you can customize this behavior with this options +| Param | Description | +|------------------|------------------------------------------------------------------------------------| +| `includeQuery` | Boolean. Indicates if the "query" parameters disabled should be included into the OpenAPI spec. | +| `includeHeader` | Boolean. Indicates if the "header" parameters disabled should be included into the OpenAPI spec. | + +Please have a look to the [Parameters parsing](#parameters-parsing) section about duplicated parameters names in Headers and Query, this will apply also to the disabled parameters when using this feature. + # Features ## Basic conversion @@ -367,9 +377,9 @@ For fill the OpenAPI [info object](http://spec.openapis.org/oas/v3.0.3.html#info Postman don't have any field at collection level that feat with OpenAPI "version" field (is a required field in OpenAPI specification), so this library look for a variable with name `version` in Postman [collection variables](https://learning.postman.com/docs/sending-requests/variables/#defining-collection-variables) or if variable is not defined then will use the default value `1.0.0`. -You can customize all this information with the [Info option](#info-(object)). +You can customize all this information with the [Info option](#info-object). -For info about how to setup the `contact` and `license` properties have a look to section [License and Contact configuration](#license-and-contact-configuration). +For info about how to setup the `contact` and `license` properties have a look to section [Pass data as postman collection variables](#pass-data-as-postman-collection-variables). Have a look to the [SimplePost collection](https://github.com/joolfe/postman-to-openapi/blob/master/test/v21/SimplePost.json) file for an example of how to use this feature. @@ -395,13 +405,15 @@ For headers and query fields you can indicate that this parameter is mandatory/r Have a look to the [GetMethods collection](https://github.com/joolfe/postman-to-openapi/blob/master/test/resources/input/v21/GetMethods.json), [Headers collection](https://github.com/joolfe/postman-to-openapi/blob/master/test/resources/input/v21/Headers.json) and [PathParams collection](https://github.com/joolfe/postman-to-openapi/blob/master/test/resources/input/v21/PathParams.json) files for examples of how to use this features. +> **Note about duplications:** In Postman is possible to define multiples parameters with the same name/key in Query and Headers sections but in OpenAPI spec the combination of "name" and location (expressed by field "in") in parameters should be unique, to avoid generate invalid OpenAPI spec files the library will only use the first apparition of the parameters and discard the repeated ones, so take into consideration when you define your postman collection. + ## Postman authorization The OpenAPI root [security](http://spec.openapis.org/oas/v3.0.3.html#openapi-object) definition is filled using the authorization method defined at Postman Collection [authorization config](https://learning.postman.com/docs/sending-requests/authorization/#inheriting-auth). Only types 'Basic Auth' and 'Bearer Token' are supported by now. If you define an authorization at postman request level this will overwrite the global defined for this OpenAPI operation. -You can customize the global authorization definition using the [Auth option](#auth-(object)). +You can customize the global authorization definition using the [Auth option](#auth-object). Have a look to the collections [AuthBasic](https://github.com/joolfe/postman-to-openapi/blob/master/test/resources/input/v21/AuthBasic.json), [AuthBearer](https://github.com/joolfe/postman-to-openapi/blob/master/test/resources/input/v21/AuthBearer.json) and [AuthMultiple](https://github.com/joolfe/postman-to-openapi/blob/master/test/resources/input/v21/AuthMultiple.json) for examples of how to use this feature. @@ -427,7 +439,7 @@ Is as easy as define the values in the "Edit Collection" form page inside the ta The variables names will be in dot notation, for example for `contact` fields will be as `contact.name`, `contact.url`... Take into account that fields that are required by OpenAPI specs, as `contact.name`, if not provided then all the section will be ignored. -You can also customize this information using the [Info option](#info-(object)), note that info provided by options will overwrite the variables inside the Postman collection (has more priority) but values will be merged from both sources (postman variables and options). +You can also customize this information using the [Info option](#info-object), note that info provided by options will overwrite the variables inside the Postman collection (has more priority) but values will be merged from both sources (postman variables and options). ## Pass Meta-information as markdown @@ -488,9 +500,9 @@ A "form-data" request body will be describe as a `multipart/form-data` content w ## Postman raw body -When using the `raw` mode in Postman a select box appear to choose the language, please ensure that you select a language manually, even if you see that select box have "Text" as default in some verison of postman if you choose one manually this will be saved as empty. +When using the `raw` mode in Postman a select box appear to choose the language, please ensure that you select a language manually, even if you see that select box have "Text" as default in some version of postman if you choose one manually this will be saved as empty. -The default behaviour of the library when no language is choosed in the `raw` body type is to use the content type `*/*` with schema type `string`. +The default behavior of the library when no language is selected in the `raw` body type is to use the content type `*/*` with schema type `string`.
diff --git a/lib/index.js b/lib/index.js index 768bec6..abf77f7 100644 --- a/lib/index.js +++ b/lib/index.js @@ -10,7 +10,8 @@ const jsonc = require('jsonc-parser') async function postmanToOpenApi (input, output, { info = {}, defaultTag = 'default', pathDepth = 0, auth: optsAuth, servers, externalDocs = {}, folders = {}, - responseHeaders = true, replaceVars = false, additionalVars = {}, outputFormat = 'yaml' + responseHeaders = true, replaceVars = false, additionalVars = {}, outputFormat = 'yaml', + disabledParams = { includeQuery: false, includeHeader: false } } = {}) { // TODO validate? let collectionFile = await resolveInput(input) @@ -35,7 +36,7 @@ async function postmanToOpenApi (input, output, { // Empty folders will have tagged empty element = (tagged.length > 0) ? tagged.shift() : items[i] } - // If there are an empty folder at the end of the colection elements could be `undefined` + // If there are an empty folder at the end of the collection elements could be `undefined` if (element != null) { const { request: { url, method, body, description: rawDesc, header = [], auth }, @@ -53,7 +54,7 @@ async function postmanToOpenApi (input, output, { ...(description ? { description } : {}), ...parseBody(body, method), ...parseOperationAuth(auth, securitySchemes, optsAuth), - ...parseParameters(query, header, joinedPath, paramsMeta, pathVars), + ...parseParameters(query, header, joinedPath, paramsMeta, pathVars, disabledParams), ...parseResponse(response, events, responseHeaders) } } @@ -230,22 +231,39 @@ function mapFormData () { } } +/** + * Default logic to insert parameters, if parameter exist will not be inserted again. + * In Postman this means that only the first parameter is used, the repeated ones are discarded. + * This is a separated method to allow make it configurable in the future + * @param {Map} parameterMap + * @param {Object} param + * @returns the modified parameterMap + */ +const defaultParamInserter = (parameterMap, param) => { + if (!parameterMap.has(param.name)) { + parameterMap.set(param.name, param) + } + return parameterMap +} + /* Parse the Postman query and header and transform into OpenApi parameters */ -function parseParameters (query, header, paths, paramsMeta = {}, pathVars) { +function parseParameters (query, header, paths, paramsMeta = {}, pathVars, + { includeQuery = false, includeHeader = false }, paramInserter = defaultParamInserter) { // parse Headers - let parameters = header.reduce(mapParameters('header'), []) + const parameters = [...header.reduce(mapParameters('header', includeHeader, paramInserter), new Map()).values()] // parse Query - parameters = query.reduce(mapParameters('query'), parameters) + parameters.push(...query.reduce(mapParameters('query', includeQuery, paramInserter), new Map()).values()) // Path params parameters.push(...extractPathParameters(paths, paramsMeta, pathVars)) return (parameters.length) ? { parameters } : {} } /* Accumulator function for different types of parameters */ -function mapParameters (type) { - return (parameters, { key, description, value }) => { +function mapParameters (type, includeDisabled, paramInserter) { + return (parameterMap, { key, description, value, disabled }) => { + if (!includeDisabled && disabled === true) return parameterMap const required = /\[required\]/gi.test(description) - parameters.push({ + paramInserter(parameterMap, { name: key, in: type, schema: { type: inferType(value) }, @@ -253,7 +271,7 @@ function mapParameters (type) { ...(description ? { description: description.replace(/ ?\[required\] ?/gi, '') } : {}), ...(value ? { example: value } : {}) }) - return parameters + return parameterMap } } @@ -404,27 +422,17 @@ function scrapeURL (url) { } /** - * Calculate query parameters as postman collection + * Calculate query parameters in postman collection * @param {*} searchParams The searchParam instance from an URL object * @param {*} queryCollection The postman collection query section * @returns A query params array as created by postman collections Array(Obj) + * + * NOTE: This method was created because we think that some versions of postman donĀ“t add the `query` + * parameter in the url, but after some reasearch the reason why the `query` parameter can not be + * present is just because no query parameters are used so we just format the postman `query` array here. */ function compoundQueryParams (searchParams, queryCollection = []) { - // Prepare desc in query collection for easy search - const descMap = queryCollection.reduce((agr, { key, description }) => { - agr[key] = description - return agr - }, {}) - // Create the query array of objects - const query = [] - searchParams.forEach((value, key) => { - query.push({ - key, - value, - ...(descMap[key] != null ? { description: descMap[key] } : {}) - }) - }) - return query + return queryCollection } /* Parse domains from operations or options */ diff --git a/package-lock.json b/package-lock.json index 6b322f9..e89aca4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,27 +1,27 @@ { "name": "postman-to-openapi", - "version": "2.6.2", + "version": "2.7.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "postman-to-openapi", - "version": "2.6.2", + "version": "2.7.0", "license": "MIT", "dependencies": { "commander": "^8.3.0", "js-yaml": "^4.1.0", - "jsonc-parser": "3.1.0", - "marked": "^4.0.19", + "jsonc-parser": "3.2.0", + "marked": "^4.1.0", "mustache": "^4.2.0" }, "bin": { "p2o": "bin/cli.js" }, "devDependencies": { - "@commitlint/cli": "^17.1.1", + "@commitlint/cli": "^17.1.2", "@commitlint/config-conventional": "^17.1.0", - "eslint": "^8.23.0", + "eslint": "^8.23.1", "eslint-config-standard": "^17.0.0", "eslint-plugin-import": "^2.26.0", "eslint-plugin-n": "^15.2.5", @@ -31,7 +31,7 @@ "husky": "^7.0.4", "mocha": "^10.0.0", "nyc": "^15.1.0", - "typescript": "^4.8.2" + "typescript": "^4.8.3" }, "engines": { "node": ">=12 <18" @@ -441,14 +441,14 @@ } }, "node_modules/@commitlint/cli": { - "version": "17.1.1", - "resolved": "https://registry.npmjs.org/@commitlint/cli/-/cli-17.1.1.tgz", - "integrity": "sha512-xyQJNJs1j18At5wSBF6bMo1on6ZrpcHUr4duacznPU0RnywCAABDBP1s63BmhkTMdNXLVgVM4J1H2sG0HSS3IA==", + "version": "17.1.2", + "resolved": "https://registry.npmjs.org/@commitlint/cli/-/cli-17.1.2.tgz", + "integrity": "sha512-h/4Hlka3bvCLbnxf0Er2ri5A44VMlbMSkdTRp8Adv2tRiklSTRIoPGs7OEXDv3EoDs2AAzILiPookgM4Gi7LOw==", "dev": true, "dependencies": { "@commitlint/format": "^17.0.0", "@commitlint/lint": "^17.1.0", - "@commitlint/load": "^17.1.1", + "@commitlint/load": "^17.1.2", "@commitlint/read": "^17.1.0", "@commitlint/types": "^17.0.0", "execa": "^5.0.0", @@ -553,9 +553,9 @@ } }, "node_modules/@commitlint/load": { - "version": "17.1.1", - "resolved": "https://registry.npmjs.org/@commitlint/load/-/load-17.1.1.tgz", - "integrity": "sha512-jEgdDabfj58kFKZmB7rMtmQa7Feo7Ozh3KmvIlXWqrJmal5auO1RC0Iczfl52DlPn26Uo0goUDHrhoAFs2ze0Q==", + "version": "17.1.2", + "resolved": "https://registry.npmjs.org/@commitlint/load/-/load-17.1.2.tgz", + "integrity": "sha512-sk2p/jFYAWLChIfOIp/MGSIn/WzZ0vkc3afw+l4X8hGEYkvDe4gQUUAVxjl/6xMRn0HgnSLMZ04xXh5pkTsmgg==", "dev": true, "dependencies": { "@commitlint/config-validator": "^17.1.0", @@ -565,24 +565,16 @@ "@types/node": "^14.0.0", "chalk": "^4.1.0", "cosmiconfig": "^7.0.0", - "cosmiconfig-typescript-loader": "^3.0.0", + "cosmiconfig-typescript-loader": "^4.0.0", "lodash": "^4.17.19", "resolve-from": "^5.0.0", + "ts-node": "^10.8.1", "typescript": "^4.6.4" }, "engines": { "node": ">=v14" - }, - "peerDependencies": { - "ts-node": ">=10" } }, - "node_modules/@commitlint/load/node_modules/@types/node": { - "version": "14.18.26", - "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.26.tgz", - "integrity": "sha512-0b+utRBSYj8L7XAp0d+DX7lI4cSmowNaaTkk6/1SKzbKkG+doLuPusB9EOvzLJ8ahJSk03bTLIL6cWaEd4dBKA==", - "dev": true - }, "node_modules/@commitlint/message": { "version": "17.0.0", "resolved": "https://registry.npmjs.org/@commitlint/message/-/message-17.0.0.tgz", @@ -693,7 +685,6 @@ "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", "dev": true, - "peer": true, "dependencies": { "@jridgewell/trace-mapping": "0.3.9" }, @@ -706,16 +697,15 @@ "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", "dev": true, - "peer": true, "dependencies": { "@jridgewell/resolve-uri": "^3.0.3", "@jridgewell/sourcemap-codec": "^1.4.10" } }, "node_modules/@eslint/eslintrc": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.1.tgz", - "integrity": "sha512-OhSY22oQQdw3zgPOOwdoj01l/Dzl1Z+xyUP33tkSN+aqyEhymJCcPHyXt+ylW8FSe0TfRC2VG+ROQOapD0aZSQ==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.2.tgz", + "integrity": "sha512-AXYd23w1S/bv3fTs3Lz0vjiYemS08jWkI3hYyS9I1ry+0f+Yjs1wm+sU0BS8qDOPrBIkp4qHYC16I8uVtpLajQ==", "dev": true, "dependencies": { "ajv": "^6.12.4", @@ -985,29 +975,25 @@ "version": "1.0.9", "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", - "dev": true, - "peer": true + "dev": true }, "node_modules/@tsconfig/node12": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", - "dev": true, - "peer": true + "dev": true }, "node_modules/@tsconfig/node14": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", - "dev": true, - "peer": true + "dev": true }, "node_modules/@tsconfig/node16": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz", "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==", - "dev": true, - "peer": true + "dev": true }, "node_modules/@types/json5": { "version": "0.0.29", @@ -1022,11 +1008,10 @@ "dev": true }, "node_modules/@types/node": { - "version": "18.7.13", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.7.13.tgz", - "integrity": "sha512-46yIhxSe5xEaJZXWdIBP7GU4HDTG8/eo0qd9atdiL+lFpA03y8KS+lkTN834TWJj5767GbWv4n/P6efyTFt1Dw==", - "dev": true, - "peer": true + "version": "14.18.29", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.29.tgz", + "integrity": "sha512-LhF+9fbIX4iPzhsRLpK5H7iPdvW8L4IwGciXQIOEcuF62+9nw/VQVsOViAOOGxY3OlOKGLFv0sWwJXdwQeTn6A==", + "dev": true }, "node_modules/@types/normalize-package-data": { "version": "2.4.1", @@ -1072,7 +1057,6 @@ "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", "dev": true, - "peer": true, "engines": { "node": ">=0.4.0" } @@ -1174,8 +1158,7 @@ "version": "4.1.3", "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", - "dev": true, - "peer": true + "dev": true }, "node_modules/argparse": { "version": "2.0.1", @@ -1598,9 +1581,9 @@ } }, "node_modules/cosmiconfig-typescript-loader": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/cosmiconfig-typescript-loader/-/cosmiconfig-typescript-loader-3.1.2.tgz", - "integrity": "sha512-rIwakk27LtK7vjSjGgs3FDbKkq41Byw3VHRGRuAkRQLfGla+O7s+cy1FXRkjLSZ2G9z1og1bcOIsELo1w4G0Kg==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cosmiconfig-typescript-loader/-/cosmiconfig-typescript-loader-4.1.0.tgz", + "integrity": "sha512-HbWIuR5O+XO5Oj9SZ5bzgrD4nN+rfhrm2PMb0FVx+t+XIvC45n8F0oTNnztXtspWGw0i2IzHaUWFD5LzV1JB4A==", "dev": true, "engines": { "node": ">=12", @@ -1617,8 +1600,7 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", - "dev": true, - "peer": true + "dev": true }, "node_modules/cross-spawn": { "version": "7.0.3", @@ -1882,12 +1864,12 @@ } }, "node_modules/eslint": { - "version": "8.23.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.23.0.tgz", - "integrity": "sha512-pBG/XOn0MsJcKcTRLr27S5HpzQo4kLr+HjLQIyK4EiCsijDl/TB+h5uEuJU6bQ8Edvwz1XWOjpaP2qgnXGpTcA==", + "version": "8.23.1", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.23.1.tgz", + "integrity": "sha512-w7C1IXCc6fNqjpuYd0yPlcTKKmHlHHktRkzmBPZ+7cvNBQuiNjx0xaMTjAJGCafJhQkrFJooREv0CtrVzmHwqg==", "dev": true, "dependencies": { - "@eslint/eslintrc": "^1.3.1", + "@eslint/eslintrc": "^1.3.2", "@humanwhocodes/config-array": "^0.10.4", "@humanwhocodes/gitignore-to-minimatch": "^1.0.2", "@humanwhocodes/module-importer": "^1.0.1", @@ -1906,7 +1888,6 @@ "fast-deep-equal": "^3.1.3", "file-entry-cache": "^6.0.1", "find-up": "^5.0.0", - "functional-red-black-tree": "^1.0.1", "glob-parent": "^6.0.1", "globals": "^13.15.0", "globby": "^11.1.0", @@ -1915,6 +1896,7 @@ "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", + "js-sdsl": "^4.1.4", "js-yaml": "^4.1.0", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.4.1", @@ -2674,12 +2656,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==", - "dev": true - }, "node_modules/functions-have-names": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", @@ -3509,6 +3485,12 @@ "node": ">=8" } }, + "node_modules/js-sdsl": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.1.4.tgz", + "integrity": "sha512-Y2/yD55y5jteOAmY50JbUZYwk3CP3wnLPEZnlR1w9oKhITrBEtAxwuWKebFf8hMrPMgbYwFoWK/lH2sBkErELw==", + "dev": true + }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -3569,9 +3551,9 @@ } }, "node_modules/jsonc-parser": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.1.0.tgz", - "integrity": "sha512-DRf0QjnNeCUds3xTjKlQQ3DpJD51GvDjJfnxUVWg6PZTo2otSm+slzNAxU/35hF8/oJIKoG9slq30JYOsF2azg==" + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz", + "integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==" }, "node_modules/jsonfile": { "version": "6.1.0", @@ -3727,8 +3709,7 @@ "version": "1.3.6", "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "dev": true, - "peer": true + "dev": true }, "node_modules/map-obj": { "version": "4.3.0", @@ -3743,9 +3724,9 @@ } }, "node_modules/marked": { - "version": "4.0.19", - "resolved": "https://registry.npmjs.org/marked/-/marked-4.0.19.tgz", - "integrity": "sha512-rgQF/OxOiLcvgUAj1Q1tAf4Bgxn5h5JZTp04Fx4XUkVhs7B+7YA9JEWJhJpoO8eJt8MkZMwqLCNeNqj1bCREZQ==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/marked/-/marked-4.1.0.tgz", + "integrity": "sha512-+Z6KDjSPa6/723PQYyc1axYZpYYpDnECDaU6hkaf5gqBieBkMKYReL5hteF2QizhlMbgbo8umXl/clZ67+GlsA==", "bin": { "marked": "bin/marked.js" }, @@ -5321,7 +5302,6 @@ "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", "dev": true, - "peer": true, "dependencies": { "@cspotcode/source-map-support": "^0.8.0", "@tsconfig/node10": "^1.0.7", @@ -5365,7 +5345,6 @@ "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", "dev": true, - "peer": true, "engines": { "node": ">=0.3.1" } @@ -5437,9 +5416,9 @@ } }, "node_modules/typescript": { - "version": "4.8.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.2.tgz", - "integrity": "sha512-C0I1UsrrDHo2fYI5oaCGbSejwX4ch+9Y5jTQELvovfmFkK3HHSZJB8MSJcWLmCUBzQBchCrZ9rMRV6GuNrvGtw==", + "version": "4.8.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.3.tgz", + "integrity": "sha512-goMHfm00nWPa8UvR/CPSvykqf6dVV8x/dp0c5mFTMTIu0u0FlGWRioyy7Nn0PGAdHxpJZnuO/ut+PpQ8UiHAig==", "dev": true, "bin": { "tsc": "bin/tsc", @@ -5527,8 +5506,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", - "dev": true, - "peer": true + "dev": true }, "node_modules/validate-npm-package-license": { "version": "3.0.4", @@ -5740,7 +5718,6 @@ "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", "dev": true, - "peer": true, "engines": { "node": ">=6" } @@ -6073,14 +6050,14 @@ } }, "@commitlint/cli": { - "version": "17.1.1", - "resolved": "https://registry.npmjs.org/@commitlint/cli/-/cli-17.1.1.tgz", - "integrity": "sha512-xyQJNJs1j18At5wSBF6bMo1on6ZrpcHUr4duacznPU0RnywCAABDBP1s63BmhkTMdNXLVgVM4J1H2sG0HSS3IA==", + "version": "17.1.2", + "resolved": "https://registry.npmjs.org/@commitlint/cli/-/cli-17.1.2.tgz", + "integrity": "sha512-h/4Hlka3bvCLbnxf0Er2ri5A44VMlbMSkdTRp8Adv2tRiklSTRIoPGs7OEXDv3EoDs2AAzILiPookgM4Gi7LOw==", "dev": true, "requires": { "@commitlint/format": "^17.0.0", "@commitlint/lint": "^17.1.0", - "@commitlint/load": "^17.1.1", + "@commitlint/load": "^17.1.2", "@commitlint/read": "^17.1.0", "@commitlint/types": "^17.0.0", "execa": "^5.0.0", @@ -6158,9 +6135,9 @@ } }, "@commitlint/load": { - "version": "17.1.1", - "resolved": "https://registry.npmjs.org/@commitlint/load/-/load-17.1.1.tgz", - "integrity": "sha512-jEgdDabfj58kFKZmB7rMtmQa7Feo7Ozh3KmvIlXWqrJmal5auO1RC0Iczfl52DlPn26Uo0goUDHrhoAFs2ze0Q==", + "version": "17.1.2", + "resolved": "https://registry.npmjs.org/@commitlint/load/-/load-17.1.2.tgz", + "integrity": "sha512-sk2p/jFYAWLChIfOIp/MGSIn/WzZ0vkc3afw+l4X8hGEYkvDe4gQUUAVxjl/6xMRn0HgnSLMZ04xXh5pkTsmgg==", "dev": true, "requires": { "@commitlint/config-validator": "^17.1.0", @@ -6170,18 +6147,11 @@ "@types/node": "^14.0.0", "chalk": "^4.1.0", "cosmiconfig": "^7.0.0", - "cosmiconfig-typescript-loader": "^3.0.0", + "cosmiconfig-typescript-loader": "^4.0.0", "lodash": "^4.17.19", "resolve-from": "^5.0.0", + "ts-node": "^10.8.1", "typescript": "^4.6.4" - }, - "dependencies": { - "@types/node": { - "version": "14.18.26", - "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.26.tgz", - "integrity": "sha512-0b+utRBSYj8L7XAp0d+DX7lI4cSmowNaaTkk6/1SKzbKkG+doLuPusB9EOvzLJ8ahJSk03bTLIL6cWaEd4dBKA==", - "dev": true - } } }, "@commitlint/message": { @@ -6270,7 +6240,6 @@ "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", "dev": true, - "peer": true, "requires": { "@jridgewell/trace-mapping": "0.3.9" }, @@ -6280,7 +6249,6 @@ "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", "dev": true, - "peer": true, "requires": { "@jridgewell/resolve-uri": "^3.0.3", "@jridgewell/sourcemap-codec": "^1.4.10" @@ -6289,9 +6257,9 @@ } }, "@eslint/eslintrc": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.1.tgz", - "integrity": "sha512-OhSY22oQQdw3zgPOOwdoj01l/Dzl1Z+xyUP33tkSN+aqyEhymJCcPHyXt+ylW8FSe0TfRC2VG+ROQOapD0aZSQ==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.2.tgz", + "integrity": "sha512-AXYd23w1S/bv3fTs3Lz0vjiYemS08jWkI3hYyS9I1ry+0f+Yjs1wm+sU0BS8qDOPrBIkp4qHYC16I8uVtpLajQ==", "dev": true, "requires": { "ajv": "^6.12.4", @@ -6499,29 +6467,25 @@ "version": "1.0.9", "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.9.tgz", "integrity": "sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA==", - "dev": true, - "peer": true + "dev": true }, "@tsconfig/node12": { "version": "1.0.11", "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.11.tgz", "integrity": "sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag==", - "dev": true, - "peer": true + "dev": true }, "@tsconfig/node14": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.3.tgz", "integrity": "sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow==", - "dev": true, - "peer": true + "dev": true }, "@tsconfig/node16": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.3.tgz", "integrity": "sha512-yOlFc+7UtL/89t2ZhjPvvB/DeAr3r+Dq58IgzsFkOAvVC6NMJXmCGjbptdXdR9qsX7pKcTL+s87FtYREi2dEEQ==", - "dev": true, - "peer": true + "dev": true }, "@types/json5": { "version": "0.0.29", @@ -6536,11 +6500,10 @@ "dev": true }, "@types/node": { - "version": "18.7.13", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.7.13.tgz", - "integrity": "sha512-46yIhxSe5xEaJZXWdIBP7GU4HDTG8/eo0qd9atdiL+lFpA03y8KS+lkTN834TWJj5767GbWv4n/P6efyTFt1Dw==", - "dev": true, - "peer": true + "version": "14.18.29", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.29.tgz", + "integrity": "sha512-LhF+9fbIX4iPzhsRLpK5H7iPdvW8L4IwGciXQIOEcuF62+9nw/VQVsOViAOOGxY3OlOKGLFv0sWwJXdwQeTn6A==", + "dev": true }, "@types/normalize-package-data": { "version": "2.4.1", @@ -6577,8 +6540,7 @@ "version": "8.2.0", "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", - "dev": true, - "peer": true + "dev": true }, "aggregate-error": { "version": "3.1.0", @@ -6652,8 +6614,7 @@ "version": "4.1.3", "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", - "dev": true, - "peer": true + "dev": true }, "argparse": { "version": "2.0.1", @@ -6966,9 +6927,9 @@ } }, "cosmiconfig-typescript-loader": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/cosmiconfig-typescript-loader/-/cosmiconfig-typescript-loader-3.1.2.tgz", - "integrity": "sha512-rIwakk27LtK7vjSjGgs3FDbKkq41Byw3VHRGRuAkRQLfGla+O7s+cy1FXRkjLSZ2G9z1og1bcOIsELo1w4G0Kg==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cosmiconfig-typescript-loader/-/cosmiconfig-typescript-loader-4.1.0.tgz", + "integrity": "sha512-HbWIuR5O+XO5Oj9SZ5bzgrD4nN+rfhrm2PMb0FVx+t+XIvC45n8F0oTNnztXtspWGw0i2IzHaUWFD5LzV1JB4A==", "dev": true, "requires": {} }, @@ -6976,8 +6937,7 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", - "dev": true, - "peer": true + "dev": true }, "cross-spawn": { "version": "7.0.3", @@ -7178,12 +7138,12 @@ "dev": true }, "eslint": { - "version": "8.23.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.23.0.tgz", - "integrity": "sha512-pBG/XOn0MsJcKcTRLr27S5HpzQo4kLr+HjLQIyK4EiCsijDl/TB+h5uEuJU6bQ8Edvwz1XWOjpaP2qgnXGpTcA==", + "version": "8.23.1", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.23.1.tgz", + "integrity": "sha512-w7C1IXCc6fNqjpuYd0yPlcTKKmHlHHktRkzmBPZ+7cvNBQuiNjx0xaMTjAJGCafJhQkrFJooREv0CtrVzmHwqg==", "dev": true, "requires": { - "@eslint/eslintrc": "^1.3.1", + "@eslint/eslintrc": "^1.3.2", "@humanwhocodes/config-array": "^0.10.4", "@humanwhocodes/gitignore-to-minimatch": "^1.0.2", "@humanwhocodes/module-importer": "^1.0.1", @@ -7202,7 +7162,6 @@ "fast-deep-equal": "^3.1.3", "file-entry-cache": "^6.0.1", "find-up": "^5.0.0", - "functional-red-black-tree": "^1.0.1", "glob-parent": "^6.0.1", "globals": "^13.15.0", "globby": "^11.1.0", @@ -7211,6 +7170,7 @@ "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", + "js-sdsl": "^4.1.4", "js-yaml": "^4.1.0", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.4.1", @@ -7753,12 +7713,6 @@ "functions-have-names": "^1.2.2" } }, - "functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==", - "dev": true - }, "functions-have-names": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", @@ -8339,6 +8293,12 @@ "istanbul-lib-report": "^3.0.0" } }, + "js-sdsl": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.1.4.tgz", + "integrity": "sha512-Y2/yD55y5jteOAmY50JbUZYwk3CP3wnLPEZnlR1w9oKhITrBEtAxwuWKebFf8hMrPMgbYwFoWK/lH2sBkErELw==", + "dev": true + }, "js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -8384,9 +8344,9 @@ "dev": true }, "jsonc-parser": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.1.0.tgz", - "integrity": "sha512-DRf0QjnNeCUds3xTjKlQQ3DpJD51GvDjJfnxUVWg6PZTo2otSm+slzNAxU/35hF8/oJIKoG9slq30JYOsF2azg==" + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz", + "integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==" }, "jsonfile": { "version": "6.1.0", @@ -8503,8 +8463,7 @@ "version": "1.3.6", "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "dev": true, - "peer": true + "dev": true }, "map-obj": { "version": "4.3.0", @@ -8513,9 +8472,9 @@ "dev": true }, "marked": { - "version": "4.0.19", - "resolved": "https://registry.npmjs.org/marked/-/marked-4.0.19.tgz", - "integrity": "sha512-rgQF/OxOiLcvgUAj1Q1tAf4Bgxn5h5JZTp04Fx4XUkVhs7B+7YA9JEWJhJpoO8eJt8MkZMwqLCNeNqj1bCREZQ==" + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/marked/-/marked-4.1.0.tgz", + "integrity": "sha512-+Z6KDjSPa6/723PQYyc1axYZpYYpDnECDaU6hkaf5gqBieBkMKYReL5hteF2QizhlMbgbo8umXl/clZ67+GlsA==" }, "meow": { "version": "8.1.2", @@ -9681,7 +9640,6 @@ "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.9.1.tgz", "integrity": "sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==", "dev": true, - "peer": true, "requires": { "@cspotcode/source-map-support": "^0.8.0", "@tsconfig/node10": "^1.0.7", @@ -9702,8 +9660,7 @@ "version": "4.0.2", "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "dev": true, - "peer": true + "dev": true } } }, @@ -9761,9 +9718,9 @@ } }, "typescript": { - "version": "4.8.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.2.tgz", - "integrity": "sha512-C0I1UsrrDHo2fYI5oaCGbSejwX4ch+9Y5jTQELvovfmFkK3HHSZJB8MSJcWLmCUBzQBchCrZ9rMRV6GuNrvGtw==", + "version": "4.8.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.3.tgz", + "integrity": "sha512-goMHfm00nWPa8UvR/CPSvykqf6dVV8x/dp0c5mFTMTIu0u0FlGWRioyy7Nn0PGAdHxpJZnuO/ut+PpQ8UiHAig==", "dev": true }, "unbox-primitive": { @@ -9819,8 +9776,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", - "dev": true, - "peer": true + "dev": true }, "validate-npm-package-license": { "version": "3.0.4", @@ -9984,8 +9940,7 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", - "dev": true, - "peer": true + "dev": true }, "yocto-queue": { "version": "0.1.0", diff --git a/package.json b/package.json index 263148e..1fbb33c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "postman-to-openapi", - "version": "2.6.2", + "version": "2.7.0", "description": "Convert postman collection to OpenAPI spec", "main": "lib/index.js", "types": "types/index.d.ts", @@ -45,9 +45,9 @@ }, "homepage": "https://github.com/joolfe/postman-to-openapi#readme", "devDependencies": { - "@commitlint/cli": "^17.1.1", + "@commitlint/cli": "^17.1.2", "@commitlint/config-conventional": "^17.1.0", - "eslint": "^8.23.0", + "eslint": "^8.23.1", "eslint-config-standard": "^17.0.0", "eslint-plugin-import": "^2.26.0", "eslint-plugin-n": "^15.2.5", @@ -57,7 +57,7 @@ "husky": "^7.0.4", "mocha": "^10.0.0", "nyc": "^15.1.0", - "typescript": "^4.8.2" + "typescript": "^4.8.3" }, "commitlint": { "extends": [ @@ -89,8 +89,8 @@ "dependencies": { "commander": "^8.3.0", "js-yaml": "^4.1.0", - "jsonc-parser": "3.1.0", - "marked": "^4.0.19", + "jsonc-parser": "3.2.0", + "marked": "^4.1.0", "mustache": "^4.2.0" }, "husky": { diff --git a/test/index.spec.js b/test/index.spec.js index 2925182..886b396 100644 --- a/test/index.spec.js +++ b/test/index.spec.js @@ -62,6 +62,10 @@ const EXPECTED_RAW_BODY = readFileSync('./test/resources/output/RawBody.yml', 'u const EXPECTED_NULL_HEADER = readFileSync('./test/resources/output/NullHeader.yml', 'utf8') const EXPECTED_COLLECTION_WRAPPER = readFileSync('./test/resources/output/CollectionWrapper.yml', 'utf8') const EXPECTED_COLLECTION_JSON_COMMENTS = readFileSync('./test/resources/output/JsonComments.yml', 'utf8') +const EXPECTED_DISABLED_PARAMS_DEFAULT = readFileSync('./test/resources/output/DisabledParamsDefault.yml', 'utf8') +const EXPECTED_DISABLED_PARAMS_ALL = readFileSync('./test/resources/output/DisabledParamsAll.yml', 'utf8') +const EXPECTED_DISABLED_PARAMS_QUERY = readFileSync('./test/resources/output/DisabledParamsQuery.yml', 'utf8') +const EXPECTED_DISABLED_PARAMS_HEADER = readFileSync('./test/resources/output/DisabledParamsHeader.yml', 'utf8') const AUTH_DEFINITIONS = { myCustomAuth: { @@ -125,6 +129,7 @@ describe('Library specs', function () { const COLLECTION_RESPONSES_JSON_ERROR = `./test/resources/input/${version}/ResponsesJsonError.json` const COLLECTION_RESPONSES_EMPTY = `./test/resources/input/${version}/ResponsesEmpty.json` const COLLECTION_JSON_COMMENTS = `./test/resources/input/${version}/JsonComments.json` + const COLLECTION_DISABLED = `./test/resources/input/${version}/DisabledParams.json` it('should work with a basic transform', async function () { const result = await postmanToOpenApi(COLLECTION_BASIC, OUTPUT_PATH, {}) @@ -497,6 +502,39 @@ describe('Library specs', function () { const result = await postmanToOpenApi(COLLECTION_BASIC, OUTPUT_PATH, { outputFormat: 'json' }) equal(result, EXPECTED_BASIC_JSON) }) + + it('should not parse `disabled` parameters', async function () { + const result = await postmanToOpenApi(COLLECTION_DISABLED, OUTPUT_PATH) + equal(result, EXPECTED_DISABLED_PARAMS_DEFAULT) + }) + + it('should parse `disabled` parameters if option is used', async function () { + const result = await postmanToOpenApi(COLLECTION_DISABLED, OUTPUT_PATH, { + disabledParams: { + includeQuery: true, + includeHeader: true + } + }) + equal(result, EXPECTED_DISABLED_PARAMS_ALL) + }) + + it('should include `disable` query but not header', async function () { + const result = await postmanToOpenApi(COLLECTION_DISABLED, OUTPUT_PATH, { + disabledParams: { + includeQuery: true + } + }) + equal(result, EXPECTED_DISABLED_PARAMS_QUERY) + }) + + it('should include `disable` headers but not query', async function () { + const result = await postmanToOpenApi(COLLECTION_DISABLED, OUTPUT_PATH, { + disabledParams: { + includeHeader: true + } + }) + equal(result, EXPECTED_DISABLED_PARAMS_HEADER) + }) }) }) diff --git a/test/resources/input/v2/DisabledParams.json b/test/resources/input/v2/DisabledParams.json new file mode 100644 index 0000000..58a6933 --- /dev/null +++ b/test/resources/input/v2/DisabledParams.json @@ -0,0 +1,121 @@ +{ + "info": { + "_postman_id": "43c37e23-7cc8-4e6b-acf1-46396b4f4bfd", + "name": "DisabledParams", + "description": "Test API for disabled parameters feature", + "schema": "https://schema.getpostman.com/json/collection/v2.0.0/collection.json", + "_exporter_id": "64956" + }, + "item": [ + { + "name": "Get list of users", + "request": { + "method": "GET", + "header": [ + { + "key": "X-My-Header", + "value": "hudjilksns78jsijns090", + "description": "Custom header [required]", + "type": "text" + }, + { + "key": "X-My-Header", + "value": "1234567890", + "description": "Custom header disabled [required]", + "type": "text", + "disabled": true + }, + { + "key": "X-Other", + "value": "other", + "description": "Another header [REQUIRED]", + "type": "text" + }, + { + "key": "No-description", + "value": "header without description", + "type": "text" + }, + { + "key": "No-value", + "value": "", + "description": "header without value", + "type": "text" + }, + { + "key": "X-Disabled-Header", + "value": "QWERTY", + "description": "Disabled parameter", + "type": "text", + "disabled": true + } + ], + "url": { + "raw": "https://api.io/:section/users?name=Jhon&review=true", + "protocol": "https", + "host": [ + "api", + "io" + ], + "path": [ + ":section", + "users" + ], + "query": [ + { + "key": "age", + "value": "45", + "description": "Disabled param", + "disabled": true + }, + { + "key": "name", + "value": "Jhon", + "description": "Filter by name" + }, + { + "key": "review", + "value": "true", + "description": "Indicate if should be reviewed or not" + }, + { + "key": "name", + "value": "Mark", + "description": "Disabled param duplicated", + "disabled": true + } + ], + "variable": [ + { + "key": "section", + "value": "spain", + "description": "A path parameter" + } + ] + }, + "description": "Obtain a list of users that fullfill the conditions of the filters" + }, + "response": [] + } + ], + "event": [ + { + "listen": "prerequest", + "script": { + "type": "text/javascript", + "exec": [ + "" + ] + } + }, + { + "listen": "test", + "script": { + "type": "text/javascript", + "exec": [ + "" + ] + } + } + ] +} \ No newline at end of file diff --git a/test/resources/input/v21/DisabledParams.json b/test/resources/input/v21/DisabledParams.json new file mode 100644 index 0000000..d9f712b --- /dev/null +++ b/test/resources/input/v21/DisabledParams.json @@ -0,0 +1,121 @@ +{ + "info": { + "_postman_id": "43c37e23-7cc8-4e6b-acf1-46396b4f4bfd", + "name": "DisabledParams", + "description": "Test API for disabled parameters feature", + "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json", + "_exporter_id": "64956" + }, + "item": [ + { + "name": "Get list of users", + "request": { + "method": "GET", + "header": [ + { + "key": "X-My-Header", + "value": "hudjilksns78jsijns090", + "description": "Custom header [required]", + "type": "text" + }, + { + "key": "X-My-Header", + "value": "1234567890", + "description": "Custom header disabled [required]", + "type": "text", + "disabled": true + }, + { + "key": "X-Other", + "value": "other", + "description": "Another header [REQUIRED]", + "type": "text" + }, + { + "key": "No-description", + "value": "header without description", + "type": "text" + }, + { + "key": "No-value", + "value": "", + "description": "header without value", + "type": "text" + }, + { + "key": "X-Disabled-Header", + "value": "QWERTY", + "description": "Disabled parameter", + "type": "text", + "disabled": true + } + ], + "url": { + "raw": "https://api.io/:section/users?name=Jhon&review=true", + "protocol": "https", + "host": [ + "api", + "io" + ], + "path": [ + ":section", + "users" + ], + "query": [ + { + "key": "age", + "value": "45", + "description": "Disabled param", + "disabled": true + }, + { + "key": "name", + "value": "Jhon", + "description": "Filter by name" + }, + { + "key": "review", + "value": "true", + "description": "Indicate if should be reviewed or not" + }, + { + "key": "name", + "value": "Mark", + "description": "Disabled param duplicated", + "disabled": true + } + ], + "variable": [ + { + "key": "section", + "value": "spain", + "description": "A path parameter" + } + ] + }, + "description": "Obtain a list of users that fullfill the conditions of the filters" + }, + "response": [] + } + ], + "event": [ + { + "listen": "prerequest", + "script": { + "type": "text/javascript", + "exec": [ + "" + ] + } + }, + { + "listen": "test", + "script": { + "type": "text/javascript", + "exec": [ + "" + ] + } + } + ] +} \ No newline at end of file diff --git a/test/resources/output/DisabledParamsAll.yml b/test/resources/output/DisabledParamsAll.yml new file mode 100644 index 0000000..2ccc7ba --- /dev/null +++ b/test/resources/output/DisabledParamsAll.yml @@ -0,0 +1,75 @@ +openapi: 3.0.0 +info: + title: DisabledParams + description: Test API for disabled parameters feature + version: 1.0.0 +servers: + - url: https://api.io +paths: + /{section}/users: + get: + tags: + - default + summary: Get list of users + description: Obtain a list of users that fullfill the conditions of the filters + parameters: + - name: X-My-Header + in: header + schema: + type: string + required: true + description: Custom header + example: hudjilksns78jsijns090 + - name: X-Other + in: header + schema: + type: string + required: true + description: Another header + example: other + - name: No-description + in: header + schema: + type: string + example: header without description + - name: No-value + in: header + schema: + type: string + description: header without value + - name: X-Disabled-Header + in: header + schema: + type: string + description: Disabled parameter + example: QWERTY + - name: age + in: query + schema: + type: integer + description: Disabled param + example: '45' + - name: name + in: query + schema: + type: string + description: Filter by name + example: Jhon + - name: review + in: query + schema: + type: boolean + description: Indicate if should be reviewed or not + example: 'true' + - name: section + in: path + schema: + type: string + required: true + description: A path parameter + example: spain + responses: + '200': + description: Successful response + content: + application/json: {} diff --git a/test/resources/output/DisabledParamsDefault.yml b/test/resources/output/DisabledParamsDefault.yml new file mode 100644 index 0000000..57511e5 --- /dev/null +++ b/test/resources/output/DisabledParamsDefault.yml @@ -0,0 +1,63 @@ +openapi: 3.0.0 +info: + title: DisabledParams + description: Test API for disabled parameters feature + version: 1.0.0 +servers: + - url: https://api.io +paths: + /{section}/users: + get: + tags: + - default + summary: Get list of users + description: Obtain a list of users that fullfill the conditions of the filters + parameters: + - name: X-My-Header + in: header + schema: + type: string + required: true + description: Custom header + example: hudjilksns78jsijns090 + - name: X-Other + in: header + schema: + type: string + required: true + description: Another header + example: other + - name: No-description + in: header + schema: + type: string + example: header without description + - name: No-value + in: header + schema: + type: string + description: header without value + - name: name + in: query + schema: + type: string + description: Filter by name + example: Jhon + - name: review + in: query + schema: + type: boolean + description: Indicate if should be reviewed or not + example: 'true' + - name: section + in: path + schema: + type: string + required: true + description: A path parameter + example: spain + responses: + '200': + description: Successful response + content: + application/json: {} diff --git a/test/resources/output/DisabledParamsHeader.yml b/test/resources/output/DisabledParamsHeader.yml new file mode 100644 index 0000000..9276888 --- /dev/null +++ b/test/resources/output/DisabledParamsHeader.yml @@ -0,0 +1,69 @@ +openapi: 3.0.0 +info: + title: DisabledParams + description: Test API for disabled parameters feature + version: 1.0.0 +servers: + - url: https://api.io +paths: + /{section}/users: + get: + tags: + - default + summary: Get list of users + description: Obtain a list of users that fullfill the conditions of the filters + parameters: + - name: X-My-Header + in: header + schema: + type: string + required: true + description: Custom header + example: hudjilksns78jsijns090 + - name: X-Other + in: header + schema: + type: string + required: true + description: Another header + example: other + - name: No-description + in: header + schema: + type: string + example: header without description + - name: No-value + in: header + schema: + type: string + description: header without value + - name: X-Disabled-Header + in: header + schema: + type: string + description: Disabled parameter + example: QWERTY + - name: name + in: query + schema: + type: string + description: Filter by name + example: Jhon + - name: review + in: query + schema: + type: boolean + description: Indicate if should be reviewed or not + example: 'true' + - name: section + in: path + schema: + type: string + required: true + description: A path parameter + example: spain + responses: + '200': + description: Successful response + content: + application/json: {} diff --git a/test/resources/output/DisabledParamsQuery.yml b/test/resources/output/DisabledParamsQuery.yml new file mode 100644 index 0000000..f06bca8 --- /dev/null +++ b/test/resources/output/DisabledParamsQuery.yml @@ -0,0 +1,69 @@ +openapi: 3.0.0 +info: + title: DisabledParams + description: Test API for disabled parameters feature + version: 1.0.0 +servers: + - url: https://api.io +paths: + /{section}/users: + get: + tags: + - default + summary: Get list of users + description: Obtain a list of users that fullfill the conditions of the filters + parameters: + - name: X-My-Header + in: header + schema: + type: string + required: true + description: Custom header + example: hudjilksns78jsijns090 + - name: X-Other + in: header + schema: + type: string + required: true + description: Another header + example: other + - name: No-description + in: header + schema: + type: string + example: header without description + - name: No-value + in: header + schema: + type: string + description: header without value + - name: age + in: query + schema: + type: integer + description: Disabled param + example: '45' + - name: name + in: query + schema: + type: string + description: Filter by name + example: Jhon + - name: review + in: query + schema: + type: boolean + description: Indicate if should be reviewed or not + example: 'true' + - name: section + in: path + schema: + type: string + required: true + description: A path parameter + example: spain + responses: + '200': + description: Successful response + content: + application/json: {} diff --git a/test/resources/output/GetMethods.yml b/test/resources/output/GetMethods.yml index fdb3270..190d2e6 100644 --- a/test/resources/output/GetMethods.yml +++ b/test/resources/output/GetMethods.yml @@ -69,7 +69,7 @@ paths: schema: type: string description: Should be parsed as string - example: 2022-06-23T10:00:00.000 01:00 + example: '2022-06-23T10:00:00.000+01:00' responses: '200': description: Successful response diff --git a/types/index.d.ts b/types/index.d.ts index f4af157..cb9d678 100644 --- a/types/index.d.ts +++ b/types/index.d.ts @@ -70,6 +70,13 @@ export interface FoldersOption { separator: string } +export interface DisabledParamsOptions { + // Default to `false` + includeQuery?: boolean, + // Default to `false` + includeHeader?: boolean +} + export interface Options { info?: InfoObject, defaultTag?: string, @@ -84,7 +91,8 @@ export interface Options { replaceVars?: boolean, additionalVars?: { [key: string]: string }, // Default value 'yaml' - outputFormat?: 'json' | 'yaml' + outputFormat?: 'json' | 'yaml', + disabledParams?: DisabledParamsOptions } export default function postmanToOpenApi (input: string, output?: string, options?: Options) : Promise