From bff436682af1a1e7e517e1619dfe053730ec5e9d Mon Sep 17 00:00:00 2001 From: Paolo Bergamaschi Date: Mon, 4 Sep 2023 12:03:41 +0200 Subject: [PATCH 1/4] feat: tag block management This features add the management of the "tags" blocks, that resumes all the tag of all the operations, and offers the possibility to describe the tag. The new feature import the "tags" block if available, and filters it based on the list of the tags of the output file The new feature --- index.js | 13 ++++++ test/tags/input.yaml | 86 +++++++++++++++++++++++++++++++++++++++ test/tags/options.yaml | 1 + test/tags/output.yaml | 46 +++++++++++++++++++++ test/tags3/input.yaml | 89 +++++++++++++++++++++++++++++++++++++++++ test/tags3/options.yaml | 1 + test/tags3/output.yaml | 49 +++++++++++++++++++++++ 7 files changed, 285 insertions(+) create mode 100644 test/tags/input.yaml create mode 100644 test/tags/options.yaml create mode 100644 test/tags/output.yaml create mode 100644 test/tags3/input.yaml create mode 100644 test/tags3/options.yaml create mode 100644 test/tags3/output.yaml diff --git a/index.js b/index.js index f1c90a0..b4340d2 100644 --- a/index.js +++ b/index.js @@ -75,6 +75,10 @@ function extract(obj, options) { src.basePath = obj.basePath; } } + if(obj.tags) { + src.tags = obj.tags + } + src.paths = {}; if (src.openapi) { src.components = {}; @@ -102,6 +106,8 @@ function extract(obj, options) { } let paths = {}; + const usedTags = new Set(); + if (options.operationid.length) { for (let id of options.operationid) { for (let p in obj.paths) { @@ -111,6 +117,7 @@ function extract(obj, options) { if (!paths[p]) paths[p] = {}; paths[p][o] = clone(op); deref(paths[p][o],src,obj); + usedTags.add(...op.tags); } } } @@ -123,6 +130,7 @@ function extract(obj, options) { if (options.method && obj.paths[options.path][options.method]) { paths[options.path][options.method] = clone(obj.paths[options.path][options.method]); deref(paths[options.path][options.method],src,obj); + usedTags.add(...paths[options.path][o].tags); } else if (options.path) { for (let o in obj.paths[options.path]) { @@ -131,6 +139,7 @@ function extract(obj, options) { if (!options.method || options.method === o) { paths[options.path][o] = clone(obj.paths[options.path][o]); deref(paths[options.path][o],src,obj); + usedTags.add(...paths[options.path][o].tags); } } } @@ -202,6 +211,10 @@ function extract(obj, options) { } } + if (src.tags) { + src.tags = src.tags.filter(tag => usedTags.has(tag.name)); + } + return src; } diff --git a/test/tags/input.yaml b/test/tags/input.yaml new file mode 100644 index 0000000..6d141ec --- /dev/null +++ b/test/tags/input.yaml @@ -0,0 +1,86 @@ +swagger: '2.0' +schemes: + - http +host: xkcd.com +basePath: / +info: + description: 'Webcomic of romance, sarcasm, math, and language.' + title: XKCD + version: 1.0.0 + x-apisguru-categories: + - media + x-logo: + url: 'http://imgs.xkcd.com/static/terrible_small_logo.png' + x-origin: + - format: swagger + url: 'https://raw.githubusercontent.com/APIs-guru/unofficial_openapi_specs/master/xkcd.com/1.0.0/swagger.yaml' + version: '2.0' + x-providerName: xkcd.com + x-tags: + - humor + - comics + x-unofficialSpec: true +tags: + - name: fetch + description: fetches a specific entity + - name: latest + description: retrieve the latest +externalDocs: + url: 'https://xkcd.com/json.html' +securityDefinitions: {} +paths: + /info.0.json: + get: + operationId: getLatest + description: | + Fetch current comic and metadata. + responses: + '200': + description: OK + schema: + $ref: '#/definitions/comic' + tags: + - latest + '/{comicId}/info.0.json': + get: + operationId: getComic + description: | + Fetch comics and metadata by comic id. + parameters: + - in: path + name: comicId + required: true + type: number + responses: + '200': + description: OK + schema: + $ref: '#/definitions/comic' + tags: + - fetch +definitions: + comic: + properties: + alt: + type: string + day: + type: string + img: + type: string + link: + type: string + month: + type: string + news: + type: string + num: + type: number + safe_title: + type: string + title: + type: string + transcript: + type: string + year: + type: string + type: object diff --git a/test/tags/options.yaml b/test/tags/options.yaml new file mode 100644 index 0000000..b62a9ba --- /dev/null +++ b/test/tags/options.yaml @@ -0,0 +1 @@ +operationid: getLatest diff --git a/test/tags/output.yaml b/test/tags/output.yaml new file mode 100644 index 0000000..c438652 --- /dev/null +++ b/test/tags/output.yaml @@ -0,0 +1,46 @@ +swagger: "2.0" +info: + title: XKCD + version: 1.0.0 +tags: + - name: latest + description: retrieve the latest +paths: + /info.0.json: + get: + operationId: getLatest + description: | + Fetch current comic and metadata. + responses: + "200": + description: OK + schema: + $ref: "#/definitions/comic" + tags: + - latest +definitions: + comic: + properties: + alt: + type: string + day: + type: string + img: + type: string + link: + type: string + month: + type: string + news: + type: string + num: + type: number + safe_title: + type: string + title: + type: string + transcript: + type: string + year: + type: string + type: object diff --git a/test/tags3/input.yaml b/test/tags3/input.yaml new file mode 100644 index 0000000..875d8c6 --- /dev/null +++ b/test/tags3/input.yaml @@ -0,0 +1,89 @@ +openapi: 3.0.0 +info: + description: Webcomic of romance, sarcasm, math, and language. + title: XKCD + version: 1.0.0 + x-apisguru-categories: + - media + x-logo: + url: http://imgs.xkcd.com/static/terrible_small_logo.png + x-origin: + - format: swagger + url: https://raw.githubusercontent.com/APIs-guru/unofficial_openapi_specs/master/xkcd.com/1.0.0/swagger.yaml + version: "2.0" + x-providerName: xkcd.com + x-tags: + - humor + - comics + x-unofficialSpec: true +externalDocs: + url: https://xkcd.com/json.html +tags: + - name: fetch + description: fetches a specific entity + - name: latest + description: retrieve the latest +paths: + /info.0.json: + get: + operationId: getLatest + description: | + Fetch current comic and metadata. + responses: + "200": + description: OK + content: + "*/*": + schema: + $ref: "#/components/schemas/comic" + tags: + - latest + "/{comicId}/info.0.json": + get: + operationId: getComic + description: | + Fetch comics and metadata by comic id. + parameters: + - in: path + name: comicId + required: true + schema: + type: number + responses: + "200": + description: OK + content: + "*/*": + schema: + $ref: "#/components/schemas/comic" + tags: + - fetch +servers: + - url: http://xkcd.com/ +components: + schemas: + comic: + properties: + alt: + type: string + day: + type: string + img: + type: string + link: + type: string + month: + type: string + news: + type: string + num: + type: number + safe_title: + type: string + title: + type: string + transcript: + type: string + year: + type: string + type: object diff --git a/test/tags3/options.yaml b/test/tags3/options.yaml new file mode 100644 index 0000000..b62a9ba --- /dev/null +++ b/test/tags3/options.yaml @@ -0,0 +1 @@ +operationid: getLatest diff --git a/test/tags3/output.yaml b/test/tags3/output.yaml new file mode 100644 index 0000000..83198a3 --- /dev/null +++ b/test/tags3/output.yaml @@ -0,0 +1,49 @@ +openapi: 3.0.0 +info: + title: XKCD + version: 1.0.0 +tags: + - name: latest + description: retrieve the latest +paths: + /info.0.json: + get: + operationId: getLatest + description: | + Fetch current comic and metadata. + responses: + "200": + description: OK + content: + "*/*": + schema: + $ref: "#/components/schemas/comic" + tags: + - latest +components: + schemas: + comic: + properties: + alt: + type: string + day: + type: string + img: + type: string + link: + type: string + month: + type: string + news: + type: string + num: + type: number + safe_title: + type: string + title: + type: string + transcript: + type: string + year: + type: string + type: object From 4c096803bb028a0ae010525284dddad31253d0dd Mon Sep 17 00:00:00 2001 From: Paolo Bergamaschi Date: Mon, 4 Sep 2023 12:34:07 +0200 Subject: [PATCH 2/4] fix: operationID not correctly working Apparently when specified in vscode "launch.json", operationID appears with a trailing space, I added a .trim() to fix that --- index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.js b/index.js index b4340d2..551913b 100644 --- a/index.js +++ b/index.js @@ -113,7 +113,7 @@ function extract(obj, options) { for (let p in obj.paths) { for (let o in obj.paths[p]) { let op = obj.paths[p][o]; - if (op.operationId && op.operationId === id) { + if (op.operationId && op.operationId === id.trim()) { if (!paths[p]) paths[p] = {}; paths[p][o] = clone(op); deref(paths[p][o],src,obj); From 66ad9e4d1507bb8e941750c4f5dea15c2559c268 Mon Sep 17 00:00:00 2001 From: Paolo Bergamaschi Date: Thu, 14 Sep 2023 09:28:19 +0200 Subject: [PATCH 3/4] BUGFIX: potential "null reference" corrected --- index.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/index.js b/index.js index 551913b..b33269f 100644 --- a/index.js +++ b/index.js @@ -117,7 +117,8 @@ function extract(obj, options) { if (!paths[p]) paths[p] = {}; paths[p][o] = clone(op); deref(paths[p][o],src,obj); - usedTags.add(...op.tags); + if(op && op.tags) + usedTags.add(...op.tags); } } } From 23671fecb5717244e883915b9c4f643cf8aafe71 Mon Sep 17 00:00:00 2001 From: Paolo Bergamaschi Date: Thu, 14 Sep 2023 11:19:38 +0200 Subject: [PATCH 4/4] BUGFIX: resolved bug in definition resolution postponed definition resolution in order to correctly resolve definitions inside response definition --- index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.js b/index.js index b33269f..6a3eff8 100644 --- a/index.js +++ b/index.js @@ -167,11 +167,11 @@ function extract(obj, options) { } } - deref(src.definitions,src,obj); deref(src.headers,src,obj); deref(src.responses,src,obj); deref(src.parameters,src,obj); deref(src.components,src,obj); + deref(src.definitions,src,obj); if (options.openai) { recurse(src,{},function(obj,key,state){