diff --git a/package-lock.json b/package-lock.json index 4942e576..2cc98753 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "aas-portal-project", - "version": "2.26.29", + "version": "3.0.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "aas-portal-project", - "version": "2.26.29", + "version": "3.0.0", "license": "Apache-2.0", "workspaces": [ "./projects/common", @@ -15,6 +15,7 @@ "./projects/aas-portal" ], "devDependencies": { + "@babel/polyfill": "^7.4.4", "@semantic-release/git": "^10.0.1", "@semantic-release/gitlab": "^12.0.5" } @@ -2678,6 +2679,17 @@ "@babel/core": "^7.0.0" } }, + "node_modules/@babel/polyfill": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/polyfill/-/polyfill-7.4.4.tgz", + "integrity": "sha512-WlthFLfhQQhh+A2Gn5NSFl0Huxz36x86Jn+E9OW7ibK8edKPq+KLy4apM1yDpQ8kJOVi1OVjpP4vSDLdrI04dg==", + "deprecated": "🚨 This package has been deprecated in favor of separate inclusion of a polyfill and regenerator-runtime (when needed). See the @babel/polyfill docs (https://babeljs.io/docs/en/babel-polyfill) for more information.", + "dev": true, + "dependencies": { + "core-js": "^2.6.5", + "regenerator-runtime": "^0.13.2" + } + }, "node_modules/@babel/preset-env": { "version": "7.22.9", "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.22.9.tgz", @@ -9900,6 +9912,14 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/core-js": { + "version": "2.6.12", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.12.tgz", + "integrity": "sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==", + "deprecated": "core-js@<3.23.3 is no longer maintained and not recommended for usage due to the number of issues. Because of the V8 engine whims, feature detection in old core-js versions could cause a slowdown up to 100x even if nothing is polyfilled. Some versions have web compatibility issues. Please, upgrade your dependencies to the actual version of core-js.", + "dev": true, + "hasInstallScript": true + }, "node_modules/core-js-compat": { "version": "3.32.0", "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.32.0.tgz", @@ -31150,7 +31170,7 @@ } }, "projects/aas-lib": { - "version": "2.0.0", + "version": "3.0.0", "peerDependencies": { "@angular/animations": "^16.1.8", "@angular/common": "^16.1.8", @@ -31168,11 +31188,10 @@ "@ngx-translate/http-loader": "^8.0.0", "@popperjs/core": "^2.11.8", "@xmldom/xmldom": "^0.8.10", - "aas-lib": "2.0.0", "bootstrap": "^5.3.1", "bootstrap-icons": "^1.10.5", "chart.js": "^4.3.3", - "common": "2.0.0", + "common": "3.0.0", "jwt-decode": "^3.1.2", "lodash-es": "^4.17.21", "rxjs": "~7.8.1", @@ -31181,7 +31200,7 @@ } }, "projects/aas-portal": { - "version": "2.0.0", + "version": "3.0.0", "license": "Apache-2.0", "dependencies": { "@angular/animations": "^16.1.8", @@ -31200,11 +31219,11 @@ "@ngx-translate/http-loader": "^8.0.0", "@popperjs/core": "^2.11.8", "@xmldom/xmldom": "^0.8.10", - "aas-lib": "2.0.0", + "aas-lib": "3.0.0", "bootstrap": "^5.3.1", "bootstrap-icons": "^1.10.5", "chart.js": "^4.3.3", - "common": "2.0.0", + "common": "3.0.0", "jwt-decode": "^3.1.2", "lodash-es": "^4.17.21", "rxjs": "~7.8.1", @@ -31250,7 +31269,7 @@ "dependencies": { "@xmldom/xmldom": "^0.8.10", "bcryptjs": "^2.4.3", - "common": "2.0.0", + "common": "3.0.0", "cors": "^2.8.5", "express": "^4.18.2", "form-data": "^4.0.0", @@ -31313,7 +31332,7 @@ "dev": true }, "projects/common": { - "version": "2.0.0", + "version": "3.0.0", "license": "Apache-2.0", "peerDependencies": { "lodash-es": "^4.17.21" @@ -33009,6 +33028,16 @@ "@babel/helper-plugin-utils": "^7.22.5" } }, + "@babel/polyfill": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/polyfill/-/polyfill-7.4.4.tgz", + "integrity": "sha512-WlthFLfhQQhh+A2Gn5NSFl0Huxz36x86Jn+E9OW7ibK8edKPq+KLy4apM1yDpQ8kJOVi1OVjpP4vSDLdrI04dg==", + "dev": true, + "requires": { + "core-js": "^2.6.5", + "regenerator-runtime": "^0.13.2" + } + }, "@babel/preset-env": { "version": "7.22.9", "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.22.9.tgz", @@ -36750,11 +36779,11 @@ "@typescript-eslint/eslint-plugin": "^6.2.1", "@typescript-eslint/parser": "^6.2.1", "@xmldom/xmldom": "^0.8.10", - "aas-lib": "2.0.0", + "aas-lib": "3.0.0", "bootstrap": "^5.3.1", "bootstrap-icons": "^1.10.5", "chart.js": "^4.3.3", - "common": "2.0.0", + "common": "3.0.0", "eslint": "^8.46.0", "jasmine-core": "^5.1.0", "jest": "^29.6.2", @@ -36798,7 +36827,7 @@ "@xmldom/xmldom": "^0.8.10", "babel-plugin-transform-import-meta": "^2.2.1", "bcryptjs": "^2.4.3", - "common": "2.0.0", + "common": "3.0.0", "cors": "^2.8.5", "esbuild": "^0.18.19", "eslint": "^8.46.0", @@ -38491,6 +38520,12 @@ } } }, + "core-js": { + "version": "2.6.12", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.12.tgz", + "integrity": "sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==", + "dev": true + }, "core-js-compat": { "version": "3.32.0", "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.32.0.tgz", diff --git a/package.json b/package.json index 14c8b799..b06ac1ce 100644 --- a/package.json +++ b/package.json @@ -35,6 +35,7 @@ "./projects/aas-portal" ], "devDependencies": { + "@babel/polyfill": "^7.4.4", "@semantic-release/git": "^10.0.1", "@semantic-release/gitlab": "^12.0.5" } diff --git a/projects/aas-lib/package.build.json b/projects/aas-lib/package.build.json index d29d9702..2478f2df 100644 --- a/projects/aas-lib/package.build.json +++ b/projects/aas-lib/package.build.json @@ -29,11 +29,11 @@ "@ngx-translate/http-loader": "^8.0.0", "@popperjs/core": "^2.11.8", "@xmldom/xmldom": "^0.8.10", - "aas-lib": "2.0.0", + "aas-lib": "3.0.0", "bootstrap": "^5.3.1", "bootstrap-icons": "^1.10.5", "chart.js": "^4.3.3", - "common": "2.0.0", + "common": "3.0.0", "jwt-decode": "^3.1.2", "lodash-es": "^4.17.21", "rxjs": "~7.8.1", diff --git a/projects/aas-lib/package.dev.json b/projects/aas-lib/package.dev.json index 7b212e37..9e2f1f1c 100644 --- a/projects/aas-lib/package.dev.json +++ b/projects/aas-lib/package.dev.json @@ -42,11 +42,11 @@ "@ngx-translate/http-loader": "^8.0.0", "@popperjs/core": "^2.11.8", "@xmldom/xmldom": "^0.8.10", - "aas-lib": "2.0.0", + "aas-lib": "3.0.0", "bootstrap": "^5.3.1", "bootstrap-icons": "^1.10.5", "chart.js": "^4.3.3", - "common": "2.0.0", + "common": "3.0.0", "jwt-decode": "^3.1.2", "lodash-es": "^4.17.21", "rxjs": "~7.8.1", diff --git a/projects/aas-lib/package.json b/projects/aas-lib/package.json index 7b212e37..9e2f1f1c 100644 --- a/projects/aas-lib/package.json +++ b/projects/aas-lib/package.json @@ -42,11 +42,11 @@ "@ngx-translate/http-loader": "^8.0.0", "@popperjs/core": "^2.11.8", "@xmldom/xmldom": "^0.8.10", - "aas-lib": "2.0.0", + "aas-lib": "3.0.0", "bootstrap": "^5.3.1", "bootstrap-icons": "^1.10.5", "chart.js": "^4.3.3", - "common": "2.0.0", + "common": "3.0.0", "jwt-decode": "^3.1.2", "lodash-es": "^4.17.21", "rxjs": "~7.8.1", diff --git a/projects/aas-lib/src/lib/auth/auth.interceptor.ts b/projects/aas-lib/src/lib/auth/auth.interceptor.ts index f8d1a627..b9599ded 100644 --- a/projects/aas-lib/src/lib/auth/auth.interceptor.ts +++ b/projects/aas-lib/src/lib/auth/auth.interceptor.ts @@ -12,6 +12,7 @@ import { Observable } from 'rxjs'; @Injectable() export class AuthInterceptor implements HttpInterceptor { + // eslint-disable-next-line @typescript-eslint/no-explicit-any public intercept(req: HttpRequest, next: HttpHandler): Observable> { const token = localStorage.getItem('.Token'); if (token) { diff --git a/projects/aas-lib/src/lib/auth/auth.service.ts b/projects/aas-lib/src/lib/auth/auth.service.ts index 1db7e125..1ff8f2c6 100644 --- a/projects/aas-lib/src/lib/auth/auth.service.ts +++ b/projects/aas-lib/src/lib/auth/auth.service.ts @@ -54,6 +54,8 @@ export class AuthService { } else { token = null; } + } else { + token = null; } if (!token) { diff --git a/projects/aas-portal/package.json b/projects/aas-portal/package.json index 882d216c..2de067f9 100644 --- a/projects/aas-portal/package.json +++ b/projects/aas-portal/package.json @@ -32,11 +32,11 @@ "@ngx-translate/http-loader": "^8.0.0", "@popperjs/core": "^2.11.8", "@xmldom/xmldom": "^0.8.10", - "aas-lib": "2.0.0", + "aas-lib": "3.0.0", "bootstrap": "^5.3.1", "bootstrap-icons": "^1.10.5", "chart.js": "^4.3.3", - "common": "2.0.0", + "common": "3.0.0", "jwt-decode": "^3.1.2", "lodash-es": "^4.17.21", "rxjs": "~7.8.1", diff --git a/projects/aas-server/package.json b/projects/aas-server/package.json index 0fb24f27..3ecd04c7 100644 --- a/projects/aas-server/package.json +++ b/projects/aas-server/package.json @@ -21,7 +21,7 @@ "dependencies": { "@xmldom/xmldom": "^0.8.10", "bcryptjs": "^2.4.3", - "common": "2.0.0", + "common": "3.0.0", "cors": "^2.8.5", "express": "^4.18.2", "form-data": "^4.0.0", diff --git a/projects/aas-server/src/app/aas-provider/directory-scan.ts b/projects/aas-server/src/app/aas-provider/directory-scan.ts index 3afd0aed..53ac2095 100644 --- a/projects/aas-server/src/app/aas-provider/directory-scan.ts +++ b/projects/aas-server/src/app/aas-provider/directory-scan.ts @@ -24,7 +24,7 @@ export class DirectoryScan extends AASResourceScan { public async scanAsync(): Promise { try { await this.source.openAsync() - const files = await this.source.getStorage().readdir('.'); + const files = await this.source.getStorage().readDir('.'); const documents: AASDocument[] = []; for (const file of files) { diff --git a/projects/aas-server/src/app/file-storage/file-storage.ts b/projects/aas-server/src/app/file-storage/file-storage.ts index 6dfda46f..5d1d6164 100644 --- a/projects/aas-server/src/app/file-storage/file-storage.ts +++ b/projects/aas-server/src/app/file-storage/file-storage.ts @@ -14,7 +14,7 @@ export abstract class FileStorage { public abstract isDirectory(path: string): Promise; public abstract mkdir(path: string, recursive?: boolean): Promise; public abstract writeFile(path: string, data: string | Buffer): Promise; - public abstract readdir(path: string): Promise; + public abstract readDir(path: string): Promise; public abstract readFile(path: string): Promise; public abstract unlink(path: string): Promise; public abstract rename(oldPath: string, newPath: string): Promise; diff --git a/projects/aas-server/src/app/file-storage/local-file-storage.ts b/projects/aas-server/src/app/file-storage/local-file-storage.ts index bc61d978..728065cf 100644 --- a/projects/aas-server/src/app/file-storage/local-file-storage.ts +++ b/projects/aas-server/src/app/file-storage/local-file-storage.ts @@ -24,7 +24,7 @@ export class LocalFileStorage extends FileStorage { } public exists(path: string): Promise { - return new Promise(res => res(fs.existsSync(resolve(this.root, path)))); + return Promise.resolve(fs.existsSync(resolve(this.root, path))); } public async isDirectory(path: string): Promise { @@ -39,7 +39,7 @@ export class LocalFileStorage extends FileStorage { return fs.promises.writeFile(resolve(this.root, path), data); } - public readdir(path: string): Promise { + public readDir(path: string): Promise { return fs.promises.readdir(resolve(this.root, path)); } diff --git a/projects/aas-server/src/app/file-storage/own-cloud-storage.ts b/projects/aas-server/src/app/file-storage/own-cloud-storage.ts index 0ea592cb..bb1e0fec 100644 --- a/projects/aas-server/src/app/file-storage/own-cloud-storage.ts +++ b/projects/aas-server/src/app/file-storage/own-cloud-storage.ts @@ -10,40 +10,56 @@ import { FileStorage } from './file-storage.js'; import ownCloud, { OwnCloudOptions } from 'owncloud-sdk'; export class OwnCloudStorage extends FileStorage { + private promise: Promise; + private oc: ownCloud; - public readonly root: string = '/'; + constructor(arg: string | URL) { + super(); - public async connect(url: string): Promise { - const temp = new URL(url); - const username = temp.username; - const password = temp.password; - temp.username = ''; - temp.password = ''; + const url = typeof arg === 'string' ? new URL(arg) : arg; + const username = url.username; + const password = url.password; + url.username = ''; + url.password = ''; const options: OwnCloudOptions = { - baseUrl: temp.href + baseUrl: url.href } if (username && password) { options.auth = { basic: { username, password } }; } - const oc = new ownCloud(options); - - await oc.login(); + this.oc = new ownCloud(options); + this.promise = this.oc.login(); } + public readonly root: string = '/'; + public mtime(path: string): Promise { throw new Error('Method not implemented.'); } - public exists(path: string): Promise { - throw new Error('Method not implemented.'); + public async exists(path: string): Promise { + try { + await this.promise; + const fileInfo = await this.oc.files.fileInfo(path, {}); + return fileInfo != null; + } catch (error) { + throw error; + } } - public isDirectory(path: string): Promise { - throw new Error('Method not implemented.'); + public async isDirectory(path: string): Promise { + try { + await this.promise; + const fileInfo = await this.oc.files.fileInfo(path, {}); + return fileInfo.isDir(); + } catch (error) { + throw error; + } } + public mkdir(path: string, recursive?: boolean | undefined): Promise { throw new Error('Method not implemented.'); } @@ -52,8 +68,11 @@ export class OwnCloudStorage extends FileStorage { throw new Error('Method not implemented.'); } - public readdir(path: string): Promise { - throw new Error('Method not implemented.'); + public async readDir(path: string): Promise { + await this.promise; + const fileInfo = await this.oc.files.fileInfo(path, {}); + console.log(fileInfo?.isDir); + return []; } public readFile(path: string): Promise { diff --git a/projects/aas-server/src/app/template/locale-template-storage.ts b/projects/aas-server/src/app/template/locale-template-storage.ts deleted file mode 100644 index e143d057..00000000 --- a/projects/aas-server/src/app/template/locale-template-storage.ts +++ /dev/null @@ -1,86 +0,0 @@ -/****************************************************************************** - * - * Copyright (c) 2019-2023 Fraunhofer IOSB-INA Lemgo, - * eine rechtlich nicht selbstaendige Einrichtung der Fraunhofer-Gesellschaft - * zur Foerderung der angewandten Forschung e.V. - * - *****************************************************************************/ - -import { inject, singleton } from 'tsyringe'; -import fs from 'fs'; -import path from 'path'; -import { TemplateDescriptor, aas } from 'common'; -import { Logger } from '../logging/logger.js'; -import { readdir, readFile } from 'fs/promises'; -import { JsonReader } from '../packages/json-reader.js'; -import { AASReader } from '../packages/aas-reader.js'; -import { JsonReaderV2 } from '../packages/json-reader-v2.js'; -import * as aasV2 from '../types/aas-v2.js'; -import { TemplateStorage } from './template-storage.js'; -import { Variable } from '../variable.js'; - -@singleton() -export class LocalTemplateStorage extends TemplateStorage { - private readonly dir: string; - - constructor( - @inject('Logger') private readonly logger: Logger, - @inject(Variable) variable: Variable - ) { - super(); - - this.dir = path.resolve(variable.ASSETS, 'templates'); - } - - public override async readAsync(): Promise { - const descriptors: TemplateDescriptor[] = []; - if (fs.existsSync(this.dir)) { - await this.readDirAsync(this.dir, descriptors) - } - - return descriptors; - } - - private async readDirAsync(dir: string, descriptors: TemplateDescriptor[]): Promise { - for (const entry of await readdir(dir, { withFileTypes: true })) { - if (entry.isFile()) { - const file = path.join(dir, entry.name); - const format = path.extname(file).toLowerCase(); - switch (format) { - case '.json': - descriptors.push({ - name: path.basename(file, path.extname(format)), - endpoint: { type: 'file', address: file }, - format: '.json', - template: await this.readTemplateAsync(file) - }); - break; - - case '.xml': - throw new Error(`Template format '${format}' is not implemented`); - } - } - else if (entry.isDirectory()) { - await this.readDirAsync(path.join(dir, entry.name), descriptors); - } - } - } - - private async readTemplateAsync(file: string): Promise { - const referable = JSON.parse((await readFile(file)).toString()); - const reader = this.createReader(referable); - return reader.read(referable); - } - - private createReader(referable: object): AASReader { - if (typeof (referable as aas.Referable).modelType === 'string') { - return new JsonReader(this.logger); - } - - if (typeof (referable as aasV2.Referable).modelType?.name === 'string') { - return new JsonReaderV2(this.logger); - } - - throw new Error('Not implemented.'); - } -} \ No newline at end of file diff --git a/projects/aas-server/src/app/template/template-storage-factory.ts b/projects/aas-server/src/app/template/template-storage-factory.ts index e9cd1164..2bf66037 100644 --- a/projects/aas-server/src/app/template/template-storage-factory.ts +++ b/projects/aas-server/src/app/template/template-storage-factory.ts @@ -6,20 +6,30 @@ * *****************************************************************************/ +import path from 'path'; import { DependencyContainer } from 'tsyringe'; import { TemplateStorage } from './template-storage.js'; import { Variable } from '../variable.js'; -import { LocalTemplateStorage } from './locale-template-storage.js'; +import { OwnCloudStorage } from '../file-storage/own-cloud-storage.js'; +import { FileStorage } from '../file-storage/file-storage.js'; +import { LocalFileStorage } from '../file-storage/local-file-storage.js'; +import { Logger } from '../logging/logger.js'; export class TemplateStorageFactory { - constructor(private readonly container: DependencyContainer) { } + constructor( + private readonly container: DependencyContainer + ) { } public create(): TemplateStorage { - const url = this.container.resolve(Variable).TEMPLATE_STORAGE; + let fileStorage: FileStorage; + const variable = this.container.resolve(Variable); + const url = variable.TEMPLATE_STORAGE; if (url) { - throw new Error('Not implemented.'); + fileStorage = new OwnCloudStorage(url); + } else { + fileStorage = new LocalFileStorage(path.resolve(variable.ASSETS, 'templates')); } - return this.container.resolve(LocalTemplateStorage); + return new TemplateStorage(this.container.resolve('Logger'), fileStorage); } } \ No newline at end of file diff --git a/projects/aas-server/src/app/template/template-storage.ts b/projects/aas-server/src/app/template/template-storage.ts index 59d74c2e..5834658d 100644 --- a/projects/aas-server/src/app/template/template-storage.ts +++ b/projects/aas-server/src/app/template/template-storage.ts @@ -6,8 +6,69 @@ * *****************************************************************************/ -import { TemplateDescriptor } from 'common'; +import * as $path from 'path'; +import { TemplateDescriptor, aas } from 'common'; +import { Logger } from '../logging/logger.js'; +import { FileStorage } from '../file-storage/file-storage.js'; +import { AASReader } from '../packages/aas-reader.js'; +import { JsonReader } from '../packages/json-reader.js'; +import { JsonReaderV2 } from '../packages/json-reader-v2.js'; +import * as aasV2 from '../types/aas-v2.js'; -export abstract class TemplateStorage { - public abstract readAsync(): Promise; +export class TemplateStorage { + constructor( + private readonly logger: Logger, + private readonly fileStorage: FileStorage + ) { } + + public async readAsync(): Promise { + const descriptors: TemplateDescriptor[] = []; + if (await this.fileStorage.exists(this.fileStorage.root)) { + await this.readDirAsync(this.fileStorage.root, descriptors) + } + + return descriptors; + } + + private async readDirAsync(dir: string, descriptors: TemplateDescriptor[]): Promise { + for (const entry of await this.fileStorage.readDir(dir)) { + const path = $path.join(dir, entry); + if (await this.fileStorage.isDirectory(path)) { + await this.readDirAsync(path, descriptors) + } else { + const format = $path.extname(path).toLowerCase(); + switch (format) { + case '.json': + descriptors.push({ + name: $path.basename(path, $path.extname(format)), + endpoint: { type: 'file', address: path }, + format: '.json', + template: await this.readTemplateAsync(path) + }); + break; + + case '.xml': + throw new Error(`Template format '${format}' is not implemented`); + } + } + } + } + + private async readTemplateAsync(file: string): Promise { + const referable = JSON.parse((await this.fileStorage.readFile(file)).toString()); + const reader = this.createReader(referable); + return reader.read(referable); + } + + private createReader(referable: object): AASReader { + if (typeof (referable as aas.Referable).modelType === 'string') { + return new JsonReader(this.logger); + } + + if (typeof (referable as aasV2.Referable).modelType?.name === 'string') { + return new JsonReaderV2(this.logger); + } + + throw new Error('Not implemented.'); + } } \ No newline at end of file diff --git a/projects/aas-server/src/app/types/owncloud-sdk.d.ts b/projects/aas-server/src/app/types/owncloud-sdk.d.ts index e798937c..6823598b 100644 --- a/projects/aas-server/src/app/types/owncloud-sdk.d.ts +++ b/projects/aas-server/src/app/types/owncloud-sdk.d.ts @@ -9,7 +9,8 @@ declare module 'owncloud-sdk' { export interface OwnCloudAuthentication { - basic?: { username: string; password: string; } + basic?: { username: string; password: string; }; + bearer?: string; } export interface OwnCloudOptions { @@ -17,9 +18,41 @@ declare module 'owncloud-sdk' { auth?: OwnCloudAuthentication; } + export class FileInfo { + public name: string; + public type: string; + public processing: boolean; + public fileInfo: { [key: string]: string }; + + public getName(): string; + public getPath(): string; + public getSize(): number; + public getFileId(): number; + public getContentType(): string; + public getLastModified(): string; + public getProperty(property: string): string; + public isDir(): boolean; + } + + export class Files { + public list(path: string, depth = '1', properties: { [key: string]: string } = {}): Promise; + public getFileContents(path: string, options?: { [key: string]: string }): Promise; + public getFileUrl(path: string): string; + public getPathForFileId(fileId: number): Promise; + public putFileContents(path: string, content: string, options: { [key: string]: string } = {}): Promise; + public createFolder(path: string): Promise; + public delete(path: string): Promise; + public fileInfo(path: string, properties: { [key: string]: string }): Promise; + public move (source: string, target: string, overwrite = false): Promise; + public copy (source: string, target: string, overwrite = false): Promise; + } + export default class ownCloud { constructor(options?: OwnCloudOptions); - public login(): Promise; + public files: Files; + + public login(): Promise; + public logout(): void; } } diff --git a/projects/aas-server/src/app/ws-server.ts b/projects/aas-server/src/app/ws-server.ts index 01a242cf..cb0bcd1b 100644 --- a/projects/aas-server/src/app/ws-server.ts +++ b/projects/aas-server/src/app/ws-server.ts @@ -1,3 +1,11 @@ +/****************************************************************************** + * + * Copyright (c) 2019-2023 Fraunhofer IOSB-INA Lemgo, + * eine rechtlich nicht selbstaendige Einrichtung der Fraunhofer-Gesellschaft + * zur Foerderung der angewandten Forschung e.V. + * + *****************************************************************************/ + import { inject, singleton } from 'tsyringe'; import { WebSocket, WebSocketServer } from 'ws'; import http from 'http'; diff --git a/projects/aas-server/src/test/template/template-storage.spec.ts b/projects/aas-server/src/test/template/template-storage.spec.ts new file mode 100644 index 00000000..922dcbf7 --- /dev/null +++ b/projects/aas-server/src/test/template/template-storage.spec.ts @@ -0,0 +1,49 @@ +/****************************************************************************** + * + * Copyright (c) 2019-2023 Fraunhofer IOSB-INA Lemgo, + * eine rechtlich nicht selbstaendige Einrichtung der Fraunhofer-Gesellschaft + * zur Foerderung der angewandten Forschung e.V. + * + *****************************************************************************/ + +import { describe, beforeEach, it, expect, jest } from '@jest/globals'; +import { TemplateStorage } from '../../app/template/template-storage.js'; +import { createSpyObj } from '../utils.js'; +import { Logger } from '../../app/logging/logger.js'; +import { FileStorage } from '../../app/file-storage/file-storage.js'; +import { aas } from 'common'; + +describe('TemplateStorage', function () { + let templateStorage: TemplateStorage; + let logger: jest.Mocked; + let fileStorage: jest.Mocked; + + beforeEach(function () { + logger = createSpyObj(['error']); + fileStorage = createSpyObj(['exists', 'readDir', 'readFile']); + templateStorage = new TemplateStorage(logger, fileStorage); + }) + + it('should create', function () { + expect(templateStorage).toBeTruthy(); + }); + + describe('readAsync', function () { + let submodel: aas.Submodel; + + beforeEach(function() { + submodel = { + id: 'http://aas/submodel', + idShort: 'aSubmodel', + modelType: 'Submodel' + }; + }); + + it('reads all available templates', async function () { + fileStorage.exists.mockResolvedValue(true); + fileStorage.readDir.mockResolvedValue(['submodel.json']); + fileStorage.readFile.mockResolvedValue(Buffer.from(JSON.stringify({submodel}))); + await expect(templateStorage.readAsync()).resolves.toEqual([submodel]); + }); + }); +}); \ No newline at end of file