@multitenantkit/adapter-persistence-supabase 0.2.8 → 0.2.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -10,6 +10,7 @@ Supabase persistence adapter for MultiTenantKit. Works in both **Node.js** and *
10
10
  - 🔄 Full CRUD operations for Users, Organizations, and OrganizationMemberships
11
11
  - 🎨 Custom fields support with column mapping
12
12
  - 📄 Pagination support
13
+ - 🔗 Unit of Work pattern support (non-transactional)
13
14
 
14
15
  ## Installation
15
16
 
@@ -17,65 +18,21 @@ Supabase persistence adapter for MultiTenantKit. Works in both **Node.js** and *
17
18
  npm install @multitenantkit/adapter-persistence-supabase @supabase/supabase-js
18
19
  ```
19
20
 
21
+ > 💡 **For a complete solution** including use cases and system adapters, use `@multitenantkit/sdk-supabase` instead. This package provides only the persistence layer (repositories).
22
+
20
23
  ## Usage
21
24
 
22
- ### Quick Start (Recommended)
25
+ ### Quick Start with SDK (Recommended)
26
+
27
+ For most users, we recommend using the complete Supabase SDK:
23
28
 
24
29
  ```typescript
25
- import {
26
- createSupabaseAdapters,
27
- createUseCases
28
- } from '@multitenantkit/adapter-persistence-supabase';
30
+ import { createSupabaseAdapters, createUseCases } from '@multitenantkit/sdk-supabase';
29
31
  import { createClient } from '@supabase/supabase-js';
30
32
 
31
- // Create Supabase client
32
- const client = createClient(
33
- process.env.SUPABASE_URL!,
34
- process.env.SUPABASE_SERVICE_ROLE_KEY!
35
- );
36
-
37
- // Create all adapters (persistence + system)
38
- const adapters = createSupabaseAdapters({ client });
39
-
40
- // Create use cases
41
- const useCases = createUseCases(adapters);
42
-
43
- // Use the API
44
- const result = await useCases.users.createUser.execute(
45
- { externalId: 'user-123', username: 'john@example.com' },
46
- { requestId: 'req-1', externalId: 'system' }
47
- );
48
- ```
49
-
50
- ### In Supabase Edge Functions (Deno)
51
-
52
- ```typescript
53
- // supabase/functions/api/index.ts
54
- import { createClient } from 'https://esm.sh/@supabase/supabase-js@2';
55
- import {
56
- createSupabaseAdapters,
57
- createUseCases
58
- } from 'https://esm.sh/@multitenantkit/adapter-persistence-supabase';
59
-
60
- Deno.serve(async (req) => {
61
- const client = createClient(
62
- Deno.env.get('SUPABASE_URL')!,
63
- Deno.env.get('SUPABASE_SERVICE_ROLE_KEY')!
64
- );
65
-
66
- const adapters = createSupabaseAdapters({ client });
67
- const useCases = createUseCases(adapters);
68
-
69
- // Handle requests...
70
- const user = await useCases.users.getUser.execute(
71
- { userId: 'user-123' },
72
- { requestId: 'req-1', externalId: 'system' }
73
- );
74
-
75
- return new Response(JSON.stringify(user), {
76
- headers: { 'Content-Type': 'application/json' }
77
- });
78
- });
33
+ const client = createClient(SUPABASE_URL, SUPABASE_SERVICE_ROLE_KEY);
34
+ const { adapters, toolkitOptions } = createSupabaseAdapters({ client });
35
+ const useCases = createUseCases(adapters, toolkitOptions);
79
36
  ```
80
37
 
81
38
  ### Using Repositories Directly
@@ -126,66 +83,88 @@ const repos = createSupabaseRepositories<UserCustomFields>({
126
83
  });
127
84
  ```
128
85
 
129
- ### Using Repositories Directly (Deno)
86
+ ### Using in Supabase Edge Functions (Deno)
87
+
88
+ For Edge Functions, use the complete SDK which handles Deno-specific setup:
130
89
 
131
90
  ```typescript
132
- // Alternative: use repositories directly without use cases
133
- import { createClient } from 'https://esm.sh/@supabase/supabase-js@2';
134
- import { SupabaseUserRepository } from 'https://esm.sh/@multitenantkit/adapter-persistence-supabase';
135
-
136
- Deno.serve(async (req) => {
137
- const client = createClient(
138
- Deno.env.get('SUPABASE_URL')!,
139
- Deno.env.get('SUPABASE_SERVICE_ROLE_KEY')!
140
- );
141
-
142
- const userRepo = new SupabaseUserRepository(client);
143
- const user = await userRepo.findByExternalId('user-123');
144
-
145
- return new Response(JSON.stringify(user), {
146
- headers: { 'Content-Type': 'application/json' }
147
- });
148
- });
91
+ // supabase/functions/api/index.ts
92
+ import { createSupabaseAdapters, createUseCases } from '@multitenantkit/sdk-supabase';
93
+ import { buildEdgeFunction } from '@multitenantkit/adapter-transport-supabase-edge';
94
+ import { createClient } from '@supabase/supabase-js';
95
+
96
+ const client = createClient(
97
+ Deno.env.get('SUPABASE_URL')!,
98
+ Deno.env.get('SUPABASE_SERVICE_ROLE_KEY')!
99
+ );
100
+
101
+ const { adapters, toolkitOptions } = createSupabaseAdapters({ client });
102
+ const useCases = createUseCases(adapters, toolkitOptions);
103
+ // ... build handlers and start server
104
+ ```
105
+
106
+ ### Using Repositories Directly (Advanced)
107
+
108
+ For advanced use cases where you only need the repositories:
109
+
110
+ ```typescript
111
+ import { createClient } from '@supabase/supabase-js';
112
+ import { SupabaseUserRepository } from '@multitenantkit/adapter-persistence-supabase';
113
+
114
+ const client = createClient(SUPABASE_URL, SUPABASE_SERVICE_ROLE_KEY);
115
+ const userRepo = new SupabaseUserRepository(client);
116
+ const user = await userRepo.findByExternalId('user-123');
149
117
  ```
150
118
 
151
119
  ## Database Schema
152
120
 
153
- This adapter expects the following tables in your Supabase database:
121
+ This adapter expects the following tables in your Supabase database.
154
122
 
155
- ### users
123
+ > 💡 For a complete migration script with indexes, triggers, and RLS policies, see the `000_full_setup.sql` file in the MultiTenantKit repository.
124
+
125
+ ### profiles (users)
126
+
127
+ By default, the SDK uses `public.profiles` instead of `auth.users` because `auth.users` is not accessible via PostgREST.
156
128
 
157
129
  ```sql
158
- create table users (
159
- id uuid primary key,
160
- external_id text unique not null,
130
+ create table public.profiles (
131
+ id uuid references auth.users(id) on delete cascade primary key,
132
+ external_id text not null,
161
133
  username text not null,
162
134
  created_at timestamptz not null default now(),
163
135
  updated_at timestamptz not null default now(),
164
- deleted_at timestamptz
136
+ deleted_at timestamptz,
137
+ -- Add your custom fields here
138
+ first_name text,
139
+ last_name text
165
140
  );
166
141
  ```
167
142
 
168
143
  ### organizations
169
144
 
170
145
  ```sql
171
- create table organizations (
172
- id uuid primary key,
173
- owner_user_id uuid references users(id),
146
+ create table public.organizations (
147
+ id uuid primary key default gen_random_uuid(),
148
+ owner_user_id uuid references public.profiles(id),
174
149
  created_at timestamptz not null default now(),
175
150
  updated_at timestamptz not null default now(),
176
- deleted_at timestamptz
151
+ archived_at timestamptz,
152
+ deleted_at timestamptz,
153
+ -- Add your custom fields here
154
+ name text not null,
155
+ slug text unique
177
156
  );
178
157
  ```
179
158
 
180
159
  ### organization_memberships
181
160
 
182
161
  ```sql
183
- create table organization_memberships (
184
- id uuid primary key,
185
- user_id uuid references users(id),
162
+ create table public.organization_memberships (
163
+ id uuid primary key default gen_random_uuid(),
164
+ user_id uuid references public.profiles(id),
186
165
  username text not null,
187
- organization_id uuid references organizations(id),
188
- role_code text not null check (role_code in ('owner', 'admin', 'member')),
166
+ organization_id uuid not null references public.organizations(id),
167
+ role_code text not null default 'member',
189
168
  invited_at timestamptz,
190
169
  joined_at timestamptz,
191
170
  left_at timestamptz,
@@ -213,6 +192,32 @@ Creates all repositories with shared configuration.
213
192
  - `SupabaseOrganizationRepository` - Organization CRUD operations
214
193
  - `SupabaseOrganizationMembershipRepository` - Membership CRUD operations
215
194
 
195
+ ### Unit of Work
196
+
197
+ - `SupabaseUnitOfWork` - Unit of Work pattern implementation
198
+
199
+ ## Unit of Work (Transaction Support)
200
+
201
+ This adapter includes a `SupabaseUnitOfWork` implementation that follows the Unit of Work pattern.
202
+
203
+ > ⚠️ **Important:** This is a **non-transactional** implementation. The Supabase JS client does not support native database transactions. Operations are executed sequentially without automatic rollback.
204
+
205
+ ```typescript
206
+ import { createSupabaseRepositories } from '@multitenantkit/adapter-persistence-supabase';
207
+
208
+ const { uow } = createSupabaseRepositories({ client });
209
+
210
+ // Operations run sequentially (no automatic rollback on failure)
211
+ await uow.transaction(async (repos) => {
212
+ await repos.organizations.insert(organization, context);
213
+ await repos.organizationMemberships.insert(membership, context);
214
+ });
215
+ ```
216
+
217
+ For true ACID transactions, consider:
218
+ - Using the PostgreSQL adapter with direct connection (`@multitenantkit/adapter-persistence-postgres`)
219
+ - Implementing RPC/stored procedures in Supabase
220
+
216
221
  ## Environment Variables
217
222
 
218
223
  | Variable | Description |
@@ -9,6 +9,7 @@ import type { SupabaseClient } from '@supabase/supabase-js';
9
9
  import { SupabaseOrganizationMembershipRepository } from '../repositories/SupabaseOrganizationMembershipRepository';
10
10
  import { SupabaseOrganizationRepository } from '../repositories/SupabaseOrganizationRepository';
11
11
  import { SupabaseUserRepository } from '../repositories/SupabaseUserRepository';
12
+ import { SupabaseUnitOfWork } from '../uow/SupabaseUnitOfWork';
12
13
  /**
13
14
  * Options for creating Supabase repositories
14
15
  */
@@ -22,6 +23,7 @@ export interface SupabaseFactoryOptions<TUserCustomFields, TOrganizationCustomFi
22
23
  * Bundle of Supabase repositories
23
24
  */
24
25
  export interface SupabaseRepositoryBundle<TUserCustomFields, TOrganizationCustomFields, TOrganizationMembershipCustomFields> {
26
+ uow: SupabaseUnitOfWork<TUserCustomFields, TOrganizationCustomFields, TOrganizationMembershipCustomFields>;
25
27
  userRepository: SupabaseUserRepository<TUserCustomFields>;
26
28
  organizationRepository: SupabaseOrganizationRepository<TOrganizationCustomFields>;
27
29
  organizationMembershipRepository: SupabaseOrganizationMembershipRepository<TUserCustomFields, TOrganizationCustomFields, TOrganizationMembershipCustomFields>;
@@ -1 +1 @@
1
- {"version":3,"file":"SupabaseFactory.d.ts","sourceRoot":"","sources":["../../src/factory/SupabaseFactory.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kCAAkC,CAAC;AACvE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,wCAAwC,EAAE,MAAM,0DAA0D,CAAC;AACpH,OAAO,EAAE,8BAA8B,EAAE,MAAM,gDAAgD,CAAC;AAChG,OAAO,EAAE,sBAAsB,EAAE,MAAM,wCAAwC,CAAC;AAEhF;;GAEG;AACH,MAAM,WAAW,sBAAsB,CACnC,iBAAiB,EACjB,yBAAyB,EACzB,mCAAmC;IAEnC,+BAA+B;IAC/B,MAAM,EAAE,cAAc,CAAC;IACvB,mEAAmE;IACnE,cAAc,CAAC,EAAE,cAAc,CAC3B,iBAAiB,EACjB,yBAAyB,EACzB,mCAAmC,CACtC,CAAC;CACL;AAED;;GAEG;AACH,MAAM,WAAW,wBAAwB,CACrC,iBAAiB,EACjB,yBAAyB,EACzB,mCAAmC;IAEnC,cAAc,EAAE,sBAAsB,CAAC,iBAAiB,CAAC,CAAC;IAC1D,sBAAsB,EAAE,8BAA8B,CAAC,yBAAyB,CAAC,CAAC;IAClF,gCAAgC,EAAE,wCAAwC,CACtE,iBAAiB,EACjB,yBAAyB,EACzB,mCAAmC,CACtC,CAAC;CACL;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,0BAA0B,CAEtC,iBAAiB,GAAG,EAAE,EAEtB,yBAAyB,GAAG,EAAE,EAE9B,mCAAmC,GAAG,EAAE,EAExC,OAAO,EAAE,sBAAsB,CAC3B,iBAAiB,EACjB,yBAAyB,EACzB,mCAAmC,CACtC,GACF,wBAAwB,CACvB,iBAAiB,EACjB,yBAAyB,EACzB,mCAAmC,CACtC,CAkBA"}
1
+ {"version":3,"file":"SupabaseFactory.d.ts","sourceRoot":"","sources":["../../src/factory/SupabaseFactory.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kCAAkC,CAAC;AACvE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,wCAAwC,EAAE,MAAM,0DAA0D,CAAC;AACpH,OAAO,EAAE,8BAA8B,EAAE,MAAM,gDAAgD,CAAC;AAChG,OAAO,EAAE,sBAAsB,EAAE,MAAM,wCAAwC,CAAC;AAChF,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAE/D;;GAEG;AACH,MAAM,WAAW,sBAAsB,CACnC,iBAAiB,EACjB,yBAAyB,EACzB,mCAAmC;IAEnC,+BAA+B;IAC/B,MAAM,EAAE,cAAc,CAAC;IACvB,mEAAmE;IACnE,cAAc,CAAC,EAAE,cAAc,CAC3B,iBAAiB,EACjB,yBAAyB,EACzB,mCAAmC,CACtC,CAAC;CACL;AAED;;GAEG;AACH,MAAM,WAAW,wBAAwB,CACrC,iBAAiB,EACjB,yBAAyB,EACzB,mCAAmC;IAEnC,GAAG,EAAE,kBAAkB,CACnB,iBAAiB,EACjB,yBAAyB,EACzB,mCAAmC,CACtC,CAAC;IACF,cAAc,EAAE,sBAAsB,CAAC,iBAAiB,CAAC,CAAC;IAC1D,sBAAsB,EAAE,8BAA8B,CAAC,yBAAyB,CAAC,CAAC;IAClF,gCAAgC,EAAE,wCAAwC,CACtE,iBAAiB,EACjB,yBAAyB,EACzB,mCAAmC,CACtC,CAAC;CACL;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,0BAA0B,CAEtC,iBAAiB,GAAG,EAAE,EAEtB,yBAAyB,GAAG,EAAE,EAE9B,mCAAmC,GAAG,EAAE,EAExC,OAAO,EAAE,sBAAsB,CAC3B,iBAAiB,EACjB,yBAAyB,EACzB,mCAAmC,CACtC,GACF,wBAAwB,CACvB,iBAAiB,EACjB,yBAAyB,EACzB,mCAAmC,CACtC,CAuBA"}
@@ -7,6 +7,7 @@
7
7
  import { SupabaseOrganizationMembershipRepository } from '../repositories/SupabaseOrganizationMembershipRepository';
8
8
  import { SupabaseOrganizationRepository } from '../repositories/SupabaseOrganizationRepository';
9
9
  import { SupabaseUserRepository } from '../repositories/SupabaseUserRepository';
10
+ import { SupabaseUnitOfWork } from '../uow/SupabaseUnitOfWork';
10
11
  /**
11
12
  * Create all Supabase repositories
12
13
  *
@@ -25,6 +26,7 @@ import { SupabaseUserRepository } from '../repositories/SupabaseUserRepository';
25
26
  export function createSupabaseRepositories(options) {
26
27
  const { client, toolkitOptions } = options;
27
28
  return {
29
+ uow: new SupabaseUnitOfWork(client, toolkitOptions),
28
30
  userRepository: new SupabaseUserRepository(client, toolkitOptions),
29
31
  organizationRepository: new SupabaseOrganizationRepository(client, toolkitOptions),
30
32
  organizationMembershipRepository: new SupabaseOrganizationMembershipRepository(client, toolkitOptions)
@@ -1 +1 @@
1
- {"version":3,"file":"SupabaseFactory.js","sourceRoot":"","sources":["../../src/factory/SupabaseFactory.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,EAAE,wCAAwC,EAAE,MAAM,0DAA0D,CAAC;AACpH,OAAO,EAAE,8BAA8B,EAAE,MAAM,gDAAgD,CAAC;AAChG,OAAO,EAAE,sBAAsB,EAAE,MAAM,wCAAwC,CAAC;AAqChF;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,0BAA0B,CAQtC,OAIC;IAMD,MAAM,EAAE,MAAM,EAAE,cAAc,EAAE,GAAG,OAAO,CAAC;IAE3C,OAAO;QACH,cAAc,EAAE,IAAI,sBAAsB,CACtC,MAAM,EACN,cAAqB,CACxB;QACD,sBAAsB,EAAE,IAAI,8BAA8B,CACtD,MAAM,EACN,cAAqB,CACxB;QACD,gCAAgC,EAAE,IAAI,wCAAwC,CAI5E,MAAM,EAAE,cAAc,CAAC;KAC5B,CAAC;AACN,CAAC"}
1
+ {"version":3,"file":"SupabaseFactory.js","sourceRoot":"","sources":["../../src/factory/SupabaseFactory.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,EAAE,wCAAwC,EAAE,MAAM,0DAA0D,CAAC;AACpH,OAAO,EAAE,8BAA8B,EAAE,MAAM,gDAAgD,CAAC;AAChG,OAAO,EAAE,sBAAsB,EAAE,MAAM,wCAAwC,CAAC;AAChF,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AA0C/D;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,0BAA0B,CAQtC,OAIC;IAMD,MAAM,EAAE,MAAM,EAAE,cAAc,EAAE,GAAG,OAAO,CAAC;IAE3C,OAAO;QACH,GAAG,EAAE,IAAI,kBAAkB,CAIzB,MAAM,EAAE,cAAc,CAAC;QACzB,cAAc,EAAE,IAAI,sBAAsB,CACtC,MAAM,EACN,cAAqB,CACxB;QACD,sBAAsB,EAAE,IAAI,8BAA8B,CACtD,MAAM,EACN,cAAqB,CACxB;QACD,gCAAgC,EAAE,IAAI,wCAAwC,CAI5E,MAAM,EAAE,cAAc,CAAC;KAC5B,CAAC;AACN,CAAC"}
package/dist/index.d.ts CHANGED
@@ -27,4 +27,5 @@ export { type UserDbRow, UserMapper } from './mappers/UserMapper';
27
27
  export { SupabaseOrganizationMembershipRepository } from './repositories/SupabaseOrganizationMembershipRepository';
28
28
  export { SupabaseOrganizationRepository } from './repositories/SupabaseOrganizationRepository';
29
29
  export { SupabaseUserRepository } from './repositories/SupabaseUserRepository';
30
+ export { SupabaseUnitOfWork } from './uow/SupabaseUnitOfWork';
30
31
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAGH,OAAO,EACH,oBAAoB,EACpB,oBAAoB,EACpB,KAAK,cAAc,EACnB,KAAK,cAAc,EACtB,MAAM,yBAAyB,CAAC;AAGjC,OAAO,EACH,0BAA0B,EAC1B,KAAK,sBAAsB,EAC3B,KAAK,wBAAwB,EAChC,MAAM,2BAA2B,CAAC;AAGnC,OAAO,EAAE,KAAK,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AAC1F,OAAO,EACH,KAAK,2BAA2B,EAChC,4BAA4B,EAC/B,MAAM,wCAAwC,CAAC;AAChD,OAAO,EAAE,KAAK,SAAS,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAGlE,OAAO,EAAE,wCAAwC,EAAE,MAAM,yDAAyD,CAAC;AACnH,OAAO,EAAE,8BAA8B,EAAE,MAAM,+CAA+C,CAAC;AAC/F,OAAO,EAAE,sBAAsB,EAAE,MAAM,uCAAuC,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAGH,OAAO,EACH,oBAAoB,EACpB,oBAAoB,EACpB,KAAK,cAAc,EACnB,KAAK,cAAc,EACtB,MAAM,yBAAyB,CAAC;AAGjC,OAAO,EACH,0BAA0B,EAC1B,KAAK,sBAAsB,EAC3B,KAAK,wBAAwB,EAChC,MAAM,2BAA2B,CAAC;AAGnC,OAAO,EAAE,KAAK,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AAC1F,OAAO,EACH,KAAK,2BAA2B,EAChC,4BAA4B,EAC/B,MAAM,wCAAwC,CAAC;AAChD,OAAO,EAAE,KAAK,SAAS,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAGlE,OAAO,EAAE,wCAAwC,EAAE,MAAM,yDAAyD,CAAC;AACnH,OAAO,EAAE,8BAA8B,EAAE,MAAM,+CAA+C,CAAC;AAC/F,OAAO,EAAE,sBAAsB,EAAE,MAAM,uCAAuC,CAAC;AAG/E,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC"}
package/dist/index.js CHANGED
@@ -31,4 +31,6 @@ export { UserMapper } from './mappers/UserMapper';
31
31
  export { SupabaseOrganizationMembershipRepository } from './repositories/SupabaseOrganizationMembershipRepository';
32
32
  export { SupabaseOrganizationRepository } from './repositories/SupabaseOrganizationRepository';
33
33
  export { SupabaseUserRepository } from './repositories/SupabaseUserRepository';
34
+ // Unit of Work
35
+ export { SupabaseUnitOfWork } from './uow/SupabaseUnitOfWork';
34
36
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,2BAA2B;AAC3B,OAAO,EACH,oBAAoB,EACpB,oBAAoB,EAGvB,MAAM,yBAAyB,CAAC;AAEjC,oBAAoB;AACpB,OAAO,EACH,0BAA0B,EAG7B,MAAM,2BAA2B,CAAC;AAEnC,UAAU;AACV,OAAO,EAA0B,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AAC1F,OAAO,EAEH,4BAA4B,EAC/B,MAAM,wCAAwC,CAAC;AAChD,OAAO,EAAkB,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAElE,eAAe;AACf,OAAO,EAAE,wCAAwC,EAAE,MAAM,yDAAyD,CAAC;AACnH,OAAO,EAAE,8BAA8B,EAAE,MAAM,+CAA+C,CAAC;AAC/F,OAAO,EAAE,sBAAsB,EAAE,MAAM,uCAAuC,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,2BAA2B;AAC3B,OAAO,EACH,oBAAoB,EACpB,oBAAoB,EAGvB,MAAM,yBAAyB,CAAC;AAEjC,oBAAoB;AACpB,OAAO,EACH,0BAA0B,EAG7B,MAAM,2BAA2B,CAAC;AAEnC,UAAU;AACV,OAAO,EAA0B,kBAAkB,EAAE,MAAM,8BAA8B,CAAC;AAC1F,OAAO,EAEH,4BAA4B,EAC/B,MAAM,wCAAwC,CAAC;AAChD,OAAO,EAAkB,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAElE,eAAe;AACf,OAAO,EAAE,wCAAwC,EAAE,MAAM,yDAAyD,CAAC;AACnH,OAAO,EAAE,8BAA8B,EAAE,MAAM,+CAA+C,CAAC;AAC/F,OAAO,EAAE,sBAAsB,EAAE,MAAM,uCAAuC,CAAC;AAE/E,eAAe;AACf,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC"}
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Supabase Unit of Work Implementation
3
+ *
4
+ * IMPORTANT: This is a non-transactional implementation.
5
+ * Supabase JS client does not support native database transactions.
6
+ * Operations are executed sequentially without automatic rollback.
7
+ *
8
+ * For true ACID transactions, consider:
9
+ * - Using PostgreSQL adapter with direct connection
10
+ * - Implementing RPC/stored procedures in Supabase
11
+ *
12
+ * This implementation allows the framework to function with Supabase
13
+ * while acknowledging the transactional limitations.
14
+ */
15
+ import type { RepositoryBundle, ToolkitOptions, UnitOfWork } from '@multitenantkit/domain-contracts';
16
+ import type { SupabaseClient } from '@supabase/supabase-js';
17
+ /**
18
+ * Supabase-based Unit of Work implementation
19
+ *
20
+ * NOTE: This is a non-transactional implementation that executes
21
+ * operations sequentially. If an operation fails mid-way, previous
22
+ * operations will NOT be rolled back automatically.
23
+ *
24
+ * Generic support for custom fields:
25
+ * @template TUserCustomFields - Custom fields for UserRepository
26
+ * @template TOrganizationCustomFields - Custom fields for OrganizationRepository
27
+ * @template TOrganizationMembershipCustomFields - Custom fields for OrganizationMembershipRepository
28
+ */
29
+ export declare class SupabaseUnitOfWork<TUserCustomFields = {}, TOrganizationCustomFields = {}, TOrganizationMembershipCustomFields = {}> implements UnitOfWork<TUserCustomFields, TOrganizationCustomFields, TOrganizationMembershipCustomFields> {
30
+ private readonly client;
31
+ private readonly toolkitOptions?;
32
+ constructor(client: SupabaseClient, toolkitOptions?: ToolkitOptions<TUserCustomFields, TOrganizationCustomFields, TOrganizationMembershipCustomFields> | undefined);
33
+ /**
34
+ * Execute work with repository bundle
35
+ *
36
+ * WARNING: This is NOT a true database transaction.
37
+ * Operations are executed sequentially without rollback capability.
38
+ * If an operation fails, previous operations will persist.
39
+ *
40
+ * @param work - Function containing the operations to execute
41
+ * @returns Result of the work function
42
+ */
43
+ transaction<T>(work: (repos: RepositoryBundle<TUserCustomFields, TOrganizationCustomFields, TOrganizationMembershipCustomFields>) => Promise<T>): Promise<T>;
44
+ }
45
+ //# sourceMappingURL=SupabaseUnitOfWork.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SupabaseUnitOfWork.d.ts","sourceRoot":"","sources":["../../src/uow/SupabaseUnitOfWork.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EACR,gBAAgB,EAChB,cAAc,EACd,UAAU,EACb,MAAM,kCAAkC,CAAC;AAC1C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAK5D;;;;;;;;;;;GAWG;AACH,qBAAa,kBAAkB,CAE3B,iBAAiB,GAAG,EAAE,EAEtB,yBAAyB,GAAG,EAAE,EAE9B,mCAAmC,GAAG,EAAE,CAC1C,YACM,UAAU,CACN,iBAAiB,EACjB,yBAAyB,EACzB,mCAAmC,CACtC;IAGD,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAC;gBADf,MAAM,EAAE,cAAc,EACtB,cAAc,CAAC,EAAE,cAAc,CAC5C,iBAAiB,EACjB,yBAAyB,EACzB,mCAAmC,CACtC,YAAA;IAGL;;;;;;;;;OASG;IACG,WAAW,CAAC,CAAC,EACf,IAAI,EAAE,CACF,KAAK,EAAE,gBAAgB,CACnB,iBAAiB,EACjB,yBAAyB,EACzB,mCAAmC,CACtC,KACA,OAAO,CAAC,CAAC,CAAC,GAChB,OAAO,CAAC,CAAC,CAAC;CAyBhB"}
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Supabase Unit of Work Implementation
3
+ *
4
+ * IMPORTANT: This is a non-transactional implementation.
5
+ * Supabase JS client does not support native database transactions.
6
+ * Operations are executed sequentially without automatic rollback.
7
+ *
8
+ * For true ACID transactions, consider:
9
+ * - Using PostgreSQL adapter with direct connection
10
+ * - Implementing RPC/stored procedures in Supabase
11
+ *
12
+ * This implementation allows the framework to function with Supabase
13
+ * while acknowledging the transactional limitations.
14
+ */
15
+ import { SupabaseOrganizationMembershipRepository } from '../repositories/SupabaseOrganizationMembershipRepository';
16
+ import { SupabaseOrganizationRepository } from '../repositories/SupabaseOrganizationRepository';
17
+ import { SupabaseUserRepository } from '../repositories/SupabaseUserRepository';
18
+ /**
19
+ * Supabase-based Unit of Work implementation
20
+ *
21
+ * NOTE: This is a non-transactional implementation that executes
22
+ * operations sequentially. If an operation fails mid-way, previous
23
+ * operations will NOT be rolled back automatically.
24
+ *
25
+ * Generic support for custom fields:
26
+ * @template TUserCustomFields - Custom fields for UserRepository
27
+ * @template TOrganizationCustomFields - Custom fields for OrganizationRepository
28
+ * @template TOrganizationMembershipCustomFields - Custom fields for OrganizationMembershipRepository
29
+ */
30
+ export class SupabaseUnitOfWork {
31
+ client;
32
+ toolkitOptions;
33
+ constructor(client, toolkitOptions) {
34
+ this.client = client;
35
+ this.toolkitOptions = toolkitOptions;
36
+ }
37
+ /**
38
+ * Execute work with repository bundle
39
+ *
40
+ * WARNING: This is NOT a true database transaction.
41
+ * Operations are executed sequentially without rollback capability.
42
+ * If an operation fails, previous operations will persist.
43
+ *
44
+ * @param work - Function containing the operations to execute
45
+ * @returns Result of the work function
46
+ */
47
+ async transaction(work) {
48
+ // Create repository bundle with the Supabase client
49
+ const repos = {
50
+ users: new SupabaseUserRepository(this.client, this.toolkitOptions),
51
+ organizations: new SupabaseOrganizationRepository(this.client, this.toolkitOptions),
52
+ organizationMemberships: new SupabaseOrganizationMembershipRepository(this.client, this.toolkitOptions)
53
+ };
54
+ // Execute the work (non-transactional)
55
+ return await work(repos);
56
+ }
57
+ }
58
+ //# sourceMappingURL=SupabaseUnitOfWork.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SupabaseUnitOfWork.js","sourceRoot":"","sources":["../../src/uow/SupabaseUnitOfWork.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAQH,OAAO,EAAE,wCAAwC,EAAE,MAAM,0DAA0D,CAAC;AACpH,OAAO,EAAE,8BAA8B,EAAE,MAAM,gDAAgD,CAAC;AAChG,OAAO,EAAE,sBAAsB,EAAE,MAAM,wCAAwC,CAAC;AAEhF;;;;;;;;;;;GAWG;AACH,MAAM,OAAO,kBAAkB;IAeN;IACA;IAFrB,YACqB,MAAsB,EACtB,cAIhB;QALgB,WAAM,GAAN,MAAM,CAAgB;QACtB,mBAAc,GAAd,cAAc,CAI9B;IACF,CAAC;IAEJ;;;;;;;;;OASG;IACH,KAAK,CAAC,WAAW,CACb,IAMe;QAEf,oDAAoD;QACpD,MAAM,KAAK,GAIP;YACA,KAAK,EAAE,IAAI,sBAAsB,CAC7B,IAAI,CAAC,MAAM,EACX,IAAI,CAAC,cAAqB,CAC7B;YACD,aAAa,EAAE,IAAI,8BAA8B,CAC7C,IAAI,CAAC,MAAM,EACX,IAAI,CAAC,cAAqB,CAC7B;YACD,uBAAuB,EAAE,IAAI,wCAAwC,CAInE,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,cAAc,CAAC;SACtC,CAAC;QAEF,uCAAuC;QACvC,OAAO,MAAM,IAAI,CAAC,KAAK,CAAC,CAAC;IAC7B,CAAC;CACJ"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@multitenantkit/adapter-persistence-supabase",
3
- "version": "0.2.8",
3
+ "version": "0.2.9",
4
4
  "type": "module",
5
5
  "description": "Supabase persistence adapter for MultiTenantKit - works in Node.js and Deno/Edge Functions",
6
6
  "keywords": [