Skip to content

Adrianmjim/nestjs-supabase-js

Repository files navigation

Nest Logo
Supabase

Test codecov NPM Version NPM Download Stats

Description

The Supabase module for NestJS.

Installation

Install the dependencies via npm, pnpm or yarn:

npm:

$ npm i -s @nestjs/common @supabase/supabase-js nestjs-supabase-js

pnpm:

$ pnpm add @nestjs/common @supabase/supabase-js nestjs-supabase-js

yarn:

$ yarn add @nestjs/common @supabase/supabase-js nestjs-supabase-js

Configuration

First, import the module into your NestJS application and configure it using the configuration key provided by Supabase.

import { Module } from '@nestjs/common';
import { SupabaseModule } from 'nestjs-supabase-js';

@Module({
  imports: [
    SupabaseModule.forRoot({
      supabaseKey: 'YOUR_SUPABASE_KEY',
      supabaseUrl: 'YOUR_SUPABASE_URL',
    }),
  ],
})
export class AppModule {}

Or, You can configure it asynchronously as follows:

import { Module } from '@nestjs/common';
import { SupabaseModule } from 'nestjs-supabase-js';

@Module({
  imports: [
    SupabaseModule.forRootAsync({
      imports: [],
      inject: [],
      useFactory: () => ({
        supabaseKey: 'YOUR_SUPABASE_KEY',
        supabaseUrl: 'YOUR_SUPABASE_URL',
      }),
    }),
  ],
})
export class AppModule {}

Multiple connections

In certain situations, we will need to connect to different Supabase projects, with this module this is possible:

import { Module } from '@nestjs/common';
import { SupabaseModule } from 'nestjs-supabase-js';

@Module({
  imports: [
    SupabaseModule.forRoot([
      {
        name: 'connection1',
        supabaseConfig: {
          supabaseKey: 'YOUR_SUPABASE_KEY',
          supabaseUrl: 'YOUR_SUPABASE_URL',
        },
      },
      {
        name: 'connection2',
        supabaseConfig: {
          supabaseKey: 'YOUR_SUPABASE_KEY',
          supabaseUrl: 'YOUR_SUPABASE_URL',
        },
      },
    ]),
  ],
})
export class AppModule {}

Or asynchronously:

import { Module } from '@nestjs/common';
import { SupabaseModule } from 'nestjs-supabase-js';

@Module({
  imports: [
    SupabaseModule.forRootAsync({
      imports: [],
      inject: [],
      useFactory: () => ([
        {
          name: 'connection1',
          supabaseConfig: {
            supabaseKey: 'YOUR_SUPABASE_KEY',
            supabaseUrl: 'YOUR_SUPABASE_URL',
          },
        },
        {
          name: 'connection2',
          supabaseConfig: {
            supabaseKey: 'YOUR_SUPABASE_KEY',
            supabaseUrl: 'YOUR_SUPABASE_URL',
          },
        },
      ]),
    }),
  ],
})
export class AppModule {}

Usage

First, inject the client into the module where you want to use it:

import { Module } from '@nestjs/common';
import { SupabaseModule } from 'nestjs-supabase-js';

@Module({
  imports: [
    SupabaseModule.injectClient(),
  ],
})
export class CatModule {}

Or, for a specific connection:

import { Module } from '@nestjs/common';
import { SupabaseModule } from 'nestjs-supabase-js';

@Module({
  imports: [
    SupabaseModule.injectClient('connection1', 'connection2'),
  ],
})
export class CatModule {}

Now you can use the Supabase client in any provider of your module:

import { SupabaseClient } from '@supabase/supabase-js';

export class CatService {
  constructor(private readonly supabaseClient: SupabaseClient) {}

  public doSomething(): void {

  }
}

Or, for a specific connection:

import { SupabaseClient } from '@supabase/supabase-js';
import { InjectSupabaseClient } from 'nestjs-supabase-js';

export class CatService {
  constructor(
    @InjectSupabaseClient('connection1') private readonly supabaseClient1: SupabaseClient,
    @InjectSupabaseClient('connection2') private readonly supabaseClient2: SupabaseClient,
  ) {}

  public doSomething(): void {

  }
}

It's also possible to use the InjectSupabaseClient decorator to inject the Supabase client when you don't want to explicitly type it with the client:

import { SupabaseClient } from '@supabase/supabase-js';
import { InjectSupabaseClient } from 'nestjs-supabase-js';

export class CatService {
  constructor(
    @InjectSupabaseClient() private readonly supabaseClient: unknown,
  ) {}

  public doSomething(): void {

  }
}

Authentication

This library provides a base guard to authenticate requests using the Supabase auth client.

Usage

To create your own guard that authenticates against Supabase, you just need to create a new guard that extends BaseSupabaseAuthGuard and implements the method extractTokenFromRequest. This implementation should define how to extract the token from the request, which might be in the headers, cookies, or query parameters.

import { Injectable, ExecutionContext } from '@nestjs/common';
import { SupabaseClient } from '@supabase/supabase-js';
import { BaseSupabaseAuthGuard } from 'nestjs-supabase-js';

@Injectable()
export class MyAuthGuard extends BaseSupabaseAuthGuard {
  public constructor(supabaseClient: SupabaseClient) {
    super(supabaseClient);
  }

  protected extractTokenFromRequest(request: Request): string | undefined {
    return request.headers.authorization;
  }
}

Then, you can bind the guard as described in the NestJS documentation.

🤝 Contributing contributions welcome

Contributions, issues and feature requests are welcome.

Authors

👤 Adrián Martínez Jiménez

See also the list of contributors who participated in this project.

Show Your Support

Please ⭐️ this repository if this project helped you!

📝 License

Copyright © 2024 Adrián Martínez Jiménez.

This project is licensed under the MIT License - see the LICENSE file for details.