Even more documentation
This commit is contained in:
Generated
+190
@@ -15,6 +15,7 @@
|
||||
"devDependencies": {
|
||||
"@types/node": "^20.8.2",
|
||||
"@types/uuid": "^9.0.6",
|
||||
"typedoc": "^0.25.3",
|
||||
"typescript": "^5.2.2"
|
||||
}
|
||||
},
|
||||
@@ -35,6 +36,99 @@
|
||||
"integrity": "sha512-BT2Krtx4xaO6iwzwMFUYvWBWkV2pr37zD68Vmp1CDV196MzczBRxuEpD6Pr395HAgebC/co7hOphs53r8V7jew==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/ansi-sequence-parser": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-sequence-parser/-/ansi-sequence-parser-1.1.1.tgz",
|
||||
"integrity": "sha512-vJXt3yiaUL4UU546s3rPXlsry/RnM730G1+HkpKE012AN0sx1eOrxSu95oKDIonskeLTijMgqWZ3uDEe3NFvyg==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/balanced-match": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
|
||||
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/brace-expansion": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
|
||||
"integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"balanced-match": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/jsonc-parser": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz",
|
||||
"integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/lunr": {
|
||||
"version": "2.3.9",
|
||||
"resolved": "https://registry.npmjs.org/lunr/-/lunr-2.3.9.tgz",
|
||||
"integrity": "sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/marked": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/marked/-/marked-4.3.0.tgz",
|
||||
"integrity": "sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"marked": "bin/marked.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 12"
|
||||
}
|
||||
},
|
||||
"node_modules/minimatch": {
|
||||
"version": "9.0.3",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz",
|
||||
"integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"brace-expansion": "^2.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16 || 14 >=14.17"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
}
|
||||
},
|
||||
"node_modules/shiki": {
|
||||
"version": "0.14.5",
|
||||
"resolved": "https://registry.npmjs.org/shiki/-/shiki-0.14.5.tgz",
|
||||
"integrity": "sha512-1gCAYOcmCFONmErGTrS1fjzJLA7MGZmKzrBNX7apqSwhyITJg2O102uFzXUeBxNnEkDA9vHIKLyeKq0V083vIw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"ansi-sequence-parser": "^1.1.0",
|
||||
"jsonc-parser": "^3.2.0",
|
||||
"vscode-oniguruma": "^1.7.0",
|
||||
"vscode-textmate": "^8.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/typedoc": {
|
||||
"version": "0.25.3",
|
||||
"resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.25.3.tgz",
|
||||
"integrity": "sha512-Ow8Bo7uY1Lwy7GTmphRIMEo6IOZ+yYUyrc8n5KXIZg1svpqhZSWgni2ZrDhe+wLosFS8yswowUzljTAV/3jmWw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"lunr": "^2.3.9",
|
||||
"marked": "^4.3.0",
|
||||
"minimatch": "^9.0.3",
|
||||
"shiki": "^0.14.1"
|
||||
},
|
||||
"bin": {
|
||||
"typedoc": "bin/typedoc"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 16"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"typescript": "4.6.x || 4.7.x || 4.8.x || 4.9.x || 5.0.x || 5.1.x || 5.2.x"
|
||||
}
|
||||
},
|
||||
"node_modules/typescript": {
|
||||
"version": "5.2.2",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz",
|
||||
@@ -59,6 +153,18 @@
|
||||
"bin": {
|
||||
"uuid": "dist/bin/uuid"
|
||||
}
|
||||
},
|
||||
"node_modules/vscode-oniguruma": {
|
||||
"version": "1.7.0",
|
||||
"resolved": "https://registry.npmjs.org/vscode-oniguruma/-/vscode-oniguruma-1.7.0.tgz",
|
||||
"integrity": "sha512-L9WMGRfrjOhgHSdOYgCt/yRMsXzLDJSL7BPrOZt73gU0iWO4mpqzqQzOz5srxqTvMBaR0XZTSrVWo4j55Rc6cA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/vscode-textmate": {
|
||||
"version": "8.0.0",
|
||||
"resolved": "https://registry.npmjs.org/vscode-textmate/-/vscode-textmate-8.0.0.tgz",
|
||||
"integrity": "sha512-AFbieoL7a5LMqcnOF04ji+rpXadgOXnZsxQr//r83kLPr7biP7am3g9zbaZIaBGwBRWeSvoMD4mgPdX3e4NWBg==",
|
||||
"dev": true
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
@@ -79,6 +185,78 @@
|
||||
"integrity": "sha512-BT2Krtx4xaO6iwzwMFUYvWBWkV2pr37zD68Vmp1CDV196MzczBRxuEpD6Pr395HAgebC/co7hOphs53r8V7jew==",
|
||||
"dev": true
|
||||
},
|
||||
"ansi-sequence-parser": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-sequence-parser/-/ansi-sequence-parser-1.1.1.tgz",
|
||||
"integrity": "sha512-vJXt3yiaUL4UU546s3rPXlsry/RnM730G1+HkpKE012AN0sx1eOrxSu95oKDIonskeLTijMgqWZ3uDEe3NFvyg==",
|
||||
"dev": true
|
||||
},
|
||||
"balanced-match": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
|
||||
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
|
||||
"dev": true
|
||||
},
|
||||
"brace-expansion": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
|
||||
"integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"balanced-match": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"jsonc-parser": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz",
|
||||
"integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==",
|
||||
"dev": true
|
||||
},
|
||||
"lunr": {
|
||||
"version": "2.3.9",
|
||||
"resolved": "https://registry.npmjs.org/lunr/-/lunr-2.3.9.tgz",
|
||||
"integrity": "sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==",
|
||||
"dev": true
|
||||
},
|
||||
"marked": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/marked/-/marked-4.3.0.tgz",
|
||||
"integrity": "sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A==",
|
||||
"dev": true
|
||||
},
|
||||
"minimatch": {
|
||||
"version": "9.0.3",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz",
|
||||
"integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"brace-expansion": "^2.0.1"
|
||||
}
|
||||
},
|
||||
"shiki": {
|
||||
"version": "0.14.5",
|
||||
"resolved": "https://registry.npmjs.org/shiki/-/shiki-0.14.5.tgz",
|
||||
"integrity": "sha512-1gCAYOcmCFONmErGTrS1fjzJLA7MGZmKzrBNX7apqSwhyITJg2O102uFzXUeBxNnEkDA9vHIKLyeKq0V083vIw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ansi-sequence-parser": "^1.1.0",
|
||||
"jsonc-parser": "^3.2.0",
|
||||
"vscode-oniguruma": "^1.7.0",
|
||||
"vscode-textmate": "^8.0.0"
|
||||
}
|
||||
},
|
||||
"typedoc": {
|
||||
"version": "0.25.3",
|
||||
"resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.25.3.tgz",
|
||||
"integrity": "sha512-Ow8Bo7uY1Lwy7GTmphRIMEo6IOZ+yYUyrc8n5KXIZg1svpqhZSWgni2ZrDhe+wLosFS8yswowUzljTAV/3jmWw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"lunr": "^2.3.9",
|
||||
"marked": "^4.3.0",
|
||||
"minimatch": "^9.0.3",
|
||||
"shiki": "^0.14.1"
|
||||
}
|
||||
},
|
||||
"typescript": {
|
||||
"version": "5.2.2",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz",
|
||||
@@ -89,6 +267,18 @@
|
||||
"version": "9.0.1",
|
||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz",
|
||||
"integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA=="
|
||||
},
|
||||
"vscode-oniguruma": {
|
||||
"version": "1.7.0",
|
||||
"resolved": "https://registry.npmjs.org/vscode-oniguruma/-/vscode-oniguruma-1.7.0.tgz",
|
||||
"integrity": "sha512-L9WMGRfrjOhgHSdOYgCt/yRMsXzLDJSL7BPrOZt73gU0iWO4mpqzqQzOz5srxqTvMBaR0XZTSrVWo4j55Rc6cA==",
|
||||
"dev": true
|
||||
},
|
||||
"vscode-textmate": {
|
||||
"version": "8.0.0",
|
||||
"resolved": "https://registry.npmjs.org/vscode-textmate/-/vscode-textmate-8.0.0.tgz",
|
||||
"integrity": "sha512-AFbieoL7a5LMqcnOF04ji+rpXadgOXnZsxQr//r83kLPr7biP7am3g9zbaZIaBGwBRWeSvoMD4mgPdX3e4NWBg==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,6 +32,7 @@
|
||||
"devDependencies": {
|
||||
"@types/node": "^20.8.2",
|
||||
"@types/uuid": "^9.0.6",
|
||||
"typedoc": "^0.25.3",
|
||||
"typescript": "^5.2.2"
|
||||
},
|
||||
"dependencies": {
|
||||
|
||||
@@ -5,14 +5,29 @@ import Traverser from "./helper/traverser";
|
||||
import AIDParser from "./parser/AIDParser";
|
||||
import { SubmodelElementCollection } from "@aas-core-works/aas-core3.0-typescript/dist/types/types";
|
||||
|
||||
/**
|
||||
* The AIMC Mapper.
|
||||
* @remarks
|
||||
* This class is used to map properties t endpoints.
|
||||
*/
|
||||
export default class AIMCMapper {
|
||||
|
||||
/**
|
||||
* The map.
|
||||
*/
|
||||
private map: AIMCMap = new Map();
|
||||
|
||||
/**
|
||||
* Creates the mapper.
|
||||
* @param env The AAS Environment
|
||||
*/
|
||||
public constructor(private readonly env: types.Environment) {
|
||||
this.generate();
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the map from the AAS Environment.
|
||||
*/
|
||||
private generate(): void {
|
||||
const aimc = AIMCParser.parse(this.env);
|
||||
if (aimc === null) return;
|
||||
@@ -51,14 +66,29 @@ export default class AIMCMapper {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @returns The complete map
|
||||
*/
|
||||
public getMap(): AIMCMap {
|
||||
return this.map;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get endpoint for a specific Element
|
||||
* @param element Element
|
||||
* @returns Endpoint description or undefined if not found
|
||||
*/
|
||||
public get(element: types.Class): ConnectionConfiguration | undefined {
|
||||
return this.map.get(element);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all endpoints for a idShort
|
||||
* Can return multiple as idShorts are not necessarily unique
|
||||
* @param idShort idShort of the element
|
||||
* @returns Endpoints descriptions of elements with that idShort
|
||||
*/
|
||||
public getByIdShort(idShort: string): ConnectionConfiguration[] {
|
||||
const result = [];
|
||||
for (const [e, cc] of this.map.entries()) {
|
||||
@@ -67,6 +97,11 @@ export default class AIMCMapper {
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an element by its endpoint
|
||||
* @param path Absolute endpoint path
|
||||
* @returns Elements that use that path
|
||||
*/
|
||||
public reverseGet(path: string): types.Class[] {
|
||||
const result = [];
|
||||
|
||||
|
||||
@@ -2,7 +2,18 @@
|
||||
import { readdirSync, readFileSync } from "fs";
|
||||
import { types, jsonization } from "@aas-core-works/aas-core3.0-typescript";
|
||||
|
||||
/**
|
||||
* Helper class to import AAS-Environments from files.
|
||||
*/
|
||||
export default class FileImporter {
|
||||
|
||||
/**
|
||||
* Read an AAS-Environment from a file.
|
||||
* @param path Filepath
|
||||
* @returns Environment
|
||||
* @throws Error if file is not a JSON file
|
||||
* @throws Any IO error on file read operation
|
||||
*/
|
||||
public static readAASByPath(path: string): types.Environment {
|
||||
if (!path.endsWith(".json")) throw new Error("File must be a JSON file");
|
||||
|
||||
@@ -15,6 +26,11 @@ export default class FileImporter {
|
||||
return aasJson.mustValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Import all AAS-Environments from a directory.
|
||||
* @param path Directory path
|
||||
* @returns Environments
|
||||
*/
|
||||
public static readAllAASFromPath(path: string): types.Environment[] {
|
||||
|
||||
return FileImporter.getAllAASFilePaths(path).map(file => {
|
||||
@@ -27,6 +43,11 @@ export default class FileImporter {
|
||||
}).filter(aas => aas !== null) as types.Environment[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all JSON files from a directory.
|
||||
* @param aasPath Directory path
|
||||
* @returns Paths of the JSON files
|
||||
*/
|
||||
private static getAllAASFilePaths(aasPath: string): string[] {
|
||||
const files = readdirSync(aasPath);
|
||||
return files.filter(file => file.endsWith(".json")).map(file => `${aasPath}/${file}`);
|
||||
|
||||
@@ -3,28 +3,58 @@ import { types } from "@aas-core-works/aas-core3.0-typescript";
|
||||
import { RelationshipElement } from "@aas-core-works/aas-core3.0-typescript/dist/types/types";
|
||||
import { ResolvedRelationshipElement } from "../types/common";
|
||||
|
||||
/**
|
||||
* Keytypes which are globally identifiable.
|
||||
*/
|
||||
const GLOBALLY_IDENTIFIABLES = [types.KeyTypes.GlobalReference, types.KeyTypes.AssetAdministrationShell, types.KeyTypes.ConceptDescription, types.KeyTypes.Identifiable, types.KeyTypes.Submodel]
|
||||
|
||||
/**
|
||||
* Helper to traverse the AAS-Environment.
|
||||
*/
|
||||
export default class Traverser {
|
||||
|
||||
/**
|
||||
* Find an AAS by its ID.
|
||||
* @param environment Environment to search in
|
||||
* @param id ID
|
||||
* @returns AAS or null if not found
|
||||
*/
|
||||
public static findAASById(environment: types.Environment, id: string): types.AssetAdministrationShell | null {
|
||||
if (environment.assetAdministrationShells === null) return null;
|
||||
|
||||
return (environment.assetAdministrationShells.find(aas => aas.id === id)) ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find a Submodel by its ID.
|
||||
* @param environment Environment to search in
|
||||
* @param id ID
|
||||
* @returns Submodel or null if not found
|
||||
*/
|
||||
public static findSMById(environment: types.Environment, id: string): types.Submodel | null {
|
||||
if (environment.submodels === null) return null;
|
||||
|
||||
return (environment.submodels.find(sm => sm.id === id)) ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find Submodel by its idShort.
|
||||
* @param environment Environment to search in
|
||||
* @param id idShort
|
||||
* @returns Submodel or null if not found
|
||||
*/
|
||||
public static findSMByIdShort(environment: types.Environment, id: string): types.Submodel | null {
|
||||
if (environment.submodels === null) return null;
|
||||
|
||||
return (environment.submodels.find(sm => sm.idShort === id)) ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve a reference to an element.
|
||||
* @param env Environment to search in
|
||||
* @param ref Reference
|
||||
* @returns Element or null if not found
|
||||
*/
|
||||
public static resolveReference(env: types.Environment, ref: types.Reference): types.Class | null {
|
||||
if (ref.type === types.ReferenceTypes.ExternalReference) return null; // Not implemented
|
||||
|
||||
@@ -42,6 +72,12 @@ export default class Traverser {
|
||||
return current;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve both references of a relationship element
|
||||
* @param env Environment to search in
|
||||
* @param relationship Relationship element
|
||||
* @returns Resolved relationship element or null if not found
|
||||
*/
|
||||
public static resolveRelationship(env: types.Environment, relationship: RelationshipElement): ResolvedRelationshipElement | null {
|
||||
const first = Traverser.resolveReference(env, relationship.first);
|
||||
const second = Traverser.resolveReference(env, relationship.second);
|
||||
@@ -50,9 +86,15 @@ export default class Traverser {
|
||||
return { first, second };
|
||||
}
|
||||
|
||||
public static traverseByShortIds(start: types.Class, shortIds: string[]): types.Class | null {
|
||||
/**
|
||||
* Traverse downwards from a start element by using idShorts.
|
||||
* @param start Start element
|
||||
* @param idShorts Array of idShorts to traverse by
|
||||
* @returns Target element at the end of the path or null if not found
|
||||
*/
|
||||
public static traverseByShortIds(start: types.Class, idShorts: string[]): types.Class | null {
|
||||
let current: types.Class | null = start;
|
||||
for (const shortId of shortIds) {
|
||||
for (const shortId of idShorts) {
|
||||
if (current === null) break;
|
||||
|
||||
current = Traverser.findChildByIdShort(current, shortId);
|
||||
@@ -61,12 +103,25 @@ export default class Traverser {
|
||||
return current;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get element by using idShorts from an submodel.
|
||||
* @param env Environment to search in
|
||||
* @param submodelOrIdShort Submodel element or Submodel idShort
|
||||
* @param idShorts idShorts to traverse by
|
||||
* @returns Target element at the end of the path or null if not found
|
||||
*/
|
||||
public static getElementByIdPath(env: types.Environment, submodelOrIdShort: string | types.Submodel, idShorts: string[]): types.Class | null {
|
||||
const sm = typeof submodelOrIdShort === "string" ? Traverser.findSMByIdShort(env, submodelOrIdShort) : submodelOrIdShort;
|
||||
if (sm === null) return null;
|
||||
return Traverser.traverseByShortIds(sm, idShorts);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find an element using a function to check.
|
||||
* @param start Start element
|
||||
* @param checkFunction Function to find the element. First element which evaluates to true using this function will be returned.
|
||||
* @returns Element or null if not found
|
||||
*/
|
||||
public static findElement(start: types.Class, checkFunction: (element: types.Class) => boolean): types.Class | null {
|
||||
for (const element of start.descend()) {
|
||||
if (checkFunction(element)) return element;
|
||||
@@ -75,6 +130,12 @@ export default class Traverser {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find a child element by its idShort.
|
||||
* @param start Start element
|
||||
* @param idShort idShort to search for
|
||||
* @returns Child element or null if not found
|
||||
*/
|
||||
public static findChildByIdShort(start: types.Class, idShort: string): types.Class | null {
|
||||
for (const child of start.descendOnce()) {
|
||||
if ((child as any).idShort === idShort) return child;
|
||||
|
||||
@@ -7,48 +7,146 @@ type ConnectionType = "ON_DEMAND" | "PERMANENT";
|
||||
|
||||
export type OnEventCallback = (response: any) => void
|
||||
|
||||
/**
|
||||
* Abstract class for an connector to an asset.
|
||||
* This should be used as base class for your own connectors.
|
||||
*/
|
||||
export default abstract class InterfaceConnectionObject<ConfigInterface> {
|
||||
/**
|
||||
* A name for your connector.
|
||||
* @remarks
|
||||
* Currently not used.
|
||||
*/
|
||||
public static readonly connectorName: string;
|
||||
/**
|
||||
* Which protocols are supported by your connector.
|
||||
* This is really important later so the AAS can decide which connector to use!
|
||||
*/
|
||||
public static readonly uriProtocol: string[]|string;
|
||||
/**
|
||||
* The type of connection your connector uses.
|
||||
* @remarks
|
||||
* Currently not used.
|
||||
*/
|
||||
public static readonly connectionType: ConnectionType;
|
||||
/**
|
||||
* Whether your connector supports subscriptions.
|
||||
* @remarks
|
||||
* Currently not used.
|
||||
*/
|
||||
public static readonly supportsSubscriptions: boolean;
|
||||
|
||||
/**
|
||||
* A store for all observers and their callbacks.
|
||||
*/
|
||||
protected readonly observerStore: Record<any, ((value: any) => void)[]> = {};
|
||||
/**
|
||||
* A store for all event subscriptions and their callbacks.
|
||||
*/
|
||||
protected readonly eventSubStore: Record<any, ((value: any) => void)[]> = {};
|
||||
/**
|
||||
* A store for all async action handles and their results.
|
||||
*/
|
||||
protected readonly asyncActionStateStore: Record<any, {finished: boolean, result: any}> = {};
|
||||
|
||||
/**
|
||||
* Creates the connector.
|
||||
* @param connectionParameter Connection parameter for your connector.
|
||||
* @param endpointMetadata {@link EndpointMetadata}
|
||||
* @param mapper {@link AIMCMapper}
|
||||
* @param onConnectorEvent Callback when an event is received.
|
||||
*/
|
||||
public constructor(
|
||||
protected readonly connectionParameter: ConfigInterface,
|
||||
public readonly endpointMetadata: EndpointMetadata,
|
||||
protected readonly mapper: AIMCMapper,
|
||||
protected readonly onConnectorEvent: OnEventCallback) {}
|
||||
|
||||
/**
|
||||
* This should connect the Connector to the asset.
|
||||
* @returns Whether the connection was successful.
|
||||
*/
|
||||
public abstract connect(): boolean;
|
||||
|
||||
/**
|
||||
* This should disconnect the Connector from the asset (if it even is connected).
|
||||
*/
|
||||
public abstract disconnect(): void;
|
||||
|
||||
/**
|
||||
* Read a property value from the asset.
|
||||
* @param prop Property
|
||||
* @returns Value of property casted to the type it says it should be.
|
||||
*/
|
||||
public abstract readProperty(prop: types.Property): void;
|
||||
|
||||
/**
|
||||
* Write a property value to the asset.
|
||||
* @param prop Property
|
||||
* @param value Value to write.
|
||||
*/
|
||||
public abstract writeProperty(prop: types.Property, value: any): void;
|
||||
|
||||
/**
|
||||
* Observe a property value from the asset.
|
||||
* @param prop Property
|
||||
* @param callback Callback to call when the property changes.
|
||||
* @returns Whether the creation of an observer was successful.
|
||||
*/
|
||||
public abstract observeProperty(prop: types.Property, callback: (value: any) => void): boolean;
|
||||
|
||||
/**
|
||||
* Call an action on the asset synchronously.
|
||||
* @param action Action
|
||||
* @param args Arguments
|
||||
* @returns Return value of the action.
|
||||
*/
|
||||
public abstract callActionSync(action: types.Operation, args: Record<string, any>): any;
|
||||
|
||||
/**
|
||||
* Call an action on the asset asynchronously.
|
||||
* @param action Action
|
||||
* @param args Arguments
|
||||
* @returns Handle for the async action.
|
||||
*/
|
||||
public abstract callActionAsync(action: types.Operation, args: Record<string, any>): string | null;
|
||||
|
||||
public readAsyncActionState(handle: string): any {
|
||||
/**
|
||||
* Read the state of an async action.
|
||||
* @param handle Handle of the async action.
|
||||
* @returns Whether the async action is finished.
|
||||
*/
|
||||
public readAsyncActionState(handle: string): boolean {
|
||||
return this.asyncActionStateStore[handle].finished;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read the result of an async action.
|
||||
* @param handle Handle of the async action.
|
||||
* @returns Result of the async action.
|
||||
*/
|
||||
public readAsyncActionResponse(handle: string): any {
|
||||
return this.asyncActionStateStore[handle].result;
|
||||
};
|
||||
|
||||
/**
|
||||
* Subscribe to an event.
|
||||
* @param event Event
|
||||
* @param callback Callback to call when the event occurs.
|
||||
* @returns Whether the subscription was successful.
|
||||
*/
|
||||
public abstract subscribeEvent(event: types.BasicEventElement, callback: (event: types.BasicEventElement) => void): boolean;
|
||||
|
||||
/**
|
||||
* Unsubscribe from an event.
|
||||
* @param event Event
|
||||
*/
|
||||
public abstract unsubscribeEvent(event: types.BasicEventElement): void;
|
||||
|
||||
/**
|
||||
* Generate a handle for an async action.
|
||||
* @returns Handle
|
||||
*/
|
||||
protected generateAsyncHandle() {
|
||||
const handle = v4();
|
||||
this.asyncActionStateStore[handle] = {finished: false, result: null};
|
||||
|
||||
@@ -27,15 +27,46 @@ type InterfaceConnectionEntry<ConfigInterface> = {
|
||||
config: ConfigInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* The core of the library.
|
||||
* @remarks
|
||||
* Here are all Interface Servers and Connectors are created and managed.
|
||||
* Also every request is handled here.
|
||||
*/
|
||||
export default class MultiMessageBroker {
|
||||
private static instance: MultiMessageBroker|null = null;
|
||||
|
||||
/**
|
||||
* Whether the broker is prepared.
|
||||
*/
|
||||
private prepared: boolean = false;
|
||||
|
||||
/**
|
||||
* All registered AASs.
|
||||
*/
|
||||
private aasRegistrations: AASRegistrationPrepared[] = [];
|
||||
/**
|
||||
* All registered Interface Connectors.
|
||||
*/
|
||||
private interfaceConnections: InterfaceConnectionEntry<any>[] = [];
|
||||
|
||||
public constructor() {}
|
||||
private constructor() {}
|
||||
|
||||
public registerAAS<T>(registration: AASRegistration): void {
|
||||
/**
|
||||
* Get the singleton instance of the broker.
|
||||
*/
|
||||
public static getInstance(): MultiMessageBroker {
|
||||
if (this.instance === null) this.instance = new MultiMessageBroker();
|
||||
return this.instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register an AAS.
|
||||
* @remarks
|
||||
* This will also create the {@link AIMCMapper} for the AAS
|
||||
* @param registration AAS registration
|
||||
*/
|
||||
public registerAAS(registration: AASRegistration): void {
|
||||
this.aasRegistrations.push({
|
||||
...registration,
|
||||
serverInstances: [],
|
||||
@@ -44,10 +75,20 @@ export default class MultiMessageBroker {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Register an Interface Connector.
|
||||
* @param interfaceConnectionEntry Interface connector registration
|
||||
* @typeParam T - The config interface for your interface connector.
|
||||
*/
|
||||
public registerInterfaceConnection<T>(interfaceConnectionEntry: InterfaceConnectionEntry<T>): void {
|
||||
this.interfaceConnections.push(interfaceConnectionEntry);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare the broker.
|
||||
* @remarks
|
||||
* This will create instances of the {@link AASInterfaceServer} and {@link InterfaceConnectionObject} classes.
|
||||
*/
|
||||
public prepare(): void {
|
||||
for (const registration of this.aasRegistrations) {
|
||||
|
||||
@@ -92,6 +133,9 @@ export default class MultiMessageBroker {
|
||||
this.prepared = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Start the broker.
|
||||
*/
|
||||
public start(): void {
|
||||
if (!this.prepared) this.prepare();
|
||||
|
||||
@@ -101,6 +145,12 @@ export default class MultiMessageBroker {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback on an server request
|
||||
* @param request Request
|
||||
* @param registration AAS Registration
|
||||
* @returns Value or success state or nothing based on the request type
|
||||
*/
|
||||
private onInterfaceRequest(request: Request, registration: AASRegistrationPrepared): any {
|
||||
|
||||
const getConnector = (target: types.Class) => {
|
||||
@@ -162,6 +212,10 @@ export default class MultiMessageBroker {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback on a connector event.
|
||||
* @param response
|
||||
*/
|
||||
private onConnectorEvent(response: any) {
|
||||
for (const aas of this.aasRegistrations) {
|
||||
for (const server of aas.serverInstances ?? []) {
|
||||
|
||||
+38
-1
@@ -1,18 +1,55 @@
|
||||
import { types } from "@aas-core-works/aas-core3.0-typescript";
|
||||
import type { Request, OnRequestCallback } from "./types/requests";
|
||||
import type { OnRequestCallback } from "./types/requests";
|
||||
|
||||
/**
|
||||
* Abstract class for an interface server.
|
||||
* This should be used as base class for your own interface servers!
|
||||
*
|
||||
* @typeParam ConfigInterface - The config interface for your interface server.
|
||||
*/
|
||||
export default abstract class AASInterfaceServer<ConfigInterface> {
|
||||
/**
|
||||
* A name for your interface server.
|
||||
* @remarks
|
||||
* Currently unused
|
||||
*/
|
||||
public static readonly serverInterfaceName: string;
|
||||
/**
|
||||
* Whether your interface server supports subscriptions.
|
||||
* @remarks
|
||||
* Currently unused
|
||||
*/
|
||||
public static readonly supportsSubscriptions: boolean;
|
||||
|
||||
/**
|
||||
* Crate the interface server.
|
||||
* @param config Interface server config
|
||||
* @param aas AAS Environment for the server
|
||||
* @param onRequestCallback Callback when a request is received and parsed
|
||||
*/
|
||||
constructor(
|
||||
protected readonly config: ConfigInterface,
|
||||
protected readonly aas: types.Environment,
|
||||
protected readonly onRequestCallback: OnRequestCallback) {}
|
||||
|
||||
/**
|
||||
* Prepare the interface server.
|
||||
* @remarks
|
||||
* Here you can create routes, listeners, callbacks,...
|
||||
*/
|
||||
public abstract prepare(): void;
|
||||
/**
|
||||
* Run the interface server.
|
||||
*/
|
||||
public abstract run(): void;
|
||||
/**
|
||||
* Stop the interface server.
|
||||
*/
|
||||
public abstract stop(): void;
|
||||
/**
|
||||
* Notify observers/subscribers about an event.
|
||||
* @param event Event to notify the interface server about
|
||||
*/
|
||||
public abstract notify(event: any): void;
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user