SWC and Decorators (e.g. TypeORM)
Unanswered
Multiflora rose seed chalcid posted this in #help-forum
Multiflora rose seed chalcidOP
Hi I am looking for a way to configure SWC in nextjs to "understand" decorators as it should in TypeScript.
For example adding typeorm to Nextjs will break because the SWC compiler does not understand what to do with the Decorators in Entities.
I tried something like
For now nothing really worked.
I am very thankful for any help on this aside from "use another ORM".
kind regards,
Kaos
For example adding typeorm to Nextjs will break because the SWC compiler does not understand what to do with the Decorators in Entities.
I tried something like
const nextConfig: NextConfig = {
reactStrictMode: true,
experimental: {
serverActions: {},
},
async redirects() {
await bootstrap();
return [];
},
swc: (config: any) => ({
...config,
jsc: {
...config.jsc,
parser: {
...config.jsc.parser,
syntax: 'typescript',
decorators: true,
dynamicImport: true,
},
transform: {
...config.jsc.transform,
legacyDecorator: true,
decoratorMetadata: true,
},
},
}),
};
For now nothing really worked.
I am very thankful for any help on this aside from "use another ORM".
kind regards,
Kaos
15 Replies
@Cinnamon I can help u
Multiflora rose seed chalcidOP
I got it fixed.
Thank you anyways!
Thank you anyways!
Satin Angora
@Multiflora rose seed chalcid how did you fix it broski?
I am trying to migrate to nextjs 14 but for some reason
Datasource.initialize()
fails for me, but for next 13 it works okay@Satin Angora I am trying to migrate to nextjs 14 but for some reason `Datasource.initialize()` fails for me, but for next 13 it works okay
Multiflora rose seed chalcidOP
Can you share the code you use to create the DataSource and where you want to initialize?
BTW I am on Nextjs 15.3
Satin Angora
const AppDataSource = new DataSource(dbConfig)
const initializeDataSource = async () => {
if (!AppDataSource.isInitialized) {
await AppDataSource.initialize()
}
if (!isProduction() && (await AppDataSource.showMigrations())) {
throw new Error(`You have pending migrations. Run 'pnpm dev:migration:run'.`)
}
}
const getManager = async (): Promise<typeorm.EntityManager> => {
await initializeDataSource()
return AppDataSource.manager
}
export const AuthAdapter = (): AtlasAuthAdapter => {
return {
/** Using the provider id and the id of the user for a specific account, get the user. */
getUserByAccount: async (
userIdentityAttributes: Pick<AdapterAccount, 'provider' | 'providerAccountId'>,
): Promise<AdapterUser | null> => {
console.log('1')
const manager = await getManager()
console.log('2')
const { provider, providerAccountId } = userIdentityAttributes
const userIdentity = await manager.findOne(UserIdentity, {
where: { provider: provider as UserIdentityProvider, providerAccountId },
relations: { user: { userScopes: true } },
})
console.log('3')
if (!userIdentity) return null
console.log('4')
return toAdapterUser(userIdentity.user)
},
}
}
It fails in my
adapter
in getUserByAccount
function and I tracked it down it fails in this call AppDataSource.initialize()
@Multiflora rose seed chalcid BTW I am on Nextjs 15.3
Satin Angora
I am on
I tracked down exactly which nextjs release broke it and it is this one: https://github.com/vercel/next.js/releases/tag/v13.5.7-canary.12
13.5
and trying to migrate to 14.2
so I can migrate to 15
soon as well, but I am pretty stuck with this 😦I tracked down exactly which nextjs release broke it and it is this one: https://github.com/vercel/next.js/releases/tag/v13.5.7-canary.12
Multiflora rose seed chalcidOP
okay, where is the AuthAdapter being called in the nextjs lifecycle?
Satin Angora
I use
This is where i invoke AuthAdapter()
and in my:
I have this:
next-auth
v4apps/portal-app/app/api/auth/[...nextauth]/constants.ts
This is where i invoke AuthAdapter()
const authAdapter = AuthAdapter()
export const authConfig: NextAuthOptions = {
providers: [],
adapter: authAdapter,
....more config stuff
}
and in my:
apps/portal-app/app/api/auth/[...nextauth]/route.ts
I have this:
import NextAuth from 'next-auth'
import { authConfig } from './constants'
const handler = NextAuth(authConfig)
export { handler as GET, handler as POST }
Multiflora rose seed chalcidOP
the problem is you never fully await the initialization I would say.
try to return
try to return
AppDataSource.initialize()
and use that in getManager
.This is my code, runs fine.
// lib/db.ts
import 'reflect-metadata';
import { DataSource } from 'typeorm';
import config from '../../typeorm.config';
let dataSource: DataSource | null = null;
let initializationPromise: Promise<DataSource> | null = null;
export async function getDataSource(): Promise<DataSource> {
if (!dataSource) {
if (!initializationPromise) {
initializationPromise = new DataSource(config)
.initialize()
.then((ds) => {
dataSource = ds;
return ds;
})
.catch((error) => {
console.error('Database connection error:', error);
initializationPromise = null;
throw error;
});
}
return initializationPromise;
}
return dataSource;
}
export async function closeDataSource(): Promise<void> {
if (dataSource && dataSource.isInitialized) {
try {
await dataSource.destroy();
dataSource = null;
initializationPromise = null;
} catch (error) {
console.error('Error closing database connection', error);
}
}
}
Satin Angora
okay I am gonna take a look at it, thank you so much! ❤️ I will let you know once I fix it