Skip to content

Commit

Permalink
adds js-yaml and updated from PR feedback
Browse files Browse the repository at this point in the history
  • Loading branch information
nichlaes committed Nov 13, 2024
1 parent 787c8e9 commit 243ce87
Show file tree
Hide file tree
Showing 20 changed files with 169 additions and 68 deletions.
12 changes: 12 additions & 0 deletions servers/lib/libms.yaml.sample
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
port: '4001'
mode: 'git'
local-path: '..\\..\\files\\test'
log-level: 'debug'
apollo-path: '/lib'
graphql-playground: 'true'

git-repos:
- user-1:
repo-url: 'https://github.com/isomorphic-git/lightning-fs'
- user-2:
repo-url: 'https://github.com/isomorphic-git/lightning-fs'
6 changes: 4 additions & 2 deletions servers/lib/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@into-cps-association/libms",
"version": "0.5.0",
"version": "0.5.1",
"description": "microservices that handles request by fetching and returning the file-names and folders of given directory",
"author": "phillip.boe.jensen@gmail.com",
"contributors": [
Expand Down Expand Up @@ -50,6 +50,7 @@
"globals": "^15.11.0",
"graphql": "^16.9.0",
"isomorphic-git": "^1.27.1",
"js-yaml": "^4.1.0",
"mock-fs": "^5.3.0",
"reflect-metadata": "^0.2.2",
"rxjs": "^7.8.1",
Expand Down Expand Up @@ -83,6 +84,7 @@
"ts-jest": "^29.2.5",
"ts-node": "^10.9.2",
"tsconfig-paths": "4.2.0",
"typescript": "^5.6.3"
"typescript": "^5.6.3",
"@types/js-yaml": "^4.0.9"
}
}
13 changes: 6 additions & 7 deletions servers/lib/src/app.module.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,21 @@
import { ConfigModule, ConfigService } from '@nestjs/config';
import { Module } from '@nestjs/common';
import { GraphQLModule } from '@nestjs/graphql';
import { ApolloDriver } from '@nestjs/apollo';
import { join } from 'path';
import FilesModule from './files/files.module.js';
import Config from './config/config.service.js';
import { ConfigModule } from './config/config.module.js';

@Module({
imports: [
ConfigModule.forRoot({
isGlobal: true,
}),
ConfigModule,
GraphQLModule.forRootAsync({
driver: ApolloDriver,
useFactory: (configService: ConfigService) => ({
useFactory: (configService: Config) => ({
autoSchemaFile: join(process.cwd(), 'src/schema.gql'),
path: configService.get<string>('APOLLO_PATH'),
path: configService.getApolloPath(),
}),
inject: [ConfigService],
inject: [Config],
}),
FilesModule,
],
Expand Down
30 changes: 15 additions & 15 deletions servers/lib/src/bootstrap.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { NestFactory } from '@nestjs/core';
import { ConfigService } from '@nestjs/config';
import * as dotenv from 'dotenv';
import AppModule from './app.module.js';
import cloudCMD from './cloudcmd/cloudcmd.js';
import Config from './config/config.service.js';
import { Logger } from '@nestjs/common';

type BootstrapOptions = {
config?: string;
Expand All @@ -11,30 +11,30 @@ type BootstrapOptions = {
};

export default async function bootstrap(options?: BootstrapOptions) {
const configFile = dotenv.config({
path: options?.config ?? '.env',
override: true,
});
if (configFile.error && process.env.LOCAL_PATH === undefined) {
// eslint-disable-next-line no-console
console.error(configFile.error);
const logger = new Logger(bootstrap.name);

if (options.config === undefined) {
this.logger.error('No configuration file was provided');
if (options.runHelp) {
options.runHelp();
} else {
process.exit(1);
}
}
process.env.LIBMS_CONFIG_PATH = options.config;

const app = await NestFactory.create(AppModule);
const configService = app.get(ConfigService);
const port = configService.get<number>('PORT');
const localPath = configService.get<string>('LOCAL_PATH');
const mode = configService.get<string>('MODE');
const configService = app.get(Config);
const port = configService.getPort();
const localPath = configService.getLocalPath();
const mode = configService.getMode();

console.log(`\x1b[32mStarting libms in \x1b[33m${mode} \x1b[32mmode, serving files from \x1b[34m${localPath} \x1b[32mon port \x1b[35m${port}\x1b[0m`);
logger.log(
`\x1b[32mStarting libms in \x1b[33m${mode} \x1b[32mmode, serving files from \x1b[34m${localPath} \x1b[32mon port \x1b[35m${port}\x1b[0m`,
);

if (options.httpServer) {
cloudCMD(app, options.httpServer, configService.get<string>('LOCAL_PATH'));
cloudCMD(app, options.httpServer, configService.getLocalPath());
}

await app.listen(port);
Expand Down
13 changes: 13 additions & 0 deletions servers/lib/src/config/config.model.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
export type ConfigValues = {
'port': number;
'local-path': string;
'mode': string;
'log-level': string;
'apollo-path': string;
'graphql-playground': string;
'git-repos': {[key: string]: GitRepo}[];
};

export type GitRepo = {
'repo-url': string;
};
22 changes: 22 additions & 0 deletions servers/lib/src/config/config.module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { Global, Module } from '@nestjs/common';
import Config from './config.service.js';
import * as nestConfig from '@nestjs/config';

@Global()
@Module({
imports: [nestConfig.ConfigModule.forRoot({ isGlobal: true })],
providers: [
{
provide: Config,
useFactory: async (envConfigservice: nestConfig.ConfigService) => {
const confPath = envConfigservice.get<string>('LIBMS_CONFIG_PATH');
const config = new Config();
await config.loadConfig(confPath);
return config;
},
inject: [nestConfig.ConfigService],
},
],
exports: [Config],
})
export class ConfigModule {}
50 changes: 50 additions & 0 deletions servers/lib/src/config/config.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { readFileSync } from 'fs';
import * as yaml from 'js-yaml';
import { Injectable, Logger } from '@nestjs/common';
import {ConfigValues, GitRepo } from './config.model.js';
import resolveFile from './util.js';

@Injectable()
export default class Config {
private configValues: ConfigValues;
private logger: Logger;

constructor() {
this.logger = new Logger(Config.name);
}

async loadConfig(configPath: string): Promise<void> {
if (configPath !== undefined) {
this.configValues = yaml.load(
readFileSync(resolveFile(configPath), 'utf8'),
) as ConfigValues;
}
this.logger.log('Config loaded', this.configValues);

}

getLocalPath(): string {
return this.configValues['local-path'];
}

getApolloPath(): string {
return this.configValues['apollo-path'];
}

getMode(): string {
return this.configValues['mode'];
}

getPort(): number {
return this.configValues['port'];
}
getLogLevel(): string {
return this.configValues['log-level'];
}
getGraphqlPlayground(): string {
return this.configValues['graphql-playground'];
}
getGitRepos(): {[key: string]: GitRepo}[] {
return this.configValues['git-repos'];
}
}
5 changes: 5 additions & 0 deletions servers/lib/src/config/util.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import path from 'node:path';

export default function resolveFile(name: string): string {
return path.resolve(name);
}
6 changes: 3 additions & 3 deletions servers/lib/src/files/files-service.factory.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import { Injectable } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { IFilesService } from './interfaces/files.service.interface.js';
import Config from 'src/config/config.service.js';

@Injectable()
export default class FilesServiceFactory {
static async create(
configService: ConfigService,
configService: Config,
fileServices: IFilesService[],
): Promise<IFilesService> {
const mode = configService.get<string>('MODE');
const mode = configService.getMode();
const service = fileServices.find((s) => s.getMode() == mode);

if (service == undefined) {
Expand Down
6 changes: 3 additions & 3 deletions servers/lib/src/files/files.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import LocalFilesService from './local/local-files.service.js';
import GitFilesService from './git/git-files.service.js';
import { FILE_SERVICE } from './interfaces/files.service.interface.js';
import FilesServiceFactory from './files-service.factory.js';
import { ConfigService } from '@nestjs/config';
import Config from '../config/config.service.js';

@Module({
imports: [LocalFilesModule, GitFilesModule],
Expand All @@ -15,14 +15,14 @@ import { ConfigService } from '@nestjs/config';
{
provide: FILE_SERVICE,
useFactory: async (
configService: ConfigService,
configService: Config,
localFilesService: LocalFilesService,
gitFilesService: GitFilesService,
) => {
const fileServices = [localFilesService, gitFilesService];
return await FilesServiceFactory.create(configService, fileServices);
},
inject: [ConfigService, LocalFilesService, GitFilesService],
inject: [Config, LocalFilesService, GitFilesService],
},
],
})
Expand Down
34 changes: 12 additions & 22 deletions servers/lib/src/files/git/git-files.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,56 +2,46 @@ import { Inject, Injectable, Logger } from '@nestjs/common';
import { Project } from 'src/types.js';
import { IFilesService } from '../interfaces/files.service.interface.js';
import { CONFIG_MODE } from '../../enums/config-mode.enum.js';
import { ConfigService } from '@nestjs/config';
import * as git from 'isomorphic-git';
import * as fs from 'fs';
import * as http from 'isomorphic-git/http/node/index.cjs';
import LocalFilesService from '../local/local-files.service.js';
import Config from '../../config/config.service.js';

@Injectable()
export default class GitFilesService implements IFilesService {
private readonly dataPath: string;
private readonly logger: Logger;
@Inject(LocalFilesService) private localFilesService: LocalFilesService;

constructor(private configService: ConfigService) {
this.dataPath = this.configService.get('LOCAL_PATH');
constructor(private configService: Config) {
this.dataPath = this.configService.getLocalPath();
this.logger = new Logger(GitFilesService.name);
}


async init(): Promise<void> {
await this.cloneRepositories();
}

private cloneRepositories(): Promise<void[]> {
let userRepoUrl = '';
let userRepoUrls = [];
let userCounter = 1;
while (
(userRepoUrl = this.configService.get(
`GIT_USER${userCounter}_REPO_URL`,
)) !== undefined
) {
userRepoUrls.push(
userRepoUrl.includes('.git') ? userRepoUrl : userRepoUrl + '.git',
);
++userCounter;
}
const userRepoConfigs = this.configService.getGitRepos();

const clonePromises = userRepoConfigs.map((repoConf) => {
const user = Object.keys(repoConf)[0];
const repoUrl = repoConf[user]['repo-url'];

const clonePromises = userRepoUrls.map((userRepoUrl, i) => {
return git
.clone({
fs,
http,
dir: this.dataPath + `/user${i + 1}`,
url: userRepoUrl,
dir: this.dataPath + `/${user}`,
url: repoUrl.includes('.git') ? repoUrl : repoUrl + '.git',
ref: 'main',
singleBranch: true,
depth: 1,
})
.then(() => this.logger.log('done cloning ' + userRepoUrl));
.then(() => this.logger.log('done cloning ' + repoUrl));
});

return Promise.all(clonePromises);
}

Expand Down
6 changes: 3 additions & 3 deletions servers/lib/src/files/local/local-files.service.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
import { Injectable, InternalServerErrorException } from '@nestjs/common';
import * as fs from 'fs';
import { join } from 'path';
import { ConfigService } from '@nestjs/config';
import { Project } from 'src/types.js';
import { IFilesService } from '../interfaces/files.service.interface.js';
import { CONFIG_MODE } from '../../enums/config-mode.enum.js';
import Config from '../../config/config.service.js';

@Injectable()
export default class LocalFilesService implements IFilesService {
private readonly dataPath: string;

constructor(private configService: ConfigService) {
this.dataPath = this.configService.get('LOCAL_PATH');
constructor(private configService: Config) {
this.dataPath = this.configService.getLocalPath();
}

init(): Promise<void> {
Expand Down
2 changes: 1 addition & 1 deletion servers/lib/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import { Command } from 'commander';
import bootstrap from './bootstrap.js';

type ProgramOptions = {
export type ProgramOptions = {
config?: string;
http?: string;
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
import GitFilesService from '../../src/files/git/git-files.service';
import { FILE_SERVICE } from '../../src/files/interfaces/files.service.interface';
import FilesServiceFactory from '../../src/files/files-service.factory';
import Config from '../../src/config/config.service';

describe('Integration tests for FilesResolver', () => {
let filesResolver: FilesResolver;
Expand All @@ -26,7 +27,7 @@ describe('Integration tests for FilesResolver', () => {
{
provide: FILE_SERVICE,
useFactory: async (
configService: ConfigService,
configService: Config,
localFilesService: LocalFilesService,
gitFilesService: GitFilesService,
) => {
Expand Down Expand Up @@ -55,7 +56,7 @@ describe('Integration tests for FilesResolver', () => {
// eslint-disable-next-line no-loop-func
describe(`when MODE is ${mode}`, () => {
beforeEach(() => {
jest.spyOn(mockConfigService, 'get').mockReturnValue(mode);
jest.spyOn(mockConfigService, 'getMode').mockReturnValue(mode);
});

it('should be defined', () => {
Expand Down
2 changes: 1 addition & 1 deletion servers/lib/test/testUtil.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ export function sleep(ms) {

export class MockConfigService {
// eslint-disable-next-line class-methods-use-this
get(key: string): string {
getMode(key: string): string {
switch (key) {
case 'LOCAL_PATH':
return process.env.LOCAL_PATH;
Expand Down
Loading

0 comments on commit 243ce87

Please sign in to comment.