Error: The function (0 , import_preact_render_to_string.renderToString) is not a valid function

I am encountering an issue with my Express.js application when trying to integrate Auth.js. The API starts up fine, but when navigating beyond /api/auth, I receive a stack trace error without any logs in the console. Additionally, it redirects to /api/auth/error?error=Configuration

[auth][error] TypeError: (0 , import_preact_render_to_string.renderToString) is not a function
api:dev:at send (/Users/josh/projects/saas-starter-kit/node_modules/@auth/core/lib/pages/index.js:13:350)
api:dev:at Object.error (/Users/josh/projects/saas-starter-kit/node_modules/@auth/core/lib/pages/index.js:119:20)
api:dev:at AuthInternal (/Users/josh/projects/saas-starter-kit/node_modules/@auth/core/lib/index.js:31:31)
api:dev:at Auth (/Users/josh/projects/saas-starter-kit/node_modules/@auth/core/index.js:109:34)
api:dev:at <anonymous> (/Users/josh/projects/saas-starter-kit/node_modules/@auth/express/index.js:141:45)

Steps to reproduce:

tsconfig.json

{
  "compilerOptions": {
    "target": "es2016",                           
    "module": "commonjs",                    
    "outDir": "./dist",                            
    "esModuleInterop": true,         
    "forceConsistentCasingInFileNames": true,  
    "strict": true,
    "skipLibCheck": true 
  }
}

index.ts

import { logger } from '@repo/logger'
import 'dotenv/config'
import { createServer } from './server'

const port = process.env.PORT || 3001
const server = createServer()

server.listen(port, async() => {
    logger.info(`api server is starting: Date: ${new Date()}`)
})

server.ts

import express, { type Express } from 'express'
import morgan from 'morgan'

import { ExpressAuth } from "@auth/express"
import GitHub from "@auth/express/providers/github"

export const createServer = (): Express => {
 const app = express()

 app
  .use(express.urlencoded({ extended: true }))
  .use(express.json())
  .set("trust proxy", true)
  .use("/api/auth/*", ExpressAuth({
    debug: true,
    trustHost: true,
    providers: [
      GitHub
    ],
   }))
    .get('/status', (_, res) => {
     return res.json({ ok: true })
    })


    return app
}

.env.local

AUTH_SECRET=""
AUTH_GITHUB_ID=""
AUTH_GITHUB_SECRET=""
AUTH_URL="http://localhost:3001/api/auth"

Command to start up

dotenvx run --env-file ./.env.local -- nodemon --exec \"node -r esbuild-register ./src/index.ts\" -e .ts

Expected behavior: I expected the signin page to load successfully instead of receiving a server console error message.

Answer №1

My issue stemmed from the usage of a 'CommonJS' module in my project. Strangely enough, I'm not exactly sure how it was connected to the problem... but I found a workaround by implementing dynamic imports instead. Configuring TypeScript had become too complex for me, so I created an AuthJsDependencies loader to abstract these details away from my project. Here's an example of how I utilized it:

async function main() {
  const app = express()
  const authHandler = await AuthJsDependencies.load()
  app.use('/auth/*', authHandler) 
}

It's worth noting that this isn't the ideal async singleton pattern for loading dependencies. One peculiar aspect was the combination of CommonJS and dynamic imports. I came across a solution involving prevent typescript from transpiling dynamic imports into require(), which initially seemed impossible... but using eval actually worked for me.

import type { ExpressAuth } from "@auth/express";
import type Google from "@auth/express/providers/google";
import type SequelizeAdapter from "@auth/sequelize-adapter";

type Target = {
  ExpressAuth: typeof ExpressAuth;
  SequelizeAdapter: typeof SequelizeAdapter;
  Google: typeof Google;
};

export class AuthJsDependencies {
  private static target?: Target;

  public static async load() {
    if (!AuthJsDependencies.target) {
      AuthJsDependencies.target = await AuthJsDependencies._load();
    }

    return this.target!;
  }

  public static async _load() {
    const [
      { ExpressAuth },
      { default: SequelizeAdapter },
      { default: Google },
    ] = await Promise.all([
      eval('import("@auth/express")'),
      eval('import("@auth/sequelize-adapter")'),
      eval('import("@auth/express/providers/google")'),
    ]);

    return {
      ExpressAuth,
      SequelizeAdapter,
      Google,
    } as Target;
  }
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Converting data received from the server into a typescript type within an Angular Service

Received an array of Event type from the server. public int Id { get; set; } public string Name { get; set; } public DateTime Start { get; set; } public DateTime End { get; set; } For Angular and TypeScript, I need to transform it into the following clas ...

What is the best way to implement an interface for accurately checking each prop type?

Currently, while working with Typescript, I am looking for a solution to define an interface with specific properties inside my object of marks. At the moment, I am using "any", but I know there must be a better approach. Any guidance or advice on how to p ...

Utilizing Express and Multer for file uploads: receiving a file with a random name and unspecified format

I am a newcomer to web development, so please excuse me if this is a basic question. I am currently working on a web application that needs to upload a zip file along with some form data. For the client-side implementation, I am utilizing axios and below ...

Exploring the NestJS framework using mongoose schema, interfaces, and DTOs: A deep dive

As a newcomer to nestJS and mongoDB, I find myself questioning the need to declare DTO, schema, and interface for every collection we aim to store in our mongoDB. For example, I have a collection (unfortunately named collection) and this is the DTO I' ...

I have successfully implemented useLazyQuery in a functional component, but now I am looking to integrate it into a class component. Can you provide guidance on how to achieve

Recently, I encountered an issue with my functional component that contains 3 checkboxes and 1 button. I utilized the useLazyQuery hook to ensure that my query was only sent upon clicking the button. However, a major drawback is that my component re-rend ...

Combining values in an Angular project to create a new object with the same properties using TypeScript

Hey there! I hope your day is going well. I'm currently working on calculating multiple objects to create a new one with average values. Here's the schema: export class stats{ assists:number causedEarlySurrender:boolean champLevel:numb ...

Utilizing Angular to Showcase Nested Properties in a Kendo Grid Column

Question: In my Angular application, I am working with a Kendo Grid and using the generateColumns method to dynamically create columns for the grid. The data is fetched from an API, including a property that contains an array of roles. Below is a snippet ...

Tips on invoking a child component's function from the parent component

I'm struggling to comprehend, Is there a way to trigger a function within a child component by clicking on a button in the parent component? ...

Trouble with updating data in Angular 5 through page reload

Encountered a problem with the home, create, and edit product pages. After creating and saving data, it redirects to the home page where the latest products are displayed. Unfortunately, the newly created data does not update automatically until the page ...

Tips for transferring an object as a prop in React with the help of typescript

Learning TypeScript has been a challenge for me, as I struggle to grasp the concepts. Despite the countless times this question has been asked before, I find it difficult to apply the solutions I come across to my own code. To make matters worse, the synta ...

Manage text, PDF, and image files in a MEAN stack app by uploading and fetching them from a MongoDB database using

I have been working on developing a piece of code that allows users to create a dynamic URL, upload a file by clicking a button on the page, and then download the same file in the same format when revisiting the URL. The functionality is similar to cl1p, b ...

When I try to access localhost, it directs me to http://localhost:3000/myprofile%20 instead of localhost:/3000/myprofile

Every time I try to log into my profile page with the correct login credentials, I get redirected to http://localhost:3000/myprofile%20, but then receive a 404 error. This is what my code looks like: // Login Route router.post('/login', functi ...

Internationalization in Angular (i18n) and the powerful *ngFor directive

Within my Angular application, I have a basic component that takes a list of strings and generates a radio group based on these strings: @Component({ selector: 'radio-group', templateUrl: `<div *ngFor="let item of items"> ...

Using Typescript to retrieve a property by its name using a string as a generic type

I messed up the title, not sure the exact term for what I am trying to achieve. Type constraints are a bit confusing to me right now as I'm learning them in both F# and Typescript at the same time. I have a variable called interface state that contai ...

Leverage one Injectable service within another Injectable service in Angular 5

I am facing difficulties in utilizing an Injectable service within another Injectable service in Angular 5. Below is my crudService.ts file: import { Injectable } from '@angular/core'; import { HttpClient } from '@angular/common/http'; ...

The API response indicates that the service is currently not accessible

I'm attempting to retrieve a report from the MOZ API, but I keep receiving this response: { "status" : "503", "error_message" : "Service Temporarily Unavailable" } This is the code I am using: function MozCall(callback) { var mozCall = ' ...

Tips for performing a redirect in JavaScript/ReactJS without storing the redirection in the cache

In my TypeScript ReactJS SSR App, I have the following logic: public login() { let error: boolean = false const isLoggedIn: boolean = doSomeLogicHereLikeBackendCheck() if(isLoggedIn) { window.location.href = "/home" // this is getting c ...

Troubleshooting Problem with ES6 String Literals/Typescript in Chrome Developer Tools

I'm currently immersed in a project that involves Typescript and some of the ES6 features it offers, such as ES6 String Literals like `Something ${variable} Something else`. During my debugging process, I decided to set a breakpoint in my typescript ...

What is the best way to automatically determine the type of a callback value based on a property within the same object?

As I work on developing a DataGrid component, my goal is to create a feature where the columns can be inferred based on the type of object in each row. The usage scenario for this component would look like: const users: User[] = [ {name: 'John&apos ...

PNG file is not displayed on React TSX page despite absence of any errors

I've implemented this initial design template from GitHub (https://github.com/vikpe/react-webpack-typescript-starter). Additionally, I'm utilizing react-bootstrap and have a container that includes a backgroundImage. const heroImage = require(&q ...