diff --git a/apps/server/src/apps/h5p-library-management.app.ts b/apps/server/src/apps/h5p-library-management.app.ts index 3e16585e154..ced9d50b24d 100644 --- a/apps/server/src/apps/h5p-library-management.app.ts +++ b/apps/server/src/apps/h5p-library-management.app.ts @@ -7,10 +7,7 @@ import { install as sourceMapInstall } from 'source-map-support'; // application imports import { LegacyLogger } from '@src/core/logger'; -import { - H5PLibraryManagementModule, - H5PLibraryManagementService, -} from '@modules/h5p-library-management/h5p-library-management.module'; +import { H5PLibraryManagementModule, H5PLibraryManagementService } from '@modules/h5p-library-management'; async function bootstrap() { sourceMapInstall(); @@ -28,7 +25,6 @@ async function bootstrap() { // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access await nestApp.get(H5PLibraryManagementService).run(); - // await app.get(H5PLibraryManagementService).run(); // TODO: properly close app (there is some issue with the logger) console.log('#########################################'); console.log(`##### Close H5P Library Management ######`); diff --git a/apps/server/src/modules/h5p-editor/index.ts b/apps/server/src/modules/h5p-editor/index.ts index f8808788441..b8565a944c2 100644 --- a/apps/server/src/modules/h5p-editor/index.ts +++ b/apps/server/src/modules/h5p-editor/index.ts @@ -1 +1,3 @@ -export * from './h5p-editor.module'; +export { H5PEditorModule } from './h5p-editor.module'; +export { ContentStorage, LibraryStorage } from './service'; +export { s3ConfigContent, s3ConfigLibraries } from './h5p-editor.config'; diff --git a/apps/server/src/modules/h5p-library-management/h5p-library-management.module.ts b/apps/server/src/modules/h5p-library-management/h5p-library-management.module.ts index 08371accee4..8248aa55870 100644 --- a/apps/server/src/modules/h5p-library-management/h5p-library-management.module.ts +++ b/apps/server/src/modules/h5p-library-management/h5p-library-management.module.ts @@ -8,13 +8,14 @@ import { S3ClientModule } from '@infra/s3-client'; import { DB_PASSWORD, DB_URL, DB_USERNAME, createConfigModuleOptions } from '@src/config'; import { CoreModule } from '@src/core'; import { Logger } from '@src/core/logger'; -import { UserModule } from '../user'; -import { s3ConfigContent, s3ConfigLibraries } from '../h5p-editor/h5p-editor.config'; -import { H5PContentRepo, LibraryRepo } from '../h5p-editor/repo'; -import { ContentStorage, LibraryStorage } from '../h5p-editor/service'; -import { H5PContent, InstalledLibrary } from '../h5p-editor/entity'; -import { H5PLibraryManagementService } from './service/h5p-library-management.service'; -import { h5PLibraryManagementConfig } from './service/h5p-library-management.config'; +import { H5PEditorModule, s3ConfigContent, s3ConfigLibraries } from '@modules/h5p-editor'; +// This export is always invalid. It is not allow to export repos or entities. +// In context of no domain object exists maybe it is ok. But i think it is not needed. +// All this database / mikroORM Stuff is done in H5PEditorModule. +// If yes remove exports from modules/h5p-editor/index.ts +// import { H5PEditorModule, s3ConfigContent, s3ConfigLibraries } from '@modules/h5p-editor'; +import { H5PContent, InstalledLibrary } from '@modules/h5p-editor/entity'; +import { H5PLibraryManagementService, h5PLibraryManagementConfig } from './service'; const defaultMikroOrmOptions: MikroOrmModuleSyncOptions = { findOneOrFailHandler: (entityName: string, where: Dictionary | IPrimaryKey) => @@ -25,7 +26,7 @@ const defaultMikroOrmOptions: MikroOrmModuleSyncOptions = { const imports = [ ConfigModule.forRoot(createConfigModuleOptions(h5PLibraryManagementConfig)), CoreModule, - UserModule, + H5PEditorModule, RabbitMQWrapperModule, MikroOrmModule.forRoot({ ...defaultMikroOrmOptions, @@ -34,7 +35,7 @@ const imports = [ clientUrl: DB_URL, password: DB_PASSWORD, user: DB_USERNAME, - allowGlobalContext: true, + // allowGlobalContext: true, Please not entities: [...ALL_ENTITIES, H5PContent, InstalledLibrary], }), S3ClientModule.register([s3ConfigContent, s3ConfigLibraries]), @@ -42,13 +43,12 @@ const imports = [ const controllers = []; -const providers = [Logger, H5PLibraryManagementService, ContentStorage, H5PContentRepo, LibraryRepo, LibraryStorage]; +const providers = [Logger, H5PLibraryManagementService]; @Module({ imports, controllers, providers, - exports: [H5PLibraryManagementService], + exports: [], }) export class H5PLibraryManagementModule {} -export { H5PLibraryManagementService }; diff --git a/apps/server/src/modules/h5p-library-management/index.ts b/apps/server/src/modules/h5p-library-management/index.ts new file mode 100644 index 00000000000..442c5dac91d --- /dev/null +++ b/apps/server/src/modules/h5p-library-management/index.ts @@ -0,0 +1,2 @@ +export { H5PLibraryManagementModule } from './h5p-library-management.module'; +export { H5PLibraryManagementService } from './service'; diff --git a/apps/server/src/modules/h5p-library-management/service/h5p-library-management.service.ts b/apps/server/src/modules/h5p-library-management/service/h5p-library-management.service.ts index 31d8479a554..a63ad7953b2 100644 --- a/apps/server/src/modules/h5p-library-management/service/h5p-library-management.service.ts +++ b/apps/server/src/modules/h5p-library-management/service/h5p-library-management.service.ts @@ -9,11 +9,12 @@ import { } from '@lumieducation/h5p-server'; import ContentManager from '@lumieducation/h5p-server/build/src/ContentManager'; import ContentTypeInformationRepository from '@lumieducation/h5p-server/build/src/ContentTypeInformationRepository'; -import { Injectable, NotFoundException } from '@nestjs/common'; -import { ContentStorage, LibraryStorage } from '@src/modules/h5p-editor/service'; +import { Injectable, InternalServerErrorException, NotFoundException } from '@nestjs/common'; +import { ContentStorage, LibraryStorage } from '@src/modules/h5p-editor'; import { readFileSync } from 'fs'; import { parse } from 'yaml'; import { ConfigService } from '@nestjs/config'; +import { IHubContentType } from '@lumieducation/h5p-server/build/src/types'; import { IH5PLibraryManagementConfig } from './h5p-library-management.config'; const h5pConfig = new H5PConfig(undefined, { @@ -26,16 +27,28 @@ interface LibrariesContentType { h5p_libraries: string[]; } -function isLibrariesContentType(object: any): object is LibrariesContentType { - return 'h5p_libraries' in object; -} +function isLibrariesContentType(object: unknown): object is LibrariesContentType { + const isType = + typeof object === 'object' && + !Array.isArray(object) && + object !== null && + 'h5p_libraries' in object && + Array.isArray(object.h5p_libraries); -function isUserType(object: any): object is IUser { - return true; + return isType; } +const castToLibrariesContentType = (object: unknown): LibrariesContentType => { + if (!isLibrariesContentType(object)) { + throw new InternalServerErrorException('Invalid input type for castToLibrariesContentType'); + } + + return object; +}; + @Injectable() export class H5PLibraryManagementService { + // should all this prop private? contentTypeCache: ContentTypeCache; contentTypeRepo: ContentTypeInformationRepository; @@ -66,11 +79,10 @@ export class H5PLibraryManagementService { const contentManager = new ContentManager(this.contentStorage); this.libraryAdministration = new LibraryAdministration(this.libraryManager, contentManager); const filePath = this.configService.get('H5P_EDITOR__LIBRARY_LIST_PATH'); + const librariesYamlContent = readFileSync(filePath, { encoding: 'utf-8' }); - this.libraryWishList = []; - if (isLibrariesContentType(parse(librariesYamlContent))) { - this.libraryWishList = (parse(librariesYamlContent) as LibrariesContentType).h5p_libraries; - } + const librariesContentType = castToLibrariesContentType(parse(librariesYamlContent)); + this.libraryWishList = librariesContentType.h5p_libraries; } public async uninstallUnwantedLibraries( @@ -95,17 +107,14 @@ export class H5PLibraryManagementService { ); } - public async installLibraries(librariesToInstall: string[]): Promise { - if (librariesToInstall.length === 0) { - return; - } - const lastPositionLibrariesToInstallArray = librariesToInstall.length - 1; - // avoid conflicts, install one-by-one: - const contentType = await this.contentTypeCache.get(librariesToInstall[lastPositionLibrariesToInstallArray]); + private checkContentTypeExists(contentType: IHubContentType[]): void { if (contentType === undefined) { throw new NotFoundException('this library does not exist'); } - const userObj = { + } + + private createDefaultIUser(): IUser { + const user: IUser = { canCreateRestricted: true, canInstallRecommended: true, canUpdateAndInstallLibraries: true, @@ -114,11 +123,23 @@ export class H5PLibraryManagementService { name: 'a', type: 'local', }; - if (isUserType(userObj)) { - const user: IUser = userObj; - await this.contentTypeRepo.installContentType(librariesToInstall[lastPositionLibrariesToInstallArray], user); - await this.installLibraries(librariesToInstall.slice(0, lastPositionLibrariesToInstallArray)); + + return user; + } + + public async installLibraries(librariesToInstall: string[]): Promise { + if (librariesToInstall.length === 0) { + return; } + const lastPositionLibrariesToInstallArray = librariesToInstall.length - 1; + // avoid conflicts, install one-by-one: + const contentType = await this.contentTypeCache.get(librariesToInstall[lastPositionLibrariesToInstallArray]); + this.checkContentTypeExists(contentType); + + const user = this.createDefaultIUser(); + + await this.contentTypeRepo.installContentType(librariesToInstall[lastPositionLibrariesToInstallArray], user); + await this.installLibraries(librariesToInstall.slice(0, lastPositionLibrariesToInstallArray)); } public async run(): Promise { diff --git a/apps/server/src/modules/h5p-library-management/service/index.ts b/apps/server/src/modules/h5p-library-management/service/index.ts new file mode 100644 index 00000000000..01ed55caf01 --- /dev/null +++ b/apps/server/src/modules/h5p-library-management/service/index.ts @@ -0,0 +1,2 @@ +export * from './h5p-library-management.service'; +export * from './h5p-library-management.config';