wip: typeorm module and service

This commit is contained in:
Supan Adit Pratama 2024-11-06 01:00:33 +07:00
parent ea551f8730
commit a74cb24e9f
13 changed files with 146 additions and 4 deletions

View File

@ -0,0 +1,7 @@
import { ConfigurableModuleBuilder } from '@nestjs/common';
import { TypeORMModuleOptions } from './interfaces';
export const { ConfigurableModuleClass } =
new ConfigurableModuleBuilder<TypeORMModuleOptions>()
.setClassMethodName('forRoot')
.build();

View File

@ -0,0 +1,2 @@
export const TYPEORM_DATASOURCE = 'TYPEORM_DATASOURCE';
export const TYPEORM_REPOSITORY = 'TYPEORM_REPOSITORY';

View File

@ -0,0 +1,4 @@
export * from './typeorm.module';
export * from './typeorm.service';
export * from './interfaces';
export * from './constants';

View File

@ -0,0 +1,5 @@
export interface TypeORMModuleOptions {
entity;
synchronize?: boolean;
entities: string[];
}

View File

@ -0,0 +1 @@
export * from './config-module-options.interface';

View File

@ -0,0 +1,76 @@
import { DynamicModule, Module } from '@nestjs/common';
import { TypeormService } from './typeorm.service';
import { TypeORMModuleOptions } from './interfaces';
import { ConfigurableModuleClass } from './config.module-definition';
import { DataSource } from 'typeorm';
import { TYPEORM_DATASOURCE, TYPEORM_REPOSITORY } from './constants';
const getDatabaseCredential = (
synchronize?: boolean,
entities?: string[],
): any => {
const url = new URL(process.env.DATABASE_URL);
let entityList = [__dirname + '/../**/*.entity{.ts,.js}'];
if (entities) {
entityList = entities;
}
let protocol;
switch (url.protocol) {
case 'postgresql':
protocol = 'postgres';
break;
case 'mysql':
protocol = 'mysql';
break;
}
// Extract the necessary components
const username = url.username;
const password = url.password;
const host = url.hostname;
const port = url.port;
const databaseName = url.pathname.substring(1); // Remove the leading slash
return {
type: protocol,
host: host,
port: port,
username: username,
password: password,
database: databaseName,
entities: entityList,
synchronize: synchronize ?? false,
};
};
@Module({
providers: [TypeormService],
exports: [TypeormService],
})
export class TypeORMModule<T> extends ConfigurableModuleClass {
static forRoot(options: TypeORMModuleOptions): DynamicModule {
let providers = [
{
provide: TYPEORM_DATASOURCE,
useFactory: async () => {
const dataSource = new DataSource(
getDatabaseCredential(options.synchronize, options.entities),
);
return dataSource.initialize();
},
},
{
provide: TYPEORM_REPOSITORY,
useFactory: (dataSource: DataSource) =>
dataSource.getRepository(options.entity),
inject: [TYPEORM_DATASOURCE],
},
];
return {
...super.forRoot(options),
providers,
};
}
}

View File

@ -0,0 +1,11 @@
import { Inject, Injectable } from '@nestjs/common';
import { Repository } from 'typeorm';
import { TYPEORM_REPOSITORY } from './constants';
@Injectable()
export class TypeormService<T> {
constructor(
@Inject(TYPEORM_REPOSITORY)
private repository: Repository<T>,
) {}
}

View File

@ -0,0 +1,9 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"declaration": true,
"outDir": "../../dist/libs/typeorm"
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist", "test", "**/*spec.ts"]
}

View File

@ -24,6 +24,15 @@
"compilerOptions": {
"tsConfigPath": "libs/prisma/tsconfig.lib.json"
}
},
"typeorm": {
"type": "library",
"root": "libs/typeorm",
"entryFile": "index",
"sourceRoot": "libs/typeorm/src",
"compilerOptions": {
"tsConfigPath": "libs/typeorm/tsconfig.lib.json"
}
}
}
}

View File

@ -92,7 +92,8 @@
],
"moduleNameMapper": {
"^@aditama-labs/nest-autocrud/skeleton(|/.*)$": "<rootDir>/libs/skeleton/$1",
"^@aditama-labs/nest-autocrud/prisma(|/.*)$": "<rootDir>/libs/prisma/$1"
"^@aditama-labs/nest-autocrud/prisma(|/.*)$": "<rootDir>/libs/prisma/$1",
"^@aditama-labs/nest-autocrud/typeorm(|/.*)$": "<rootDir>/libs/typeorm/src/$1"
}
}
}
}

View File

@ -7,13 +7,22 @@ const getDatabaseCredential = (): any => {
const url = new URL(process.env.DATABASE_URL);
// Extract the necessary components
let protocol;
switch(url.protocol){
case 'postgresql':
protocol = 'postgres';
break;
case 'mysql':
protocol = 'mysql';
break;
}
const username = url.username;
const password = url.password;
const host = url.hostname;
const port = url.port;
const databaseName = url.pathname.substring(1); // Remove the leading slash
return {
type: 'postgres',
type: protocol,
host: host,
port: port,
username: username,

View File

@ -14,6 +14,8 @@
"@aditama-labs/nest-autocrud/skeleton/(.*)": "<rootDir>/../libs/skeleton/$1",
"@aditama-labs/nest-autocrud/skeleton": "<rootDir>/../libs/skeleton",
"@aditama-labs/nest-autocrud/prisma/(.*)": "<rootDir>/../libs/prisma/$1",
"@aditama-labs/nest-autocrud/prisma": "<rootDir>/../libs/prisma"
"@aditama-labs/nest-autocrud/prisma": "<rootDir>/../libs/prisma",
"@aditama-labs/nest-autocrud/typeorm/(.*)": "<rootDir>/../libs/typeorm/src/$1",
"@aditama-labs/nest-autocrud/typeorm": "<rootDir>/../libs/typeorm/src"
}
}

View File

@ -29,6 +29,12 @@
],
"@aditama-labs/nest-autocrud/prisma/*": [
"libs/prisma/*"
],
"@aditama-labs/nest-autocrud/typeorm": [
"libs/typeorm/src"
],
"@aditama-labs/nest-autocrud/typeorm/*": [
"libs/typeorm/src/*"
]
}
}