@@ -5,7 +5,8 @@ const path = require('path')
55const { v4 : uuid } = require ( 'uuid' )
66const validator = require ( 'oas-validator' ) ;
77const SchemaConvertor = require ( 'json-schema-for-openapi' )
8- const $RefParser = require ( "@apidevtools/json-schema-ref-parser" ) ;
8+ const $RefParser = require ( "@apidevtools/json-schema-ref-parser" )
9+ const isEqual = require ( 'lodash.isequal' )
910
1011class DefinitionGenerator {
1112 constructor ( serverless , options = { } ) {
@@ -29,6 +30,11 @@ class DefinitionGenerator {
2930 this . operationIds = [ ]
3031 this . schemaIDs = [ ]
3132
33+ this . componentTypes = {
34+ schemas : 'schemas' ,
35+ securitySchemes : 'securitySchemes'
36+ }
37+
3238 try {
3339 this . refParserOptions = require ( path . resolve ( 'options' , 'ref-parser.js' ) )
3440 } catch ( err ) {
@@ -455,42 +461,13 @@ class DefinitionGenerator {
455461 }
456462
457463 async dereferenceSchema ( schema ) {
458- return await $RefParser . dereference ( schema , this . refParserOptions )
464+ let deReferencedSchema = await $RefParser . dereference ( schema , this . refParserOptions )
459465 . catch ( err => {
460466 console . error ( err )
461467 throw err
462468 } )
463- }
464-
465- async schemaCreator ( schema , name ) {
466- const addToComponents = ( schema , name ) => {
467- const schemaObj = {
468- [ name ] : schema
469- }
470-
471- if ( this . openAPI ?. components ) {
472- if ( this . openAPI . components ?. schemas ) {
473- Object . assign ( this . openAPI . components . schemas , schemaObj )
474- } else {
475- Object . assign ( this . openAPI . components , { schemas : schemaObj } )
476- }
477- } else {
478- const components = {
479- components : {
480- schemas : schemaObj
481- }
482- }
483-
484- Object . assign ( this . openAPI , components )
485- }
486- }
487-
488- let deReferencedSchema = await this . dereferenceSchema ( schema )
489- . catch ( ( err ) => {
490- throw err
491- } )
492469
493- // deal with schemas that have been de-referenced poorly
470+ // deal with schemas that have been de-referenced poorly: naive
494471 if ( deReferencedSchema . $ref === '#' ) {
495472 const oldRef = schema . $ref
496473 const path = oldRef . split ( '/' )
@@ -505,35 +482,44 @@ class DefinitionGenerator {
505482 } )
506483 }
507484
508- const convertedSchema = SchemaConvertor . convert ( deReferencedSchema , name )
509- let schemaName = name
510- if ( this . schemaIDs . includes ( schemaName ) )
511- schemaName = `${ name } -${ uuid ( ) } `
512-
513- this . schemaIDs . push ( schemaName )
485+ return deReferencedSchema
486+ }
514487
515- for ( const key of Object . keys ( convertedSchema . schemas ) ) {
516- if ( key === name || key . split ( '-' ) [ 0 ] === name ) {
517- let ref = `#/components/schemas/`
488+ async schemaCreator ( schema , name ) {
489+ let schemaName = name
490+ let finalName = schemaName
491+ const dereferencedSchema = await this . dereferenceSchema ( schema )
492+ . catch ( err => {
493+ console . error ( err )
494+ throw err
495+ } )
518496
519- if ( this . openAPI ?. components ?. schemas ?. [ name ] ) {
520- if ( JSON . stringify ( convertedSchema . schemas [ key ] ) === JSON . stringify ( this . openAPI . components . schemas [ name ] ) ) {
521- return `${ ref } ${ name } `
522- }
497+ const convertedSchemas = SchemaConvertor . convert ( dereferencedSchema , schemaName )
498+
499+ for ( const convertedSchemaName of Object . keys ( convertedSchemas . schemas ) ) {
500+ const convertedSchema = convertedSchemas . schemas [ convertedSchemaName ]
501+ if ( this . existsInComponents ( convertedSchemaName ) ) {
502+ if ( this . isTheSameSchema ( convertedSchema , convertedSchemaName ) === false ) {
503+ if ( convertedSchemaName === schemaName ) {
504+ finalName = `${ schemaName } -${ uuid ( ) } `
505+ this . addToComponents ( this . componentTypes . schemas , convertedSchema , finalName )
506+ } else
507+ this . addToComponents ( this . componentTypes . schemas , convertedSchema , convertedSchemaName )
523508 }
524-
525- addToComponents ( convertedSchema . schemas [ key ] , schemaName )
526- return `${ ref } ${ schemaName } `
527509 } else {
528- if ( this . openAPI ?. components ?. schemas ?. [ key ] ) {
529- if ( JSON . stringify ( convertedSchema . schemas [ key ] ) !== JSON . stringify ( this . openAPI . components . schemas [ key ] ) ) {
530- addToComponents ( convertedSchema . schemas [ key ] , key )
531- }
532- } else {
533- addToComponents ( convertedSchema . schemas [ key ] , key )
534- }
510+ this . addToComponents ( this . componentTypes . schemas , convertedSchema , convertedSchemaName )
535511 }
536512 }
513+
514+ return `#/components/schemas/${ finalName } `
515+ }
516+
517+ existsInComponents ( name ) {
518+ return Boolean ( this . openAPI ?. components ?. schemas ?. [ name ] )
519+ }
520+
521+ isTheSameSchema ( schema , otherSchemaName ) {
522+ return isEqual ( schema , this . openAPI . components . schemas [ otherSchemaName ] )
537523 }
538524
539525 addToComponents ( type , schema , name ) {
@@ -592,7 +578,7 @@ class DefinitionGenerator {
592578 break ;
593579 }
594580
595- this . addToComponents ( ' securitySchemes' , schema , scheme )
581+ this . addToComponents ( this . componentTypes . securitySchemes , schema , scheme )
596582 }
597583 }
598584
0 commit comments