Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Confused by failure to read spec #57

Open
robogeek opened this issue Oct 22, 2024 · 1 comment
Open

Confused by failure to read spec #57

robogeek opened this issue Oct 22, 2024 · 1 comment

Comments

@robogeek
Copy link

I'm very intrigued by this tool, and am interested in using it. However, the demo described in the README throws a weird error.

I have a well defined specification that is successfully being used in a variety of OpenAPI tools. The specification is for OpenADR (https://www.openadr.org/). If you need to see the spec, it's freely available so long as you register.

This is the output. This output format is rather inscrutable since I have no idea what the actual error is. The only clue I get is that this uses oas-validator.

Below, I show a quick zx script I wrote to use oas-validator directly. Below that is the JS object output by oas-validator. The JS object looks like oas-validator thinks it is valid, and the structure it generated looks correct per the spec.

$ npx og -o og-md ../../oadr3.0.1.yaml markdown
Invalid OpenAPI file
Error [AssertionError]: expected 'string' to be 'object'
    at Assertion.fail (/home/david/Projects/openadr/openadr-3-ts-types/node/builder/node_modules/should/as-function.js:275:17)
    at Assertion.value (/home/david/Projects/openadr/openadr-3-ts-types/node/builder/node_modules/should/as-function.js:356:19)
    at checkSubSchema (/home/david/Projects/openadr/openadr-3-ts-types/node/builder/node_modules/openapi3-generator/node_modules/oas-validator/index.js:268:28)
    at walkSchema (/home/david/Projects/openadr/openadr-3-ts-types/node/builder/node_modules/oas-schema-walker/index.js:53:5)
    at walkSchema (/home/david/Projects/openadr/openadr-3-ts-types/node/builder/node_modules/oas-schema-walker/index.js:82:13)
    at Object.walkSchema (/home/david/Projects/openadr/openadr-3-ts-types/node/builder/node_modules/oas-schema-walker/index.js:64:9)
    at checkSchema (/home/david/Projects/openadr/openadr-3-ts-types/node/builder/node_modules/openapi3-generator/node_modules/oas-validator/index.js:333:8)
    at checkContent (/home/david/Projects/openadr/openadr-3-ts-types/node/builder/node_modules/openapi3-generator/node_modules/oas-validator/index.js:381:13)
    at checkResponse (/home/david/Projects/openadr/openadr-3-ts-types/node/builder/node_modules/openapi3-generator/node_modules/oas-validator/index.js:570:9)
    at checkPathItem (/home/david/Projects/openadr/openadr-3-ts-types/node/builder/node_modules/openapi3-generator/node_modules/oas-validator/index.js:783:21) {
  operator: 'to be',
  expected: 'object',
  showDiff: true,
  actual: 'string',
  stackStartFunction: [Function: assert],
  negate: false,
  assertion: <ref *1> Assertion {
    obj: 'string',
    anyOne: false,
    negate: false,
    params: {
      operator: 'to be',
      expected: 'object',
      message: undefined,
      showDiff: true,
      actual: 'string',
      stackStartFunction: [Function: assert],
      negate: false,
      assertion: [Circular *1]
    },
    onlyThis: undefined,
    light: false
  }
}
TypeError: Cannot read properties of undefined (reading 'basePath')
    at module.exports (/home/david/Projects/openadr/openadr-3-ts-types/node/builder/node_modules/openapi3-generator/lib/beautifier.js:132:30)
    at /home/david/Projects/openadr/openadr-3-ts-types/node/builder/node_modules/openapi3-generator/lib/generator.js:327:17

I wrote a quick zx script to use oas-validator

import validator from 'oas-validator';

if (!(typeof argv?.input === 'string')) {
    throw new Error(`no --input`);
}

import { promises as fsp } from 'node:fs';

const txt = await fsp.readFile(argv?.input, 'utf-8');

const openapi = YAML.parse(txt);

const options = {};
validator.validate(openapi, options)
.then(function(options){
  // options.valid contains the result of the validation, true in this branch
  console.log(options);
})
.catch(function(err){
  console.warn(err.message);
  if (options.context) console.warn('Location',options.context.pop());
});

And it gave this output:

{
  valid: true,
  context: [ '#/' ],
  warnings: [],
  lintLimit: 5,
  lintSkip: [],
  operationIds: [
    'searchAllPrograms',
    'createProgram',
    'searchProgramByProgramId',
    'updateProgram',
    'deleteProgram',
    'searchAllReports',
    'createReport',
    'searchReportsByReportID',
    'updateReport',
    'deleteReport',
    'searchAllEvents',
    'createEvent',
    'searchEventsByID',
    'updateEvent',
    'deleteEvent',
    'searchSubscriptions',
    'createSubscription',
    'searchSubscriptionByID',
    'updateSubscription',
    'deleteSubscription',
    'searchVens',
    'createVen',
    'searchVenByID',
    'updateVen',
    'deleteVen',
    'searchVenResources',
    'createResource',
    'searchVenResourceByID',
    'updateVenResource',
    'deleteVenResource',
    'fetchToken'
  ],
  allScopes: {
    oAuth2ClientCredentials: {
      read_all: 'VENs and BL can read all resources',
      write_programs: 'Only BL can write to programs',
      write_events: 'Only BL can write to events',
      write_reports: 'only VENs can write to reports',
      write_subscriptions: 'VENs and BL can write to subscriptions',
      write_vens: 'VENS and BL can write to vens and resources'
    }
  },
  openapi: {
    openapi: '3.0.0',
    servers: [ [Object] ],
    info: {
      title: 'OpenADR 3 API',
      version: '3.0.1',
      description: 'The OpenADR 3 API supports energy retailer to energy customer Demand Response programs.\n' +
        'See OpenADR 3 User Guide and Defintions for detailed descriptions of usage.\n' +
        'The API includes the following capabilities and operations:\n' +
        '\n' +
        '__Manage programs:__\n' +
        '\n' +
        '* Create/Update/Delete a program\n' +
        '* Search programs\n' +
        '\n' +
        '__Manage events:__\n' +
        '\n' +
        '* Create/Update/Delete an event\n' +
        '* Search events\n' +
        '\n' +
        '__Manage reports:__\n' +
        '\n' +
        '* Create/Update/Delete a report\n' +
        '* Search reports\n' +
        '\n' +
        '__Manage subscriptions:__\n' +
        '\n' +
        '* Create/Update/Delete subscriptions to programs, events, and reports\n' +
        '* Search subscriptions\n' +
        '* Subscriptions allows clients to register a callback URL (webhook) to be notified\n' +
        '  on the change of state of a resource\n' +
        '\n' +
        '__Manage vens:__\n' +
        '\n' +
        '* Create/Update/Delete vens and ven resources\n' +
        '* Search ven and ven resources\n' +
        '\n' +
        '__Manage tokens:__\n' +
        '\n' +
        '* Obtain an access token\n' +
        '* This endpoint is provided as a convenience and may be neglected in a commercial implementation\n',
      contact: [Object],
      license: [Object]
    },
    paths: {
      '/programs': [Object],
      '/programs/{programID}': [Object],
      '/reports': [Object],
      '/reports/{reportID}': [Object],
      '/events': [Object],
      '/events/{eventID}': [Object],
      '/subscriptions': [Object],
      '/subscriptions/{subscriptionID}': [Object],
      '/vens': [Object],
      '/vens/{venID}': [Object],
      '/vens/{venID}/resources': [Object],
      '/vens/{venID}/resources/{resourceID}': [Object],
      '/auth/token': [Object]
    },
    components: { schemas: [Object], securitySchemes: [Object] }
  },
  cache: {},
  metadata: { lines: -1, count: {} },
  fetch: <ref *1> [Function: fetch] {
    isRedirect: [Function (anonymous)],
    Promise: [Function: Promise],
    default: [Circular *1],
    Headers: [class Headers],
    Request: [class Request],
    Response: [class Response],
    FetchError: [Function: FetchError]
  },
  externals: [],
  externalRefs: {},
  rewriteRefs: true,
  resolver: { depth: 0, base: undefined, actions: [ [] ] },
  isCallback: false
}
@robogeek
Copy link
Author

I cloned the repository.

In bundler.js I commented this out:

  // try {
  //   validator.validateSync(bundledJSON, {});
  // } catch (e) {
  //   console.error('Invalid OpenAPI file');
  //   console.error(e);
  //   return;
  // }

With this commented out, the program ran correctly, and generated a Markdown file that looks good. With it uncommented, the failure shown above occurs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant