import { readdirSync, readFileSync } from "fs"; import { types, jsonization } from "@aas-core-works/aas-core3.0-typescript"; const GLOBALLY_IDENTIFIABLES = [types.KeyTypes.GlobalReference, types.KeyTypes.AssetAdministrationShell, types.KeyTypes.ConceptDescription, types.KeyTypes.Identifiable, types.KeyTypes.Submodel] export default class AASHelper { public static readAASByPath(path: string): types.Environment { if (!path.endsWith(".json")) throw new Error("File must be a JSON file"); const file = readFileSync(path, { encoding: "utf-8" }); const aas = JSON.parse(file); const aasJson = jsonization.environmentFromJsonable(aas); if (aasJson.error) throw aasJson.error; return aasJson.mustValue(); } public static readAllAASFromPath(path: string): types.Environment[] { return AASHelper.getAllAASFilePaths(path).map(file => { try { return AASHelper.readAASByPath(file); } catch (e) { console.log(`Error while reading AAS from ${file}`, e); return null; } }).filter(aas => aas !== null) as types.Environment[]; } private static getAllAASFilePaths(aasPath: string): string[] { const files = readdirSync(aasPath); return files.filter(file => file.endsWith(".json")).map(file => `${aasPath}/${file}`); } 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; } 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; } 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; } public static resolveReference(env: types.Environment, ref: types.Reference): types.Class | null { if (ref.type === types.ReferenceTypes.ExternalReference) return null; // Not implemented let current: types.Class | null = null; for (const key of ref.keys) { if (current === null && !GLOBALLY_IDENTIFIABLES.includes(key.type)) break; if (current === null) { current = AASHelper.findElement(env, element => (element as any).id === key.value) } else { current = AASHelper.findElement(current, element => (element as any).idShort === key.value) } } return current; } public static traverseByShortIds(start: types.Class, shortIds: string[]): types.Class | null { let current: types.Class | null = start; for (const shortId of shortIds) { if (current === null) break; current = AASHelper.findChildByIdShort(current, shortId); } return current; } public static getElementByIdPath(env: types.Environment, submodelOrIdShort: string | types.Submodel, idShorts: string[]): types.Class | null { const sm = typeof submodelOrIdShort === "string" ? AASHelper.findSMByIdShort(env, submodelOrIdShort) : submodelOrIdShort; if (sm === null) return null; return AASHelper.traverseByShortIds(sm, idShorts); } 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; } return null; } 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; } return null; } }