supabase-ts

Make request to supabase using the power of fp-ts, io-ts, and parsing.

Usage no npm install needed!

<script type="module">
  import supabaseTs from 'https://cdn.skypack.dev/supabase-ts';
</script>

README

supabase-ts

GitHub: SandroMaglione Twitter: SandroMaglione

What happens when the type of the response from a supabase request is different from expected? We don't want our app to crash, do we?

Welcome supabase-ts!

Make request to supabase using the power of fp-ts, io-ts, and parsing.

Use supabase with Functional Programming and fp-ts.

Getting started

npm install supabase-ts

Extend your usual SupabaseClient using createClientIO from supabase-ts.

createClientIO accepts two generic types:

  • A union of string with the names of all the tables/views of your database. supabase-ts will enforce the correct table names, no more typos!
  • The default request error type
import { createClient } from '@supabase/supabase-js';
import { createClientIO } from 'supabase-ts';

// Enforce tables and views names
type SupabaseTable = 'table1' | 'table2';
type SupabaseView = 'view1' | 'view2';

// Define default request error type
type ErrorMessage = string;

const supabaseClient = createClient('URL', 'KEY');
export const supabase = createClientIO<SupabaseTable | SupabaseView, ErrorMessage>(supabaseClient);

Use the exported supabase client to perform requests:

  • requestListWithValidation: Perform a request to supabase and return a list of values.
  • requestSingleWithValidation: Perform a request to supabase and return a single value.

For every request you must provide an io-ts type used to validate the response from supabase. supabase-ts will make sure that the shape of the return data respects the defined schema from io-ts.

const schema = t.type({ name: t.string });
type Schema = t.TypeOf<typeof schema>;
const tableValidated = {
  name: 'table1', // Required to be `string` from `SupabaseTable | SupabaseView`!
  schema,
} as const; // Required to be `const` for type-safety

const responseList: TE.TaskEither<string, readonly Schema[]> =
  supabaseClientIO.requestListWithValidation(tableValidated)(
    (query) => query.select(),
    {
      // Handle all possible errors
      onNoDataError: () => '',
      onRequestError: () => '',
      onValidationError: () => '',
    }
  );

const responseSingle: TE.TaskEither<string, Schema> =
  supabaseClientIO.requestSingleWithValidation(tableValidated)(
    (query) => query.select(),
    {
      // Handle all possible errors
      onZeroData: () => '',
      onNoDataError: () => '',
      onRequestError: () => '',
      onValidationError: () => '',
    }
  );

📃 Versioning

  • v0.2.1 - 27 November 2021
  • v0.1.3 - 24 September 2021
  • v0.1.2 - 18 September 2021
  • v0.1.1 - 17 September 2021
  • v0.1.0 - 17 September 2021

😀 Support

Currently the best way to support me would be to follow me on my Twitter.

Another option (or Option) would be to buy me a coffee.

👀 License

MIT License, see the LICENSE.md file for details.