Skip to content

Commit a86141f

Browse files
committed
FE: External references for model and json fileType
1 parent 35f154d commit a86141f

File tree

4 files changed

+143
-51
lines changed

4 files changed

+143
-51
lines changed

forward_engineering/api.js

Lines changed: 48 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ const getComponents = require('./helpers/componentsHelpers');
77
const commonHelper = require('./helpers/commonHelper');
88
const { getServers } = require('./helpers/serversHelper');
99
const getExtensions = require('./helpers/extensionsHelper');
10+
const handleReferencePath = require('./helpers/handleReferencePath');
11+
const mapJsonSchema = require('../reverse_engineering/helpers/adaptJsonSchema/mapJsonSchema');
1012

1113
module.exports = {
1214
generateModelScript(data, logger, cb) {
@@ -23,8 +25,12 @@ module.exports = {
2325

2426
const info = getInfo(data.modelData[0]);
2527
const servers = getServers(modelServers);
26-
const paths = getPaths(data.containers, containersIdsFromCallbacks);
27-
const components = getComponents(data);
28+
const externalDefinitions = JSON.parse(data.externalDefinitions || '{}').properties || {};
29+
const containers = handleRefInContainers(data.containers, externalDefinitions);
30+
const paths = getPaths(containers, containersIdsFromCallbacks);
31+
const definitions = JSON.parse(data.modelDefinitions) || {};
32+
const definitionsWithHandledReferences = mapJsonSchema(definitions, handleRef(externalDefinitions));
33+
const components = getComponents(definitionsWithHandledReferences, data.containers);
2834
const security = commonHelper.mapSecurity(modelSecurity);
2935
const tags = commonHelper.mapTags(modelTags);
3036
const externalDocs = commonHelper.mapExternalDocs(modelExternalDocs);
@@ -138,3 +144,43 @@ const removeCommentLines = (scriptString) => {
138144
.join('\n')
139145
.replace(/(.*?),\s*(\}|])/g, '$1$2');
140146
}
147+
148+
const handleRefInContainers = (containers, externalDefinitions) => {
149+
return containers.map(container => {
150+
try {
151+
const updatedSchemas = Object.keys(container.jsonSchema).reduce((schemas, id) => {
152+
const json = container.jsonSchema[id];
153+
try {
154+
const updatedSchema = mapJsonSchema(JSON.parse(json), handleRef(externalDefinitions));
155+
156+
return {
157+
...schemas,
158+
[id]: JSON.stringify(updatedSchema)
159+
};
160+
} catch (err) {
161+
return { ...schemas, [id]: json }
162+
}
163+
}, {});
164+
165+
return {
166+
...container,
167+
jsonSchema: updatedSchemas
168+
};
169+
} catch (err) {
170+
return container;
171+
}
172+
});
173+
};
174+
175+
176+
const handleRef = externalDefinitions => field => {
177+
if (!field.$ref) {
178+
return field;
179+
}
180+
const ref = handleReferencePath(externalDefinitions, field);
181+
if (!ref.$ref) {
182+
return ref;
183+
}
184+
185+
return { ...field, ...ref };
186+
};

forward_engineering/helpers/componentsHelpers/index.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@ const renameComponents = (components) => {
2222
}, {});
2323
};
2424

25-
function getComponents(data) {
26-
const componentsData = get(JSON.parse(data.modelDefinitions), 'properties', {});
25+
function getComponents(definitions, containers) {
26+
const componentsData = get(definitions, 'properties', {});
2727

2828
const schemas = renameComponents(getSchemas(componentsData.schemas));
2929
const responses = renameComponents(getResponses(componentsData.responses));
@@ -33,7 +33,7 @@ function getComponents(data) {
3333
const headers = renameComponents(getHeaders(componentsData.headers));
3434
const securitySchemes = renameComponents(getSecuritySchemes(componentsData.securitySchemes));
3535
const links = renameComponents(getLinks(componentsData.links));
36-
const callbacks = renameComponents(getCallbacks(componentsData.callbacks, data.containers));
36+
const callbacks = renameComponents(getCallbacks(componentsData.callbacks, containers));
3737

3838
const extensions = getExtensions(get(componentsData, `['Specification Extensions'].scopesExtensions`));
3939

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
const COMPONENTS_SCHEMAS_OBJECT_INDEX = 2;
2+
const REQUEST_BODY_OBJECT_INDEX = 2;
3+
const RESPONSE_NAME_INDEX = 2;
4+
const RESPONSE_OBJECT_INDEX = 3;
5+
const PATH_START_INDEX = 4;
6+
7+
const { prepareReferenceName } = require('../utils/utils');
8+
9+
const handleReferencePath = (externalDefinitions, { $ref: ref }) => {
10+
if (ref.startsWith('#')) {
11+
ref = ref.replace('#model/definitions', '#/components');
12+
13+
return { $ref: prepareReferenceName(ref) };
14+
}
15+
16+
const [ pathToFile, relativePath] = ref.split('#/');
17+
if (!relativePath) {
18+
return { $ref: prepareReferenceName(ref) };
19+
}
20+
21+
const externalDefinition = findExternalDefinition(externalDefinitions, pathToFile, relativePath);
22+
if (!externalDefinition) {
23+
return { $ref: prepareReferenceName(ref) };
24+
}
25+
26+
if (externalDefinition.fileType === 'targetSchema') {
27+
return { $ref: updateOpenApiPath(pathToFile, relativePath) };
28+
} else if (externalDefinition.fileType === 'hackoladeSchema') {
29+
return externalDefinition;
30+
}
31+
32+
return { $ref: prepareReferenceName(ref) };
33+
};
34+
35+
const findExternalDefinition = (externalDefinitions, pathToFile, relativePath) => {
36+
pathToFile = pathToFile.replace('file://', '');
37+
38+
const definitionName = Object.keys(externalDefinitions).find(name => {
39+
const definition = externalDefinitions[name];
40+
return (
41+
definition.fieldRelativePath === '#/' + relativePath &&
42+
definition.link === pathToFile
43+
);
44+
});
45+
46+
return externalDefinitions[definitionName];
47+
};
48+
49+
const updateOpenApiPath = (pathToFile, relativePath) => {
50+
let path = relativePath.split('/');
51+
if (path[0] === 'definitions') {
52+
if (path[COMPONENTS_SCHEMAS_OBJECT_INDEX] === 'schemas') {
53+
return `${pathToFile}#/components/schemas/${path.slice(PATH_START_INDEX).join('/')}`;
54+
}
55+
56+
path = ['', ...path];
57+
}
58+
59+
const schemaIndex = path.indexOf('schema');
60+
const hasSchema = schemaIndex !== -1;
61+
const isComponents = (path[1] === 'definitions');
62+
const schemaPath = !hasSchema ? [] : path.slice(schemaIndex);
63+
const pathWithoutProperties = (hasSchema ? path.slice(0, schemaIndex) : path).filter(item => item !== 'properties');
64+
const bucketWithRequest = isComponents ? ['components'] : pathWithoutProperties.slice(0,2);
65+
const parentElementName = isComponents ? 'components' : 'paths';
66+
const isResponse = pathWithoutProperties[RESPONSE_OBJECT_INDEX] === 'response';
67+
const isRequestBody = pathWithoutProperties[REQUEST_BODY_OBJECT_INDEX] === 'requestBody'
68+
69+
if (!isResponse) {
70+
if (!isRequestBody) {
71+
if (isComponents) {
72+
return `${pathToFile}#/${parentElementName}/${[ ...pathWithoutProperties.slice(2), ...schemaPath].join('/')}`;
73+
}
74+
75+
return `${pathToFile}#/${parentElementName}/${[ ...pathWithoutProperties , ...schemaPath].join('/')}`;
76+
}
77+
78+
return `${pathToFile}#/${parentElementName}/${[ ...bucketWithRequest, 'requestBody', 'content', ...pathWithoutProperties.slice(3), ...schemaPath].join('/')}`;
79+
}
80+
81+
const response = pathWithoutProperties[RESPONSE_NAME_INDEX];
82+
const pathToItem = pathWithoutProperties.slice(PATH_START_INDEX)
83+
84+
const pathWithResponses = [ ...bucketWithRequest, 'responses', response, ...pathToItem, ...schemaPath ];
85+
86+
return `${pathToFile}#/paths/${pathWithResponses.join('/')}`;
87+
};
88+
89+
module.exports = handleReferencePath;

forward_engineering/helpers/typeHelper.js

Lines changed: 3 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
const get = require('lodash.get');
22
const getExtensions = require('./extensionsHelper');
33
const { prepareReferenceName } = require('../utils/utils');
4+
const fs = require('fs');
45

56
function getType(data, key) {
67
if (!data) {
@@ -70,52 +71,8 @@ function getTypeProps(data, key) {
7071
}
7172
}
7273

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

12178
function hasRef(data = {}) {

0 commit comments

Comments
 (0)