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: generate typescript definitions #354

Merged
merged 10 commits into from
Nov 23, 2021
88 changes: 44 additions & 44 deletions packages/concerto-core/api.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,36 +2,36 @@ class BaseException extends Error {
+ void constructor(string,string)
}
class BaseFileException extends BaseException {
+ void constructor(string,string,string,string,string)
+ void constructor(string,string,string,string?,string?)
+ string getFileLocation()
+ string getShortMessage()
+ string getFileName()
}
class Concerto {
+ void constructor()
+ void validate(undefined) throws Error
+ void constructor(modelManager)
+ void validate(obj,options?) throws Error
+ void getModelManager()
+ boolean isObject()
+ void getTypeDeclaration()
+ string getIdentifier()
+ boolean isIdentifiable()
+ boolean isRelationship()
+ void setIdentifier(string)
+ string getFullyQualifiedIdentifier()
+ string toURI()
+ boolean isObject(obj)
+ void getTypeDeclaration(obj)
+ string getIdentifier(obj)
+ boolean isIdentifiable(obj)
+ boolean isRelationship(obj)
+ void setIdentifier(obj,string)
+ string getFullyQualifiedIdentifier(obj)
+ string toURI(obj)
+ void fromURI(string) throws Error
+ string getType()
+ string getNamespace()
+ string getType(obj)
+ string getNamespace(obj)
}
+ object setCurrentTime()
class Factory {
+ string newId()
+ void constructor(ModelManager)
+ Resource newResource(String,String,String,Object,boolean,String,boolean) throws TypeNotFoundException
+ Resource newConcept(String,String,String,Object,boolean,String,boolean) throws TypeNotFoundException
+ Resource newResource(String,String,String?,Object?,boolean?,String?,boolean?) throws TypeNotFoundException
+ Resource newConcept(String,String,String?,Object?,boolean?,String?,boolean?) throws TypeNotFoundException
+ Relationship newRelationship(String,String,String) throws TypeNotFoundException
+ Resource newTransaction(String,String,String,Object,String,boolean)
+ Resource newEvent(String,String,String,Object,String,boolean)
+ Resource newTransaction(String,String,String?,Object?,String?,boolean?)
+ Resource newEvent(String,String,String?,Object?,String?,boolean?)
}
class AssetDeclaration extends IdentifiedDeclaration {
+ void constructor(ModelFile,Object) throws IllegalModelException
Expand Down Expand Up @@ -69,13 +69,13 @@ class ConceptDeclaration extends ClassDeclaration {
+ void constructor(ModelFile,Object) throws IllegalModelException
}
class Decorator {
+ void constructor(Object) throws IllegalModelException
+ void constructor(ClassDeclaration|Property,Object) throws IllegalModelException
+ void getParent()
+ string getName()
+ object[] getArguments()
}
class DecoratorFactory {
+ Decorator newDecorator(Object)
+ Decorator newDecorator(ClassDeclaration|Property,Object)
}
class EnumDeclaration extends ClassDeclaration {
+ void constructor(ModelFile,Object) throws IllegalModelException
Expand All @@ -92,7 +92,7 @@ class IdentifiedDeclaration extends ClassDeclaration {
+ void constructor(ModelFile,Object) throws IllegalModelException
}
class IllegalModelException extends BaseFileException {
+ void constructor(string,ModelFile,Object,number,number,number,number,string)
+ void constructor(string,ModelFile?,Object?,number,number,number,number,string?)
}
class Introspector {
+ void constructor(ModelManager)
Expand All @@ -101,30 +101,30 @@ class Introspector {
}
class ModelFileDownloader {
+ void constructor(ModelFileLoader,Number)
+ Promise downloadExternalDependencies(ModelFile[],Object)
+ Promise downloadExternalDependencies(ModelFile[],Object?)
+ Promise runJob(Object,Object)
}
class MetaModel {
+ void createMetaModelManager()
+ object validateMetaModel(object)
+ object createNameTable(object)
+ object createNameTable(modelManager,object)
+ string resolveName(string,object)
+ object resolveTypeNames(object,object)
+ object resolveMetaModel(object,object)
+ object modelFileToMetaModel(object,boolean)
+ object modelManagerToMetaModel(object,boolean,boolean)
+ object modelFileToMetaModel(object,boolean?)
+ object modelManagerToMetaModel(object,boolean?,boolean?)
+ string decoratorArgFromMetaModel(object)
+ string decoratorFromMetaModel(object)
+ string decoratorsFromMetaModel(object,string)
+ string propertyFromMetaModel(object)
+ string declFromMetaModel(object)
+ string ctoFromMetaModel(object,boolean)
+ object modelManagerFromMetaModel(object,boolean)
+ object ctoToMetaModel(string,boolean)
+ object ctoToMetaModelAndResolve(string,boolean)
+ string ctoFromMetaModel(object,boolean?)
+ object modelManagerFromMetaModel(object,boolean?)
+ object ctoToMetaModel(string,boolean?)
+ object ctoToMetaModelAndResolve(modelManager,string,boolean?)
}
class ModelFile {
+ void constructor(ModelManager,string,string) throws IllegalModelException
+ void constructor(ModelManager,string,string?) throws IllegalModelException
+ boolean isModelFile()
+ Boolean isSystemModelFile()
+ boolean isExternal()
Expand Down Expand Up @@ -187,7 +187,7 @@ class Identifiable extends Typed {
class Relationship extends Identifiable {
+ String toString()
+ boolean isRelationship()
+ Relationship fromURI(ModelManager,String,String,String)
+ Relationship fromURI(ModelManager,String,String?,String?)
}
class Resource extends Identifiable {
+ String toString()
Expand All @@ -210,22 +210,22 @@ class ValidatedResource extends Resource {
+ void validate() throws Error
}
class ModelLoader {
+ object loadModelManager(string[],object,boolean,number)
+ object loadModelManagerFromModelFiles(object[],undefined,object,boolean,number)
+ object loadModelManager(string[],object,boolean?,number?)
+ object loadModelManagerFromModelFiles(object[],string[],object,boolean?,number?)
}
class ModelManager {
+ void constructor(object)
+ void constructor(object?)
+ boolean isModelManager()
+ Object accept(Object,Object)
+ void validateModelFile(string,string) throws IllegalModelException
+ Object addModelFile(string,string,boolean) throws IllegalModelException
+ Object updateModelFile(string,string,boolean) throws IllegalModelException
+ void validateModelFile(string,string?) throws IllegalModelException
+ Object addModelFile(string|ModelFile,string,boolean?) throws IllegalModelException
+ Object updateModelFile(string|ModelFile,string?,boolean?) throws IllegalModelException
+ void deleteModelFile(string)
+ Object[] addModelFiles(object[],undefined,boolean)
+ Object[] addModelFiles(|,string[],boolean?)
+ void validateModelFiles()
+ Promise updateExternalModels(Object,ModelFileDownloader) throws IllegalModelException
+ void writeModelsToFileSystem(string,Object,boolean)
+ Object[] getModels(Object,boolean)
+ Promise updateExternalModels(Object?,ModelFileDownloader?) throws IllegalModelException
+ void writeModelsToFileSystem(string,Object?,boolean)
+ Object[] getModels(Object?,boolean)
+ void clearModelFiles()
+ ModelFile getModelFile(string)
+ string[] getNamespaces()
Expand All @@ -245,10 +245,10 @@ class SecurityException extends BaseException {
+ void constructor(string)
}
class Serializer {
+ void constructor(Factory,ModelManager,object)
+ void constructor(Factory,ModelManager,object?)
+ void setDefaultOptions(Object)
+ Object toJSON(Resource,Object,boolean,boolean,boolean,boolean,boolean,number) throws Error
+ Resource fromJSON(Object,Object,boolean,boolean,number)
+ Object toJSON(Resource,Object?,boolean?,boolean?,boolean?,boolean?,boolean?,number?) throws Error
+ Resource fromJSON(Object,Object,boolean,boolean,number?)
}
class TypedStack {
+ void constructor(Object)
Expand All @@ -258,6 +258,6 @@ class TypedStack {
+ void clear()
}
class TypeNotFoundException extends BaseException {
+ void constructor(string,string,string)
+ void constructor(string,string?,string)
+ string getTypeName()
}
3 changes: 2 additions & 1 deletion packages/concerto-core/changelog.txt
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,10 @@
# Note that the latest public API is documented using JSDocs and is available in api.txt.
#

Version 1.2.2 {cf9d5dad911076e149b7013afe24e3dc} 2021-11-22
Version 1.2.2 {0ed9b2150eb03a620e66b1fd6a2833b5} 2021-11-22
- Remove custom instanceof and add methods to check runtime type
- Remove support for Node 12
- Generate Typescript definitions from JSDoc
- Parser directly constructs metamodel instance
- Convert MetaModel to a class for Typescript + Webpack compatability
- Update Acorn to latest and refactor the JavaScript parser so we can use static class members
Expand Down
6 changes: 3 additions & 3 deletions packages/concerto-core/lib/modelmanager.js
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ abstract concept Event {}
* Note that if there are dependencies between multiple files the files
* must be added in dependency order, or the addModelFiles method can be
* used to add a set of files irrespective of dependencies.
* @param {string} modelFile - The Concerto file as a string
* @param {string|ModelFile} modelFile - Model as a string or object
* @param {string} fileName - an optional file name to associate with the model file
* @param {boolean} [disableValidation] - If true then the model files are not validated
* @throws {IllegalModelException}
Expand Down Expand Up @@ -167,7 +167,7 @@ abstract concept Event {}
* Concerto files have a single namespace. If a Concerto file with the
* same namespace has already been added to the ModelManager then it
* will be replaced.
* @param {string} modelFile - The Concerto file as a string
* @param {string|ModelFile} modelFile - Model as a string or object
* @param {string} [fileName] - a file name to associate with the model file
* @param {boolean} [disableValidation] - If true then the model files are not validated
* @throws {IllegalModelException}
Expand Down Expand Up @@ -206,7 +206,7 @@ abstract concept Event {}

/**
* Add a set of Concerto files to the model manager.
* @param {object[]} modelFiles - An array of Concerto files as strings or ModelFile objects.
* @param {string[]|ModelFile[]} modelFiles - An array of models as strings or ModelFile objects.
* @param {string[]} [fileNames] - A array of file names to associate with the model files
* @param {boolean} [disableValidation] - If true then the model files are not validated
* @returns {Object[]} The newly added model files (internal).
Expand Down
2 changes: 1 addition & 1 deletion packages/concerto-core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
"test:watch": "nyc mocha --watch --recursive -t 10000",
"mocha": "mocha --recursive -t 10000",
"nyc": "nyc mocha --recursive -t 10000",
"build:types" : "npx -p typescript tsc lib/**/*.js index.js --declaration --allowJs --emitDeclarationOnly --outDir types"
"build:types" : "npx -p typescript tsc ./lib/**/*.js index.js --declaration --allowJs --emitDeclarationOnly --outDir types"
},
"repository": {
"type": "git",
Expand Down
56 changes: 49 additions & 7 deletions packages/concerto-core/scripts/javascriptparser.js
Original file line number Diff line number Diff line change
Expand Up @@ -461,13 +461,55 @@ class JavaScriptParser {
}
}

if (tag.type.name) {
paramTypes.push(tag.type.name);
} else if (tag.type.applications) {
paramTypes.push(tag.type.applications[0].name + '[]');
} else if (tag.type.expression) {
paramTypes.push(tag.type.expression.name);

switch(tag.type.type) {
case 'UnionType':
if(tag?.type?.elements) {
paramTypes.push(tag.type.elements.map( e => e.name).join('|'));
}
else {
throw new Error('Malformed JSDoc comment: ' + JSON.stringify(tag));
}
break;
case 'OptionalType':
if(tag?.type?.expression?.type === 'TypeApplication') {
paramTypes.push(`${tag.type.expression.applications[0].name}[]`);
}
else if(tag?.type.expression?.name) {
paramTypes.push(`${tag?.type.expression?.name}?`);
}
else if(tag?.name) {
paramTypes.push(`${tag?.name}?`);
}
else {
throw new Error('Malformed JSDoc comment: ' + JSON.stringify(tag));
}
break;
case 'AllLiteral':
if(tag?.name) {
paramTypes.push(tag.name);
}
else {
throw new Error('Malformed JSDoc comment: ' + JSON.stringify(tag));
}
break;
case 'NameExpression':
if(tag?.type?.name) {
paramTypes.push(tag.type.name);
}
else {
throw new Error('Malformed JSDoc comment: ' + JSON.stringify(tag));
}
break;
case 'TypeApplication':
if(tag?.type?.applications) {
paramTypes.push(tag.type.applications.map(e => e.name).join(',') + '[]');
}
else {
throw new Error('Malformed JSDoc comment: ' + JSON.stringify(tag));
}
break;
default:
throw new Error('Unrecognized JSDoc comment: ' + JSON.stringify(tag));
}
});
return paramTypes;
Expand Down
2 changes: 1 addition & 1 deletion packages/concerto-core/scripts/versionchecker.js
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ class VersionChecker {
if (digest !== md5) {
throw new Error('Computed public API digest did not match the digest in the changelog for the most recent version. ' +
'Increment the version number and add a new entry to the changelog (explaining your public API change) using the digest ' + digest +
'. Run \'git diff api.txt\' to understand the pubic API changes. Please ensure that TypeScript definitions are up to date by updating packages/concerto-core/types/index.ds');
'. Run \'git diff api.txt\' to understand the pubic API changes. Please ensure that TypeScript definitions are up to date by executing `npm run build:types`');
}

// we're done here...
Expand Down
36 changes: 0 additions & 36 deletions packages/concerto-core/test/scripts/javascriptparser.js
Original file line number Diff line number Diff line change
Expand Up @@ -792,42 +792,6 @@ describe('JavascriptParser', () => {
(()=>{JavascriptParser.getMethodArguments(comment);})
.should.throws(/Malformed JSDoc comment/);
});

it('Cope with different types of tag type', () => {
const comment = `
/**
* @returns {Animal[]} Something valid
*/
`;
sandbox.stub(doctrine,'parse').returns(
{
tags:[
{
type:
{
applications:['somename']
}

},
{
type:
{
expression: {name:'somename'}
}

},
{
type:
{
wibble: {name:'somename'}
}

}
]
});
JavascriptParser.getMethodArguments(comment);

});
});

describe('#getExample', () => {
Expand Down
16 changes: 16 additions & 0 deletions packages/concerto-core/types/lib/baseexception.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
export = BaseException;
/**
* A base class for all Concerto exceptions
* @extends Error
* @class
* @memberof module:concerto-core
*/
declare class BaseException extends Error {
/**
* Create the BaseException.
* @param {string} message - The exception message.
* @param {string} component - The optional component which throws this error.
*/
constructor(message: string, component: string);
component: any;
}
Loading