accordproject / concerto-codegen Goto Github PK
View Code? Open in Web Editor NEWLicense: Apache License 2.0
License: Apache License 2.0
The 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.
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
}
]
}
}
}
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"
}
}
}
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
}
This issue may be considered a follow-up to this issue in the concerto repository.
Vocabulary is auto-generated for $identifier, while it is supposed to be skipped in this case.
Should not auto generate vocabulary for $identifier
For this model,
concept Person identified {
o String name
}
enum Color {
o RED
o BLUE
o GREEN
}
asset Vehicle identified by vin {
o String vin
o Color color
}
asset Truck extends Vehicle {
o Double weight
}
The following vocab is generated.
#Generated vocabulary for namespace: [email protected]
locale: en
namespace: [email protected]
declarations:
- Person: Person
properties:
- $identifier: Identifier of the Person # should not be auto generated
- name: Name of the Person
- Color: Color
properties:
- RED: RED of the Color
- BLUE: BLUE of the Color
- GREEN: GREEN of the Color
- Vehicle: Vehicle
properties:
- vin: Vin of the Vehicle
- color: Color of the Vehicle
- Truck: Truck
properties:
- weight: Weight of the Truck
Fix bug in vocabularyvisitor.js in the concerto-codegen repository.
concerto compile --target vocabulary
for the above .cto file.
A team from DocuSign is getting errors when inferring from valid JSON Schema models.
Update all Concerto main repo dependencies to latest version.
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.
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.
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.
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
.
Invalid TS code is generated from this model. Looks like the logic to generate unions doesn't take into account scalars or enums.
namespace [email protected]
concept Address {
o String street
o String city
o String zip
}
concept Order {
o String sku
o Integer amount
}
concept LoyaltyStatus {
o String level
}
enum Color {
o RED
o GREEN
o BLUE
o PINK
o BLACK
o WHITE
}
concept Preferences {
o Color[] favoriteColors optional
}
@template
concept TemplateData {
o String firstName
o String lastName
o String[] middleNames
o Boolean active
o DateTime lastVisit
o Address address
o Order[] orders
o LoyaltyStatus loyaltyStatus optional
o Preferences preferences
}
Generates code that compiles.
Code doesn't compile because a union is created containing IColor
, even though Color is an enum.
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 isIt 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.
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.