mocks-server / main

Node.js mock server running live, interactive mocks in place of real APIs
https://www.mocks-server.org
Apache License 2.0
281 stars 15 forks source link

openapi error "fileContent.map is not a function" #451

Closed mafische closed 1 year ago

mafische commented 1 year ago

Describe the bug When trying to use the OpenAPI plugin, I get 13:26:21:69 [info][files] File change detected 13:26:21:70 [info][files] Loading files from folder /input/mocks 13:26:21:77 [info][mock] Selected collection: 'base' 13:26:21:79 [info][mock] Selected collection: 'base' 13:26:21:94 [error][alerts:load] Error proccesing loaded files: fileContent.map is not a function

Is this a coding error, or file handling issue? It seems to be no problem of actual content or processing the files, right?

To Reproduce start mocks container version create openapi/ directory in mocks path copy any vendor-provided OpenAPI 3.0.0 yaml file(s) into openapi/ subdirectory

Expected behavior routes being created (or errors regarding syntactical issues, maybe)

Logs 14:25:41:02 [verbose][files:loader:routes] Loaded routes from folder '/input/mocks/routes' 14:25:41:37 [error][alerts:load] Error proccesing loaded files: fileContent.map is not a function 14:25:41:38 [debug][alerts:load] TypeError: fileContent.map is not a function at /usr/app/node_modules/@mocks-server/plugin-openapi/dist/Plugin.js:120:36 at Array.map () at Plugin. (/usr/app/node_modules/@mocks-server/plugin-openapi/dist/Plugin.js:118:81) at Generator.next () at /usr/app/node_modules/@mocks-server/plugin-openapi/dist/Plugin.js:8:71 at new Promise () at __awaiter (/usr/app/node_modules/@mocks-server/plugin-openapi/dist/Plugin.js:4:12) at Plugin._getRoutesAndCollectionsFromFilesContents (/usr/app/node_modules/@mocks-server/plugin-openapi/dist/Plugin.js:117:16) at Plugin. (/usr/app/node_modules/@mocks-server/plugin-openapi/dist/Plugin.js:160:60) at Generator.next ()

Operating system, Node.js an npm versions, or browser version (please complete the following information):

Additional context found the function in plugin-openapi/dist/Plugin.js

_getRoutesAndCollectionsFromFilesContents(filesContents) { return __awaiter(this, void 0, void 0, function* () { const openApiRoutesAndCollections = yield Promise.all(filesContents.map((fileDetails) => { const fileContent = fileDetails.content; return fileContent.map((openAPIDefinition) => {

javierbrea commented 1 year ago

Hi @mafische , The plugin expects that each file exports an array of OpenAPI route definitions, as any other type of route definitions in Mocks Server. Note that loading directly an OpenAPI yaml file would not work, because you have to provide a Mocks Server openAPI definition, with the OpenAPI document defined in the document property. The plugin needs a basePath to be defined to create the routes, etc. You can load OpenAPI files from Mocks Server OpenAPI routes using the ref feature, if you prefer to keep the vendor OpenAPI definitions separated, for example:

module.exports = [
  {
    basePath: "/testing-api",
    document: {
      $ref: "../documents/openapi.json"
    }
  }
];

But, anyway, the error is not handled properly, and so, the message is not clear, you're right. Files exporting an object instead of an array should produce an appropriate error message.

gvych commented 1 year ago

Very often OpenAPI is stored in YAML format. Looks like at the moment we always need to convert YAML to JSON, or modify YAML using yq (analog of jq) before we can use it for Mocks-server. That is a shame, because we would need to create/support this "pipeline" for both local development and CI/CD.

Can we leverage some sort of Babel pre-processing for that (sorry, not very familiar with Babel)? Or can we contribute to the project with any kind of OpenAPI YAML file inclusion support?

javierbrea commented 1 year ago

Hi @gvych, if you need to load yaml files containing the OpenAPI documents, you could try using the js-yaml library or another yaml conversor, and load them as in the example above, but providing the whole document instead of using the ref feature:

const fs   = require("fs");
const yaml = require("js-yaml");

module.exports = [
  {
    basePath: "/testing-api",
    document: yaml.load(fs.readFileSync("/path/to/openapi.yaml","utf8")),
  }
];

Anyway, if you want to contribute with a better solution for loading separated files containing yaml or json OpenAPI documents, you'll be welcome, of course 😃