supabase-integration v1.0.1
Supabase Integration
A comprehensive npm package to integrate Supabase with JavaScript, TypeScript, and React. This package provides ready-to-use services for authentication and basic CRUD operations on your Supabase database.
Features
- Authentication: Sign up, sign in, sign out, OAuth integration (e.g., Google, GitHub).
- Database Operations: Create, Read, Update, Delete (CRUD) operations on your Supabase tables.
- Call Postgres Functions: Execute stored procedures in your Supabase database.
Installation
npm install supabase-integration
Usage
Initialization
Before using the package, you need to initialize it with your Supabase project credentials. Replace 'https://your-supabase-url.supabase.co'
and 'your-anon-key'
with your actual Supabase URL and anonymous key.
// JavaScript or TypeScript
import SupabaseIntegration from "supabase-integration";
const supabase = new SupabaseIntegration({
supabaseUrl: "https://your-supabase-url.supabase.co",
supabaseKey: "your-anon-key",
});
// React (typically done in a separate file like supabaseClient.js or supabaseClient.ts)
import SupabaseIntegration from "supabase-integration";
const supabase = new SupabaseIntegration({
supabaseUrl: "https://your-supabase-url.supabase.co",
supabaseKey: "your-anon-key",
});
export default supabase;
JavaScript
Authentication
Sign Up
const { data, error } = await supabase.auth.signUp({
email: "user@example.com",
password: "securepassword",
});
if (error) {
console.error("Sign Up Error:", error.message);
} else {
console.log("Sign Up Success:", data);
}
Sign In
const { data, error } = await supabase.auth.signIn({
email: "user@example.com",
password: "securepassword",
});
if (error) {
console.error("Sign In Error:", error.message);
} else {
console.log("Sign In Success:", data);
}
Sign In with OAuth
const { data, error } = await supabase.auth.signInWithOAuth({
provider: "google", // e.g., 'google', 'github'
redirectTo: "https://your-app.com/welcome",
scopes: "openid email profile",
queryParams: { prompt: "consent" },
});
if (error) {
console.error("OAuth Sign In Error:", error.message);
} else {
console.log("OAuth Sign In Success:", data);
// The user will be redirected to the OAuth provider's sign-in page.
}
Sign Out
const { error } = await supabase.auth.signOut();
if (error) {
console.error("Sign Out Error:", error.message);
} else {
console.log("Sign Out Success");
}
CRUD Operations
Create (Insert)
const { data: insertData, error: insertError } =
await supabase.database.insertData(
"users",
{
email: "newuser@example.com",
name: "New User",
},
{ returnData: true }
);
if (insertError) {
console.error("Insert Error:", insertError.message);
} else {
console.log("Insert Success:", insertData);
}
Read (Fetch)
const { data: fetchData, error: fetchError } =
await supabase.database.fetchData("users", {
select: "id, email, name",
order: "id:asc",
limit: 10,
});
if (fetchError) {
console.error("Fetch Error:", fetchError.message);
} else {
console.log("Fetch Success:", fetchData);
}
Update
const { data: updateData, error: updateError } =
await supabase.database.updateData(
"users",
{ name: "Updated User" },
{ id: 1 },
{ returnData: true }
);
if (updateError) {
console.error("Update Error:", updateError.message);
} else {
console.log("Update Success:", updateData);
}
Delete
const { data: deleteData, error: deleteError } =
await supabase.database.deleteData("users", { id: 1 }, { returnData: true });
if (deleteError) {
console.error("Delete Error:", deleteError.message);
} else {
console.log("Delete Success:", deleteData);
}
Call a Postgres Function
const { data, error } = await supabase.database.callFunction(
"your_function_name",
{
arg1: "value1",
arg2: "value2",
}
);
if (error) {
console.error("Function Call Error:", error.message);
} else {
console.log("Function Call Success:", data);
}
TypeScript
Using the package with TypeScript provides enhanced type safety and IntelliSense support.
Initialization
import SupabaseIntegration from "supabase-integration";
interface SupabaseConfig {
supabaseUrl: string;
supabaseKey: string;
}
const config: SupabaseConfig = {
supabaseUrl: "https://your-supabase-url.supabase.co",
supabaseKey: "your-anon-key",
};
const supabase = new SupabaseIntegration(config);
Authentication
Sign Up
interface SignUpResponse {
data: {
user: {
id: string;
email: string;
// other user fields
};
session: any; // Define more specific types as needed
} | null;
error: any; // Define more specific error types as needed
}
const { data, error }: SignUpResponse = await supabase.auth.signUp({
email: "user@example.com",
password: "securepassword",
});
if (error) {
console.error("Sign Up Error:", error.message);
} else {
console.log("Sign Up Success:", data);
}
Sign In
interface SignInResponse {
data: {
session: any; // Define more specific types as needed
user: {
id: string;
email: string;
// other user fields
};
} | null;
error: any;
}
const { data, error }: SignInResponse = await supabase.auth.signIn({
email: "user@example.com",
password: "securepassword",
});
if (error) {
console.error("Sign In Error:", error.message);
} else {
console.log("Sign In Success:", data);
}
Sign In with OAuth
interface OAuthOptions {
provider: "google" | "github" | string;
redirectTo?: string;
scopes?: string;
queryParams?: Record<string, string>;
}
const oauthOptions: OAuthOptions = {
provider: "github",
redirectTo: "https://your-app.com/welcome",
};
const { data, error } = await supabase.auth.signInWithOAuth(oauthOptions);
if (error) {
console.error("OAuth Sign In Error:", error.message);
} else {
console.log("OAuth Sign In Success:", data);
}
Sign Out
const { error } = await supabase.auth.signOut();
if (error) {
console.error("Sign Out Error:", error.message);
} else {
console.log("Sign Out Success");
}
CRUD Operations
Create (Insert)
interface User {
id: string;
email: string;
name: string;
}
interface InsertResponse {
data: User[] | null;
error: any;
}
const { data: insertData, error: insertError }: InsertResponse =
await supabase.database.insertData(
"users",
{
email: "newuser@example.com",
name: "New User",
},
{ returnData: true }
);
if (insertError) {
console.error("Insert Error:", insertError.message);
} else {
console.log("Insert Success:", insertData);
}
Read (Fetch)
interface FetchResponse<T> {
data: T[] | null;
error: any;
}
interface User {
id: string;
email: string;
name: string;
}
const { data: fetchData, error: fetchError }: FetchResponse<User> =
await supabase.database.fetchData("users", {
select: "id, email, name",
order: "id:asc",
limit: 10,
});
if (fetchError) {
console.error("Fetch Error:", fetchError.message);
} else {
console.log("Fetch Success:", fetchData);
}
Update
interface UpdateResponse<T> {
data: T[] | null;
error: any;
}
interface User {
id: string;
email: string;
name: string;
}
const { data: updateData, error: updateError }: UpdateResponse<User> =
await supabase.database.updateData(
"users",
{ name: "Updated User" },
{ id: "1" },
{ returnData: true }
);
if (updateError) {
console.error("Update Error:", updateError.message);
} else {
console.log("Update Success:", updateData);
}
Delete
interface DeleteResponse<T> {
data: T[] | null;
error: any;
}
interface User {
id: string;
email: string;
name: string;
}
const { data: deleteData, error: deleteError }: DeleteResponse<User> =
await supabase.database.deleteData(
"users",
{ id: "1" },
{ returnData: true }
);
if (deleteError) {
console.error("Delete Error:", deleteError.message);
} else {
console.log("Delete Success:", deleteData);
}
Call a Postgres Function
interface FunctionResponse {
data: any;
error: any;
}
const { data, error }: FunctionResponse = await supabase.database.callFunction(
"your_function_name",
{
arg1: "value1",
arg2: "value2",
}
);
if (error) {
console.error("Function Call Error:", error.message);
} else {
console.log("Function Call Success:", data);
}
React
Integrating supabase-integration
with React allows you to manage authentication and CRUD operations seamlessly within your React components. Below are the steps and examples to help you get started.
1. Initialize Supabase in a Separate File
Create a file named supabaseClient.js
or supabaseClient.ts
in your project's src
directory.
// src/supabaseClient.js
import SupabaseIntegration from "supabase-integration";
const supabase = new SupabaseIntegration({
supabaseUrl: "https://your-supabase-url.supabase.co",
supabaseKey: "your-anon-key",
});
export default supabase;
2. Set Up a React Context (Optional but Recommended)
Using React Context allows you to provide the supabase
instance throughout your application without prop drilling.
// src/contexts/SupabaseContext.jsx
import React, { createContext, useContext, useState, useEffect } from "react";
import supabase from "../supabaseClient";
const SupabaseContext = createContext();
export const SupabaseProvider = ({ children }) => {
const [user, setUser] = useState(null);
useEffect(() => {
// Listen to authentication state changes
const unsubscribe = supabase.auth.onAuthStateChange((event, session) => {
setUser(session?.user || null);
});
// Fetch the current session
supabase.auth.fetchData().then(({ data }) => {
setUser(data?.user || null);
});
return () => {
unsubscribe();
};
}, []);
return (
<SupabaseContext.Provider value={{ supabase, user }}>
{children}
</SupabaseContext.Provider>
);
};
export const useSupabase = () => {
return useContext(SupabaseContext);
};
3. Wrap Your Application with the SupabaseProvider
// src/index.jsx
import React from "react";
import ReactDOM from "react-dom";
import App from "./App";
import { SupabaseProvider } from "./contexts/SupabaseContext";
ReactDOM.render(
<React.StrictMode>
<SupabaseProvider>
<App />
</SupabaseProvider>
</React.StrictMode>,
document.getElementById("root")
);
4. Use Supabase in Your Components
AuthButtons Component
// src/components/AuthButtons.jsx
import React from "react";
import { useSupabase } from "../contexts/SupabaseContext";
const AuthButtons = () => {
const { supabase } = useSupabase();
const handleGoogleSignIn = async () => {
const { data, error } = await supabase.auth.signInWithOAuth({
provider: "google",
redirectTo: "https://your-app.com/welcome",
});
if (error) {
console.error("OAuth Sign In Error:", error.message);
alert(`Sign in failed: ${error.message}`);
} else {
console.log("OAuth Sign In Success:", data);
// The user will be redirected to the OAuth provider's sign-in page.
}
};
const handleSignOut = async () => {
const { error } = await supabase.auth.signOut();
if (error) {
console.error("Sign Out Error:", error.message);
alert(`Sign out failed: ${error.message}`);
} else {
console.log("Sign Out Success");
}
};
return (
<div>
<button onClick={handleGoogleSignIn}>Sign In with Google</button>
<button onClick={handleSignOut}>Sign Out</button>
</div>
);
};
export default AuthButtons;
App Component
// src/App.jsx
import React from "react";
import { useSupabase } from "./contexts/SupabaseContext";
import AuthButtons from "./components/AuthButtons";
const App = () => {
const { user } = useSupabase();
return (
<div>
<h1>Supabase Integration Example</h1>
{user ? <p>Welcome, {user.email}</p> : <p>Please sign in</p>}
<AuthButtons />
</div>
);
};
export default App;
CRUD Operations Example
// src/components/UserList.jsx
import React, { useEffect, useState } from "react";
import { useSupabase } from "../contexts/SupabaseContext";
const UserList = () => {
const { supabase } = useSupabase();
const [users, setUsers] = useState([]);
const [error, setError] = useState(null);
useEffect(() => {
const fetchUsers = async () => {
const { data, error } = await supabase.database.fetchData("users", {
select: "id, email, name",
order: "id:asc",
limit: 10,
});
if (error) {
setError(error.message);
} else {
setUsers(data);
}
};
fetchUsers();
}, [supabase]);
if (error) {
return <p>Error fetching users: {error}</p>;
}
return (
<div>
<h2>User List</h2>
{users.length === 0 ? (
<p>No users found.</p>
) : (
<ul>
{users.map((user) => (
<li key={user.id}>
{user.email} - {user.name}
</li>
))}
</ul>
)}
</div>
);
};
export default UserList;
Configuration
This package does not rely on environment files (.env
). Instead, configuration values are passed directly through the SupabaseIntegration
constructor as shown in the initialization examples above.
Contributing
Contributions are welcome! Please open an issue or submit a pull request for any improvements or bug fixes.
License
Example Project Structure
After integrating with React, your project structure might look like this:
your-react-app/
├── src/
│ ├── components/
│ │ ├── AuthButtons.jsx
│ │ └── UserList.jsx
│ ├── contexts/
│ │ └── SupabaseContext.jsx
│ ├── supabaseClient.js
│ ├── App.jsx
│ └── index.jsx
├── package.json
├── tsconfig.json
├── README.md
└── .gitignore