asyncapi / bundler

Combine multiple AsyncAPI specification files into one.
Apache License 2.0
29 stars 15 forks source link

Add option to specify baseFileDir or cwd #136

Closed nilkanth987 closed 7 months ago

nilkanth987 commented 1 year ago

Reason/Context

Add an option to specify the base file's directory so we can correctly check for relative references of separate files in the specifications.

I created an asyncapi.yml in the docs folder and in that file I referenced other files with the relative path. And this causes unresolved reference to the file.

Description

Here is an example of the asyncapi.yml file in docs directory

asyncapi: 2.6.0
info:
  title: Test app
  description: This document describes the REST API endpoints and SOCKET events
  version: 0.0.1
servers:
  $ref: "servers.yml#/servers"

Here is the serves.yml file in docs directory

servers:
  production:
    url: test.com/{basePath}
    description: Production server
    protocol: https
    security:
      - JWT: []
    variables:
      basePath:
        default: api/v2

Here is the app.js code in root directory

async function exposeApiDocumentation() {
  try {
    const generator = new Generator('@asyncapi/html-template', path.resolve('public/docs/ui'), { forceWrite: true, install: true })
    generator.generateFromFile('docs/asyncapi.yml')
    const filePaths = [];
    readdirSync(path.resolve('docs')).forEach(item => {
      var filePath = path.join(path.resolve('docs'), item);
      var stat = statSync(filePath);
      if (stat.isFile() && item !== "asyncapi.yml") {
        filePaths.push(filePath)
      } else if (stat.isDirectory()) {
        readdirSync(filePath).forEach(file => {
          var filePath2 = path.join(filePath, file);
          var stat2 = statSync(filePath2);
          if (stat2.isFile())
            filePaths.push(filePath2)
        })
      }
    })
    const pathAsyncapi = path.join(path.resolve('docs'), 'asyncapi.yml')
    const document = await bundle(
      filePaths.map(filePath => {
        return readFileSync(filePath, { encoding: 'utf-8' })
      }),
      {
        base: readFileSync(pathAsyncapi, { encoding: 'utf-8' }),
        referenceIntoComponents: true,
      }
    )
    writeFileSync('public/docs/asyncapi.yml', document.yml());
    app.use('/public', express.static('public'))
  } catch (e) {
    console.log(e)
    getLogger().error(`Error generating api documentation : ${e}`)
  }
}

exposeApiDocumentation()

This is the error that I get

{
  stack: 'ResolverError: Error opening file "XXXX/servers.yml" \n' +
    "ENOENT: no such file or directory, open 'XXXX/servers.yml'\n" +
    '    at ReadFileContext.callback (XXXX/node_modules/@apidevtools/json-schema-ref-parser/lib/resolvers/file.js:52:20)\n' +
    '    at FSReqCallback.readFileAfterOpen [as oncomplete] (node:fs:327:13)\n' +
    '    at FSReqCallback.callbackTrampoline (node:internal/async_hooks:130:17)',
  code: 'ERESOLVER',
  message: 'Error opening file "XXXX/servers.yml" \n' +
    "ENOENT: no such file or directory, open 'XXXX/servers.yml'",
  source: 'XXXX/servers.yml',
  path: null,
  toJSON: [Function: toJSON],
  ioErrorCode: 'ENOENT',
  name: 'ResolverError',
  footprint: 'null+XXXX/servers.yml+ERESOLVER+Error opening file "XXXX/servers.yml" \n' +
    "ENOENT: no such file or directory, open 'XXXX/servers.yml'",
  toString: [Function: toString]
}

Let me know if I could help

github-actions[bot] commented 1 year ago

Welcome to AsyncAPI. Thanks a lot for reporting your first issue. Please check out our contributors guide and the instructions about a basic recommended setup useful for opening a pull request.
Keep in mind there are also other channels you can use to interact with AsyncAPI community. For more details check out this issue.

Souvikns commented 1 year ago

@nilkanth987 are you having the same issue as https://github.com/asyncapi/bundler/issues/35.

nilkanth987 commented 1 year ago

@Souvikns , Sorry for delayed reply. Yes the issue is same BUT I DID PUT THE GENERATOR SCRIPT FILE IN SAME DIRECTORY AS THE asyncapi.yml FILE AND IT FIXES THE ISSUE, but it does not reference properly the files that are inside the different folder.

HERE IS MY DIRECTORY STRUCTURE

docs
  - schemas
      - schema1.yml     
      - schema2.yml
  - components
      - comp1.yml      (ref: ../schemas/schema1.yml     THIS IS NOT RESOLVED)
      - comp2.yml
  asyncapi.yml
  bundleScript.cjs    (Tried this)

app.js    (Tried this)

Let me know if you need any clarity

jonaslagoni commented 1 year ago

Need the same feature.

asyncapi-bot commented 6 months ago

:tada: This issue has been resolved in version 0.5.0 :tada:

The release is available on:

Your semantic-release bot :package::rocket: