#Error with Fastify instance and session types
35 messages · Page 1 of 1 (latest)
Code:
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { ConfigService } from '@nestjs/config';
import { VersioningType } from '@nestjs/common';
import {
FastifyAdapter,
NestFastifyApplication,
} from '@nestjs/platform-fastify';
import { FastifyInstance } from 'fastify';
import secureSession from '@fastify/secure-session';
import * as passport from 'passport';
async function bootstrap() {
const app = await NestFactory.create<NestFastifyApplication>(
AppModule,
new FastifyAdapter(),
);
const fastifyInstance: FastifyInstance = app.getHttpAdapter().getInstance();
fastifyInstance
.addHook('onRequest', async (req, res) => {
req.socket['encrypted'] = process.env.NODE_ENV === 'production';
res.header('X-Powered-By', 'CyberSecurity');
})
.decorateReply('setHeader', function (name: string, value: unknown) {
this.header(name, value);
})
.decorateReply('end', function () {
this.send('');
});
const configService = app.get(ConfigService);
const port = configService.get<string>('PORT', '');
// Throttler - Protection
app.enableCors({
origin: '*',
methods: 'GET, HEAD, PUT, PATCH, POST, DELETE',
allowedHeaders: 'Content-Type, Authorization',
credentials: true,
});
app.enableVersioning({
type: VersioningType.URI,
defaultVersion: '1',
});
await app.register(secureSession, {
sessionName: configService.get<string>('SESSION_NAME', ''),
cookieName: configService.get<string>('SESSION_COOKIE', ''),
expiry: configService.get<string>('SESSION_EXPIRATION_TIME', ''),
cookie: {
path: '/',
},
secret: configService.get<string>('SESSION_SECRET', ''),
salt: configService.get<string>('SESSION_SALT', ''),
});
app.use(passport.initialize());
app.use(passport.session());
await app.listen(port);
}
bootstrap();
Error:
src/main.ts:18:9 - error TS2740: Type 'FastifyInstance<RawServerDefault, IncomingMessage, ServerResponse<IncomingMessage>, FastifyBaseLogger, FastifyTypeProviderDefault>' is missing the following properties from type 'FastifyInstance<RawServerDefault, IncomingMessage, ServerResponse<IncomingMessage>, FastifyBaseLogger, FastifyTypeProviderDefault>': serializeCookie, parseCookie, createSecureSession, decodeSecureSession, and 3 more.
18 const fastifyInstance: FastifyInstance = app.getHttpAdapter().getInstance();
~~~~~~~~~~~~~~~
src/main.ts:57:22 - error TS2345: Argument of type 'FastifySecureSession' is not assignable to parameter of type 'FastifyPluginCallback<SecureSessionPluginOptions | (SecureSessionPluginOptions & Required<Pick<SecureSessionPluginOptions, "sessionName">>)[]> | FastifyPluginAsync<...> | Promise<...> | Promise<...>'.
Type 'FastifySecureSession' is not assignable to type 'FastifyPluginCallback<SecureSessionPluginOptions | (SecureSessionPluginOptions & Required<Pick<SecureSessionPluginOptions, "sessionName">>)[]>'.
Types of parameters 'instance' and 'instance' are incompatible.
Type 'import("H:/xampp/htdocs/devdj/sso/node-sso/server/node_modules/@nestjs/platform-fastify/node_modules/fastify/types/instance").FastifyInstance<import("H:/xampp/htdocs/devdj/sso/node-sso/server/node_modules/@nestjs/platform-fastify/node_modules/fastify/types/utils").RawServerDefault, import("http").IncomingMessage, im...' is not assignable to type 'import("H:/xampp/htdocs/devdj/sso/node-sso/server/node_modules/fastify/types/instance").FastifyInstance<import("H:/xampp/htdocs/devdj/sso/node-sso/server/node_modules/fastify/types/utils").RawServerDefault, import("http").IncomingMessage, import("http").ServerResponse<import("http").IncomingMessage>, import("H:/xamp...'.
57 await app.register(secureSession, {
Node Packages:
"dependencies": {
"@fastify/secure-session": "^7.5.1",
"@nestjs/class-validator": "^0.13.4",
"@nestjs/common": "^10.3.9",
"@nestjs/config": "^3.2.2",
"@nestjs/core": "^10.3.9",
"@nestjs/jwt": "^10.2.0",
"@nestjs/passport": "^10.0.3",
"@nestjs/platform-express": "^10.3.9",
"@nestjs/platform-fastify": "^10.3.9",
"@nestjs/typeorm": "^10.0.2",
"@types/bcrypt": "^5.0.2",
"bcrypt": "^5.1.1",
"fastify": "^4.28.0",
"joi": "^17.13.3",
"passport": "^0.7.0",
"passport-local": "^1.0.0",
"pg": "^8.12.0",
"reflect-metadata": "^0.1.13",
"rxjs": "^7.2.0",
"typeorm": "^0.3.20"
},
"devDependencies": {
"@nestjs/cli": "^10.3.2",
"@nestjs/schematics": "^10.1.1",
"@nestjs/testing": "^10.3.9",
"@types/express": "^4.17.13",
"@types/jest": "29.5.1",
"@types/node": "18.16.12",
"@types/passport": "^1.0.16",
"@types/supertest": "^2.0.11",
"@typescript-eslint/eslint-plugin": "^5.0.0",
"@typescript-eslint/parser": "^5.0.0",
"eslint": "^8.0.1",
"eslint-config-prettier": "^8.3.0",
"eslint-plugin-prettier": "^4.0.0",
"jest": "29.5.0",
"prettier": "^2.3.2",
"source-map-support": "^0.5.20",
"supertest": "^6.1.3",
"ts-jest": "29.1.0",
"ts-loader": "^9.2.3",
"ts-node": "^10.0.0",
"tsconfig-paths": "4.2.0",
"typescript": "^5.0.0"
},
Config
# Session - Config
SESSION_NAME = "auth-session"
SESSION_COOKIE = "auth-sid"
SESSION_EXPIRATION_TIME = 90 * 24 * 60 * 60 # 90 days
SESSION_SECRET = ""
SESSION_SALT = ""
App Module:
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { ConfigModule, ConfigService } from '@nestjs/config';
import { TypeOrmModule } from '@nestjs/typeorm';
import { TypeOrmConfigService } from './config/typeorm.config';
import { join } from 'path';
import { envSchema } from './config/env.schema';
import { PassportModule } from '@nestjs/passport';
import { AuthModule } from './auth/auth.module';
import { UsersModule } from './users/users.module';
@Module({
imports: [
ConfigModule.forRoot({
ignoreEnvFile: !!process.env.CI,
envFilePath: join(__dirname, '..', '.env'),
validationSchema: envSchema,
}),
TypeOrmModule.forRootAsync({
useClass: TypeOrmConfigService,
}),
PassportModule.registerAsync({
imports: [ConfigModule],
inject: [ConfigService],
useFactory: async (configService: ConfigService) => ({
defaultStrategy: configService.get('jwt.defaultStrategy'),
}),
}),
AuthModule,
UsersModule,
],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
can't you drop the explicit type for that variable fastifyInstance?
I do managed to reproduce the same error here but I wondering if it's expected or not..
I guess you can see the reason on this by running npm ls fastify
You'll probably see 2 versions of fastify instead of one, which may lead to such type incompatibility errors as each interface has come from different versions of fastify
Yeah I see
@nestjs/[email protected]
│ └── [email protected]
└── [email protected]
So what I should to do?
install [email protected]
I'll open a new issue tomorrow to suggest a minor improvement that should allow you to use the latest version of fastify with no worries
Any updates?
So, the only solution is to use an older version of Fastify or remove the types?
I see that the version in the adapter has been changed to 28.0. I installed it, but it still doesn't solve the problem. If I understand correctly, all types, even those for the request, should be imported from Fastify and not from @nestjs/common. So why don't you make it so that the types are provided by your package instead of requiring an additional installation of Fastify for the types? Since @nestjs/platform-fastify includes Fastify, you could export the types so they are available globally.
Uninstall fastify from your side or use the exact same version as per nestjs
No need to export from @nestjs/platform-fastity. You can import them from fastify
It’s just a matter of having the exact same module. So run npm ls fastity and see if all of occurrences are dedup
I have the same version, and the type error still occurs.
The strangest thing is that it still shows I have version 4.28.1.
PS H:\xampp\htdocs\devdj\sso\server> npm ls fastify
[email protected] H:\xampp\htdocs\devdj\sso\server
├─┬ @nestjs/[email protected]
│ └── [email protected]
└── [email protected]
Packages:
"@nestjs/platform-fastify": "^10.3.10",
"fastify": "^4.28.0",
that's why then
But package @nestjs/platform-fastify uses version 4.28.0
that will only work when you have the exact the same version, as I said
I'd suggest you to pin fastify's version
but you'll have to make it in sync with the version from @nestjs/platform-fastify
so I guess the best approach would be removing fastify from your hard deps
But that's the version I have installed, 4.28.0, because that's what I have in my package.json.
looks like you don't know how semver ranges works
This post has been marked as resolved. :white_check_mark:
Please read through the conversation and resolution, if you are having the same issue. If you were the original author of the post and the issue is still fresh (within a few days) and you are still have having trouble, continue to reply here. If you are not the original author of the post or the post has aged, start a new thread linking this one as relevant to your problem, providing as much additional information as possible.
Thanks, it works, but if I uninstall Fastify, I won't be able to use the types for the request.
Becouse I need get type from fastify
import { FastifyRequest } from 'fastify';
Post('login')
@HttpCode(HttpStatus.OK)
@UsePipes(ValidationPipe)
@UseGuards(LocalAuthGuard)
@AuditLog(AuditAction.Login)
async login(
@ReqUser() user: User,
@Req() req: FastifyRequest,
): Promise<LoginResponse> {
return await this.authService.login(user, req);
}