Skip to content

Confused by failure to read spec #57

Open
@robogeek

Description

@robogeek

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
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions