1
1
import type { JSONSchema } from '@apidevtools/json-schema-ref-parser' ;
2
- import RefParser from '@apidevtools/json-schema-ref-parser' ;
3
2
import type {
4
3
JSONSchema4 ,
5
4
JSONSchema6Definition ,
6
5
JSONSchema7Definition ,
7
6
} from 'json-schema' ;
8
- import clone from 'clone' ;
9
7
import type { Options , SchemaType , SchemaTypeKeys } from './types' ;
10
- import { getVocabulary , schemaWalk , vocabularies } from './lib/walker' ;
11
8
import { oas3schema } from './lib/openApiSchema' ;
9
+ import { Walker } from 'json-schema-walker' ;
12
10
13
11
class InvalidTypeError extends Error {
14
12
constructor ( message : string ) {
@@ -29,53 +27,14 @@ const allowedKeywords = [
29
27
...Object . keys ( oas3schema . definitions . Schema . properties ) ,
30
28
] ;
31
29
32
- function isCyclic ( obj : any ) {
33
- const seenObjects = new Set ( ) ;
34
-
35
- function detect ( obj : any ) {
36
- if ( obj && typeof obj === 'object' ) {
37
- if ( seenObjects . has ( obj ) ) {
38
- return true ;
39
- }
40
- seenObjects . add ( obj ) ;
41
- for ( const key in obj ) {
42
- // eslint-disable-next-line no-prototype-builtins
43
- if ( obj . hasOwnProperty ( key ) && detect ( obj [ key ] ) ) {
44
- return true ;
45
- }
46
- }
47
- }
48
- return false ;
49
- }
50
-
51
- return detect ( obj ) ;
52
- }
53
-
54
30
const convert = async < T = JSONSchema > (
55
31
schema : T ,
56
32
options ?: Options
57
33
) : Promise < SchemaType > => {
58
- const {
59
- cloneSchema = true ,
60
- dereference = false ,
61
- dereferenceOptions,
62
- } = options || { } ;
63
- let schemaToUse = schema as SchemaType ;
64
-
65
- if ( cloneSchema ) {
66
- schemaToUse = clone ( schema ) ;
67
- }
68
-
69
- const parser = new RefParser ( ) ;
70
- if ( dereference ) {
71
- // We run the risk of circular references here
72
- const res = await parser . dereference ( schema , dereferenceOptions || { } ) ;
73
- schemaToUse = res as SchemaType ;
74
- }
75
-
76
- const vocab = getVocabulary ( schemaToUse , vocabularies . DRAFT_04 ) ;
77
- schemaWalk ( schemaToUse , convertSchema , null , vocab ) ;
78
- return schemaToUse ;
34
+ const walker = new Walker < T > ( ) ;
35
+ await walker . loadSchema ( schema , options ) ;
36
+ await walker . walk ( convertSchema , walker . vocabularies . DRAFT_07 ) ;
37
+ return walker . rootSchema ;
79
38
} ;
80
39
81
40
function stripIllegalKeywords ( schema : SchemaType ) {
@@ -114,20 +73,29 @@ function convertSchema(schema: SchemaType | undefined) {
114
73
schema = convertIllegalKeywordsAsExtensions ( schema ) ;
115
74
return schema ;
116
75
}
117
-
118
- function validateType ( type : string | string [ ] ) {
119
- const validTypes = [
120
- 'null' ,
121
- 'boolean' ,
122
- 'object' ,
123
- 'array' ,
124
- 'number' ,
125
- 'string' ,
126
- 'integer' ,
127
- ] ;
76
+ const validTypes = new Set ( [
77
+ 'null' ,
78
+ 'boolean' ,
79
+ 'object' ,
80
+ 'array' ,
81
+ 'number' ,
82
+ 'string' ,
83
+ 'integer' ,
84
+ ] ) ;
85
+ function validateType ( type : any ) {
86
+ if ( typeof type === 'object' && ! Array . isArray ( type ) ) {
87
+ // Refs are allowed because they fix circular references
88
+ if ( type . $ref ) {
89
+ return ;
90
+ }
91
+ // this is a de-referenced circular ref
92
+ if ( type . properties ) {
93
+ return ;
94
+ }
95
+ }
128
96
const types = Array . isArray ( type ) ? type : [ type ] ;
129
97
types . forEach ( ( type ) => {
130
- if ( validTypes . indexOf ( type ) < 0 && type !== undefined )
98
+ if ( type && ! validTypes . has ( type ) )
131
99
throw new InvalidTypeError ( 'Type "' + type + '" is not a valid type' ) ;
132
100
} ) ;
133
101
}
0 commit comments