Skip to content

Commit 1827b41

Browse files
supabase service snippet
1 parent 59c4021 commit 1827b41

File tree

5 files changed

+299
-0
lines changed

5 files changed

+299
-0
lines changed
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"author": "Sandro Maglione <sandro@sandromaglione.com>",
3+
"license": "MIT",
4+
"scripts": {
5+
"db-types": "supabase gen types typescript --project-id <project_id> --schema public > database/database.ts"
6+
},
7+
"devDependencies": {
8+
"typescript": "^5.6.3"
9+
},
10+
"dependencies": {
11+
"@supabase/supabase-js": "^2.46.1",
12+
"effect": "^3.10.8"
13+
}
14+
}

supabase-service-in-effect/pnpm-lock.yaml

Lines changed: 171 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import * as _Supabase from "@supabase/supabase-js";
2+
import { Config, Context, Data, Effect, Layer, Redacted } from "effect";
3+
import type { Database } from "./database"; // 👈 Generated types
4+
5+
interface SupabaseConfig {
6+
readonly url: string;
7+
readonly key: Redacted.Redacted;
8+
}
9+
10+
class SupabaseError extends Data.TaggedError("SupabaseError")<
11+
Readonly<{
12+
error: _Supabase.PostgrestError;
13+
}>
14+
> {}
15+
16+
const make = ({ key, url }: SupabaseConfig) =>
17+
Effect.gen(function* (_) {
18+
const client = yield* Effect.sync(() =>
19+
_Supabase.createClient<Database>(url, Redacted.value(key))
20+
);
21+
22+
const query = <A>(
23+
body: (
24+
_: typeof client
25+
) => PromiseLike<_Supabase.PostgrestSingleResponse<A>>
26+
) =>
27+
Effect.async<A, SupabaseError, never>((cb) => {
28+
body(client).then(({ data, error }) => {
29+
if (error) {
30+
cb(Effect.fail(new SupabaseError({ error })));
31+
} else {
32+
cb(Effect.succeed(data));
33+
}
34+
});
35+
});
36+
37+
return { query, client };
38+
});
39+
40+
export class Supabase extends Context.Tag("Supabase")<
41+
Supabase,
42+
Effect.Effect.Success<ReturnType<typeof make>>
43+
>() {
44+
static readonly Live = (config: Config.Config.Wrap<SupabaseConfig>) =>
45+
Config.unwrap(config).pipe(
46+
Effect.flatMap(make),
47+
Layer.effect(this),
48+
Layer.orDie
49+
);
50+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
export type Json =
2+
| string
3+
| number
4+
| boolean
5+
| null
6+
| { [key: string]: Json | undefined }
7+
| Json[];
8+
9+
export interface Database {
10+
public: {
11+
Tables: {
12+
user: {
13+
Row: {
14+
created_at: string;
15+
email: string;
16+
id: string;
17+
};
18+
Insert: {
19+
created_at?: string;
20+
email: string;
21+
id: string;
22+
};
23+
Update: {
24+
created_at?: string;
25+
email?: string;
26+
id?: string;
27+
};
28+
Relationships: [];
29+
};
30+
};
31+
Views: {
32+
[_ in never]: never;
33+
};
34+
Functions: {
35+
[_ in never]: never;
36+
};
37+
Enums: {
38+
[_ in never]: never;
39+
};
40+
CompositeTypes: {
41+
[_ in never]: never;
42+
};
43+
};
44+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
"compilerOptions": {
3+
"esModuleInterop": true,
4+
"skipLibCheck": true,
5+
"target": "es2022",
6+
"allowJs": true,
7+
"resolveJsonModule": true,
8+
"moduleDetection": "force",
9+
"isolatedModules": true,
10+
"verbatimModuleSyntax": true,
11+
"strict": true,
12+
"noUncheckedIndexedAccess": true,
13+
"noImplicitOverride": true,
14+
"module": "preserve",
15+
"noEmit": true,
16+
"lib": ["es2022"]
17+
},
18+
"include": ["**/*.ts", "**/*.tsx"],
19+
"exclude": ["node_modules"]
20+
}

0 commit comments

Comments
 (0)