diff --git a/lib/bundle.js b/lib/bundle.js index 63f88e8..b1a90d9 100644 --- a/lib/bundle.js +++ b/lib/bundle.js @@ -26,7 +26,8 @@ let path = require('path'), 'securitySchemes', 'links', 'callbacks' - ]; + ], + deref = require('./deref.js'); /** @@ -137,9 +138,7 @@ function getContentFromTrace(content, partial) { partial = partial[0] === jsonPointerLevelSeparator ? partial.substring(1) : partial; const trace = partial.split(jsonPointerLevelSeparator); let currentValue = content; - for (let place of trace) { - currentValue = currentValue[place]; - } + currentValue = deref._getEscaped(content, trace, undefined); return currentValue; } @@ -351,7 +350,13 @@ function generateComponentsObject (documentContext, rootContent, refTypeResolver refData.inline = refData.keyInComponents.length === 0; } if (local) { - refData.nodeContent = getContentFromTrace(refData.nodeContent, local); + let contentFromTrace = getContentFromTrace(refData.nodeContent, local); + if (!contentFromTrace) { + refData.nodeContent = { $ref: `${localPointer + local}` }; + } + else { + refData.nodeContent = contentFromTrace; + } } if (refData.inline) { refData.node = refData.nodeContent; diff --git a/test/data/toBundleExamples/referenced_info/expected.json b/test/data/toBundleExamples/referenced_info/expected.json new file mode 100644 index 0000000..228d281 --- /dev/null +++ b/test/data/toBundleExamples/referenced_info/expected.json @@ -0,0 +1,80 @@ +{ + "openapi": "3.0.2", + "info": { + "version": "1.0.0", + "title": "Swagger Petstore", + "description": "A sample API that uses a petstore as an example to demonstrate features in the swagger-2.0 specification", + "termsOfService": "http://swagger.io/terms/", + "contact": { + "name": "Swagger API Team", + "email": "apiteam@swagger.io", + "url": "http://swagger.io" + }, + "license": { + "name": "Apache 2.0", + "url": "https://www.apache.org/licenses/LICENSE-2.0.html" + } + }, + "paths": { + "/pets": { + "get": { + "description": "Returns all pets alesuada ac...", + "operationId": "findPets", + "responses": { + "200": { + "description": "pet response", + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Pet" + } + } + }, + "default": { + "description": "unexpected error", + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + }, + "components": { + "schemas": { + "Pet": { + "required": [ + "id", + "name" + ], + "properties": { + "id": { + "type": "integer", + "format": "int64" + }, + "name": { + "type": "string" + }, + "tag": { + "type": "string" + } + } + }, + "Error": { + "required": [ + "code", + "message" + ], + "properties": { + "code": { + "type": "integer", + "format": "int32" + }, + "message": { + "type": "string" + } + } + } + } + } +} \ No newline at end of file diff --git a/test/data/toBundleExamples/referenced_info/info/info.yaml b/test/data/toBundleExamples/referenced_info/info/info.yaml new file mode 100644 index 0000000..938fb64 --- /dev/null +++ b/test/data/toBundleExamples/referenced_info/info/info.yaml @@ -0,0 +1,11 @@ +version: 1.0.0 +title: Swagger Petstore +description: A sample API that uses a petstore as an example to demonstrate features in the swagger-2.0 specification +termsOfService: http://swagger.io/terms/ +contact: + name: Swagger API Team + email: apiteam@swagger.io + url: http://swagger.io +license: + name: Apache 2.0 + url: https://www.apache.org/licenses/LICENSE-2.0.html diff --git a/test/data/toBundleExamples/referenced_info/root.yaml b/test/data/toBundleExamples/referenced_info/root.yaml new file mode 100644 index 0000000..81755ca --- /dev/null +++ b/test/data/toBundleExamples/referenced_info/root.yaml @@ -0,0 +1,45 @@ + +openapi: "3.0.2" +info: + "$ref": "./info/info.yaml" + +paths: + /pets: + get: + description: Returns all pets alesuada ac... + operationId: findPets + responses: + "200": + description: pet response + schema: + type: array + items: + $ref: "#/components/schemas/Pet" + default: + description: unexpected error + schema: + $ref: "#/components/schemas/Error" +components: + schemas: + Pet: + required: + - id + - name + properties: + id: + type: integer + format: int64 + name: + type: string + tag: + type: string + Error: + required: + - code + - message + properties: + code: + type: integer + format: int32 + message: + type: string diff --git a/test/data/toBundleExamples/referenced_paths/expected.json b/test/data/toBundleExamples/referenced_paths/expected.json new file mode 100644 index 0000000..5c353cf --- /dev/null +++ b/test/data/toBundleExamples/referenced_paths/expected.json @@ -0,0 +1,109 @@ +{ + "openapi": "3.0.2", + "info": { + "version": "1.0.0", + "title": "Swagger Petstore", + "description": "A sample API that uses a petstore as an example to demonstrate features in the swagger-2.0 specification", + "termsOfService": "http://swagger.io/terms/", + "contact": { + "name": "Swagger API Team", + "email": "apiteam@swagger.io", + "url": "http://swagger.io" + }, + "license": { + "name": "Apache 2.0", + "url": "https://www.apache.org/licenses/LICENSE-2.0.html" + } + }, + "paths": { + "/pets": { + "get": { + "description": "Returns all pets alesuada ac...", + "operationId": "findPets", + "responses": { + "200": { + "description": "pet response", + "content": { + "application/json": { + "schema": { + "required": [ + "code", + "message" + ], + "properties": { + "code": { + "type": "integer", + "format": "int32" + }, + "message": { + "type": "string" + } + } + } + } + } + }, + "default": { + "description": "unexpected error", + "content": { + "application/json": { + "schema": { + "required": [ + "code", + "message" + ], + "properties": { + "code": { + "type": "integer", + "format": "int32" + }, + "message": { + "type": "string" + } + } + } + } + } + } + } + } + } + }, + "components": { + "schemas": { + "Pet": { + "required": [ + "id", + "name" + ], + "properties": { + "id": { + "type": "integer", + "format": "int64" + }, + "name": { + "type": "string" + }, + "tag": { + "type": "string" + } + } + }, + "Error": { + "required": [ + "code", + "message" + ], + "properties": { + "code": { + "type": "integer", + "format": "int32" + }, + "message": { + "type": "string" + } + } + } + } + } +} \ No newline at end of file diff --git a/test/data/toBundleExamples/referenced_paths/paths/path.yaml b/test/data/toBundleExamples/referenced_paths/paths/path.yaml new file mode 100644 index 0000000..dab6ca5 --- /dev/null +++ b/test/data/toBundleExamples/referenced_paths/paths/path.yaml @@ -0,0 +1,31 @@ +description: Returns all pets alesuada ac... +operationId: findPets +responses: + "200": + description: pet response + content: + application/json: + schema: + required: + - code + - message + properties: + code: + type: integer + format: int32 + message: + type: string + default: + description: unexpected error + content: + application/json: + schema: + required: + - code + - message + properties: + code: + type: integer + format: int32 + message: + type: string diff --git a/test/data/toBundleExamples/referenced_paths/paths/paths.yaml b/test/data/toBundleExamples/referenced_paths/paths/paths.yaml new file mode 100644 index 0000000..e826f5c --- /dev/null +++ b/test/data/toBundleExamples/referenced_paths/paths/paths.yaml @@ -0,0 +1,3 @@ +/pets: + get: + "$ref": "./path.yaml" diff --git a/test/data/toBundleExamples/referenced_paths/root.yaml b/test/data/toBundleExamples/referenced_paths/root.yaml new file mode 100644 index 0000000..a3a73c7 --- /dev/null +++ b/test/data/toBundleExamples/referenced_paths/root.yaml @@ -0,0 +1,40 @@ + +openapi: "3.0.2" +info: + version: 1.0.0 + title: Swagger Petstore + description: A sample API that uses a petstore as an example to demonstrate features in the swagger-2.0 specification + termsOfService: http://swagger.io/terms/ + contact: + name: Swagger API Team + email: apiteam@swagger.io + url: http://swagger.io + license: + name: Apache 2.0 + url: https://www.apache.org/licenses/LICENSE-2.0.html +paths: + "$ref": "./paths/paths.yaml" +components: + schemas: + Pet: + required: + - id + - name + properties: + id: + type: integer + format: int64 + name: + type: string + tag: + type: string + Error: + required: + - code + - message + properties: + code: + type: integer + format: int32 + message: + type: string diff --git a/test/data/toBundleExamples/referenced_paths_local_schema/expected.json b/test/data/toBundleExamples/referenced_paths_local_schema/expected.json new file mode 100644 index 0000000..2797fb7 --- /dev/null +++ b/test/data/toBundleExamples/referenced_paths_local_schema/expected.json @@ -0,0 +1,94 @@ +{ + "openapi": "3.0.2", + "info": { + "version": "1.0.0", + "title": "Swagger Petstore", + "description": "A sample API that uses a petstore as an example to demonstrate features in the swagger-2.0 specification", + "termsOfService": "http://swagger.io/terms/", + "contact": { + "name": "Swagger API Team", + "email": "apiteam@swagger.io", + "url": "http://swagger.io" + }, + "license": { + "name": "Apache 2.0", + "url": "https://www.apache.org/licenses/LICENSE-2.0.html" + } + }, + "paths": { + "/pets": { + "get": { + "description": "Returns all pets", + "operationId": "findPets", + "responses": { + "200": { + "description": "pet response", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/~1paths~1path.yaml%23~1components~1schemas~1Pet" + } + } + } + } + }, + "default": { + "description": "unexpected error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/~1paths~1path.yaml%23~1components~1schemas~1Error" + } + } + } + } + } + } + } + }, + "components": { + "schemas": { + "Pet": { + "required": [ + "id", + "name" + ], + "properties": { + "id": { + "type": "integer", + "format": "int64" + }, + "name": { + "type": "string" + }, + "tag": { + "type": "string" + } + } + }, + "Error": { + "required": [ + "code", + "message" + ], + "properties": { + "code": { + "type": "integer", + "format": "int32" + }, + "message": { + "type": "string" + } + } + }, + "/paths/path.yaml#/components/schemas/Pet": { + "$ref": "#/components/schemas/Pet" + }, + "/paths/path.yaml#/components/schemas/Error": { + "$ref": "#/components/schemas/Error" + } + } + } +} \ No newline at end of file diff --git a/test/data/toBundleExamples/referenced_paths_local_schema/paths/path.yaml b/test/data/toBundleExamples/referenced_paths_local_schema/paths/path.yaml new file mode 100644 index 0000000..85d11f8 --- /dev/null +++ b/test/data/toBundleExamples/referenced_paths_local_schema/paths/path.yaml @@ -0,0 +1,17 @@ +description: Returns all pets +operationId: findPets +responses: + "200": + description: pet response + content: + application/json: + schema: + type: array + items: + $ref: "#/components/schemas/Pet" + default: + description: unexpected error + content: + application/json: + schema: + $ref: "#/components/schemas/Error" diff --git a/test/data/toBundleExamples/referenced_paths_local_schema/paths/paths.yaml b/test/data/toBundleExamples/referenced_paths_local_schema/paths/paths.yaml new file mode 100644 index 0000000..e826f5c --- /dev/null +++ b/test/data/toBundleExamples/referenced_paths_local_schema/paths/paths.yaml @@ -0,0 +1,3 @@ +/pets: + get: + "$ref": "./path.yaml" diff --git a/test/data/toBundleExamples/referenced_paths_local_schema/root.yaml b/test/data/toBundleExamples/referenced_paths_local_schema/root.yaml new file mode 100644 index 0000000..a3a73c7 --- /dev/null +++ b/test/data/toBundleExamples/referenced_paths_local_schema/root.yaml @@ -0,0 +1,40 @@ + +openapi: "3.0.2" +info: + version: 1.0.0 + title: Swagger Petstore + description: A sample API that uses a petstore as an example to demonstrate features in the swagger-2.0 specification + termsOfService: http://swagger.io/terms/ + contact: + name: Swagger API Team + email: apiteam@swagger.io + url: http://swagger.io + license: + name: Apache 2.0 + url: https://www.apache.org/licenses/LICENSE-2.0.html +paths: + "$ref": "./paths/paths.yaml" +components: + schemas: + Pet: + required: + - id + - name + properties: + id: + type: integer + format: int64 + name: + type: string + tag: + type: string + Error: + required: + - code + - message + properties: + code: + type: integer + format: int32 + message: + type: string diff --git a/test/data/toBundleExamples/referenced_tags/expected.json b/test/data/toBundleExamples/referenced_tags/expected.json new file mode 100644 index 0000000..e9aa5d7 --- /dev/null +++ b/test/data/toBundleExamples/referenced_tags/expected.json @@ -0,0 +1,94 @@ +{ + "openapi": "3.0.2", + "info": { + "version": "1.0.0", + "title": "Swagger Petstore", + "description": "A sample API that uses a petstore as an example to demonstrate features in the swagger-2.0 specification", + "termsOfService": "http://swagger.io/terms/", + "contact": { + "name": "Swagger API Team", + "email": "apiteam@swagger.io", + "url": "http://swagger.io" + }, + "license": { + "name": "Apache 2.0", + "url": "https://www.apache.org/licenses/LICENSE-2.0.html" + } + }, + "paths": { + "/pets": { + "get": { + "tags": [ + "Authorization" + ], + "description": "Returns all pets alesuada ac...", + "operationId": "findPets", + "responses": { + "200": { + "description": "pet response", + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Pet" + } + } + }, + "default": { + "description": "unexpected error", + "schema": { + "$ref": "#/components/schemas/Error" + } + } + } + } + } + }, + "tags": [ + { + "name": "Authorization", + "x-bx-tag": "authorization", + "x-bx-priority": true + }, + { + "name": "Bx Sign", + "x-bx-tag": "sign_requests" + } + ], + "components": { + "schemas": { + "Pet": { + "required": [ + "id", + "name" + ], + "properties": { + "id": { + "type": "integer", + "format": "int64" + }, + "name": { + "type": "string" + }, + "tag": { + "type": "string" + } + } + }, + "Error": { + "required": [ + "code", + "message" + ], + "properties": { + "code": { + "type": "integer", + "format": "int32" + }, + "message": { + "type": "string" + } + } + } + } + } +} \ No newline at end of file diff --git a/test/data/toBundleExamples/referenced_tags/root.yaml b/test/data/toBundleExamples/referenced_tags/root.yaml new file mode 100644 index 0000000..492ce86 --- /dev/null +++ b/test/data/toBundleExamples/referenced_tags/root.yaml @@ -0,0 +1,58 @@ + +openapi: "3.0.2" +info: + version: 1.0.0 + title: Swagger Petstore + description: A sample API that uses a petstore as an example to demonstrate features in the swagger-2.0 specification + termsOfService: http://swagger.io/terms/ + contact: + name: Swagger API Team + email: apiteam@swagger.io + url: http://swagger.io + license: + name: Apache 2.0 + url: https://www.apache.org/licenses/LICENSE-2.0.html +paths: + /pets: + get: + tags: + - Authorization + description: Returns all pets alesuada ac... + operationId: findPets + responses: + "200": + description: pet response + schema: + type: array + items: + $ref: "#/components/schemas/Pet" + default: + description: unexpected error + schema: + $ref: "#/components/schemas/Error" +tags: + "$ref": "./tags/tags.yaml" +components: + schemas: + Pet: + required: + - id + - name + properties: + id: + type: integer + format: int64 + name: + type: string + tag: + type: string + Error: + required: + - code + - message + properties: + code: + type: integer + format: int32 + message: + type: string diff --git a/test/data/toBundleExamples/referenced_tags/tags/tags.yaml b/test/data/toBundleExamples/referenced_tags/tags/tags.yaml new file mode 100644 index 0000000..a123fd4 --- /dev/null +++ b/test/data/toBundleExamples/referenced_tags/tags/tags.yaml @@ -0,0 +1,6 @@ +- name: Authorization + x-bx-tag: authorization + x-bx-priority: true + +- name: Bx Sign + x-bx-tag: sign_requests diff --git a/test/unit/bundle.test.js b/test/unit/bundle.test.js index 5cc833b..2cdb984 100644 --- a/test/unit/bundle.test.js +++ b/test/unit/bundle.test.js @@ -18,7 +18,12 @@ let expect = require('chai').expect, nestedHard = path.join(__dirname, BUNDLES_FOLDER + '/multiple_references_from_root_components'), localFromExternal = path.join(__dirname, BUNDLES_FOLDER + '/bring_local_dependencies_from_external'), localFromExternalMultiple = path - .join(__dirname, BUNDLES_FOLDER + '/bring_local_dependencies_from_external_multiple_local'); + .join(__dirname, BUNDLES_FOLDER + '/bring_local_dependencies_from_external_multiple_local'), + refTags = path.join(__dirname, BUNDLES_FOLDER + '/referenced_tags'), + refInfo = path.join(__dirname, BUNDLES_FOLDER + '/referenced_info'), + refPaths = path.join(__dirname, BUNDLES_FOLDER + '/referenced_paths'), + refPathsRefToLocalSchema = path.join(__dirname, BUNDLES_FOLDER + '/referenced_paths_local_schema'); + describe('bundle files method - 3.0', function () { it('Should return bundled file as json - schema_from_response', async function () { @@ -619,6 +624,128 @@ describe('bundle files method - 3.0', function () { expect(res.result).to.be.true; expect(res.output.data.bundledContent).to.be.equal(expected); }); + + it('Should return bundled file with referenced tags from root', async function () { + let contentRootFile = fs.readFileSync(refTags + '/root.yaml', 'utf8'), + tags = fs.readFileSync(refTags + '/tags/tags.yaml', 'utf8'), + expected = fs.readFileSync(refTags + '/expected.json', 'utf8'), + input = { + type: 'folder', + specificationVersion: '3.0', + rootFiles: [ + { + path: '/root.yaml', + content: contentRootFile + } + ], + data: [ + { + path: '/tags/tags.yaml', + content: tags + } + ], + options: {}, + bundleFormat: 'JSON' + }; + const res = await Converter.bundle(input); + expect(res).to.not.be.empty; + expect(res.result).to.be.true; + expect(res.output.data.bundledContent).to.be.equal(expected); + }); + + it('Should return bundled file with referenced info from root', async function () { + let contentRootFile = fs.readFileSync(refInfo + '/root.yaml', 'utf8'), + info = fs.readFileSync(refInfo + '/info/info.yaml', 'utf8'), + expected = fs.readFileSync(refInfo + '/expected.json', 'utf8'), + input = { + type: 'folder', + specificationVersion: '3.0', + rootFiles: [ + { + path: '/root.yaml', + content: contentRootFile + } + ], + data: [ + { + path: '/info/info.yaml', + content: info + } + ], + options: {}, + bundleFormat: 'JSON' + }; + const res = await Converter.bundle(input); + expect(res).to.not.be.empty; + expect(res.result).to.be.true; + expect(res.output.data.bundledContent).to.be.equal(expected); + }); + + it('Should return bundled file with referenced paths from root', async function () { + let contentRootFile = fs.readFileSync(refPaths + '/root.yaml', 'utf8'), + paths = fs.readFileSync(refPaths + '/paths/paths.yaml', 'utf8'), + path = fs.readFileSync(refPaths + '/paths/path.yaml', 'utf8'), + expected = fs.readFileSync(refPaths + '/expected.json', 'utf8'), + input = { + type: 'folder', + specificationVersion: '3.0', + rootFiles: [ + { + path: '/root.yaml', + content: contentRootFile + } + ], + data: [ + { + path: '/paths/paths.yaml', + content: paths + }, + { + path: '/paths/path.yaml', + content: path + } + ], + options: {}, + bundleFormat: 'JSON' + }; + const res = await Converter.bundle(input); + expect(res).to.not.be.empty; + expect(res.result).to.be.true; + expect(res.output.data.bundledContent).to.be.equal(expected); + }); + + it('Should return bundled file with referenced paths from root - path references local schema', async function () { + let contentRootFile = fs.readFileSync(refPathsRefToLocalSchema + '/root.yaml', 'utf8'), + paths = fs.readFileSync(refPathsRefToLocalSchema + '/paths/paths.yaml', 'utf8'), + path = fs.readFileSync(refPathsRefToLocalSchema + '/paths/path.yaml', 'utf8'), + expected = fs.readFileSync(refPathsRefToLocalSchema + '/expected.json', 'utf8'), + input = { + type: 'folder', + specificationVersion: '3.0', + rootFiles: [ + { + path: '/root.yaml', + content: contentRootFile + } + ], + data: [ + { + path: '/paths/paths.yaml', + content: paths + }, + { + path: '/paths/path.yaml', + content: path + } + ], + options: {}, + bundleFormat: 'JSON' + }; + const res = await Converter.bundle(input); + expect(res).to.not.be.empty; + expect(res.result).to.be.true; + expect(res.output.data.bundledContent).to.be.equal(expected); + }); });