Skip to content

Commit 045c5cd

Browse files
committed
External definitions
1 parent bec748b commit 045c5cd

File tree

6 files changed

+114
-10
lines changed

6 files changed

+114
-10
lines changed

forward_engineering/helpers/componentsHelpers/parametersHelper.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ function mapParameter(data, required) {
3232
name: data.parameterName,
3333
in: getIn(data.type),
3434
description: data.description,
35-
required: (required || data.required) || undefined,
35+
required: !!(required || data.required) || undefined,
3636
deprecated: data.deprecated,
3737
allowEmptyValue: data.allowEmptyValue,
3838
style: data.style,

forward_engineering/helpers/typeHelper.js

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,10 +71,44 @@ function getTypeProps(data, key) {
7171
function getRef({ $ref: ref }) {
7272
if (ref.startsWith('#')) {
7373
ref = ref.replace('#model/definitions', '#/components');
74+
75+
return { $ref: prepareReferenceName(ref) };
7476
}
7577

76-
return { $ref: prepareReferenceName(ref) };
77-
}
78+
const [ pathToFile, relativePath] = ref.split('#/');
79+
if (!relativePath) {
80+
return { $ref: prepareReferenceName(ref) };
81+
}
82+
83+
let path = relativePath.split('/');
84+
if (path[0] === 'definitions') {
85+
if (path[2] === 'schemas') {
86+
return { $ref: `${pathToFile}#/components/schemas/${path.slice(4).join('/')}` };
87+
}
88+
89+
path = ['', ...path];
90+
}
91+
92+
const schemaIndex = path.indexOf('schema');
93+
const schemaPath = schemaIndex === -1 ? [] : path.slice(schemaIndex);
94+
const pathWithoutProperties = path.slice(0, schemaIndex).filter(item => item !== 'properties');
95+
const bucketWithRequest = (path[1] === 'definitions') ? path[1] : pathWithoutProperties.slice(0,2);
96+
97+
if (pathWithoutProperties[3] !== 'response') {
98+
if (pathWithoutProperties[2] !== 'requestBody') {
99+
return { $ref: `${pathToFile}#/paths/${[ ...pathWithoutProperties, ...schemaPath].join('/')}` };
100+
}
101+
102+
return { $ref: `${pathToFile}#/paths/${[ ...bucketWithRequest, 'requestBody', 'content', ...pathWithoutProperties.slice(3), ...schemaPath].join('/')}` };
103+
}
104+
105+
const response = pathWithoutProperties[2];
106+
const pathToItem = pathWithoutProperties.slice(4)
107+
108+
const pathWithResponses = [ ...bucketWithRequest, 'responses', response, ...pathToItem, ...schemaPath ];
109+
110+
return { $ref: `${pathToFile}#/paths/${pathWithResponses.join('/')}` };
111+
};
78112

79113
function hasRef(data = {}) {
80114
return data.$ref ? true : false;

package.json

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "OpenAPI",
3-
"version": "0.1.11",
4-
"versionDate": "2019-12-26",
3+
"version": "0.1.12",
4+
"versionDate": "2020-01-03",
55
"author": "hackolade",
66
"engines": {
77
"hackolade": "3.3.0",
@@ -71,7 +71,8 @@
7171
"disableRelationships": true,
7272
"disableJsonPreview": false,
7373
"enableErdToggle": true,
74-
"enableStackedNestedCollections": true
74+
"enableStackedNestedCollections": true,
75+
"externalDefinitionsFromTargetSchema": true
7576
}
7677
},
7778
"description": "Hackolade plugin for OpenAPI",

reverse_engineering/api.js

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ const commonHelper = require('./helpers/commonHelper');
44
const dataHelper = require('./helpers/dataHelper');
55
const errorHelper = require('./helpers/errorHelper');
66
const adaptJsonSchema = require('./helpers/adaptJsonSchema/adaptJsonSchema');
7+
const resolveExternalDefinitionPathHelper = require('./helpers/resolveExternalDefinitionPathHelper');
78
const validationHelper = require('../forward_engineering/helpers/validationHelper');
89

910
module.exports = {
@@ -61,7 +62,11 @@ module.exports = {
6162
} catch(e) {
6263
callback(commonHelper.handleErrorObject(e, 'Adapt JSON Schema'), data);
6364
}
64-
}
65+
},
66+
67+
resolveExternalDefinitionPath(data, logger, callback) {
68+
resolveExternalDefinitionPathHelper.resolvePath(data, callback);
69+
}
6570
};
6671

6772
const convertOpenAPISchemaToHackolade = (openAPISchema, fieldOrder) => {
@@ -74,7 +79,7 @@ const convertOpenAPISchemaToHackolade = (openAPISchema, fieldOrder) => {
7479
};
7580

7681
const getOpenAPISchema = (data, filePath) => new Promise((resolve, reject) => {
77-
const { extension, fileName } = commonHelper.getPathData(filePath);
82+
const { extension, fileName } = commonHelper.getPathData(data, filePath);
7883

7984
try {
8085
const openAPISchemaWithModelName = dataHelper.getOpenAPIJsonSchema(data, fileName, extension);

reverse_engineering/helpers/commonHelper.js

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ const yaml = require('js-yaml');
66
const errorHelper = require('./errorHelper');
77

88
const CHOICES = ['allOf', 'oneOf', 'anyOf', 'not'];
9+
const ALLOWED_EXTENSIONS = ['.json', '.yaml'];
910

1011
const getFileData = (filePath) => new Promise((resolve, reject) => {
1112
fs.readFile(filePath, 'utf-8', (error, content) => {
@@ -17,10 +18,43 @@ const getFileData = (filePath) => new Promise((resolve, reject) => {
1718
});
1819
});
1920

20-
const getPathData = (filePath) => {
21+
const isJson = data => {
22+
try {
23+
JSON.parse(data);
24+
25+
return true;
26+
} catch (err) {
27+
return false;
28+
}
29+
};
30+
31+
const isYaml = data => {
32+
try {
33+
yaml.load(data);
34+
35+
return true;
36+
} catch (err) {
37+
return false;
38+
}
39+
};
40+
41+
const getPathData = (data, filePath) => {
2142
const extension = path.extname(filePath);
2243
const fileName = path.basename(filePath, extension);
23-
return {extension, fileName };
44+
45+
if (ALLOWED_EXTENSIONS.includes(extension)) {
46+
return { extension, fileName };
47+
}
48+
49+
if (isJson(data)) {
50+
return { extension: '.json', fileName };
51+
}
52+
53+
if (isYaml(data)) {
54+
return { extension: '.yaml', fileName };
55+
}
56+
57+
return { extension, fileName };
2458
};
2559

2660
const handleErrorObject = (error, title) => {
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
const resolvePath = (data, callback) => {
2+
let path = (data.path || '').split('/');
3+
if (!path[0]) {
4+
path = path.slice(1);
5+
}
6+
if (!path[0]) {
7+
return callback({
8+
title: 'Resolve external definition path error',
9+
message: 'External definition path is not valid'
10+
}, data.path || '');
11+
}
12+
if (path[0] === 'components' || path[0] === 'definitions') {
13+
return callback(null, 'definitions' + addPropertiesToPath(path.slice(1)));
14+
}
15+
16+
const bucket = path[1];
17+
const request = path[2];
18+
19+
if (path[3] === 'responses') {
20+
return callback(null, `${bucket}/${request}/${path[4]}${addPropertiesToPath(['response', ...path.slice(5)])}`);
21+
}
22+
23+
return callback(null, `${bucket}/${request}${addPropertiesToPath(path.slice(3))}`);
24+
};
25+
26+
const addPropertiesToPath = path => path.length ? '/properties/' + path.join('/properties/') : '';
27+
28+
module.exports = {
29+
resolvePath
30+
};

0 commit comments

Comments
 (0)