Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(tools): parse OpenAPI to Concerto Metamodel JSON #594

Merged
32 changes: 26 additions & 6 deletions packages/concerto-cli/lib/commands.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@ const c = require('ansi-colors');
const fs = require('fs');
const path = require('path');
const semver = require('semver');
const toJsonSchema = require('@openapi-contrib/openapi-schema-to-json-schema');
const migrate = require('json-schema-migrate');

const Logger = require('@accordproject/concerto-util').Logger;
const FileWriter = require('@accordproject/concerto-util').FileWriter;
Expand Down Expand Up @@ -586,11 +584,33 @@ class Commands {
let schema = JSON.parse(fs.readFileSync(input, 'utf8'));

if (format.toLowerCase() === 'openapi'){
const jsonSchema = toJsonSchema(schema);
migrate.draft2020(jsonSchema);
return CodeGen.InferFromJsonSchema(namespace, typeName, jsonSchema, options);
const inferredConcertoJsonModel = CodeGen.OpenApiToConcertoVisitor
.parse(schema)
.accept(
(new CodeGen.OpenApiToConcertoVisitor),
{
metaModelNamespace: '[email protected]',
namespace,
},
);

return Printer.toCTO(
inferredConcertoJsonModel.models[0]
);
}
return CodeGen.InferFromJsonSchema(namespace, typeName, schema, options);
const inferredConcertoJsonModel = CodeGen.JSONSchemaToConcertoVisitor
.parse(schema)
.accept(
(new CodeGen.JSONSchemaToConcertoVisitor),
{
metaModelNamespace: '[email protected]',
namespace,
},
);

return Printer.toCTO(
inferredConcertoJsonModel.models[0]
);
}
}

Expand Down
2 changes: 0 additions & 2 deletions packages/concerto-cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,8 @@
"@accordproject/concerto-metamodel": "3.6.0",
"@accordproject/concerto-tools": "3.6.0",
"@accordproject/concerto-util": "3.6.0",
"@openapi-contrib/openapi-schema-to-json-schema": "^3.2.0",
"ansi-colors": "4.1.3",
"glob": "^7.2.0",
"json-schema-migrate": "^2.0.0",
"semver": "7.3.5",
"yargs": "17.3.1"
},
Expand Down
51 changes: 23 additions & 28 deletions packages/concerto-cli/test/cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -569,44 +569,39 @@ describe('concerto-cli', () => {

describe('#infer', async () => {
it('should infer a Concerto model from a JSON Schema', async () => {
const obj = await Commands.inferConcertoSchema(
path.resolve(__dirname, 'models/jsonschema.json'),
'concerto.test.jsonSchema',
const inferredConcertoModel = await Commands.inferConcertoSchema(
path.resolve(__dirname, 'models/json-schema-model.json'),
'com.test@1.0.0',
);
obj.should.equal(`namespace concerto.test.jsonSchema

concept Root {
o String name optional
o Root[] children optional
}
const desiredConcertoModel = fs.readFileSync(
path.resolve(
__dirname, 'models/inferred-from-json-schema-model.cto'
), 'utf8'
);

`);
(inferredConcertoModel + '\n').should.equal(
desiredConcertoModel
);
});

it('should infer a Concerto model from an Open API Spec', async () => {
const obj = await Commands.inferConcertoSchema(
path.resolve(__dirname, 'models/petstore.json'),
'petstore',
it('should infer a Concerto model from an Open API definition', async () => {
const inferredConcertoModel = await Commands.inferConcertoSchema(
path.resolve(__dirname, 'models/open-api-definition.json'),
'[email protected]',
'Root',
'openapi'
);
obj.should.equal(`namespace petstore

concept Pet {
o NewPet pet optional
}

concept NewPet {
o String name
o String tag optional
}

concept ErrorModel {
o Integer code
o String message
}
const desiredConcertoModel = fs.readFileSync(
path.resolve(
__dirname, 'models/inferred-from-open-api-definition.cto'
), 'utf8'
);

`);
(inferredConcertoModel + '\n').should.equal(
desiredConcertoModel
);
});
});

Expand Down
115 changes: 115 additions & 0 deletions packages/concerto-cli/test/models/inferred-from-json-schema-model.cto
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
namespace [email protected]

concept Root {
o String firstName
o String lastName
o DateTime dob
o DateTime graduationDate optional
o Integer age
o Double height range=[50,]
o String favouriteFood optional
o Root$_properties$_children[] children
o Root$_properties$_company company
o String alternative optional
}

concept Root$_properties$_children {
o String name
o Integer age
o String hairColor
o Boolean coolDude
o String missing optional
o Root$_properties$_children$_properties$_pet pet
o String[] favoriteColors
o Integer[] favoriteNumbers
o String[] mixed
o String[] arrayOfNull
o String[] emptyArray
o Root$_properties$_children$_properties$_favoritePets[] favoritePets
o Root$_properties$_children$_properties$_stuff[] stuff
o String alternative optional
}

concept Root$_properties$_children$_properties$_pet {
o String name
o String breed
}

concept Root$_properties$_children$_properties$_favoritePets {
o String name
o String breed
}

concept Root$_properties$_children$_properties$_stuff {
o String sku
o Double price
o Pet product
}

concept Root$_properties$_company {
o String name
o Root$_properties$_company$_properties$_employees[] employees
}

concept Root$_properties$_company$_properties$_employees {
o String name
}

concept Children {
o String name
o Integer age range=[,150]
o String hairColor
o Boolean coolDude
o String missing optional
o Pet pet
o Color[] favoriteColors
o Integer[] favoriteNumbers range=[,999999]
o String[] mixed
o String[] arrayOfNull
o String[] emptyArray
o Pet[] favoritePets
o definitions$_Children$_properties$_stuff[] stuff
@StringifiedJson
o String json optional
mttrbrts marked this conversation as resolved.
Show resolved Hide resolved
@StringifiedJson
o String jsonWithAdditionalProperties optional
o Double alternation optional
}

concept definitions$_Children$_properties$_stuff {
o String sku
o Double price
o Pet product
}

enum Color {
o blue
o green
o red
o yellow
o orange
}

concept Pet {
o String name
o String breed regex=/^[a-zA-Z]*$/
}

concept Stuff {
o String sku
o Double price range=[,99999999]
o Pet product
}

concept Company {
o String name
o definitions$_Company$_properties$_employees[] employees
}

concept definitions$_Company$_properties$_employees {
o String name
}

concept Employees {
o String name
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
namespace [email protected]

concept address {
o String city optional
o String country optional
o String line1 optional
o String line2 optional
o String postal_code optional
o String state optional
}

concept customer {
o Integer created
o String id
o address address optional
@StringifiedJson
o String metadata optional
o components$_schemas$_customer$_properties$_foo foo optional
}

concept components$_schemas$_customer$_properties$_foo {
o components$_schemas$_customer$_properties$_foo$_properties$_bar bar optional
}

concept components$_schemas$_customer$_properties$_foo$_properties$_bar {
o String har optional
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,16 @@
"type": "string"
},
"age": {
"type": "integer"
"type": "integer",
"minimum": 0,
"exclusiveMaximum": 150
},
"hairColor": {
"type": "string"
},
"coolDude": {
"type": "boolean"
"type": "boolean",
"default": "true"
},
"missing": {
"type": "string"
Expand All @@ -42,7 +45,8 @@
"favoriteNumbers": {
"type": "array",
"items": {
"type": "integer"
"type": "integer",
"exclusiveMaximum": 999999
}
},
"mixed": {
Expand Down Expand Up @@ -104,6 +108,13 @@
"json": {
"type": "object"
},
"jsonWithAdditionalProperties": {
"type": "object",
"additionalProperties": {
"maxLength": 500,
"type": "string"
}
},
"alternation": {
"oneOf": [
{ "type": "number" },
Expand Down Expand Up @@ -147,7 +158,8 @@
"type": "string"
},
"breed": {
"type": "string"
"type": "string",
"pattern": "^[a-zA-Z]*$"
}
},
"required": ["$class", "name", "breed"]
Expand All @@ -167,7 +179,8 @@
"type": "string"
},
"price": {
"type": "number"
"type": "number",
"exclusiveMaximum": 99999999.0
},
"product": {
"title": "Pet",
Expand Down Expand Up @@ -253,11 +266,21 @@
"format": "date-time",
"type": "string"
},
"graduationDate": {
"format": "date",
"type": "string"
},
"age": {
"type": "integer"
"type": "integer",
"minimum": 0
},
"height": {
"type": "number"
"type": "number",
"minimum": 50.0
},
"favouriteFood": {
"format": "food",
"type": "string"
},
"children": {
"type": "array",
Expand Down Expand Up @@ -377,7 +400,8 @@
"type": "string"
},
"price": {
"type": "number"
"type": "number",
"minimum": 0.0
},
"product": {
"title": "Pet",
Expand Down
10 changes: 0 additions & 10 deletions packages/concerto-cli/test/models/jsonschema.json

This file was deleted.

Loading