Skip to content
This repository was archived by the owner on Feb 27, 2025. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21,310 changes: 20,179 additions & 1,131 deletions package-lock.json

Large diffs are not rendered by default.

16 changes: 12 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,25 @@
"chai": "^4.2.0",
"mocha": "^7.1.1",
"nyc": "^15.0.1",
"ts-node": "^8.8.2",
"ts-node": "^8.10.2",
"typescript": "^3.8.3"
},
"dependencies": {
"@api-modeling/amf-client-js": "^4.1.10",
"@api-modeling/api-modeling-metadata": "^0.1.3",
"@api-modeling/amf-client-js": "^4.1.12",
"@api-modeling/api-modeling-metadata": "^0.1.4",
"@api-modeling/metadata-store": "^0.1.17",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Model-bindings cannot depend on the metadata-store

"@types/n3": "^1.4.3",
"@types/uuid": "^7.0.2",
"cross-fetch": "^3.0.4",
"deep-equal": "^2.0.4",
"file-api": "^0.10.4",
"filereader": "^0.10.3",
"jsonld": "^3.1.1",
"jsonld-streaming-parser": "^2.0.0",
"n3": "^1.3.5",
"ts-md5": "^1.2.7"
"source-map-support": "^0.5.19",
"ts-md5": "^1.2.7",
"uuid": "^8.0.0",
"yaml": "^1.10.0"
}
}
9 changes: 8 additions & 1 deletion src/main/bindings/AMLBindingsPlugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ export class AMLBindingsPlugin extends BindingsPlugin {
try {
const resource = resources[0];

const parser = new AmlParser(resource.url, resource.text);
const parser = new AmlParser(resource.url, resource.text || '');
let baseUnit = await parser.parse();
const name = baseUnit.id.split("/").pop();
const module = new meta.Module("Imported spec " + name);
Expand Down Expand Up @@ -59,9 +59,16 @@ export class AMLBindingsPlugin extends BindingsPlugin {

} catch (e) {
console.log("ERROR:" + e.message)
console.log(e.stack)
throw e;
}
}
updateBindings(bindName : string): void {

}
initBindings(bindUuid: string): string {
return ''
}

}

Expand Down
10 changes: 10 additions & 0 deletions src/main/bindings/APIContractBindingsPlugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,20 @@ import {VOCAB} from "./api_contract/constants";
import {APIContractExporter} from "./api_contract/exporter";
import {ApiGenerator} from "./utils/apiGenerator";

import { NamedNode,DataFactory } from 'n3';
const { namedNode } = DataFactory;
import { schPref } from '@api-modeling/metadata-store'

const rdfType : NamedNode = namedNode(schPref.rdf + 'type')


const SUPPORTED_FORMATS = [ApiParser.RAML1, ApiParser.OAS3 + ".0", ApiParser.OAS2, ApiParser.AMF_GRAPH, ApiParser.JSON_SCHEMA];
const SUPPORTED_SYNTAXES = [ApiParser.YAML, ApiParser.JSONLD, ApiParser.JSON]

export class APIContractBindingsPlugin extends BindingsPlugin {

updateBindings(bindName : string):void{}
initBindings(bindUuid: string): string { return '' }

async export(configuration: ConfigurationParameter[], graphs: meta.DialectWrapper[]): Promise<Resource[]> {
const bindings: meta.ModelBindingsDialect[] = [];
Expand Down Expand Up @@ -125,6 +134,7 @@ export class APIContractBindingsPlugin extends BindingsPlugin {
return Promise.resolve(allWrappers);
} catch (e) {
console.log("ERROR:" + e.message)
console.log(e.stack)
throw e;
}
}
Expand Down
43 changes: 42 additions & 1 deletion src/main/bindings/BindingsPlugin.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,19 @@
import * as meta from "@api-modeling/api-modeling-metadata";
import { schPref, DataStore } from '@api-modeling/metadata-store'

import { v4 as uuidv4 } from 'uuid';
import { NamedNode,DataFactory } from 'n3';
const { namedNode, literal } = DataFactory;

const rdfType : NamedNode = namedNode(schPref.rdf + 'type')
const df : DataStore = DataStore.getDataStore()

/**
* Some external resource plugins will work with. Just a URL identifying the resource and the text of the resource.
*/
export interface Resource {
url: string
text: string
text?: string
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How can you get or generate a resource without data?

}

/**
Expand All @@ -16,10 +24,12 @@ export interface ConfigurationParameter {
value: any
}


/**
* Common interface for all bindings plugins
*/
export abstract class BindingsPlugin {
constructor(){}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why?

/**
* Imports resources into DialectWrappers containing the native model graphs
* @param configuration
Expand All @@ -33,4 +43,35 @@ export abstract class BindingsPlugin {
* @param graphs
*/
abstract async export(configuration: ConfigurationParameter[], graphs: meta.DialectWrapper[]): Promise<Resource[]>

abstract updateBindings(bindName : string): void
abstract initBindings(bindUuid: string): string

private bindName = namedNode(schPref.bind + 'Binding')
private uuidName = namedNode(schPref.amldata + 'uuid')
private bdsName = namedNode(schPref.bind + 'bindingDeclarationSource')
private bsName = namedNode(schPref.bind + 'bindingSource')
private bbName = namedNode(schPref.bind + 'boundBy')
private bName = namedNode(schPref.bind + 'binding')
protected dde = namedNode('http://a.ml/vocabularies/meta#DialectDomainElement')
protected de = namedNode('http://a.ml/vocabularies/document#DomainElement')

createBinding(regime: string, bindingDeclSrc: string, source : string){
let uuid = uuidv4()
let bindName = 'http://mulesoft.com/modeling/bindings/' + uuid
let bindNode = namedNode(bindName)
let sourceNode = namedNode('http://mulesoft.com/modeling/instances/uuid/'+source)
let graph = namedNode(regime)
let bindingDeclarationSource = namedNode(bindingDeclSrc)
let stupid = `file://${process.cwd()}/node_modules/@api-modeling/api-modeling-metadata/model/bindings/schema/modelBindingsDialect.yaml#/declarations/Binding`
df.store.addQuad(bindNode, rdfType, namedNode(bindName),graph)
df.store.addQuad(bindNode, rdfType, this.dde,graph)
df.store.addQuad(bindNode, rdfType, this.de,graph)
df.store.addQuad(bindNode, rdfType, namedNode(stupid), graph)
df.store.addQuad(bindNode,this.uuidName, literal(uuid), graph)
df.store.addQuad(bindNode, this.bsName, sourceNode, graph)
df.store.addQuad(bindNode, this.bdsName, namedNode(bindingDeclSrc), graph)
return bindName
}

}
77 changes: 71 additions & 6 deletions src/main/bindings/CIMBindingsPlugin.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
import {BindingsPlugin, ConfigurationParameter, Resource} from "./BindingsPlugin";
import { NamedNode,DataFactory } from 'n3';
const { namedNode } = DataFactory;
import { DataStore, schPref } from '@api-modeling/metadata-store'

const rdfType : NamedNode = namedNode(schPref.rdf + 'type')

import {
DialectWrapper,
ModularityDialect,
Expand All @@ -16,8 +22,8 @@ import {CIMExporter} from "./cim/exporter";
import {applyMixins} from "./utils/mixins";
import {VOCAB} from "./cim/constants";

const df = DataStore.getDataStore()
export class CIMBindingsPlugin extends BindingsPlugin {

constructor() {
super();
}
Expand All @@ -43,13 +49,21 @@ export class CIMBindingsPlugin extends BindingsPlugin {


// Data Models
const entityMap: {[name: string]: string} = {};
const entityMap: {[name: string]: Entity} = {};
entityGroupsDataModels.forEach((dm) => {
// @ts-ignore
dm.entities?.forEach((e) => entityMap[e['@id']] = e.uuid)
dm.entities?.forEach((e) => entityMap[e['@id']] = e)
})
const dataModels: DataModel[] = entityGroupsDataModels.map((entityGroup) => {
const entities = this.parseEntityGroup(store, entityGroup, entityMap);
//const entityMap : { [key: string] : Entity} = {}
const extendsMap : { [key: string] : string } = {}
const entities = this.parseEntityGroup(store, entityGroup, entityMap, extendsMap);

Object.entries(extendsMap).forEach(ex => {
entityMap[ex[0]].extends = entityMap[ex[1]]
})

//const entities = this.parseEntityGroup(store, entityGroup, entityMap);
entityGroup.entities = entities;
return entityGroup;
});
Expand Down Expand Up @@ -136,7 +150,9 @@ export class CIMBindingsPlugin extends BindingsPlugin {
if (sa.uuid.indexOf("cim/subjectarea/") > -1) {
subjectAreaId = sa.uuid.split("cim/subjectarea/").pop()!;
}
const entityGroups = entityGroupsDataModels.map((dm) => this.exportEntityGroup(subjectAreaId, dm!, version.value, entityLinkingMap));
const entityGroups = entityGroupsDataModels.map((dm) =>
this.exportEntityGroup(subjectAreaId, dm!, version.value, entityLinkingMap)
);
let json = {
"@id": subjectAreaId + "SubjectArea",
"@type": "SubjectArea",
Expand Down Expand Up @@ -172,8 +188,57 @@ export class CIMBindingsPlugin extends BindingsPlugin {
}

protected async parseGlobalFile(resource: Resource, store?: n3.Store): Promise<n3.Store> {
return await graph.loadGraph(resource.text, store);
return await graph.loadGraph(resource.text ? resource.text : '', store);
}
private modName : NamedNode = namedNode(schPref.amlm + 'Module')
private boundName = namedNode(schPref.bind + "boundBy")
private dmName = namedNode(schPref.amldm + 'DataModel')
private uuidNN = namedNode(schPref.amldata+'uuid')
private binding = namedNode('http://a.ml/vocabularies/bindings#binding')

updateBindings(bindName : string):void{
//finding who doesn't have a binding
// get all Modules not "boundBy" bindName
const rootBind = namedNode(bindName)
let modsToAnnotate = df.store.getSubjects(rdfType,this.modName,null).
filter((m : any) => df.store.getObjects(m, this.boundName,null).
filter((o : any) => df.store.countQuads(o,rdfType,null,rootBind) > 0).length === 0)
modsToAnnotate.forEach((mta) => {
let uuid = df.store.getObjects(mta,this.uuidNN,null)[0].value
let bindingName = this.createBinding(bindName, 'http://mulesoft.com/modeling/instances/bindings/cim/SubjectAreaBinding', uuid)
df.store.addQuad(rootBind, this.binding, namedNode(bindingName), rootBind)
})
// get all DataModels not "boundBy" bindname
let dmsToAnnotate = df.store.getSubjects(rdfType,this.dmName,null).
filter((m) => df.store.getObjects(m, this.boundName,null).
filter((o) => df.store.countQuads(o,rdfType,null,rootBind) > 0).length === 0)
dmsToAnnotate.forEach((mta) => {
let uuid = df.store.getObjects(mta,this.uuidNN,null)[0].value
let bindingName = this.createBinding(bindName, 'http://mulesoft.com/modeling/instances/bindings/cim/EntityGroupBinding', uuid)
df.store.addQuad(rootBind, this.binding, namedNode(bindingName), rootBind)
})

}
private bindingModel = namedNode('http://a.ml/vocabularies/bindings#BindingModel')
//private dde = namedNode('http://a.ml/vocabularies/meta#DialectDomainElement')
//private de = namedNode('http://a.ml/vocabularies/document#DomainElement')
private bd = namedNode('http://a.ml/vocabularies/bindings#bindingDeclaration')
private cimNN = namedNode('http://mulesoft.com/modeling/instances/bindings/cim')
private bs = namedNode('http://a.ml/vocabularies/bindings#bindingSource')
private cimd = namedNode('http://mulesoft.com/modeling/instances/uuid/cim_distribution')
initBindings(bindUuid: string): string {
let bn = namedNode('http://mulesoft.com/modeling/bindings/'+bindUuid)
df.store.addQuad(bn, this.uuidNN,namedNode(bindUuid),bn)
df.store.addQuad(bn, rdfType, this.bindingModel,bn)
let stupid = `file://${process.cwd()}/node_modules/@api-modeling/api-modeling-metadata/model/bindings/schema/modelBindingsDialect.yaml#/declarations/BindingsModel`
df.store.addQuad(bn, rdfType, this.dde,bn)
df.store.addQuad(bn, rdfType, this.de,bn)
df.store.addQuad(bn, rdfType, namedNode(stupid), bn)
df.store.addQuad(bn, this.bd, this.cimNN)
df.store.addQuad(bn, this.bs, this.cimd)
return 'http://mulesoft.com/modeling/bindings/'+bindUuid
}


}

Expand Down
14 changes: 11 additions & 3 deletions src/main/bindings/api_contract/importer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -141,9 +141,12 @@ export class APIContractImporter {
}

private parseResource(endpoint: amf.model.domain.EndPoint, parent: string, pathParams: string[], group: amf.model.domain.EndPoint[], accEntities: meta.Entity[], accResources: meta.Resource[], entityMap: {[id: string]: string}): meta.Resource {
/* Moving down belos because 'isCollection' isn't a member on resource
const resource = new meta.Resource();
accResources.push(resource);
resource.operations = [];
*/
let resource = new meta.Resource()

const getOperation = endpoint.operations.find((op) => op.method.value() === "get");
let resp: amf.model.domain.Response|undefined;
Expand All @@ -160,7 +163,10 @@ export class APIContractImporter {
let effectiveShape = payload.schema
if (effectiveShape instanceof amf.model.domain.ArrayShape) {
effectiveShape = (<amf.model.domain.ArrayShape>effectiveShape).items;
resource.isCollection = true
resource = new meta.CollectionResource()
//resource.isCollection = true
} else {
resource = new meta.Resource();
}
const entity = this.adaptOrCreate(effectiveShape, endpoint.id + "get", accEntities, entityMap)
if (entity) {
Expand All @@ -170,6 +176,8 @@ export class APIContractImporter {
}
}
}
accResources.push(resource);
resource.operations = [];
const otherOperations = endpoint.operations.filter((op) => op.method.value() !== "get");
if (otherOperations.length > 0) {
otherOperations.forEach((op) => {
Expand Down Expand Up @@ -292,7 +300,7 @@ export class APIContractImporter {
}

private parseGetOperation(newPathParams: amf.model.domain.Parameter[], apiOperation: amf.model.domain.Operation, acc: meta.Entity[], entityMap: {[id: string]: string}): meta.Operation {
const operation = new meta.Operation();
const operation = new meta.ReadOperation();
operation.uuid = Md5.hashStr(apiOperation.id).toString();
operation.isMutation = false;

Expand All @@ -308,7 +316,7 @@ export class APIContractImporter {
}

private parseMutableOperation(newPathParams: amf.model.domain.Parameter[], apiOperation: amf.model.domain.Operation, acc: meta.Entity[], entityMap: {[id: string]: string}): meta.Operation {
const operation = new meta.Operation();
const operation = new meta.UpdateOperation();
operation.uuid = Md5.hashStr(apiOperation.id).toString();
operation.isMutation = true;

Expand Down
7 changes: 5 additions & 2 deletions src/main/bindings/cim/exporter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,6 @@ export class CIMExporter {
const propDomain = propAcc[path] || [];
propDomain.push(id)
propAcc[path] = propDomain

return json;
});

Expand Down Expand Up @@ -235,6 +234,10 @@ export class CIMExporter {
}

protected toId(name: string) {
return name.replace(/\s+/, "").replace("_", "")
try {
return name.replace(/\s+/, "").replace("_", "")
} catch(e){
return ""
}
}
}
Loading