How to dynamic import a local typescript file - node.js

I have 2 files in the same folder. I want to dynamically import MyInterfaces.ts into index.ts.
// MyInterfaces.ts
export interface MyInterface1 {
id: number;
name: string;
}
// index.ts
async function importMyInterfaces() {
const myInterfaces = await import("./MyInterfaces");
const data1: myInterfaces.MyInterface1 = {
id: 1,
name: "John Doe",
};
}
I cannot figure how to achieve this without errors TS2503: Cannot find namespace 'myInterfaces'. I tried wrapping MyInterfaces.ts in a namespace but that didnt work either:
// MyInterfaces.ts
export namespace MyInterfaces {
export interface MyInterface1 {
id: number;
name: string;
}
}
// index.ts
async function importMyInterfaces() {
const {MyInterfaces} = await import("./MyInterfaces");
const data1: MyInterfaces.MyInterface1 = {
id: 1,
name: "John Doe",
};
}
TS2503: Cannot find namespace 'MyInterfaces'.
My tsconfig is set as follows with node 18:
{
"compilerOptions": {
"module": "commonjs",
"noImplicitReturns": true,
"noUnusedLocals": true,
"outDir": "lib",
"sourceMap": true,
"strict": true,
"target": "es2017"
},
"compileOnSave": true,
"include": [
"src"
]
}

If MyInterface1 was a default export, then you could asynchronously import and find the typeof within the importMyInterfaces() call.
MyInterfaces.ts
export default interface MyInterface1 {
id: number;
name: string;
}
index.ts
async function importMyInterfaces() {
const MyInterface1 = await import("./MyInterfaces");
const data1: typeof MyInterface1 = {
id: 1,
name: "John Doe"
};
console.log("data1", data1);
}
If you don't need to import asynchronously, then you can simply import at the top of index.ts.
MyInterfaces.ts
export interface MyInterface1 {
id: number;
name: string;
}
index.ts
import { MyInterface1 } from './MyInterfaces';
async function importMyInterfaces() {
const data1: MyInterface1 = {
id: 1,
name: "John Doe",
};
}

Related

How to access databaseprovider into other modules in nestjs using sequalize

I have database provider which has a db instance, I would like to use that instance in other modules to write raw queries using sequalize. But eventhough i have imported the database module in my other module, i couldn't able to access the db instance.
const { Sequelize, DataTypes } = require('sequelize');
import { databaseConfig } from './database.config';
/**
* SEQUELIZE variable is stored in a file named
* 'constants' so it can be easily reused anywhere
* without being subject to human error.
*/
let sequelize: any = null;
export const databaseProviders = [{
provide: 'SEQUELIZE',
useFactory: async () => {
let config: any;
switch (process.env.NODE_ENV) {
case 'DEVELOPMENT':
config = databaseConfig.development;
break;
case 'LOCAL':
config = databaseConfig.local;
break;
default:
config = databaseConfig.development;
}
sequelize = new Sequelize(config);
let series = ['907', '908', '909', '910', '912'];
let tableModels = [];
// Creating dynamic tables as per mobile number sequence
for (const serial of series) {
let modelObj = sequelize.define(`number_series_${serial}`, {
id: {
type: DataTypes.BIGINT,
allowNull: false,
autoIncrement: true,
unique: true,
primaryKey: true,
},
mobile_number: {
type: DataTypes.STRING,
allowNull: false,
unique: true,
},
reference_number: {
type: DataTypes.STRING,
unique: true,
},
status: {
type: DataTypes.STRING,
allowNull: false
},
last_createdAt: {
type: DataTypes.DATE,
defaultValue: DataTypes.NOW,
allowNull: false,
},
last_updatedAt: {
type: DataTypes.DATE,
defaultValue: DataTypes.NOW,
onUpdate: DataTypes.NOW as any,
allowNull: false,
}
}, {
freezeTableName: true
});
tableModels.push(modelObj);
}
// sequelize.addModels(tableModels);
await sequelize.sync();
return sequelize;
},
}];
Is there anyway that i can use this databaseProviders in other modules by injecting this provider.
Here is my database module file
import { Module } from '#nestjs/common';
import { databaseProviders } from './database.providers';
#Module({
providers: [...databaseProviders],
exports: [...databaseProviders],
})
export class DatabaseModule { }
Here is my other module file, where i'm importing database module.
import { Module } from '#nestjs/common';
import { MobileNumberService } from './mobile-number.service';
import { MobileNumberController } from './mobile-number.controller';
import { DatabaseModule } from '../../core/database/database.module';
import { AuthModule } from 'src/auth/auth.module';
#Module({
imports: [DatabaseModule, AuthModule],
controllers: [MobileNumberController],
providers: [MobileNumberService]
})
export class MobileNumberModule { }
Here is my controller file, where i want to use DB instance to write raw sequalize queries.
import { Controller, Get, Post, Body, Patch, Param, Delete, UseGuards, Req, Res, Inject, Injectable } from '#nestjs/common';
import { MobileNumberService } from './mobile-number.service';
import { CreateMobileNumberDto } from './dto/create-mobile-number.dto';
import { UpdateMobileNumberDto } from './dto/update-mobile-number.dto';
import { JwtAuthGuard } from 'src/auth/guards/jwt-auth.guard';
import { LocalAuthGuard } from 'src/auth/guards/local.auth.guard';
import { AuthService } from 'src/auth/auth.service';
#Injectable()
#Controller('mobile-number')
export class MobileNumberController {
constructor(
private readonly mobileNumberService: MobileNumberService,
private authService: AuthService) { }
#Get("getAll")
async findAll() {
// let getAll = this.connection.query('select * from zoloz_transaction_logs');
// console.log(getAll);
// return getAll;
}
}
Is there anyway that i can use the same instance to write raw queries from the database provider or is there any efficient way.
Thanks in Advance

Jest test runs indefinitely, & yarn run test --runInBand throws error Command failed with signal "SIGSEGV"

My test runs indefinitely without results (see image below). I am pretty new to setting up backend testing environment. Any guidance is much appreciated.
I have provided the snippets of my code, please let me know if you need any additional information.
I tried the below commands.
--clearCache option which did not work
--runInBand option lead to a new error, error Command failed with signal "SIGSEGV".
// testHelper.js
import { DataSource, DataSourceOptions } from "typeorm";
import Database from "better-sqlite3";
export class TestHelper {
private static _instance: TestHelper;
private constructor() { }
public static get instance(): TestHelper {
if (!this._instance) this._instance = new TestHelper();
return this._instance;
}
private dbConnect!: DataSource;
private testdb!: any;
async setupTestDB() {
this.testdb = new Database(":memory:", { verbose: console.log });
this.dbConnect = new DataSource({
name: "default",
type: "better-sqlite3",
database: ":memory:",
entities: ["src/entities/**/*.ts"],
synchronize: true,
} as DataSourceOptions);
await this.dbConnect.initialize()
}
teardownTestDB() {
this.dbConnect.destroy();
this.testdb.close();
}
}
// test.ts
import MyEntity from "entities/MyEntity";
import { TestHelper } from './__utils/testHelper';
beforeAll(async () => {
return await TestHelper.instance.setupTestDB();
});
afterAll(() => {
return TestHelper.instance.teardownTestDB();
});
test("create test data and fetch it", async () => {
await MyEntity.insert({
name: "sqlTestEntity"
});
let sqlTestEntity = await MyEntity.find({
where: {
id: '1'
}
});
expect(sqlTestEntity[0].name).toBe("sqlTestEntity");
});
//package.json
"scripts": {
....
"test": "NODE_OPTIONS=--experimental-vm-modules npx jest",
....
}
"typeorm": "0.3",
"#types/jest": "^28.1.7",
"jest": "^28.1.3",
// jest.config.js
/** #type {import('ts-jest/dist/types').InitialOptionsTsJest} */
export default {
preset: 'ts-jest',
testEnvironment: 'node',
testTimeout: 20000,
roots: ['src'],
modulePaths: ['<rootDir>/src'],
testPathIgnorePatterns: [
'<rootDir>/node_modules/', "/__utils"
],
moduleDirectories: [
"src"
],
transform: {
"^.+\\.js?$": "babel-jest",
"^.+\\.ts?$": "ts-jest"
},
testRegex: "(/__tests__/.*|(\\.|/)(test|spec))\\.(js?|tsx?)$",
"transform": {
"^.+\\.(t|j)s$": "ts-jest"
},
testEnvironment: "node",
"moduleNameMapper": {
"src/(.*)": "<rootDir>/src/$1"
},
globals: {
"ts-jest": {
"useESM": true
}
},
extensionsToTreatAsEsm: ['.ts'],
moduleNameMapper: {
'^(\\.{1,2}/.*)\\.js$': '$1',
},
};

NestJ app is not running after running yarn command to install all package

I have run yarn comment to install a new package added by my teammate, after doing that it showing this error.
Argument of type '{ imports: (typeof TypeOrmConfigModule)[]; inject: (typeof ConfigService)[]; name: "default"; useExisting: typeof TypeOrmConfigService; connectionFactory: (options: any) => Promise<...>; }' is not assignable to parameter of type 'TypeOrmModuleAsyncOptions'.
Object literal may only specify known properties, and 'connectionFactory' does not exist in type 'TypeOrmModuleAsyncOptions'.
57 connectionFactory: async (options) => {
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
58 const connection = await createConnection(options);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
59 return connection;
~~~~~~~~~~~~~~~~~~~~~~~~~~
60 },
My app. modele .ts file. error is on 57 number line.
/**dependencies */
import { HttpModule } from '#nestjs/axios';
import { MiddlewareConsumer, Module, NestModule } from '#nestjs/common';
import { ConfigModule, ConfigService } from '#nestjs/config';
import { RouterModule } from '#nestjs/core';
import { TypeOrmModule } from '#nestjs/typeorm';
import { createConnection } from 'typeorm';
/**controllers */
import { AppController } from './app.controller';
/**services */
import { AppService } from './app.service';
import { AdminModule } from './modules/admin/admin.module';
import { MasterdataModule } from './modules/admin/masterdata';
import { UniCareerModule } from './modules/admin/uni-career';
import { AgentModule } from './modules/agent/agent.module';
import { CounsellorModule } from './modules/counsellor/counsellor.module';
import { MentorModule } from './modules/mentor/mentor.module';
import { StudentModule } from './modules/student/student.module';
import { StudyModule } from './modules/study/study.module';
import { UniversityModule } from './modules/university/university.module';
import { PublicApiModule } from './public-api';
import { PublicUniversityModule } from './public-api/university';
/**validate env config */
import { validate } from './uni-engine/config/env.validation';
import {
TypeOrmConfigModule,
TypeOrmConfigService,
} from './uni-engine/config/typeorm-config';
import { MailModule } from './uni-engine/mail/mail.module';
/** logger middleware */
import { LoggerMiddleware } from './uni-engine/middleware';
/**modules */
import { UniEngineModule } from './uni-engine/uni-engine.module';
import { UniEngineService } from './uni-engine/uni-engine.service';
import { OnlineLearningModule } from './modules/online-learning/online-learning.module';
import { ScheduleModule } from '#nestjs/schedule';
import { UniChatModule } from './modules/uni-chat/uni-chat.module';
#Module({
imports: [
/**initialize nest js config module */
ConfigModule.forRoot({
validate: validate,
//responsible for use config values globally
isGlobal: true,
}),
//type orm dependencies integration
TypeOrmModule.forRootAsync({
imports: [TypeOrmConfigModule],
inject: [ConfigService],
// Use useFactory, useClass, or useExisting
// to configure the ConnectionOptions.
name: TypeOrmConfigService.connectionName,
useExisting: TypeOrmConfigService,
// connectionFactory receives the configured ConnectionOptions
// and returns a Promise<Connection>.
connectionFactory: async (options) => {
const connection = await createConnection(options);
return connection;
},
}),
//module prefix for modules
RouterModule.register([
//module prefix for admin
{
path: 'admin',
module: AdminModule,
},
{
path: 'admin',
module: MasterdataModule,
},
//module prefix for uni career module
{
path: 'uni-career',
module: UniCareerModule,
},
//module prefix for study module
{
path: 'study',
module: StudyModule,
},
//module prefix for university module
{
path: 'university',
module: UniversityModule,
},
{
path: 'public',
module: PublicApiModule,
},
{
path: 'public',
module: PublicUniversityModule,
},
{
path: 'student',
module: StudentModule,
},
{
path: 'counsellor',
module: CounsellorModule,
},
{
path: 'agent',
module: AgentModule,
},
{
path: 'mentor',
module: MentorModule,
},
{
path: 'online-learning',
module: OnlineLearningModule,
},
]),
UniEngineModule,
AdminModule,
StudyModule,
MailModule,
PublicApiModule,
UniversityModule,
HttpModule,
StudentModule,
CounsellorModule,
MentorModule,
AgentModule,
OnlineLearningModule,
//scheduler module
ScheduleModule.forRoot(),
UniChatModule,
],
controllers: [AppController],
providers: [AppService, UniEngineService],
})
export class AppModule implements NestModule {
configure(consumer: MiddlewareConsumer) {
consumer.apply(LoggerMiddleware).forRoutes('*');
}
}
It was running code. I have just run a yarn command. This project is running on other computers with the same Node Version and yarn version. How can I solve the issue?

Nestjs and nestjs-i18n: Internationalization not working in Custom Exception Filter

I am trying to use an exception filter in my NestJS app. I have to translate my exception message into another language based on the request value. I have two languages file en and fr.
I have initialized i18N in my app.module.ts as per the following:
#Module({
imports: [
I18nModule.forRoot({
fallbackLanguage: 'en',
parser: I18nJsonParser,
parserOptions: {
path: path.join(__dirname, '/i18n/'),
},
resolvers: [
PathResolver,
{ use: QueryResolver, options: ['lang', 'locale', 'l'] },
AcceptLanguageResolver
]
}),
],
controllers: [AppController],
providers: [AppService,
{
provide: APP_FILTER,
useClass: NotFoundExceptionFilter,
},
{
provide: APP_FILTER,
useClass: HttpExceptionFilter,
}
],
})
export class AppModule { }
My Exception filter class looks like this:
#Catch(HttpException)
export class HttpExceptionFilter implements ExceptionFilter<HttpException> {
constructor(private readonly i18n: I18nService) { }
async catch(exception: HttpException, host: ArgumentsHost) {
const ctx = host.switchToHttp();
const response = ctx.getResponse();
const request = ctx.getRequest();
const statusCode = exception.getStatus();
await this.i18n.translate('message.Unauthorized', { lang: 'fr' }).then(message => {
console.log('message -> ', message);
response.status(403).send({
status: 6,
message: message,
data: null
});
})
}
}
I am throwing an exception from the LocalAuthGuard file:
#Injectable()
export class LocalAuthGuard implements CanActivate {
canActivate(context: ExecutionContext,): boolean | Promise<boolean> | Observable<boolean> {
const request = context.switchToHttp().getRequest().body;
if(isEmpty(request.authkey)){
return false;
}else{
return true;
}
}
}
I have just put here my sample code from the project. When I run this project by some specific URL, I am not getting messages in the specific language. I am getting the following output in my console log.
message -> message.Unauthorized
It should return the message in fr language.
Can anybody help me, where am I going wrong?
I forgot to add the path in nest-cli.json. If we put the path in that file as below then the above code perfectly works fine.
{
"collection": "#nestjs/schematics",
"sourceRoot": "src",
"compilerOptions": {
"assets": ["i18n/**/*","ssl/**/*"]
}
}

How to configure Knex.ts in TypeScript project?

I am trying to configure Knexfile in TypeScript. I created knexfile.ts with knex init -x ts:
const defaults = {
client: 'postgresql',
connection: {
host: DB_HOST,
user: DB_USER,
password: DB_PASSWORD,
database: DB_DATABASE
},
pool: {
min: 2,
max: 10
},
migrations: {
tableName: 'knex_migrations'
}
};
const knexConfig = {
local: {
client: 'sqlite3',
connection: {
filename: './dev.sqlite3'
}
},
development: {
...defaults,
debug: true,
useNullAsDefault: true
},
production: {
...defaults
}
};
export default knexConfig;
And then I create knex.ts file to make connection:
import Knex, { Config } from 'knex';
import knexConfig from '../utils/knexfile';
import { NODE_ENV } from '../utils/config';
// Set environment from `.env`
const knex = Knex(knexConfig[NODE_ENV]);
export default knex;
But I got an error at (knexConfig[NODE_ENV]), saying that:
(alias) const NODE_ENV: string
import NODE_ENV
Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{ local: { client: string; connection: { filename: string; }; }; development: { debug: boolean; useNullAsDefault: boolean; client: string; connection: { host: string; user: string; password: string; database: string; }; pool: { ...; }; migrations: { ...; }; }; production: { ...; }; }'.
No index signature with a parameter of type 'string' was found on type '{ local: { client: string; connection: { filename: string; }; }; development: { debug: boolean; useNullAsDefault: boolean; client: string; connection: { host: string; user: string; password: string; database: string; }; pool: { ...; }; migrations: { ...; }; }; production: { ...; }; }'.ts(7053)
========================================================
What am I doing wrong?
Please help.
I believe you can either supress these errors by setting:
"suppressImplicitAnyIndexErrors": true,
in your tsconfig.json
or you can create an index signature for the knexConfig object in some way:
interface KnexConfig {
[key: string]: object;
};
const knexConfig: KnexConfig = {
local: {
client: 'sqlite3',
connection: {
filename: './dev.sqlite3'
}
},
development: {
...defaults,
debug: true,
useNullAsDefault: true
},
production: {
...defaults
}
};
For more possibilities see the possible duplicate of this question: How do I prevent the error "Index signature of object type implicitly has an 'any' type" when compiling typescript with noImplicitAny flag enabled?
For the future, at version ^1.0.4, knex export all types in Knex interface, so
import { Knex } from "knex";
and get the config autocomplete
module.exports = {
client: "mysql",
connection: {
filename: path.resolve(__dirname, "src", "database", "connection.ts"),
},
migrations: {
directory: path.resolve(__dirname, "src", "database", "migrations"),
},
} as Knex.Config;

Resources