accordproject / concerto-codegen Goto Github PK
View Code? Open in Web Editor NEWLicense: Apache License 2.0
License: Apache License 2.0
While writing Visitor for Rust land, came across this error for a supposedly valid model file.
Run this code in root of concerto-codegen
repo.
'use strict';
const { ModelManager } = require('@accordproject/concerto-core');
const { FileWriter } = require('@accordproject/concerto-util');
const Visitor = require('./lib/codegen/fromcto/jsonschema/jsonschemavisitor');
const model = `namespace [email protected]
import org.accordproject.contract.* from https://models.accordproject.org/accordproject/contract.cto
import org.accordproject.runtime.* from https://models.accordproject.org/accordproject/runtime.cto
transaction MyRequest extends Request {
o String input
}
transaction MyResponse extends Response {
o String output
}
asset HelloWorldClause extends Clause {
o String name
}`;
const modelManager = new ModelManager();
modelManager.addCTOModel(model);
const parameters = {
fileWriter: new FileWriter('./output')
};
const visitor = new Visitor();
modelManager.accept(visitor, parameters);
console.log('Done');
As this is a valid model then expected the model to be validated by basemodelmanager.js
.
The basemodelmanager.js
throw an error on line 201 modelFile.validate();
.
IllegalModelException: Namespace is not defined for type "org.accordproject.contract.*".
at /Users/martin/Dev/accord/concerto-codegen/node_modules/@accordproject/concerto-core/lib/introspect/modelfile.js:233:23
at Array.forEach (<anonymous>)
at ModelFile.validate (/Users/martin/Dev/accord/concerto-codegen/node_modules/@accordproject/concerto-core/lib/introspect/modelfile.js:225:27)
at ModelManager.addModelFile (/Users/martin/Dev/accord/concerto-codegen/node_modules/@accordproject/concerto-core/lib/basemodelmanager.js:201:27)
at ModelManager.addModel (/Users/martin/Dev/accord/concerto-codegen/node_modules/@accordproject/concerto-core/lib/basemodelmanager.js:234:14)
at ModelManager.addCTOModel (/Users/martin/Dev/accord/concerto-codegen/node_modules/@accordproject/concerto-core/lib/modelmanager.js:80:21)
at Object.<anonymous> (/Users/martin/Dev/accord/concerto-codegen/testharness.js:30:14)
at Module._compile (node:internal/modules/cjs/loader:1246:14)
at Module._extensions..js (node:internal/modules/cjs/loader:1300:10)
at Module.load (node:internal/modules/cjs/loader:1103:32) {
component: '@accordproject/concerto-util',
fileLocation: undefined,
shortMessage: 'Namespace is not defined for type "org.accordproject.contract.*".',
fileName: null
}
Rollup fails to bundle this module because of the browser entry point incorrect in package.json.
Trying to bundle @accordproject/template-engine, which depends on this module.
Should be able to bundle this module.
Rollup fails with an error saying that is cannot resolve the @accordproject/concerto-codegen module.
Update package.json.
Currently graph.findConnectedGraph
does not use the type hierarchy, meaning that types that extend a target type are dropped from a filtered model.
Using the code below we can "tree shake" the model manager, to remove all types that are not connected to a root/target type, and then render the result as a PlantUML diagram. Although the output is correct, it is aggressive in that if we have a model containing derived types that could be used in place of an abstract type the derived types are removed, leaving only the abstract type.
if (process.argv.length > 2) {
const graphVisitor = new Common.ConcertoGraphVisitor();
const graph = new Common.DirectedGraph();
mm.accept(graphVisitor, { graph });
const connectedGraph = graph.findConnectedGraph(process.argv[2]);
// now create a new model manager that only includes types
// that are included in the dependency graph
const filteredModelManager = mm.filter((declaration) =>
connectedGraph.hasVertex(declaration.getFullyQualifiedName())
);
const visitor = new CodeGen.PlantUMLVisitor();
const parameters = {
fileWriter: new FileWriter("."),
showCompositionRelationships: true,
hideBaseModel: true,
};
filteredModelManager.accept(visitor, parameters);
}
It would be very useful to be able to optionally take into account the type hierarchy in the call to graph.findConnectedGraph
allowing the caller to say "find everything connected to this type, and include all derived types that appear in the model".
Derived types are removed as they are not directly connected in the graph.
[email protected]
and Cat
are not included, although the abstract type Pet
which they extend isThe generated C# code cannot be compiled when models contain any reserved .NET keywords.
Eg, 'fixed', 'void', 'event', 'virtual' etc.. https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/
enum invoice_amount_type {
o fixed
o maximum
}
enum issuing_card_type {
o physical
o virtual
}
enum invoice_status {
o deleted
o draft
o open
o paid
o uncollectible
o void
}
Any generated csharp code should be compilable.
We can add a trailing underscore char to the reserved keyword.
Generate cshar code for any of the model provided in the above example. Add the generated models to any csharp project and try t build the project.
Update all Concerto main repo dependencies to latest version.
Models containing enums generate invalid TS code.
Code should compile.
Enums are included in the Union type, prefixed by an I
. Enums are imported, also prefixed by an I
.
When inferring from JSON Schema, we may produce Concerto CTO with properties starting with $
, which is invalid.
When trying to infer:
{
"$schema": "http://json-schema.org/draft-07/schema#",
"definitions": {
"Foo": {
"type": "object",
"properties": {
"$bar": {
"type": "string"
},
"ba$z": {
"type": "string"
}
},
"required": [
"$bar",
"ba$z"
]
}
}
}
we would like to get this Concerto CTO file:
namespace [email protected]
concept Foo {
o String _$bar
o String ba$z
}
Instead we're getting:
namespace [email protected]
concept Foo {
o String $bar
o String ba$z
}
The $bar
above is problematic.
An error gets thrown when converting JSON Schema to Concerto.
We expect this Concerto output:
namespace [email protected]
concept DataIOWriteDataByUri {
o String name
o String type
o ActionContractSchema_alias_969551601_132_307_969551601_0_1080360522385_ input
o ActionContractSchema_alias_893869671_313_536_893869671_0_10591185408304_ output
}
concept ActionContractSchema_alias_969551601_132_307_969551601_0_1080360522385_ {
o String uri
@StringifiedJson
o String data
}
concept ActionContractSchema_alias_893869671_313_536_893869671_0_10591185408304_ {
o String id
}
We get this error:
concerto infer --namespace com.docusign.app --format jsonschema --input packages/data-models/src/schemas/contracts/actions/verify/v1/bank-account.json --output example.cto
10:46:42 AM - ERROR: Cannot read properties of undefined (reading 'enum')
TypeError: Cannot read properties of undefined (reading 'enum')
at JsonSchemaVisitor.visitDefinition (/Users/andrew.wilson/.nvm/versions/node/v18.12.0/lib/node_modules/@accordproject/concerto-cli/node_modules/@accordproject/concerto-tools/lib/codegen/fromJsonSchema/cto/jsonSchemaVisitor.js:765:36)
at JsonSchemaVisitor.visit (/Users/andrew.wilson/.nvm/versions/node/v18.12.0/lib/node_modules/@accordproject/concerto-cli/node_modules/@accordproject/concerto-tools/lib/codegen/fromJsonSchema/cto/jsonSchemaVisitor.js:926:25)
at Definition.accept (/Users/andrew.wilson/.nvm/versions/node/v18.12.0/lib/node_modules/@accordproject/concerto-cli/node_modules/@accordproject/concerto-tools/lib/codegen/fromJsonSchema/cto/jsonSchemaClasses.js:38:24)
at JsonSchemaVisitor.visitLocalReference (/Users/andrew.wilson/.nvm/versions/node/v18.12.0/lib/node_modules/@accordproject/concerto-cli/node_modules/@accordproject/concerto-tools/lib/codegen/fromJsonSchema/cto/jsonSchemaVisitor.js:375:19)
at JsonSchemaVisitor.visit (/Users/andrew.wilson/.nvm/versions/node/v18.12.0/lib/node_modules/@accordproject/concerto-cli/node_modules/@accordproject/concerto-tools/lib/codegen/fromJsonSchema/cto/jsonSchemaVisitor.js:905:25)
at LocalReference.accept (/Users/andrew.wilson/.nvm/versions/node/v18.12.0/lib/node_modules/@accordproject/concerto-cli/node_modules/@accordproject/concerto-tools/lib/codegen/fromJsonSchema/cto/jsonSchemaClasses.js:38:24)
at JsonSchemaVisitor.visitReference (/Users/andrew.wilson/.nvm/versions/node/v18.12.0/lib/node_modules/@accordproject/concerto-cli/node_modules/@accordproject/concerto-tools/lib/codegen/fromJsonSchema/cto/jsonSchemaVisitor.js:401:18)
at JsonSchemaVisitor.visit (/Users/andrew.wilson/.nvm/versions/node/v18.12.0/lib/node_modules/@accordproject/concerto-cli/node_modules/@accordproject/concerto-tools/lib/codegen/fromJsonSchema/cto/jsonSchemaVisitor.js:908:25)
at Reference.accept (/Users/andrew.wilson/.nvm/versions/node/v18.12.0/lib/node_modules/@accordproject/concerto-cli/node_modules/@accordproject/concerto-tools/lib/codegen/fromJsonSchema/cto/jsonSchemaClasses.js:38:24)
at JsonSchemaVisitor.visitProperty (/Users/andrew.wilson/.nvm/versions/node/v18.12.0/lib/node_modules/@accordproject/concerto-cli/node_modules/@accordproject/concerto-tools/lib/codegen/fromJsonSchema/cto/jsonSchemaVisitor.js:518:15)
We would like to issue this command
concerto infer --namespace com.docusign.app --format jsonschema --input ./jsonSchemaFromTypescriptShapes.json --output ./example.cto
Where jsonSchemaFromTypescriptShapes.json
contains this valid JSON Schema:
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$ref": "#/definitions/DataIOWriteDataByUri",
"definitions": {
"DataIOWriteDataByUri": {
"type": "object",
"properties": {
"name": {
"type": "string",
"const": "Contracts.Actions.DataIO.Version3.WriteDataByUri"
},
"type": {
"type": "string",
"const": "action"
},
"input": {
"$ref": "#/definitions/ActionContractSchema%3CActionContractSchema%3Calias-969551601-132-307-969551601-0-1080360522385%3E%3E"
},
"output": {
"$ref": "#/definitions/ActionContractSchema%3CActionContractSchema%3Calias-969551601-307-463-969551601-0-10801928584726%3E%3E"
}
},
"required": [
"input",
"name",
"output",
"type"
],
"additionalProperties": false,
"description": "This action contract handles writing data to a specific URI"
},
"ActionContractSchema<ActionContractSchema<alias-969551601-132-307-969551601-0-1080360522385>>": {
"$ref": "#/definitions/ActionContractSchema%3Calias-969551601-132-307-969551601-0-1080360522385%3E",
"description": "Action Contract Schema"
},
"ActionContractSchema<alias-969551601-132-307-969551601-0-1080360522385>": {
"type": "object",
"additionalProperties": false,
"properties": {
"uri": {
"type": "string"
},
"data": {
"type": "object",
"additionalProperties": {}
}
},
"required": [
"data",
"uri"
],
"description": "Action Contract Schema"
},
"ActionContractSchema<ActionContractSchema<alias-969551601-307-463-969551601-0-10801928584726>>": {
"$ref": "#/definitions/ActionContractSchema%3Calias-969551601-307-463-969551601-0-10801928584726%3E",
"description": "Action Contract Schema"
},
"ActionContractSchema<alias-969551601-307-463-969551601-0-10801928584726>": {
"$ref": "#/definitions/ActionContractSchema%3CActionContractSchema%3Calias-893869671-313-536-893869671-0-10591185408304%3E%3E",
"description": "Action Contract Schema"
},
"ActionContractSchema<ActionContractSchema<alias-893869671-313-536-893869671-0-10591185408304>>": {
"$ref": "#/definitions/ActionContractSchema%3Calias-893869671-313-536-893869671-0-10591185408304%3E",
"description": "Action Contract Schema"
},
"ActionContractSchema<alias-893869671-313-536-893869671-0-10591185408304>": {
"type": "object",
"properties": {
"id": {
"type": "string"
}
},
"required": [
"id"
],
"additionalProperties": false,
"description": "Action Contract Schema"
}
}
}
This Concerto code gets generated:
namespace [email protected]
concept VerifyBankAccount {
o String name
o String type
o ActionContractSchema_alias_246531724_141_346_246531724_0_16261588163527_ input
o VerifyResponse output
}
concept ActionContractSchema_alias_246531724_141_346_246531724_0_16261588163527_ {
o Double accountNumber
o definitions$_ActionContractSchema_alias_246531724_141_346_246531724_0_16261588163527_$_properties$_accountType accountType
o Double routingNumber
}
enum definitions$_ActionContractSchema_alias_246531724_141_346_246531724_0_16261588163527_$_properties$_accountType {
o checking
o savings
o credit_card
o loan
}
concept VerifyResponse {
o Boolean verified
}
This error gets thrown:
9:49:43 AM - ERROR: Cannot read properties of undefined (reading 'path')
TypeError: Cannot read properties of undefined (reading 'path')
at JsonSchemaVisitor.visitProperty (/Users/andrew.wilson/.nvm/versions/node/v18.12.0/lib/node_modules/@accordproject/concerto-cli/node_modules/@accordproject/concerto-codegen/lib/codegen/fromJsonSchema/cto/jsonSchemaVisitor.js:551:45)
at JsonSchemaVisitor.visit (/Users/andrew.wilson/.nvm/versions/node/v18.12.0/lib/node_modules/@accordproject/concerto-cli/node_modules/@accordproject/concerto-codegen/lib/codegen/fromJsonSchema/cto/jsonSchemaVisitor.js:948:25)
at Property.accept (/Users/andrew.wilson/.nvm/versions/node/v18.12.0/lib/node_modules/@accordproject/concerto-cli/node_modules/@accordproject/concerto-codegen/lib/codegen/fromJsonSchema/cto/jsonSchemaClasses.js:38:24)
at /Users/andrew.wilson/.nvm/versions/node/v18.12.0/lib/node_modules/@accordproject/concerto-cli/node_modules/@accordproject/concerto-codegen/lib/codegen/fromJsonSchema/cto/jsonSchemaVisitor.js:642:48
at Array.map (<anonymous>)
at JsonSchemaVisitor.visitProperties (/Users/andrew.wilson/.nvm/versions/node/v18.12.0/lib/node_modules/@accordproject/concerto-cli/node_modules/@accordproject/concerto-codegen/lib/codegen/fromJsonSchema/cto/jsonSchemaVisitor.js:641:14)
at JsonSchemaVisitor.visit (/Users/andrew.wilson/.nvm/versions/node/v18.12.0/lib/node_modules/@accordproject/concerto-cli/node_modules/@accordproject/concerto-codegen/lib/codegen/fromJsonSchema/cto/jsonSchemaVisitor.js:951:25)
at Properties.accept (/Users/andrew.wilson/.nvm/versions/node/v18.12.0/lib/node_modules/@accordproject/concerto-cli/node_modules/@accordproject/concerto-codegen/lib/codegen/fromJsonSchema/cto/jsonSchemaClasses.js:38:24)
at JsonSchemaVisitor.visitNonEnumDefinition (/Users/andrew.wilson/.nvm/versions/node/v18.12.0/lib/node_modules/@accordproject/concerto-cli/node_modules/@accordproject/concerto-codegen/lib/codegen/fromJsonSchema/cto/jsonSchemaVisitor.js:723:15)
at JsonSchemaVisitor.visit (/Users/andrew.wilson/.nvm/versions/node/v18.12.0/lib/node_modules/@accordproject/concerto-cli/node_modules/@accordproject/concerto-codegen/lib/codegen/fromJsonSchema/cto/jsonSchemaVisitor.js:954:25)
Run the following:
concerto infer --namespace com.docusign.app --format jsonschema --input packages/data-models/src/schemas/contracts/actions/verify/v1/bank-account.json --output example.cto
Where bank-account.json
contains:
{
"$schema": "http://json-schema.org/draft-07/schema#",
"$ref": "#/definitions/VerifyBankAccount",
"definitions": {
"VerifyBankAccount": {
"type": "object",
"properties": {
"name": {
"type": "string",
"const": "Contracts.Actions.Verify.Version1.BankAccount"
},
"type": {
"type": "string",
"const": "action"
},
"input": {
"$ref": "#/definitions/ActionContractSchema%3CActionContractSchema%3Calias-246531724-141-346-246531724-0-16261588163527%3E%3E"
},
"output": {
"$ref": "#/definitions/ActionContractSchema%3CActionContractSchema%3Calias-246531724-346-450-246531724-0-1626237990000%3E%3E"
}
},
"required": [
"input",
"name",
"output",
"type"
],
"additionalProperties": false,
"description": "Bank Account"
},
"ActionContractSchema<ActionContractSchema<alias-246531724-141-346-246531724-0-16261588163527>>": {
"$ref": "#/definitions/ActionContractSchema%3Calias-246531724-141-346-246531724-0-16261588163527%3E",
"description": "Action Contract Schema"
},
"ActionContractSchema<alias-246531724-141-346-246531724-0-16261588163527>": {
"type": "object",
"properties": {
"accountNumber": {
"type": "number"
},
"accountType": {
"type": "string",
"enum": [
"checking",
"savings",
"credit-card",
"loan"
]
},
"routingNumber": {
"type": "number"
}
},
"required": [
"accountNumber",
"accountType",
"routingNumber"
],
"additionalProperties": false,
"description": "Action Contract Schema"
},
"ActionContractSchema<ActionContractSchema<alias-246531724-346-450-246531724-0-1626237990000>>": {
"$ref": "#/definitions/ActionContractSchema%3Calias-246531724-346-450-246531724-0-1626237990000%3E",
"description": "Action Contract Schema"
},
"ActionContractSchema<alias-246531724-346-450-246531724-0-1626237990000>": {
"$ref": "#/definitions/VerifyResponse",
"description": "Action Contract Schema"
},
"VerifyResponse": {
"anyOf": [
{
"type": "object",
"properties": {
"verified": {
"type": "boolean",
"const": true
}
},
"required": [
"verified"
],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"verified": {
"type": "boolean",
"const": false
},
"verifyFailureReason": {
"type": "string"
}
},
"required": [
"verified",
"verifyFailureReason"
],
"additionalProperties": false
}
]
}
}
}
Concerto has a number of reserved words that cannot be used in a valid Concerto file. Currently the JSON Schema inference code lets us create a Concerto file with these reserved words.
That should not be the case and and error must be thrown that an invalid file is about be created.
A team from DocuSign is getting errors when inferring from valid JSON Schema models.
It would make adoption more manageable for codegen if we can clearly articulate differences in compiled results. At a minimum, we should develop a documentation summary with featuresets (e.g., inheritance, metamodel differences, etc.) that can be easily grasped at a high level.
Today, language deltas are documented separately for each codegen subtarget. By putting it in a single view, we can more readily understand differences, expected results, etc.
Cannot create a namespace containing a concept called Transaction
.
Should allow this, concept names should use the namespace.
Generated code does not compile because the concerto
system namespace contains a type called Transaction
and the two type names collide.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.